@@ -4,6 +4,7 @@ use rustc_ast::*;
44use rustc_expand:: expand:: AstFragment ;
55use rustc_hir:: def:: { CtorKind , CtorOf , DefKind } ;
66use rustc_hir:: def_id:: LocalDefId ;
7+ use rustc_middle:: hir:: map:: { named_span, until_within} ;
78use rustc_span:: hygiene:: LocalExpnId ;
89use rustc_span:: symbol:: { kw, sym, Symbol } ;
910use rustc_span:: Span ;
@@ -31,18 +32,20 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
3132 node_id : NodeId ,
3233 name : Symbol ,
3334 def_kind : DefKind ,
35+ def_span : Span ,
3436 span : Span ,
3537 ) -> LocalDefId {
3638 let parent_def = self . parent_def ;
3739 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
4042 ) ;
4143 self . resolver . create_def (
4244 parent_def,
4345 node_id,
4446 name,
4547 def_kind,
48+ def_span,
4649 self . expansion . to_expn_id ( ) ,
4750 span. with_parent ( None ) ,
4851 )
@@ -78,7 +81,7 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
7881 self . visit_macro_invoc ( field. id ) ;
7982 } else {
8083 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 ) ;
8285 self . with_parent ( def, |this| visit:: walk_field_def ( this, field) ) ;
8386 }
8487 }
@@ -91,6 +94,33 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
9194 }
9295}
9396
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+
94124impl < ' a , ' b , ' tcx > visit:: Visitor < ' a > for DefCollector < ' a , ' b , ' tcx > {
95125 fn visit_item ( & mut self , i : & ' a Item ) {
96126 debug ! ( "visit_item: {:?}" , i) ;
@@ -127,7 +157,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
127157 return visit:: walk_item ( self , i) ;
128158 }
129159 } ;
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 ) ;
131161
132162 if let Some ( macro_data) = opt_macro_data {
133163 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> {
143173 ctor_node_id,
144174 kw:: Empty ,
145175 DefKind :: Ctor ( CtorOf :: Struct , ctor_kind) ,
176+ this. resolver . tcx . def_span ( this. parent_def ) ,
146177 i. span ,
147178 ) ;
148179 }
@@ -171,8 +202,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
171202 // then the closure_def will never be used, and we should avoid generating a
172203 // def-id for it.
173204 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+ ) ;
176212 self . with_parent ( closure_def, |this| this. visit_block ( body) ) ;
177213 }
178214 return ;
@@ -183,19 +219,27 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
183219 }
184220
185221 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 ) ;
187225 visit:: walk_use_tree ( self , use_tree, id) ;
188226 }
189227
190228 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+ }
195239 ForeignItemKind :: MacCall ( _) => return self . visit_macro_invoc ( fi. id ) ,
196240 } ;
197241
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 ) ;
199243
200244 self . with_parent ( def, |this| visit:: walk_foreign_item ( this, fi) ) ;
201245 }
@@ -204,13 +248,20 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
204248 if v. is_placeholder {
205249 return self . visit_macro_invoc ( v. id ) ;
206250 }
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+ ) ;
208258 self . with_parent ( def, |this| {
209259 if let Some ( ( ctor_kind, ctor_node_id) ) = CtorKind :: from_ast ( & v. data ) {
210260 this. create_def (
211261 ctor_node_id,
212262 kw:: Empty ,
213263 DefKind :: Ctor ( CtorOf :: Variant , ctor_kind) ,
264+ this. resolver . tcx . def_span ( this. parent_def ) ,
214265 v. span ,
215266 ) ;
216267 }
@@ -237,7 +288,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
237288 GenericParamKind :: Type { .. } => DefKind :: TyParam ,
238289 GenericParamKind :: Const { .. } => DefKind :: ConstParam ,
239290 } ;
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 ) ;
241292
242293 // impl-Trait can happen inside generic parameters, like
243294 // ```
@@ -251,14 +302,19 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
251302 }
252303
253304 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+ } ) ,
258314 AssocItemKind :: MacCall ( ..) => return self . visit_macro_invoc ( i. id ) ,
259315 } ;
260316
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 ) ;
262318 self . with_parent ( def, |this| visit:: walk_assoc_item ( this, i, ctxt) ) ;
263319 }
264320
@@ -270,7 +326,13 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
270326 }
271327
272328 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+ ) ;
274336 self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
275337 }
276338
@@ -280,23 +342,35 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
280342 ExprKind :: Closure ( ref closure) => {
281343 // Async closures desugar to closures inside of closures, so
282344 // 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 ) ;
284349 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+ ) ,
288361 Async :: No => closure_def,
289362 }
290363 }
291364 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 )
293366 }
294367 ExprKind :: ConstBlock ( ref constant) => {
295368 let def = self . create_def (
296369 constant. id ,
297370 kw:: Empty ,
298371 DefKind :: InlineConst ,
299372 constant. value . span ,
373+ constant. value . span ,
300374 ) ;
301375 self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
302376 return ;
0 commit comments