@@ -4,6 +4,7 @@ use rustc_ast::*;
4
4
use rustc_expand:: expand:: AstFragment ;
5
5
use rustc_hir:: def:: { CtorKind , CtorOf , DefKind } ;
6
6
use rustc_hir:: def_id:: LocalDefId ;
7
+ use rustc_middle:: hir:: map:: { named_span, until_within} ;
7
8
use rustc_span:: hygiene:: LocalExpnId ;
8
9
use rustc_span:: symbol:: { kw, sym, Symbol } ;
9
10
use rustc_span:: Span ;
@@ -31,18 +32,20 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
31
32
node_id : NodeId ,
32
33
name : Symbol ,
33
34
def_kind : DefKind ,
35
+ def_span : Span ,
34
36
span : Span ,
35
37
) -> LocalDefId {
36
38
let parent_def = self . parent_def ;
37
39
debug ! (
38
- "create_def(node_id={:?}, def_kind={:?}, parent_def={:?})" ,
39
- node_id, def_kind, parent_def
40
+ "create_def(node_id={:?}, def_kind={:?}, parent_def={:?}, def_span={:?} )" ,
41
+ node_id, def_kind, parent_def, def_span
40
42
) ;
41
43
self . resolver . create_def (
42
44
parent_def,
43
45
node_id,
44
46
name,
45
47
def_kind,
48
+ def_span,
46
49
self . expansion . to_expn_id ( ) ,
47
50
span. with_parent ( None ) ,
48
51
)
@@ -78,7 +81,7 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
78
81
self . visit_macro_invoc ( field. id ) ;
79
82
} else {
80
83
let name = field. ident . map_or_else ( || sym:: integer ( index ( self ) ) , |ident| ident. name ) ;
81
- let def = self . create_def ( field. id , name, DefKind :: Field , field. span ) ;
84
+ let def = self . create_def ( field. id , name, DefKind :: Field , field. span , field . span ) ;
82
85
self . with_parent ( def, |this| visit:: walk_field_def ( this, field) ) ;
83
86
}
84
87
}
@@ -91,6 +94,33 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
91
94
}
92
95
}
93
96
97
+ fn def_span_for_item ( i : & Item ) -> Span {
98
+ match & i. kind {
99
+ ItemKind :: ForeignMod ( _) => i. span ,
100
+ ItemKind :: GlobalAsm ( _) => i. span ,
101
+ ItemKind :: Fn ( f) => f. sig . span . find_ancestor_in_same_ctxt ( i. span ) . unwrap_or ( i. span ) ,
102
+ ItemKind :: Static ( s) => until_within ( i. span , s. ty . span ) ,
103
+ ItemKind :: Const ( c) => until_within ( i. span , c. ty . span ) ,
104
+ ItemKind :: Impl ( im) => until_within ( i. span , im. generics . where_clause . span ) ,
105
+ ItemKind :: MacroDef ( _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
106
+ ItemKind :: Mod ( _, _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
107
+ ItemKind :: TyAlias ( _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
108
+ ItemKind :: TraitAlias ( _, _) => {
109
+ named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) )
110
+ }
111
+ ItemKind :: ExternCrate ( _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
112
+ ItemKind :: Union ( _, _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
113
+ ItemKind :: Enum ( ..) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
114
+ ItemKind :: Struct ( ..) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
115
+ ItemKind :: Trait ( t) => {
116
+ let end = if let Some ( b) = t. bounds . last ( ) { b. span ( ) } else { t. generics . span } ;
117
+ until_within ( i. span , end)
118
+ }
119
+ ItemKind :: Use ( _) => unreachable ! ( ) ,
120
+ ItemKind :: MacCall ( _) => unreachable ! ( ) ,
121
+ }
122
+ }
123
+
94
124
impl < ' a , ' b , ' tcx > visit:: Visitor < ' a > for DefCollector < ' a , ' b , ' tcx > {
95
125
fn visit_item ( & mut self , i : & ' a Item ) {
96
126
debug ! ( "visit_item: {:?}" , i) ;
@@ -127,7 +157,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
127
157
return visit:: walk_item ( self , i) ;
128
158
}
129
159
} ;
130
- let def_id = self . create_def ( i. id , i. ident . name , def_kind, i. span ) ;
160
+ let def_id = self . create_def ( i. id , i. ident . name , def_kind, def_span_for_item ( i ) , i. span ) ;
131
161
132
162
if let Some ( macro_data) = opt_macro_data {
133
163
self . resolver . macro_map . insert ( def_id. to_def_id ( ) , macro_data) ;
@@ -143,6 +173,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
143
173
ctor_node_id,
144
174
kw:: Empty ,
145
175
DefKind :: Ctor ( CtorOf :: Struct , ctor_kind) ,
176
+ this. resolver . tcx . def_span ( this. parent_def ) ,
146
177
i. span ,
147
178
) ;
148
179
}
@@ -176,6 +207,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
176
207
coroutine_kind. closure_id ( ) ,
177
208
kw:: Empty ,
178
209
DefKind :: Closure ,
210
+ body. span . find_ancestor_in_same_ctxt ( span) . unwrap_or ( span) ,
179
211
span,
180
212
) ;
181
213
self . with_parent ( closure_def, |this| this. visit_block ( body) ) ;
@@ -190,19 +222,27 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
190
222
}
191
223
192
224
fn visit_use_tree ( & mut self , use_tree : & ' a UseTree , id : NodeId , _nested : bool ) {
193
- self . create_def ( id, kw:: Empty , DefKind :: Use , use_tree. span ) ;
225
+ let def_span =
226
+ use_tree. prefix . span . find_ancestor_in_same_ctxt ( use_tree. span ) . unwrap_or ( use_tree. span ) ;
227
+ self . create_def ( id, kw:: Empty , DefKind :: Use , def_span, use_tree. span ) ;
194
228
visit:: walk_use_tree ( self , use_tree, id) ;
195
229
}
196
230
197
231
fn visit_foreign_item ( & mut self , fi : & ' a ForeignItem ) {
198
- let def_kind = match fi. kind {
199
- ForeignItemKind :: Static ( _, mt, _) => DefKind :: Static ( mt) ,
200
- ForeignItemKind :: Fn ( _) => DefKind :: Fn ,
201
- ForeignItemKind :: TyAlias ( _) => DefKind :: ForeignTy ,
232
+ let ( def_kind, def_span) = match & fi. kind {
233
+ ForeignItemKind :: Static ( ty, mt, _) => {
234
+ ( DefKind :: Static ( * mt) , until_within ( fi. span , ty. span ) )
235
+ }
236
+ ForeignItemKind :: Fn ( f) => {
237
+ ( DefKind :: Fn , until_within ( fi. span , f. sig . decl . output . span ( ) ) )
238
+ }
239
+ ForeignItemKind :: TyAlias ( _) => {
240
+ ( DefKind :: ForeignTy , named_span ( fi. span , fi. ident , None ) )
241
+ }
202
242
ForeignItemKind :: MacCall ( _) => return self . visit_macro_invoc ( fi. id ) ,
203
243
} ;
204
244
205
- let def = self . create_def ( fi. id , fi. ident . name , def_kind, fi. span ) ;
245
+ let def = self . create_def ( fi. id , fi. ident . name , def_kind, def_span , fi. span ) ;
206
246
207
247
self . with_parent ( def, |this| visit:: walk_foreign_item ( this, fi) ) ;
208
248
}
@@ -211,13 +251,20 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
211
251
if v. is_placeholder {
212
252
return self . visit_macro_invoc ( v. id ) ;
213
253
}
214
- let def = self . create_def ( v. id , v. ident . name , DefKind :: Variant , v. span ) ;
254
+ let def = self . create_def (
255
+ v. id ,
256
+ v. ident . name ,
257
+ DefKind :: Variant ,
258
+ named_span ( v. span , v. ident , None ) ,
259
+ v. span ,
260
+ ) ;
215
261
self . with_parent ( def, |this| {
216
262
if let Some ( ( ctor_kind, ctor_node_id) ) = CtorKind :: from_ast ( & v. data ) {
217
263
this. create_def (
218
264
ctor_node_id,
219
265
kw:: Empty ,
220
266
DefKind :: Ctor ( CtorOf :: Variant , ctor_kind) ,
267
+ this. resolver . tcx . def_span ( this. parent_def ) ,
221
268
v. span ,
222
269
) ;
223
270
}
@@ -244,7 +291,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
244
291
GenericParamKind :: Type { .. } => DefKind :: TyParam ,
245
292
GenericParamKind :: Const { .. } => DefKind :: ConstParam ,
246
293
} ;
247
- self . create_def ( param. id , param. ident . name , def_kind, param. ident . span ) ;
294
+ self . create_def ( param. id , param. ident . name , def_kind, param. span ( ) , param . ident . span ) ;
248
295
249
296
// impl-Trait can happen inside generic parameters, like
250
297
// ```
@@ -258,14 +305,19 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
258
305
}
259
306
260
307
fn visit_assoc_item ( & mut self , i : & ' a AssocItem , ctxt : visit:: AssocCtxt ) {
261
- let def_kind = match & i. kind {
262
- AssocItemKind :: Fn ( ..) => DefKind :: AssocFn ,
263
- AssocItemKind :: Const ( ..) => DefKind :: AssocConst ,
264
- AssocItemKind :: Type ( ..) => DefKind :: AssocTy ,
308
+ let ( def_kind, def_span) = match & i. kind {
309
+ AssocItemKind :: Fn ( f) => {
310
+ ( DefKind :: AssocFn , f. sig . span . find_ancestor_in_same_ctxt ( i. span ) . unwrap_or ( i. span ) )
311
+ }
312
+ AssocItemKind :: Const ( c) => ( DefKind :: AssocConst , until_within ( i. span , c. ty . span ) ) ,
313
+ AssocItemKind :: Type ( ty) => ( DefKind :: AssocTy , {
314
+ let end = if let Some ( b) = ty. bounds . last ( ) { b. span ( ) } else { ty. generics . span } ;
315
+ until_within ( i. span , end)
316
+ } ) ,
265
317
AssocItemKind :: MacCall ( ..) => return self . visit_macro_invoc ( i. id ) ,
266
318
} ;
267
319
268
- let def = self . create_def ( i. id , i. ident . name , def_kind, i. span ) ;
320
+ let def = self . create_def ( i. id , i. ident . name , def_kind, def_span , i. span ) ;
269
321
self . with_parent ( def, |this| visit:: walk_assoc_item ( this, i, ctxt) ) ;
270
322
}
271
323
@@ -277,7 +329,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
277
329
}
278
330
279
331
fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
280
- let def = self . create_def ( constant. id , kw:: Empty , DefKind :: AnonConst , constant. value . span ) ;
332
+ let def = self . create_def (
333
+ constant. id ,
334
+ kw:: Empty ,
335
+ DefKind :: AnonConst ,
336
+ constant. value . span ,
337
+ constant. value . span ,
338
+ ) ;
281
339
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
282
340
}
283
341
@@ -287,26 +345,35 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
287
345
ExprKind :: Closure ( ref closure) => {
288
346
// Async closures desugar to closures inside of closures, so
289
347
// we must create two defs.
290
- let closure_def = self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span ) ;
348
+ let def_span =
349
+ closure. fn_decl_span . find_ancestor_inside ( expr. span ) . unwrap_or ( expr. span ) ;
350
+ let closure_def =
351
+ self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , def_span, expr. span ) ;
291
352
match closure. coroutine_kind {
292
353
Some ( coroutine_kind) => self . create_def (
293
354
coroutine_kind. closure_id ( ) ,
294
355
kw:: Empty ,
295
356
DefKind :: Closure ,
357
+ closure
358
+ . body
359
+ . span
360
+ . find_ancestor_in_same_ctxt ( expr. span )
361
+ . unwrap_or ( expr. span ) ,
296
362
expr. span ,
297
363
) ,
298
364
None => closure_def,
299
365
}
300
366
}
301
367
ExprKind :: Gen ( _, _, _) => {
302
- self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span )
368
+ self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span , expr . span )
303
369
}
304
370
ExprKind :: ConstBlock ( ref constant) => {
305
371
let def = self . create_def (
306
372
constant. id ,
307
373
kw:: Empty ,
308
374
DefKind :: InlineConst ,
309
375
constant. value . span ,
376
+ constant. value . span ,
310
377
) ;
311
378
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
312
379
return ;
0 commit comments