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;
        self.cx.current_expansion.depth = 0;

        // 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 (invoc, res) = if let Some(invoc) = invocations.pop() {
                invoc
            } 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 res = match res {
                Some(res) => res,
                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(res) => res,
                        Err(Indeterminate) => {
                            // Cannot resolve, will retry this invocation later.
                            undetermined_invocations.push((invoc, None));
                            continue;
                        }
                    }
                }
            };

            let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
            self.cx.current_expansion = invoc.expansion_data.clone();
            self.cx.force_mode = force;

            // FIXME(jseyfried): Refactor out the following logic
            let fragment_kind = invoc.fragment_kind;
            let (expanded_fragment, new_invocations) = match res {
                InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
                    ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
                    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(InvocationRes::Single(ext))));
                            continue;
                        }
                    }
                },
                InvocationRes::DeriveContainer(_exts) => {
                    // FIXME: Consider using the derive resolutions (`_exts`) immediately,
                    // instead of enqueuing the derives to be resolved again later.
                    let (derives, mut item) = match invoc.kind {
                        InvocationKind::DeriveContainer { derives, item } => (derives, item),
                        _ => unreachable!(),
                    };
                    let (item, derive_placeholders) = if !item.derive_allowed() {
                        self.error_derive_forbidden_on_non_adt(&derives, &item);
                        item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
                        (item, Vec::new())
                    } else {
                        let mut item = StripUnconfigured {
                            sess: self.cx.sess,
                            features: self.cx.ecfg.features,
                        }
                        .fully_configure(item);
                        item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));

                        invocations.reserve(derives.len());
                        let derive_placeholders = derives
                            .into_iter()
                            .map(|path| {
                                let expn_id = ExpnId::fresh(None);
                                invocations.push((
                                    Invocation {
                                        kind: InvocationKind::Derive { path, item: item.clone() },
                                        fragment_kind,
                                        expansion_data: ExpansionData {
                                            id: expn_id,
                                            ..self.cx.current_expansion.clone()
                                        },
                                    },
                                    None,
                                ));
                                NodeId::placeholder_from_expn_id(expn_id)
                            })
                            .collect::<Vec<_>>();
                        (item, derive_placeholders)
                    };

                    let fragment = fragment_kind.expect_from_annotatables(::std::iter::once(item));
                    self.collect_invocations(fragment, &derive_placeholders)
                }
            };

            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::new(self.cx, self.monotonic);
        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.
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;
        self.cx.current_expansion.depth = 0;
        // 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 (invoc, res) = if let Some(invoc) = invocations.pop() {
                invoc
            } 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 res = match res {
                Some(res) => res,
                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(res) => res,
                        Err(Indeterminate) => {
                            // Cannot resolve, will retry this invocation later.
                            undetermined_invocations.push((invoc, None));
                            continue;
                        }
                    }
                }
            };
            let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
            self.cx.current_expansion = invoc.expansion_data.clone();
            self.cx.force_mode = force;
            // FIXME(jseyfried): Refactor out the following logic
            let fragment_kind = invoc.fragment_kind;
            let (expanded_fragment, new_invocations) = match res {
                InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
                    ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
                    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(InvocationRes::Single(ext))));
                            continue;
                        }
                    }
                },
                InvocationRes::DeriveContainer(_exts) => {
                    // FIXME: Consider using the derive resolutions (`_exts`) immediately,
                    // instead of enqueuing the derives to be resolved again later.
                    let (derives, mut item) = match invoc.kind {
                        InvocationKind::DeriveContainer { derives, item } => (derives, item),
                        _ => unreachable!(),
                    };
                    let (item, derive_placeholders) = if !item.derive_allowed() {
                        self.error_derive_forbidden_on_non_adt(&derives, &item);
                        item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
                        (item, Vec::new())
                    } else {
                        let mut item = StripUnconfigured {
                            sess: self.cx.sess,
                            features: self.cx.ecfg.features,
                        }
                        .fully_configure(item);
                        item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
                        invocations.reserve(derives.len());
                        let derive_placeholders = derives
                            .into_iter()
                            .map(|path| {
                                let expn_id = ExpnId::fresh(None);
                                invocations.push((
                                    Invocation {
                                        kind: InvocationKind::Derive { path, item: item.clone() },
                                        fragment_kind,
                                        expansion_data: ExpansionData {
                                            id: expn_id,
                                            ..self.cx.current_expansion.clone()
                                        },
                                    },
                                    None,
                                ));
                                NodeId::placeholder_from_expn_id(expn_id)
                            })
                            .collect::<Vec<_>>();
                        (item, derive_placeholders)
                    };
                    let fragment = fragment_kind.expect_from_annotatables(::std::iter::once(item));
                    self.collect_invocations(fragment, &derive_placeholders)
                }
            };
            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::new(self.cx, self.monotonic);
        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 ; self . cx . current_expansion . depth = 0 ; // 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 ( invoc , res ) = if let Some ( invoc ) = invocations . pop ( ) { invoc } 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 res = match res { Some ( res ) => res , 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 ( res ) => res , Err ( Indeterminate ) => { // Cannot resolve, will retry this invocation later. undetermined_invocations . push ( ( invoc , None ) ) ; continue ; } } } } ; let ExpansionData { depth , id : expn_id , .. } = invoc . expansion_data ; self . cx . current_expansion = invoc . expansion_data . clone ( ) ; self . cx . force_mode = force ; // FIXME(jseyfried): Refactor out the following logic let fragment_kind = invoc . fragment_kind ; let ( expanded_fragment , new_invocations ) = match res { InvocationRes :: Single ( ext ) => match self . expand_invoc ( invoc , & ext . kind ) { ExpandResult :: Ready ( fragment ) => self . collect_invocations ( fragment , & [ ] ) , ExpandResult :: Retry ( invoc ) => { if force { self . cx . span_bug ( invoc . span ( ) , " " , ) ; } else { // Cannot expand, will retry this invocation later. undetermined_invocations . push ( ( invoc , Some ( InvocationRes :: Single ( ext ) ) ) ) ; continue ; } } } , InvocationRes :: DeriveContainer ( _exts ) => { // FIXME: Consider using the derive resolutions (`_exts`) immediately, // instead of enqueuing the derives to be resolved again later. let ( derives , mut item ) = match invoc . kind { InvocationKind :: DeriveContainer { derives , item } => ( derives , item ) , _ => unreachable ! ( ) , } ; let ( item , derive_placeholders ) = if ! item . derive_allowed ( ) { self . error_derive_forbidden_on_non_adt ( & derives , & item ) ; item . visit_attrs ( | attrs | attrs . retain ( | a | ! a . has_name ( sym :: derive ) ) ) ; ( item , Vec :: new ( ) ) } else { let mut item = StripUnconfigured { sess : self . cx . sess , features : self . cx . ecfg . features , } . fully_configure ( item ) ; item . visit_attrs ( | attrs | attrs . retain ( | a | ! a . has_name ( sym :: derive ) ) ) ; invocations . reserve ( derives . len ( ) ) ; let derive_placeholders = derives . into_iter ( ) . map ( | path | { let expn_id = ExpnId :: fresh ( None ) ; invocations . push ( ( Invocation { kind : InvocationKind :: Derive { path , item : item . clone ( ) } , fragment_kind , expansion_data : ExpansionData { id : expn_id , .. self . cx . current_expansion . clone ( ) } , } , None , ) ) ; NodeId :: placeholder_from_expn_id ( expn_id ) } ) . collect :: < Vec < _ > > ( ) ; ( item , derive_placeholders ) } ; let fragment = fragment_kind . expect_from_annotatables ( :: std :: iter :: once ( item ) ) ; self . collect_invocations ( fragment , & derive_placeholders ) } } ; 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 :: new ( self . cx , self . monotonic ) ; 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
&mut self
input_fragment
AstFragment