@@ -291,7 +291,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
291
291
// Unresolved macros produce dummy outputs as a recovery measure.
292
292
invocations. reverse ( ) ;
293
293
let mut expanded_fragments = Vec :: new ( ) ;
294
- let mut derives : FxHashMap < ExpnId , Vec < _ > > = FxHashMap :: default ( ) ;
294
+ let mut all_derive_placeholders : FxHashMap < ExpnId , Vec < _ > > = FxHashMap :: default ( ) ;
295
295
let mut undetermined_invocations = Vec :: new ( ) ;
296
296
let ( mut progress, mut force) = ( false , !self . monotonic ) ;
297
297
loop {
@@ -347,13 +347,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
347
347
348
348
let mut item = self . fully_configure ( item) ;
349
349
item. visit_attrs ( |attrs| attrs. retain ( |a| a. path != sym:: derive) ) ;
350
- let derives = derives. entry ( invoc. expansion_data . id ) . or_default ( ) ;
350
+ let derive_placeholders =
351
+ all_derive_placeholders. entry ( invoc. expansion_data . id ) . or_default ( ) ;
351
352
352
- derives . reserve ( traits. len ( ) ) ;
353
+ derive_placeholders . reserve ( traits. len ( ) ) ;
353
354
invocations. reserve ( traits. len ( ) ) ;
354
355
for path in traits {
355
356
let expn_id = ExpnId :: fresh ( None ) ;
356
- derives . push ( expn_id) ;
357
+ derive_placeholders . push ( NodeId :: placeholder_from_expn_id ( expn_id) ) ;
357
358
invocations. push ( Invocation {
358
359
kind : InvocationKind :: Derive { path, item : item. clone ( ) } ,
359
360
fragment_kind : invoc. fragment_kind ,
@@ -365,7 +366,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
365
366
}
366
367
let fragment = invoc. fragment_kind
367
368
. expect_from_annotatables ( :: std:: iter:: once ( item) ) ;
368
- self . collect_invocations ( fragment, derives )
369
+ self . collect_invocations ( fragment, derive_placeholders )
369
370
} else {
370
371
unreachable ! ( )
371
372
} ;
@@ -384,10 +385,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
384
385
// Finally incorporate all the expanded macros into the input AST fragment.
385
386
let mut placeholder_expander = PlaceholderExpander :: new ( self . cx , self . monotonic ) ;
386
387
while let Some ( expanded_fragments) = expanded_fragments. pop ( ) {
387
- for ( mark, expanded_fragment) in expanded_fragments. into_iter ( ) . rev ( ) {
388
- let derives = derives. remove ( & mark) . unwrap_or_else ( Vec :: new) ;
389
- placeholder_expander. add ( NodeId :: placeholder_from_expn_id ( mark) ,
390
- expanded_fragment, derives) ;
388
+ for ( expn_id, expanded_fragment) in expanded_fragments. into_iter ( ) . rev ( ) {
389
+ let derive_placeholders =
390
+ all_derive_placeholders. remove ( & expn_id) . unwrap_or_else ( Vec :: new) ;
391
+ placeholder_expander. add ( NodeId :: placeholder_from_expn_id ( expn_id) ,
392
+ expanded_fragment, derive_placeholders) ;
391
393
}
392
394
}
393
395
fragment_with_placeholders. mut_visit_with ( & mut placeholder_expander) ;
@@ -404,7 +406,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
404
406
/// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
405
407
/// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
406
408
/// prepares data for resolving paths of macro invocations.
407
- fn collect_invocations ( & mut self , mut fragment : AstFragment , derives : & [ ExpnId ] )
409
+ fn collect_invocations ( & mut self , mut fragment : AstFragment , extra_placeholders : & [ NodeId ] )
408
410
-> ( AstFragment , Vec < Invocation > ) {
409
411
// Resolve `$crate`s in the fragment for pretty-printing.
410
412
self . cx . resolver . resolve_dollar_crates ( ) ;
@@ -423,9 +425,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
423
425
collector. invocations
424
426
} ;
425
427
428
+ // FIXME: Merge `extra_placeholders` into the `fragment` as regular placeholders.
426
429
if self . monotonic {
427
430
self . cx . resolver . visit_ast_fragment_with_placeholders (
428
- self . cx . current_expansion . id , & fragment, derives ) ;
431
+ self . cx . current_expansion . id , & fragment, extra_placeholders ) ;
429
432
}
430
433
431
434
( fragment, invocations)
0 commit comments