@@ -301,11 +301,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
301
301
let orig_expansion_data = self . cx . current_expansion . clone ( ) ;
302
302
self . cx . current_expansion . depth = 0 ;
303
303
304
+ // Collect all macro invocations and replace them with placeholders.
304
305
let ( fragment_with_placeholders, mut invocations)
305
306
= self . collect_invocations ( input_fragment, & [ ] ) ;
307
+
308
+ // Optimization: if we resolve all imports now,
309
+ // we'll be able to immediately resolve most of imported macros.
306
310
self . resolve_imports ( ) ;
307
- invocations. reverse ( ) ;
308
311
312
+ // Resolve paths in all invocations and produce ouput expanded fragments for them, but
313
+ // do not insert them into our input AST fragment yet, only store in `expanded_fragments`.
314
+ // The output fragments also go through expansion recursively until no invocations are left.
315
+ // Unresolved macros produce dummy outputs as a recovery measure.
316
+ invocations. reverse ( ) ;
309
317
let mut expanded_fragments = Vec :: new ( ) ;
310
318
let mut derives = HashMap :: new ( ) ;
311
319
let mut undetermined_invocations = Vec :: new ( ) ;
@@ -411,6 +419,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
411
419
412
420
self . cx . current_expansion = orig_expansion_data;
413
421
422
+ // Finally incorporate all the expanded macros into the input AST fragment.
414
423
let mut placeholder_expander = PlaceholderExpander :: new ( self . cx , self . monotonic ) ;
415
424
while let Some ( expanded_fragments) = expanded_fragments. pop ( ) {
416
425
for ( mark, expanded_fragment) in expanded_fragments. into_iter ( ) . rev ( ) {
@@ -419,7 +428,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
419
428
expanded_fragment, derives) ;
420
429
}
421
430
}
422
-
423
431
fragment_with_placeholders. fold_with ( & mut placeholder_expander)
424
432
}
425
433
@@ -431,6 +439,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
431
439
}
432
440
}
433
441
442
+ /// Collect all macro invocations reachable at this time in this AST fragment, and replace
443
+ /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
444
+ /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
445
+ /// prepares data for resolving paths of macro invocations.
434
446
fn collect_invocations ( & mut self , fragment : AstFragment , derives : & [ Mark ] )
435
447
-> ( AstFragment , Vec < Invocation > ) {
436
448
let ( fragment_with_placeholders, invocations) = {
0 commit comments