@@ -170,9 +170,13 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
170
170
}
171
171
172
172
fn visit_variant_data ( & mut self , data : & ' a VariantData ) {
173
+ // The assumption here is that non-`cfg` macro expansion cannot change field indices.
174
+ // It currently holds because only inert attributes are accepted on fields,
175
+ // and every such attribute expands into a single field after it's resolved.
173
176
for ( index, field) in data. fields ( ) . iter ( ) . enumerate ( ) {
174
177
if field. is_placeholder {
175
178
self . visit_macro_invoc ( field. id ) ;
179
+ self . definitions . placeholder_field_indices . insert ( field. id , index) ;
176
180
continue ;
177
181
}
178
182
let name = field. ident . map ( |ident| ident. name )
@@ -338,12 +342,19 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
338
342
}
339
343
}
340
344
345
+ // This method is called only when we are visiting an individual field
346
+ // after expanding an attribute on it.
341
347
fn visit_struct_field ( & mut self , sf : & ' a StructField ) {
342
348
if sf. is_placeholder {
343
349
self . visit_macro_invoc ( sf. id )
344
350
} else {
345
- let name = sf. ident . map ( |ident| ident. name )
346
- . unwrap_or_else ( || panic ! ( "don't know the field number in this context" ) ) ;
351
+ let name = sf. ident . map_or_else (
352
+ || {
353
+ let expn_id = NodeId :: placeholder_from_expn_id ( self . expansion ) ;
354
+ sym:: integer ( self . definitions . placeholder_field_indices [ & expn_id] )
355
+ } ,
356
+ |ident| ident. name ,
357
+ ) ;
347
358
let def = self . create_def ( sf. id ,
348
359
DefPathData :: ValueNs ( name. as_interned_str ( ) ) ,
349
360
sf. span ) ;
0 commit comments