@@ -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
}
@@ -174,8 +205,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
174
205
// then the closure_def will never be used, and we should avoid generating a
175
206
// def-id for it.
176
207
if let Some ( body) = body {
177
- let closure_def =
178
- self . create_def ( closure_id, kw:: Empty , DefKind :: Closure , span) ;
208
+ let closure_def = self . create_def (
209
+ closure_id,
210
+ kw:: Empty ,
211
+ DefKind :: Closure ,
212
+ body. span . find_ancestor_in_same_ctxt ( span) . unwrap_or ( span) ,
213
+ span,
214
+ ) ;
179
215
self . with_parent ( closure_def, |this| this. visit_block ( body) ) ;
180
216
}
181
217
return ;
@@ -186,19 +222,27 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
186
222
}
187
223
188
224
fn visit_use_tree ( & mut self , use_tree : & ' a UseTree , id : NodeId , _nested : bool ) {
189
- 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 ) ;
190
228
visit:: walk_use_tree ( self , use_tree, id) ;
191
229
}
192
230
193
231
fn visit_foreign_item ( & mut self , fi : & ' a ForeignItem ) {
194
- let def_kind = match fi. kind {
195
- ForeignItemKind :: Static ( _, mt, _) => DefKind :: Static ( mt) ,
196
- ForeignItemKind :: Fn ( _) => DefKind :: Fn ,
197
- 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
+ }
198
242
ForeignItemKind :: MacCall ( _) => return self . visit_macro_invoc ( fi. id ) ,
199
243
} ;
200
244
201
- 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 ) ;
202
246
203
247
self . with_parent ( def, |this| visit:: walk_foreign_item ( this, fi) ) ;
204
248
}
@@ -207,13 +251,20 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
207
251
if v. is_placeholder {
208
252
return self . visit_macro_invoc ( v. id ) ;
209
253
}
210
- 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
+ ) ;
211
261
self . with_parent ( def, |this| {
212
262
if let Some ( ( ctor_kind, ctor_node_id) ) = CtorKind :: from_ast ( & v. data ) {
213
263
this. create_def (
214
264
ctor_node_id,
215
265
kw:: Empty ,
216
266
DefKind :: Ctor ( CtorOf :: Variant , ctor_kind) ,
267
+ this. resolver . tcx . def_span ( this. parent_def ) ,
217
268
v. span ,
218
269
) ;
219
270
}
@@ -240,7 +291,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
240
291
GenericParamKind :: Type { .. } => DefKind :: TyParam ,
241
292
GenericParamKind :: Const { .. } => DefKind :: ConstParam ,
242
293
} ;
243
- 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 ) ;
244
295
245
296
// impl-Trait can happen inside generic parameters, like
246
297
// ```
@@ -254,14 +305,19 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
254
305
}
255
306
256
307
fn visit_assoc_item ( & mut self , i : & ' a AssocItem , ctxt : visit:: AssocCtxt ) {
257
- let def_kind = match & i. kind {
258
- AssocItemKind :: Fn ( ..) => DefKind :: AssocFn ,
259
- AssocItemKind :: Const ( ..) => DefKind :: AssocConst ,
260
- 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
+ } ) ,
261
317
AssocItemKind :: MacCall ( ..) => return self . visit_macro_invoc ( i. id ) ,
262
318
} ;
263
319
264
- 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 ) ;
265
321
self . with_parent ( def, |this| visit:: walk_assoc_item ( this, i, ctxt) ) ;
266
322
}
267
323
@@ -273,7 +329,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
273
329
}
274
330
275
331
fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
276
- 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
+ ) ;
277
339
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
278
340
}
279
341
@@ -283,24 +345,38 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
283
345
ExprKind :: Closure ( ref closure) => {
284
346
// Async closures desugar to closures inside of closures, so
285
347
// we must create two defs.
286
- 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 ) ;
287
352
match closure. coro_kind {
288
353
Some (
289
354
CoroutineKind :: Async { closure_id, .. }
290
355
| CoroutineKind :: Gen { closure_id, .. } ,
291
- ) => self . create_def ( closure_id, kw:: Empty , DefKind :: Closure , expr. span ) ,
356
+ ) => self . create_def (
357
+ closure_id,
358
+ kw:: Empty ,
359
+ DefKind :: Closure ,
360
+ closure
361
+ . body
362
+ . span
363
+ . find_ancestor_in_same_ctxt ( expr. span )
364
+ . unwrap_or ( expr. span ) ,
365
+ expr. span ,
366
+ ) ,
292
367
None => closure_def,
293
368
}
294
369
}
295
370
ExprKind :: Gen ( _, _, _) => {
296
- self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span )
371
+ self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span , expr . span )
297
372
}
298
373
ExprKind :: ConstBlock ( ref constant) => {
299
374
let def = self . create_def (
300
375
constant. id ,
301
376
kw:: Empty ,
302
377
DefKind :: InlineConst ,
303
378
constant. value . span ,
379
+ constant. value . span ,
304
380
) ;
305
381
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
306
382
return ;
0 commit comments