@@ -24,6 +24,43 @@ crate enum LinkFromSrc {
24
24
External ( DefId ) ,
25
25
}
26
26
27
+ /// This struct is used only as index in the `span_map`, not as [`Span`]! `Span`s contain
28
+ /// some extra information (the syntax context) we don't need. **Do not convert this type back to
29
+ /// `Span`!!!**
30
+ #[ derive( Clone , Copy , Hash , PartialEq , Eq , Debug ) ]
31
+ crate struct LightSpan {
32
+ crate lo : u32 ,
33
+ crate hi : u32 ,
34
+ }
35
+
36
+ impl LightSpan {
37
+ /// Before explaining what this method does, some global explanations on rust's `Span`:
38
+ ///
39
+ /// Each source code file is stored in the source map in the compiler and has a
40
+ /// `lo` and a `hi` (lowest and highest bytes in this source map which can be seen as one huge
41
+ /// string to simplify things). So in this case, this represents the starting byte of the
42
+ /// current file. It'll be used later on to retrieve the "definition span" from the
43
+ /// `span_correspondance_map` (which is inside `context`).
44
+ ///
45
+ /// This when we transform the "span" we have from reading the input into a "span" which can be
46
+ /// used as index to the `span_correspondance_map` to get the definition of this item.
47
+ ///
48
+ /// So in here, `file_span_lo` is representing the "lo" byte in the global source map, and to
49
+ /// make our "span" works in there, we simply add `file_span_lo` to our values.
50
+ crate fn new_in_file ( file_span_lo : u32 , lo : u32 , hi : u32 ) -> Self {
51
+ Self { lo : lo + file_span_lo, hi : hi + file_span_lo }
52
+ }
53
+
54
+ crate fn empty ( ) -> Self {
55
+ Self { lo : 0 , hi : 0 }
56
+ }
57
+
58
+ /// Extra the `lo` and `hi` from the [`Span`] and discard the unused syntax context.
59
+ fn new_from_span ( sp : Span ) -> Self {
60
+ Self { lo : sp. lo ( ) . 0 , hi : sp. hi ( ) . 0 }
61
+ }
62
+ }
63
+
27
64
/// This function will do at most two things:
28
65
///
29
66
/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
@@ -40,7 +77,7 @@ crate fn collect_spans_and_sources(
40
77
src_root : & Path ,
41
78
include_sources : bool ,
42
79
generate_link_to_definition : bool ,
43
- ) -> ( clean:: Crate , FxHashMap < PathBuf , String > , FxHashMap < ( u32 , u32 ) , LinkFromSrc > ) {
80
+ ) -> ( clean:: Crate , FxHashMap < PathBuf , String > , FxHashMap < LightSpan , LinkFromSrc > ) {
44
81
let mut visitor = SpanMapVisitor { tcx, matches : FxHashMap :: default ( ) } ;
45
82
46
83
if include_sources {
@@ -54,13 +91,9 @@ crate fn collect_spans_and_sources(
54
91
}
55
92
}
56
93
57
- fn span_to_tuple ( span : Span ) -> ( u32 , u32 ) {
58
- ( span. lo ( ) . 0 , span. hi ( ) . 0 )
59
- }
60
-
61
94
struct SpanMapVisitor < ' tcx > {
62
95
crate tcx : TyCtxt < ' tcx > ,
63
- crate matches : FxHashMap < ( u32 , u32 ) , LinkFromSrc > ,
96
+ crate matches : FxHashMap < LightSpan , LinkFromSrc > ,
64
97
}
65
98
66
99
impl < ' tcx > SpanMapVisitor < ' tcx > {
@@ -77,12 +110,16 @@ impl<'tcx> SpanMapVisitor<'tcx> {
77
110
} ;
78
111
if let Some ( span) = self . tcx . hir ( ) . res_span ( path. res ) {
79
112
self . matches . insert (
80
- path_span. map ( span_to_tuple) . unwrap_or_else ( || span_to_tuple ( path. span ) ) ,
113
+ path_span
114
+ . map ( LightSpan :: new_from_span)
115
+ . unwrap_or_else ( || LightSpan :: new_from_span ( path. span ) ) ,
81
116
LinkFromSrc :: Local ( span) ,
82
117
) ;
83
118
} else if let Some ( def_id) = info {
84
119
self . matches . insert (
85
- path_span. map ( span_to_tuple) . unwrap_or_else ( || span_to_tuple ( path. span ) ) ,
120
+ path_span
121
+ . map ( LightSpan :: new_from_span)
122
+ . unwrap_or_else ( || LightSpan :: new_from_span ( path. span ) ) ,
86
123
LinkFromSrc :: External ( def_id) ,
87
124
) ;
88
125
}
@@ -122,8 +159,10 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
122
159
if let Some ( node) = self . tcx . hir ( ) . find ( id) {
123
160
match node {
124
161
Node :: Item ( item) => {
125
- self . matches
126
- . insert ( span_to_tuple ( item. ident . span ) , LinkFromSrc :: Local ( m. inner ) ) ;
162
+ self . matches . insert (
163
+ LightSpan :: new_from_span ( item. ident . span ) ,
164
+ LinkFromSrc :: Local ( m. inner ) ,
165
+ ) ;
127
166
}
128
167
_ => { }
129
168
}
@@ -146,12 +185,14 @@ impl Visitor<'tcx> for SpanMapVisitor<'tcx> {
146
185
if let Some ( def_id) = typeck_results. type_dependent_def_id ( expr. hir_id ) {
147
186
match hir. span_if_local ( def_id) {
148
187
Some ( span) => {
149
- self . matches
150
- . insert ( span_to_tuple ( method_span) , LinkFromSrc :: Local ( span) ) ;
188
+ self . matches . insert (
189
+ LightSpan :: new_from_span ( method_span) ,
190
+ LinkFromSrc :: Local ( span) ,
191
+ ) ;
151
192
}
152
193
None => {
153
194
self . matches . insert (
154
- span_to_tuple ( method_span) ,
195
+ LightSpan :: new_from_span ( method_span) ,
155
196
LinkFromSrc :: External ( def_id) ,
156
197
) ;
157
198
}
0 commit comments