@@ -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 :: ExternCrate ( _) => i. span ,
100
+ ItemKind :: ForeignMod ( _) => i. span ,
101
+ ItemKind :: GlobalAsm ( _) => i. span ,
102
+ ItemKind :: Fn ( f) => f. sig . span . find_ancestor_in_same_ctxt ( i. span ) . unwrap_or ( i. span ) ,
103
+ ItemKind :: Static ( s) => until_within ( i. span , s. ty . span ) ,
104
+ ItemKind :: Const ( c) => until_within ( i. span , c. ty . span ) ,
105
+ ItemKind :: Impl ( im) => until_within ( i. span , im. generics . where_clause . span ) ,
106
+ ItemKind :: MacroDef ( _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
107
+ ItemKind :: Mod ( _, _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
108
+ ItemKind :: TyAlias ( _) => named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) ) ,
109
+ ItemKind :: TraitAlias ( _, _) => {
110
+ named_span ( i. span , i. ident , i. kind . generics ( ) . map ( |g| g. span ) )
111
+ }
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
}
@@ -171,8 +202,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
171
202
// then the closure_def will never be used, and we should avoid generating a
172
203
// def-id for it.
173
204
if let Some ( body) = body {
174
- let closure_def =
175
- self . create_def ( closure_id, kw:: Empty , DefKind :: Closure , span) ;
205
+ let closure_def = self . create_def (
206
+ closure_id,
207
+ kw:: Empty ,
208
+ DefKind :: Closure ,
209
+ body. span . find_ancestor_in_same_ctxt ( span) . unwrap_or ( span) ,
210
+ span,
211
+ ) ;
176
212
self . with_parent ( closure_def, |this| this. visit_block ( body) ) ;
177
213
}
178
214
return ;
@@ -183,19 +219,27 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
183
219
}
184
220
185
221
fn visit_use_tree ( & mut self , use_tree : & ' a UseTree , id : NodeId , _nested : bool ) {
186
- self . create_def ( id, kw:: Empty , DefKind :: Use , use_tree. span ) ;
222
+ let def_span =
223
+ use_tree. prefix . span . find_ancestor_in_same_ctxt ( use_tree. span ) . unwrap_or ( use_tree. span ) ;
224
+ self . create_def ( id, kw:: Empty , DefKind :: Use , def_span, use_tree. span ) ;
187
225
visit:: walk_use_tree ( self , use_tree, id) ;
188
226
}
189
227
190
228
fn visit_foreign_item ( & mut self , fi : & ' a ForeignItem ) {
191
- let def_kind = match fi. kind {
192
- ForeignItemKind :: Static ( _, mt, _) => DefKind :: Static ( mt) ,
193
- ForeignItemKind :: Fn ( _) => DefKind :: Fn ,
194
- ForeignItemKind :: TyAlias ( _) => DefKind :: ForeignTy ,
229
+ let ( def_kind, def_span) = match & fi. kind {
230
+ ForeignItemKind :: Static ( ty, mt, _) => {
231
+ ( DefKind :: Static ( * mt) , until_within ( fi. span , ty. span ) )
232
+ }
233
+ ForeignItemKind :: Fn ( f) => {
234
+ ( DefKind :: Fn , until_within ( fi. span , f. sig . decl . output . span ( ) ) )
235
+ }
236
+ ForeignItemKind :: TyAlias ( _) => {
237
+ ( DefKind :: ForeignTy , named_span ( fi. span , fi. ident , None ) )
238
+ }
195
239
ForeignItemKind :: MacCall ( _) => return self . visit_macro_invoc ( fi. id ) ,
196
240
} ;
197
241
198
- let def = self . create_def ( fi. id , fi. ident . name , def_kind, fi. span ) ;
242
+ let def = self . create_def ( fi. id , fi. ident . name , def_kind, def_span , fi. span ) ;
199
243
200
244
self . with_parent ( def, |this| visit:: walk_foreign_item ( this, fi) ) ;
201
245
}
@@ -204,13 +248,20 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
204
248
if v. is_placeholder {
205
249
return self . visit_macro_invoc ( v. id ) ;
206
250
}
207
- let def = self . create_def ( v. id , v. ident . name , DefKind :: Variant , v. span ) ;
251
+ let def = self . create_def (
252
+ v. id ,
253
+ v. ident . name ,
254
+ DefKind :: Variant ,
255
+ named_span ( v. span , v. ident , None ) ,
256
+ v. span ,
257
+ ) ;
208
258
self . with_parent ( def, |this| {
209
259
if let Some ( ( ctor_kind, ctor_node_id) ) = CtorKind :: from_ast ( & v. data ) {
210
260
this. create_def (
211
261
ctor_node_id,
212
262
kw:: Empty ,
213
263
DefKind :: Ctor ( CtorOf :: Variant , ctor_kind) ,
264
+ this. resolver . tcx . def_span ( this. parent_def ) ,
214
265
v. span ,
215
266
) ;
216
267
}
@@ -237,7 +288,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
237
288
GenericParamKind :: Type { .. } => DefKind :: TyParam ,
238
289
GenericParamKind :: Const { .. } => DefKind :: ConstParam ,
239
290
} ;
240
- self . create_def ( param. id , param. ident . name , def_kind, param. ident . span ) ;
291
+ self . create_def ( param. id , param. ident . name , def_kind, param. span ( ) , param . ident . span ) ;
241
292
242
293
// impl-Trait can happen inside generic parameters, like
243
294
// ```
@@ -251,14 +302,19 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
251
302
}
252
303
253
304
fn visit_assoc_item ( & mut self , i : & ' a AssocItem , ctxt : visit:: AssocCtxt ) {
254
- let def_kind = match & i. kind {
255
- AssocItemKind :: Fn ( ..) => DefKind :: AssocFn ,
256
- AssocItemKind :: Const ( ..) => DefKind :: AssocConst ,
257
- AssocItemKind :: Type ( ..) => DefKind :: AssocTy ,
305
+ let ( def_kind, def_span) = match & i. kind {
306
+ AssocItemKind :: Fn ( f) => {
307
+ ( DefKind :: AssocFn , f. sig . span . find_ancestor_in_same_ctxt ( i. span ) . unwrap_or ( i. span ) )
308
+ }
309
+ AssocItemKind :: Const ( c) => ( DefKind :: AssocConst , until_within ( i. span , c. ty . span ) ) ,
310
+ AssocItemKind :: Type ( ty) => ( DefKind :: AssocTy , {
311
+ let end = if let Some ( b) = ty. bounds . last ( ) { b. span ( ) } else { ty. generics . span } ;
312
+ until_within ( i. span , end)
313
+ } ) ,
258
314
AssocItemKind :: MacCall ( ..) => return self . visit_macro_invoc ( i. id ) ,
259
315
} ;
260
316
261
- let def = self . create_def ( i. id , i. ident . name , def_kind, i. span ) ;
317
+ let def = self . create_def ( i. id , i. ident . name , def_kind, def_span , i. span ) ;
262
318
self . with_parent ( def, |this| visit:: walk_assoc_item ( this, i, ctxt) ) ;
263
319
}
264
320
@@ -270,7 +326,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
270
326
}
271
327
272
328
fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
273
- let def = self . create_def ( constant. id , kw:: Empty , DefKind :: AnonConst , constant. value . span ) ;
329
+ let def = self . create_def (
330
+ constant. id ,
331
+ kw:: Empty ,
332
+ DefKind :: AnonConst ,
333
+ constant. value . span ,
334
+ constant. value . span ,
335
+ ) ;
274
336
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
275
337
}
276
338
@@ -280,23 +342,35 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
280
342
ExprKind :: Closure ( ref closure) => {
281
343
// Async closures desugar to closures inside of closures, so
282
344
// we must create two defs.
283
- let closure_def = self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span ) ;
345
+ let def_span =
346
+ closure. fn_decl_span . find_ancestor_inside ( expr. span ) . unwrap_or ( expr. span ) ;
347
+ let closure_def =
348
+ self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , def_span, expr. span ) ;
284
349
match closure. asyncness {
285
- Async :: Yes { closure_id, .. } => {
286
- self . create_def ( closure_id, kw:: Empty , DefKind :: Closure , expr. span )
287
- }
350
+ Async :: Yes { closure_id, .. } => self . create_def (
351
+ closure_id,
352
+ kw:: Empty ,
353
+ DefKind :: Closure ,
354
+ closure
355
+ . body
356
+ . span
357
+ . find_ancestor_in_same_ctxt ( expr. span )
358
+ . unwrap_or ( expr. span ) ,
359
+ expr. span ,
360
+ ) ,
288
361
Async :: No => closure_def,
289
362
}
290
363
}
291
364
ExprKind :: Gen ( _, _, _) => {
292
- self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span )
365
+ self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span , expr . span )
293
366
}
294
367
ExprKind :: ConstBlock ( ref constant) => {
295
368
let def = self . create_def (
296
369
constant. id ,
297
370
kw:: Empty ,
298
371
DefKind :: InlineConst ,
299
372
constant. value . span ,
373
+ constant. value . span ,
300
374
) ;
301
375
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
302
376
return ;
0 commit comments