// Recursively expand all macro invocations in this AST fragment.
Recursively expand all macro invocations in this AST fragment.
Recursively expand all macro invocations in this AST fragment .
pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
        let orig_expansion_data = self.cx.current_expansion.clone();
        let orig_force_mode = self.cx.force_mode;
        // Collect all macro invocations and replace them with placeholders.
        let (mut fragment_with_placeholders, mut invocations) =
            self.collect_invocations(input_fragment, &[]);
        // Optimization: if we resolve all imports now,
        // we'll be able to immediately resolve most of imported macros.
        self.resolve_imports();
        // Resolve paths in all invocations and produce output expanded fragments for them, but
        // do not insert them into our input AST fragment yet, only store in `expanded_fragments`.
        // The output fragments also go through expansion recursively until no invocations are left.
        // Unresolved macros produce dummy outputs as a recovery measure.
        invocations.reverse();
        let mut expanded_fragments = Vec::new();
        let mut undetermined_invocations = Vec::new();
        let (mut progress, mut force) = (false, !self.monotonic);
        loop {
            let Some((invoc, ext)) = invocations.pop() else {
                self.resolve_imports();
                if undetermined_invocations.is_empty() {
                    break;
                }
                invocations = mem::take(&mut undetermined_invocations);
                force = !mem::replace(&mut progress, false);
                if force && self.monotonic {
                    self.cx.sess.delay_span_bug(
                        invocations.last().unwrap().0.span(),
                        "expansion entered force mode without producing any errors",
                    );
                }
                continue;
            };
            let ext = match ext {
                Some(ext) => ext,
                None => {
                    let eager_expansion_root = if self.monotonic {
                        invoc.expansion_data.id
                    } else {
                        orig_expansion_data.id
                    };
                    match self.cx.resolver.resolve_macro_invocation(
                        &invoc,
                        eager_expansion_root,
                        force,
                    ) {
                        Ok(ext) => ext,
                        Err(Indeterminate) => {
                            // Cannot resolve, will retry this invocation later.
                            undetermined_invocations.push((invoc, None));
                            continue;
                        }
                    }
                }
            };
            let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
            let depth = depth - orig_expansion_data.depth;
            self.cx.current_expansion = invoc.expansion_data.clone();
            self.cx.force_mode = force;
            let fragment_kind = invoc.fragment_kind;
            let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
                ExpandResult::Ready(fragment) => {
                    let mut derive_invocations = Vec::new();
                    let derive_placeholders = self
                        .cx
                        .resolver
                        .take_derive_resolutions(expn_id)
                        .map(|derives| {
                            derive_invocations.reserve(derives.len());
                            derives
                                .into_iter()
                                .map(|(path, item, _exts)| {
                                    // FIXME: Consider using the derive resolutions (`_exts`)
                                    // instead of enqueuing the derives to be resolved again later.
                                    let expn_id = LocalExpnId::fresh_empty();
                                    derive_invocations.push((
                                        Invocation {
                                            kind: InvocationKind::Derive { path, item },
                                            fragment_kind,
                                            expansion_data: ExpansionData {
                                                id: expn_id,
                                                ..self.cx.current_expansion.clone()
                                            },
                                        },
                                        None,
                                    ));
                                    NodeId::placeholder_from_expn_id(expn_id)
                                })
                                .collect::<Vec<_>>()
                        })
                        .unwrap_or_default();
                    let (fragment, collected_invocations) =
                        self.collect_invocations(fragment, &derive_placeholders);
                    // We choose to expand any derive invocations associated with this macro invocation
                    // *before* any macro invocations collected from the output fragment
                    derive_invocations.extend(collected_invocations);
                    (fragment, derive_invocations)
                }
                ExpandResult::Retry(invoc) => {
                    if force {
                        self.cx.span_bug(
                            invoc.span(),
                            "expansion entered force mode but is still stuck",
                        );
                    } else {
                        // Cannot expand, will retry this invocation later.
                        undetermined_invocations.push((invoc, Some(ext)));
                        continue;
                    }
                }
            };
            progress = true;
            if expanded_fragments.len() < depth {
                expanded_fragments.push(Vec::new());
            }
            expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
            invocations.extend(new_invocations.into_iter().rev());
        }
        self.cx.current_expansion = orig_expansion_data;
        self.cx.force_mode = orig_force_mode;
        // Finally incorporate all the expanded macros into the input AST fragment.
        let mut placeholder_expander = PlaceholderExpander::default();
        while let Some(expanded_fragments) = expanded_fragments.pop() {
            for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
                placeholder_expander
                    .add(NodeId::placeholder_from_expn_id(expn_id), expanded_fragment);
            }
        }
        fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
        fragment_with_placeholders
    }
