@@ -301,11 +301,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
301301 let orig_expansion_data = self . cx . current_expansion . clone ( ) ;
302302 self . cx . current_expansion . depth = 0 ;
303303
304+ // Collect all macro invocations and replace them with placeholders.
304305 let ( fragment_with_placeholders, mut invocations)
305306 = 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.
306310 self . resolve_imports ( ) ;
307- invocations. reverse ( ) ;
308311
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 ( ) ;
309317 let mut expanded_fragments = Vec :: new ( ) ;
310318 let mut derives = HashMap :: new ( ) ;
311319 let mut undetermined_invocations = Vec :: new ( ) ;
@@ -411,6 +419,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
411419
412420 self . cx . current_expansion = orig_expansion_data;
413421
422+ // Finally incorporate all the expanded macros into the input AST fragment.
414423 let mut placeholder_expander = PlaceholderExpander :: new ( self . cx , self . monotonic ) ;
415424 while let Some ( expanded_fragments) = expanded_fragments. pop ( ) {
416425 for ( mark, expanded_fragment) in expanded_fragments. into_iter ( ) . rev ( ) {
@@ -419,7 +428,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
419428 expanded_fragment, derives) ;
420429 }
421430 }
422-
423431 fragment_with_placeholders. fold_with ( & mut placeholder_expander)
424432 }
425433
@@ -431,6 +439,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
431439 }
432440 }
433441
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.
434446 fn collect_invocations ( & mut self , fragment : AstFragment , derives : & [ Mark ] )
435447 -> ( AstFragment , Vec < Invocation > ) {
436448 let ( fragment_with_placeholders, invocations) = {
0 commit comments