@@ -31,7 +31,7 @@ impl<'a> DefCollector<'a> {
3131 self . definitions . create_def_with_parent ( parent_def, node_id, data, self . expansion , span)
3232 }
3333
34- pub fn with_parent < F : FnOnce ( & mut Self ) > ( & mut self , parent_def : DefIndex , f : F ) {
34+ fn with_parent < F : FnOnce ( & mut Self ) > ( & mut self , parent_def : DefIndex , f : F ) {
3535 let orig_parent_def = std:: mem:: replace ( & mut self . parent_def , parent_def) ;
3636 f ( self ) ;
3737 self . parent_def = orig_parent_def;
@@ -74,6 +74,22 @@ impl<'a> DefCollector<'a> {
7474 } )
7575 }
7676
77+ fn collect_field ( & mut self , field : & ' a StructField , index : Option < usize > ) {
78+ if field. is_placeholder {
79+ self . visit_macro_invoc ( field. id ) ;
80+ } else {
81+ let name = field. ident . map ( |ident| ident. name )
82+ . or_else ( || index. map ( sym:: integer) )
83+ . unwrap_or_else ( || {
84+ let node_id = NodeId :: placeholder_from_expn_id ( self . expansion ) ;
85+ sym:: integer ( self . definitions . placeholder_field_indices [ & node_id] )
86+ } )
87+ . as_interned_str ( ) ;
88+ let def = self . create_def ( field. id , DefPathData :: ValueNs ( name) , field. span ) ;
89+ self . with_parent ( def, |this| visit:: walk_struct_field ( this, field) ) ;
90+ }
91+ }
92+
7793 pub fn visit_macro_invoc ( & mut self , id : NodeId ) {
7894 self . definitions . set_invocation_parent ( id. placeholder_to_expn_id ( ) , self . parent_def ) ;
7995 }
@@ -170,17 +186,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
170186 }
171187
172188 fn visit_variant_data ( & mut self , data : & ' a VariantData ) {
189+ // The assumption here is that non-`cfg` macro expansion cannot change field indices.
190+ // It currently holds because only inert attributes are accepted on fields,
191+ // and every such attribute expands into a single field after it's resolved.
173192 for ( index, field) in data. fields ( ) . iter ( ) . enumerate ( ) {
174- if field . is_placeholder {
175- self . visit_macro_invoc ( field. id ) ;
176- continue ;
193+ self . collect_field ( field , Some ( index ) ) ;
194+ if field . is_placeholder && field. ident . is_none ( ) {
195+ self . definitions . placeholder_field_indices . insert ( field . id , index ) ;
177196 }
178- let name = field. ident . map ( |ident| ident. name )
179- . unwrap_or_else ( || sym:: integer ( index) ) ;
180- let def = self . create_def ( field. id ,
181- DefPathData :: ValueNs ( name. as_interned_str ( ) ) ,
182- field. span ) ;
183- self . with_parent ( def, |this| visit:: walk_struct_field ( this, field) ) ;
184197 }
185198 }
186199
@@ -338,16 +351,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
338351 }
339352 }
340353
341- fn visit_struct_field ( & mut self , sf : & ' a StructField ) {
342- if sf. is_placeholder {
343- self . visit_macro_invoc ( sf. id )
344- } else {
345- let name = sf. ident . map ( |ident| ident. name )
346- . unwrap_or_else ( || panic ! ( "don't know the field number in this context" ) ) ;
347- let def = self . create_def ( sf. id ,
348- DefPathData :: ValueNs ( name. as_interned_str ( ) ) ,
349- sf. span ) ;
350- self . with_parent ( def, |this| visit:: walk_struct_field ( this, sf) ) ;
351- }
354+ // This method is called only when we are visiting an individual field
355+ // after expanding an attribute on it.
356+ fn visit_struct_field ( & mut self , field : & ' a StructField ) {
357+ self . collect_field ( field, None ) ;
352358 }
353359}
0 commit comments