pub fn fully_expand_fragment ( & mut self , input_fragment : AstFragment ) -> AstFragment { let orig_expansion_data = self . cx . current_expansion . clone ( ) ; let orig_force_mode = self . cx . force_mode ; // Collect all macro invocations and replace them with placeholders. let ( mut fragment_with_placeholders , mut invocations ) = self . collect_invocations ( input_fragment , & [ ] ) ; // Optimization: if we resolve all imports now, // we'll be able to immediately resolve most of imported macros. self . resolve_imports ( ) ; // Resolve paths in all invocations and produce output expanded fragments for them, but // do not insert them into our input AST fragment yet, only store in `expanded_fragments`. // The output fragments also go through expansion recursively until no invocations are left. // Unresolved macros produce dummy outputs as a recovery measure. invocations . reverse ( ) ; let mut expanded_fragments = Vec :: new ( ) ; let mut undetermined_invocations = Vec :: new ( ) ; let ( mut progress , mut force ) = ( false , ! self . monotonic ) ; loop { let Some ( ( invoc , ext ) ) = invocations . pop ( ) else { self . resolve_imports ( ) ; if undetermined_invocations . is_empty ( ) { break ; } invocations = mem :: take ( & mut undetermined_invocations ) ; force = ! mem :: replace ( & mut progress , false ) ; if force && self . monotonic { self . cx . sess . delay_span_bug ( invocations . last ( ) . unwrap ( ) . 0 . span ( ) , " " , ) ; } continue ; } ; let ext = match ext { Some ( ext ) => ext , None => { let eager_expansion_root = if self . monotonic { invoc . expansion_data . id } else { orig_expansion_data . id } ; match self . cx . resolver . resolve_macro_invocation ( & invoc , eager_expansion_root , force , ) { Ok ( ext ) => ext , Err ( Indeterminate ) => { // Cannot resolve, will retry this invocation later. undetermined_invocations . push ( ( invoc , None ) ) ; continue ; } } } } ; let ExpansionData { depth , id : expn_id , .. } = invoc . expansion_data ; let depth = depth - orig_expansion_data . depth ; self . cx . current_expansion = invoc . expansion_data . clone ( ) ; self . cx . force_mode = force ; let fragment_kind = invoc . fragment_kind ; let ( expanded_fragment , new_invocations ) = match self . expand_invoc ( invoc , & ext . kind ) { ExpandResult :: Ready ( fragment ) => { let mut derive_invocations = Vec :: new ( ) ; let derive_placeholders = self . cx . resolver . take_derive_resolutions ( expn_id ) . map ( | derives | { derive_invocations . reserve ( derives . len ( ) ) ; derives . into_iter ( ) . map ( | ( path , item , _exts ) | { // FIXME: Consider using the derive resolutions (`_exts`) // instead of enqueuing the derives to be resolved again later. let expn_id = LocalExpnId :: fresh_empty ( ) ; derive_invocations . push ( ( Invocation { kind : InvocationKind :: Derive { path , item } , fragment_kind , expansion_data : ExpansionData { id : expn_id , .. self . cx . current_expansion . clone ( ) } , } , None , ) ) ; NodeId :: placeholder_from_expn_id ( expn_id ) } ) . collect :: < Vec < _ > > ( ) } ) . unwrap_or_default ( ) ; let ( fragment , collected_invocations ) = self . collect_invocations ( fragment , & derive_placeholders ) ; // We choose to expand any derive invocations associated with this macro invocation // *before* any macro invocations collected from the output fragment derive_invocations . extend ( collected_invocations ) ; ( fragment , derive_invocations ) } ExpandResult :: Retry ( invoc ) => { if force { self . cx . span_bug ( invoc . span ( ) , " " , ) ; } else { // Cannot expand, will retry this invocation later. undetermined_invocations . push ( ( invoc , Some ( ext ) ) ) ; continue ; } } } ; progress = true ; if expanded_fragments . len ( ) < depth { expanded_fragments . push ( Vec :: new ( ) ) ; } expanded_fragments [ depth - 1 ] . push ( ( expn_id , expanded_fragment ) ) ; invocations . extend ( new_invocations . into_iter ( ) . rev ( ) ) ; } self . cx . current_expansion = orig_expansion_data ; self . cx . force_mode = orig_force_mode ; // Finally incorporate all the expanded macros into the input AST fragment. let mut placeholder_expander = PlaceholderExpander :: default ( ) ; while let Some ( expanded_fragments ) = expanded_fragments . pop ( ) { for ( expn_id , expanded_fragment ) in expanded_fragments . into_iter ( ) . rev ( ) { placeholder_expander . add ( NodeId :: placeholder_from_expn_id ( expn_id ) , expanded_fragment ) ; } } fragment_with_placeholders . mut_visit_with ( & mut placeholder_expander ) ; fragment_with_placeholders }
Recursively expand all macro invocations in this AST fragment.
Recursively expand all macro invocations in this AST fragment .
&mut self
input_fragment
AstFragment