Skip to main content

rustc_expand/
expand.rs

1use std::path::PathBuf;
2use std::rc::Rc;
3use std::sync::Arc;
4use std::{iter, mem, slice};
5
6use rustc_ast::mut_visit::*;
7use rustc_ast::tokenstream::TokenStream;
8use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
9use rustc_ast::{
10    self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec,
11    DUMMY_NODE_ID, DelegationSuffixes, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs,
12    HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId,
13    PatKind, StmtKind, TyKind, token,
14};
15use rustc_ast_pretty::pprust;
16use rustc_attr_parsing::parser::AllowExprMetavar;
17use rustc_attr_parsing::{
18    AttributeParser, AttributeSafety, CFG_TEMPLATE, EvalConfigResult, ShouldEmit,
19    eval_config_entry, parse_cfg, validate_attr,
20};
21use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
22use rustc_data_structures::stack::ensure_sufficient_stack;
23use rustc_errors::{PResult, msg};
24use rustc_feature::Features;
25use rustc_hir::Target;
26use rustc_hir::def::MacroKinds;
27use rustc_hir::limit::Limit;
28use rustc_parse::parser::{
29    AllowConstBlockItems, AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser,
30    RecoverColon, RecoverComma, Recovery, token_descr,
31};
32use rustc_session::Session;
33use rustc_session::errors::feature_err;
34use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
35use rustc_span::hygiene::SyntaxContext;
36use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym};
37use smallvec::SmallVec;
38
39use crate::base::*;
40use crate::config::{StripUnconfigured, attr_into_trace};
41use crate::errors::{
42    EmptyDelegationMac, GlobDelegationOutsideImpls, GlobDelegationTraitlessQpath, IncompleteParse,
43    RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
44    WrongFragmentKind,
45};
46use crate::mbe::diagnostics::annotate_err_with_kind;
47use crate::module::{
48    DirOwnership, ParsedExternalMod, mod_dir_path, mod_file_path_from_attr, parse_external_mod,
49};
50use crate::placeholders::{PlaceholderExpander, placeholder};
51use crate::stats::*;
52
53macro_rules! ast_fragments {
54    (
55        $($Kind:ident($AstTy:ty) {
56            $kind_name:expr;
57            $(one
58                fn $visit_ast:ident;
59            )?
60            $(many
61                fn $flat_map_ast_elt:ident;
62                fn $visit_ast_elt:ident($($args:tt)*);
63            )?
64            fn $make_ast:ident;
65        })*
66    ) => {
67        /// A fragment of AST that can be produced by a single macro expansion.
68        /// Can also serve as an input and intermediate result for macro expansion operations.
69        pub enum AstFragment {
70            OptExpr(Option<Box<ast::Expr>>),
71            $($Kind($AstTy),)*
72        }
73
74        /// "Discriminant" of an AST fragment.
75        #[derive(Copy, Clone, Debug, PartialEq, Eq)]
76        pub enum AstFragmentKind {
77            OptExpr,
78            $($Kind,)*
79        }
80
81        impl AstFragmentKind {
82            pub fn name(self) -> &'static str {
83                match self {
84                    AstFragmentKind::OptExpr => "expression",
85                    $(AstFragmentKind::$Kind => $kind_name,)*
86                }
87            }
88
89            fn make_from(self, result: Box<dyn MacResult + '_>) -> Option<AstFragment> {
90                match self {
91                    AstFragmentKind::OptExpr =>
92                        result.make_expr().map(Some).map(AstFragment::OptExpr),
93                    $(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
94                }
95            }
96        }
97
98        impl AstFragment {
99            fn add_placeholders(&mut self, placeholders: &[NodeId]) {
100                if placeholders.is_empty() {
101                    return;
102                }
103                match self {
104                    $($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
105                        ${ignore($flat_map_ast_elt)}
106                        placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
107                    })),)?)*
108                    _ => panic!("unexpected AST fragment kind")
109                }
110            }
111
112            pub(crate) fn make_opt_expr(self) -> Option<Box<ast::Expr>> {
113                match self {
114                    AstFragment::OptExpr(expr) => expr,
115                    _ => panic!("AstFragment::make_opt_expr called on the wrong kind of fragment"),
116                }
117            }
118
119            $(pub fn $make_ast(self) -> $AstTy {
120                match self {
121                    AstFragment::$Kind(ast) => ast,
122                    _ => panic!("AstFragment::{} called on the wrong kind of fragment", stringify!($make_ast)),
123                }
124            })*
125
126            fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy {
127                T::fragment_to_output(self)
128            }
129
130            pub(crate) fn mut_visit_with(&mut self, vis: &mut impl MutVisitor) {
131                match self {
132                    AstFragment::OptExpr(opt_expr) => {
133                        if let Some(expr) = opt_expr.take() {
134                            *opt_expr = vis.filter_map_expr(expr)
135                        }
136                    }
137                    $($(AstFragment::$Kind(ast) => vis.$visit_ast(ast),)?)*
138                    $($(AstFragment::$Kind(ast) =>
139                        ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)*
140                }
141            }
142
143            pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
144                match self {
145                    AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)),
146                    AstFragment::OptExpr(None) => {}
147                    $($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)*
148                    $($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)*
149                }
150                V::Result::output()
151            }
152        }
153
154        impl<'a, 'b> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a, 'b> {
155            $(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
156                           -> Option<$AstTy> {
157                Some(self.make(AstFragmentKind::$Kind).$make_ast())
158            })*
159        }
160    }
161}
162
163/// A fragment of AST that can be produced by a single macro expansion.
/// Can also serve as an input and intermediate result for macro expansion operations.
pub enum AstFragment {
    OptExpr(Option<Box<ast::Expr>>),
    Expr(Box<ast::Expr>),
    MethodReceiverExpr(Box<ast::Expr>),
    Pat(Box<ast::Pat>),
    Ty(Box<ast::Ty>),
    Stmts(SmallVec<[ast::Stmt; 1]>),
    Items(SmallVec<[Box<ast::Item>; 1]>),
    TraitItems(SmallVec<[Box<ast::AssocItem>; 1]>),
    ImplItems(SmallVec<[Box<ast::AssocItem>; 1]>),
    TraitImplItems(SmallVec<[Box<ast::AssocItem>; 1]>),
    ForeignItems(SmallVec<[Box<ast::ForeignItem>; 1]>),
    Arms(SmallVec<[ast::Arm; 1]>),
    ExprFields(SmallVec<[ast::ExprField; 1]>),
    PatFields(SmallVec<[ast::PatField; 1]>),
    GenericParams(SmallVec<[ast::GenericParam; 1]>),
    Params(SmallVec<[ast::Param; 1]>),
    FieldDefs(SmallVec<[ast::FieldDef; 1]>),
    Variants(SmallVec<[ast::Variant; 1]>),
    WherePredicates(SmallVec<[ast::WherePredicate; 1]>),
    Crate(ast::Crate),
}
/// "Discriminant" of an AST fragment.
pub enum AstFragmentKind {
    OptExpr,
    Expr,
    MethodReceiverExpr,
    Pat,
    Ty,
    Stmts,
    Items,
    TraitItems,
    ImplItems,
    TraitImplItems,
    ForeignItems,
    Arms,
    ExprFields,
    PatFields,
    GenericParams,
    Params,
    FieldDefs,
    Variants,
    WherePredicates,
    Crate,
}
#[automatically_derived]
impl ::core::marker::Copy for AstFragmentKind { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for AstFragmentKind { }
#[automatically_derived]
impl ::core::clone::Clone for AstFragmentKind {
    #[inline]
    fn clone(&self) -> AstFragmentKind { *self }
}
#[automatically_derived]
impl ::core::fmt::Debug for AstFragmentKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                AstFragmentKind::OptExpr => "OptExpr",
                AstFragmentKind::Expr => "Expr",
                AstFragmentKind::MethodReceiverExpr => "MethodReceiverExpr",
                AstFragmentKind::Pat => "Pat",
                AstFragmentKind::Ty => "Ty",
                AstFragmentKind::Stmts => "Stmts",
                AstFragmentKind::Items => "Items",
                AstFragmentKind::TraitItems => "TraitItems",
                AstFragmentKind::ImplItems => "ImplItems",
                AstFragmentKind::TraitImplItems => "TraitImplItems",
                AstFragmentKind::ForeignItems => "ForeignItems",
                AstFragmentKind::Arms => "Arms",
                AstFragmentKind::ExprFields => "ExprFields",
                AstFragmentKind::PatFields => "PatFields",
                AstFragmentKind::GenericParams => "GenericParams",
                AstFragmentKind::Params => "Params",
                AstFragmentKind::FieldDefs => "FieldDefs",
                AstFragmentKind::Variants => "Variants",
                AstFragmentKind::WherePredicates => "WherePredicates",
                AstFragmentKind::Crate => "Crate",
            })
    }
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for AstFragmentKind { }
#[automatically_derived]
impl ::core::cmp::PartialEq for AstFragmentKind {
    #[inline]
    fn eq(&self, other: &AstFragmentKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}
#[automatically_derived]
impl ::core::cmp::Eq for AstFragmentKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}
impl AstFragmentKind {
    pub fn name(self) -> &'static str {
        match self {
            AstFragmentKind::OptExpr => "expression",
            AstFragmentKind::Expr => "expression",
            AstFragmentKind::MethodReceiverExpr => "expression",
            AstFragmentKind::Pat => "pattern",
            AstFragmentKind::Ty => "type",
            AstFragmentKind::Stmts => "statement",
            AstFragmentKind::Items => "item",
            AstFragmentKind::TraitItems => "trait item",
            AstFragmentKind::ImplItems => "impl item",
            AstFragmentKind::TraitImplItems => "impl item",
            AstFragmentKind::ForeignItems => "foreign item",
            AstFragmentKind::Arms => "match arm",
            AstFragmentKind::ExprFields => "field expression",
            AstFragmentKind::PatFields => "field pattern",
            AstFragmentKind::GenericParams => "generic parameter",
            AstFragmentKind::Params => "function parameter",
            AstFragmentKind::FieldDefs => "field",
            AstFragmentKind::Variants => "variant",
            AstFragmentKind::WherePredicates => "where predicate",
            AstFragmentKind::Crate => "crate",
        }
    }
    fn make_from(self, result: Box<dyn MacResult + '_>)
        -> Option<AstFragment> {
        match self {
            AstFragmentKind::OptExpr =>
                result.make_expr().map(Some).map(AstFragment::OptExpr),
            AstFragmentKind::Expr =>
                result.make_expr().map(AstFragment::Expr),
            AstFragmentKind::MethodReceiverExpr =>
                result.make_method_receiver_expr().map(AstFragment::MethodReceiverExpr),
            AstFragmentKind::Pat => result.make_pat().map(AstFragment::Pat),
            AstFragmentKind::Ty => result.make_ty().map(AstFragment::Ty),
            AstFragmentKind::Stmts =>
                result.make_stmts().map(AstFragment::Stmts),
            AstFragmentKind::Items =>
                result.make_items().map(AstFragment::Items),
            AstFragmentKind::TraitItems =>
                result.make_trait_items().map(AstFragment::TraitItems),
            AstFragmentKind::ImplItems =>
                result.make_impl_items().map(AstFragment::ImplItems),
            AstFragmentKind::TraitImplItems =>
                result.make_trait_impl_items().map(AstFragment::TraitImplItems),
            AstFragmentKind::ForeignItems =>
                result.make_foreign_items().map(AstFragment::ForeignItems),
            AstFragmentKind::Arms =>
                result.make_arms().map(AstFragment::Arms),
            AstFragmentKind::ExprFields =>
                result.make_expr_fields().map(AstFragment::ExprFields),
            AstFragmentKind::PatFields =>
                result.make_pat_fields().map(AstFragment::PatFields),
            AstFragmentKind::GenericParams =>
                result.make_generic_params().map(AstFragment::GenericParams),
            AstFragmentKind::Params =>
                result.make_params().map(AstFragment::Params),
            AstFragmentKind::FieldDefs =>
                result.make_field_defs().map(AstFragment::FieldDefs),
            AstFragmentKind::Variants =>
                result.make_variants().map(AstFragment::Variants),
            AstFragmentKind::WherePredicates =>
                result.make_where_predicates().map(AstFragment::WherePredicates),
            AstFragmentKind::Crate =>
                result.make_crate().map(AstFragment::Crate),
        }
    }
}
impl AstFragment {
    fn add_placeholders(&mut self, placeholders: &[NodeId]) {
        if placeholders.is_empty() { return; }
        match self {
            AstFragment::Stmts(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::Stmts, *id, None).make_stmts()
                            })),
            AstFragment::Items(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::Items, *id, None).make_items()
                            })),
            AstFragment::TraitItems(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::TraitItems, *id,
                                        None).make_trait_items()
                            })),
            AstFragment::ImplItems(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::ImplItems, *id,
                                        None).make_impl_items()
                            })),
            AstFragment::TraitImplItems(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::TraitImplItems, *id,
                                        None).make_trait_impl_items()
                            })),
            AstFragment::ForeignItems(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::ForeignItems, *id,
                                        None).make_foreign_items()
                            })),
            AstFragment::Arms(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::Arms, *id, None).make_arms()
                            })),
            AstFragment::ExprFields(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::ExprFields, *id,
                                        None).make_expr_fields()
                            })),
            AstFragment::PatFields(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::PatFields, *id,
                                        None).make_pat_fields()
                            })),
            AstFragment::GenericParams(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::GenericParams, *id,
                                        None).make_generic_params()
                            })),
            AstFragment::Params(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::Params, *id,
                                        None).make_params()
                            })),
            AstFragment::FieldDefs(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::FieldDefs, *id,
                                        None).make_field_defs()
                            })),
            AstFragment::Variants(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::Variants, *id,
                                        None).make_variants()
                            })),
            AstFragment::WherePredicates(ast) =>
                ast.extend(placeholders.iter().flat_map(|id|
                            {
                                placeholder(AstFragmentKind::WherePredicates, *id,
                                        None).make_where_predicates()
                            })),
            _ => {
                ::core::panicking::panic_fmt(format_args!("unexpected AST fragment kind"));
            }
        }
    }
    pub(crate) fn make_opt_expr(self) -> Option<Box<ast::Expr>> {
        match self {
            AstFragment::OptExpr(expr) => expr,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::make_opt_expr called on the wrong kind of fragment"));
            }
        }
    }
    pub fn make_expr(self) -> Box<ast::Expr> {
        match self {
            AstFragment::Expr(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_expr"));
            }
        }
    }
    pub fn make_method_receiver_expr(self) -> Box<ast::Expr> {
        match self {
            AstFragment::MethodReceiverExpr(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_method_receiver_expr"));
            }
        }
    }
    pub fn make_pat(self) -> Box<ast::Pat> {
        match self {
            AstFragment::Pat(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_pat"));
            }
        }
    }
    pub fn make_ty(self) -> Box<ast::Ty> {
        match self {
            AstFragment::Ty(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_ty"));
            }
        }
    }
    pub fn make_stmts(self) -> SmallVec<[ast::Stmt; 1]> {
        match self {
            AstFragment::Stmts(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_stmts"));
            }
        }
    }
    pub fn make_items(self) -> SmallVec<[Box<ast::Item>; 1]> {
        match self {
            AstFragment::Items(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_items"));
            }
        }
    }
    pub fn make_trait_items(self) -> SmallVec<[Box<ast::AssocItem>; 1]> {
        match self {
            AstFragment::TraitItems(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_trait_items"));
            }
        }
    }
    pub fn make_impl_items(self) -> SmallVec<[Box<ast::AssocItem>; 1]> {
        match self {
            AstFragment::ImplItems(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_impl_items"));
            }
        }
    }
    pub fn make_trait_impl_items(self) -> SmallVec<[Box<ast::AssocItem>; 1]> {
        match self {
            AstFragment::TraitImplItems(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_trait_impl_items"));
            }
        }
    }
    pub fn make_foreign_items(self) -> SmallVec<[Box<ast::ForeignItem>; 1]> {
        match self {
            AstFragment::ForeignItems(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_foreign_items"));
            }
        }
    }
    pub fn make_arms(self) -> SmallVec<[ast::Arm; 1]> {
        match self {
            AstFragment::Arms(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_arms"));
            }
        }
    }
    pub fn make_expr_fields(self) -> SmallVec<[ast::ExprField; 1]> {
        match self {
            AstFragment::ExprFields(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_expr_fields"));
            }
        }
    }
    pub fn make_pat_fields(self) -> SmallVec<[ast::PatField; 1]> {
        match self {
            AstFragment::PatFields(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_pat_fields"));
            }
        }
    }
    pub fn make_generic_params(self) -> SmallVec<[ast::GenericParam; 1]> {
        match self {
            AstFragment::GenericParams(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_generic_params"));
            }
        }
    }
    pub fn make_params(self) -> SmallVec<[ast::Param; 1]> {
        match self {
            AstFragment::Params(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_params"));
            }
        }
    }
    pub fn make_field_defs(self) -> SmallVec<[ast::FieldDef; 1]> {
        match self {
            AstFragment::FieldDefs(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_field_defs"));
            }
        }
    }
    pub fn make_variants(self) -> SmallVec<[ast::Variant; 1]> {
        match self {
            AstFragment::Variants(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_variants"));
            }
        }
    }
    pub fn make_where_predicates(self) -> SmallVec<[ast::WherePredicate; 1]> {
        match self {
            AstFragment::WherePredicates(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_where_predicates"));
            }
        }
    }
    pub fn make_crate(self) -> ast::Crate {
        match self {
            AstFragment::Crate(ast) => ast,
            _ => {
                ::core::panicking::panic_fmt(format_args!("AstFragment::{0} called on the wrong kind of fragment",
                        "make_crate"));
            }
        }
    }
    fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy {
        T::fragment_to_output(self)
    }
    pub(crate) fn mut_visit_with(&mut self, vis: &mut impl MutVisitor) {
        match self {
            AstFragment::OptExpr(opt_expr) => {
                if let Some(expr) = opt_expr.take() {
                    *opt_expr = vis.filter_map_expr(expr)
                }
            }
            AstFragment::Expr(ast) => vis.visit_expr(ast),
            AstFragment::MethodReceiverExpr(ast) =>
                vis.visit_method_receiver_expr(ast),
            AstFragment::Pat(ast) => vis.visit_pat(ast),
            AstFragment::Ty(ast) => vis.visit_ty(ast),
            AstFragment::Crate(ast) => vis.visit_crate(ast),
            AstFragment::Stmts(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_stmt(ast)),
            AstFragment::Items(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_item(ast)),
            AstFragment::TraitItems(ast) =>
                ast.flat_map_in_place(|ast|
                        vis.flat_map_assoc_item(ast, AssocCtxt::Trait)),
            AstFragment::ImplItems(ast) =>
                ast.flat_map_in_place(|ast|
                        vis.flat_map_assoc_item(ast,
                            AssocCtxt::Impl { of_trait: false })),
            AstFragment::TraitImplItems(ast) =>
                ast.flat_map_in_place(|ast|
                        vis.flat_map_assoc_item(ast,
                            AssocCtxt::Impl { of_trait: true })),
            AstFragment::ForeignItems(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_foreign_item(ast)),
            AstFragment::Arms(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_arm(ast)),
            AstFragment::ExprFields(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_expr_field(ast)),
            AstFragment::PatFields(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_pat_field(ast)),
            AstFragment::GenericParams(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_generic_param(ast)),
            AstFragment::Params(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_param(ast)),
            AstFragment::FieldDefs(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_field_def(ast)),
            AstFragment::Variants(ast) =>
                ast.flat_map_in_place(|ast| vis.flat_map_variant(ast)),
            AstFragment::WherePredicates(ast) =>
                ast.flat_map_in_place(|ast|
                        vis.flat_map_where_predicate(ast)),
        }
    }
    pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V)
        -> V::Result {
        match self {
            AstFragment::OptExpr(Some(expr)) =>
                match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_expr(expr))
                    {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                },
            AstFragment::OptExpr(None) => {}
            AstFragment::Expr(ast) =>
                match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_expr(ast))
                    {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                },
            AstFragment::MethodReceiverExpr(ast) =>
                match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_method_receiver_expr(ast))
                    {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                },
            AstFragment::Pat(ast) =>
                match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_pat(ast))
                    {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                },
            AstFragment::Ty(ast) =>
                match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_ty(ast))
                    {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                },
            AstFragment::Crate(ast) =>
                match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_crate(ast))
                    {
                    core::ops::ControlFlow::Continue(()) =>
                        (),
                        #[allow(unreachable_code)]
                        core::ops::ControlFlow::Break(r) => {
                        return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                    }
                },
            AstFragment::Stmts(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_stmt(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::Items(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_item(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::TraitItems(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_assoc_item(elem,
                                AssocCtxt::Trait)) {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::ImplItems(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_assoc_item(elem,
                                AssocCtxt::Impl { of_trait: false })) {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::TraitImplItems(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_assoc_item(elem,
                                AssocCtxt::Impl { of_trait: true })) {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::ForeignItems(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_foreign_item(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::Arms(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_arm(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::ExprFields(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_expr_field(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::PatFields(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_pat_field(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::GenericParams(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_generic_param(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::Params(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_param(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::FieldDefs(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_field_def(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::Variants(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_variant(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
            AstFragment::WherePredicates(ast) =>
                for elem in &ast[..] {
                    match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit_where_predicate(elem))
                        {
                        core::ops::ControlFlow::Continue(()) =>
                            (),
                            #[allow(unreachable_code)]
                            core::ops::ControlFlow::Break(r) => {
                            return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
                        }
                    };
                },
        }
        V::Result::output()
    }
}
impl<'a, 'b> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a, 'b> {
    fn make_expr(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<Box<ast::Expr>> {
        Some(self.make(AstFragmentKind::Expr).make_expr())
    }
    fn make_method_receiver_expr(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<Box<ast::Expr>> {
        Some(self.make(AstFragmentKind::MethodReceiverExpr).make_method_receiver_expr())
    }
    fn make_pat(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<Box<ast::Pat>> {
        Some(self.make(AstFragmentKind::Pat).make_pat())
    }
    fn make_ty(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<Box<ast::Ty>> {
        Some(self.make(AstFragmentKind::Ty).make_ty())
    }
    fn make_stmts(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::Stmt; 1]>> {
        Some(self.make(AstFragmentKind::Stmts).make_stmts())
    }
    fn make_items(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[Box<ast::Item>; 1]>> {
        Some(self.make(AstFragmentKind::Items).make_items())
    }
    fn make_trait_items(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        Some(self.make(AstFragmentKind::TraitItems).make_trait_items())
    }
    fn make_impl_items(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        Some(self.make(AstFragmentKind::ImplItems).make_impl_items())
    }
    fn make_trait_impl_items(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        Some(self.make(AstFragmentKind::TraitImplItems).make_trait_impl_items())
    }
    fn make_foreign_items(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
        Some(self.make(AstFragmentKind::ForeignItems).make_foreign_items())
    }
    fn make_arms(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::Arm; 1]>> {
        Some(self.make(AstFragmentKind::Arms).make_arms())
    }
    fn make_expr_fields(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::ExprField; 1]>> {
        Some(self.make(AstFragmentKind::ExprFields).make_expr_fields())
    }
    fn make_pat_fields(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::PatField; 1]>> {
        Some(self.make(AstFragmentKind::PatFields).make_pat_fields())
    }
    fn make_generic_params(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::GenericParam; 1]>> {
        Some(self.make(AstFragmentKind::GenericParams).make_generic_params())
    }
    fn make_params(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::Param; 1]>> {
        Some(self.make(AstFragmentKind::Params).make_params())
    }
    fn make_field_defs(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::FieldDef; 1]>> {
        Some(self.make(AstFragmentKind::FieldDefs).make_field_defs())
    }
    fn make_variants(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::Variant; 1]>> {
        Some(self.make(AstFragmentKind::Variants).make_variants())
    }
    fn make_where_predicates(self:
            Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<SmallVec<[ast::WherePredicate; 1]>> {
        Some(self.make(AstFragmentKind::WherePredicates).make_where_predicates())
    }
    fn make_crate(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a, 'b>>)
        -> Option<ast::Crate> {
        Some(self.make(AstFragmentKind::Crate).make_crate())
    }
}ast_fragments! {
164    Expr(Box<ast::Expr>) {
165        "expression";
166        one fn visit_expr;
167        fn make_expr;
168    }
169    MethodReceiverExpr(Box<ast::Expr>) {
170        "expression";
171        one fn visit_method_receiver_expr;
172        fn make_method_receiver_expr;
173    }
174    Pat(Box<ast::Pat>) {
175        "pattern";
176        one fn visit_pat;
177        fn make_pat;
178    }
179    Ty(Box<ast::Ty>) {
180        "type";
181        one fn visit_ty;
182        fn make_ty;
183    }
184    Stmts(SmallVec<[ast::Stmt; 1]>) {
185        "statement";
186        many fn flat_map_stmt; fn visit_stmt();
187        fn make_stmts;
188    }
189    Items(SmallVec<[Box<ast::Item>; 1]>) {
190        "item";
191        many fn flat_map_item; fn visit_item();
192        fn make_items;
193    }
194    TraitItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
195        "trait item";
196        many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Trait);
197        fn make_trait_items;
198    }
199    ImplItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
200        "impl item";
201        many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Impl { of_trait: false });
202        fn make_impl_items;
203    }
204    TraitImplItems(SmallVec<[Box<ast::AssocItem>; 1]>) {
205        "impl item";
206        many fn flat_map_assoc_item; fn visit_assoc_item(AssocCtxt::Impl { of_trait: true });
207        fn make_trait_impl_items;
208    }
209    ForeignItems(SmallVec<[Box<ast::ForeignItem>; 1]>) {
210        "foreign item";
211        many fn flat_map_foreign_item; fn visit_foreign_item();
212        fn make_foreign_items;
213    }
214    Arms(SmallVec<[ast::Arm; 1]>) {
215        "match arm";
216        many fn flat_map_arm; fn visit_arm();
217        fn make_arms;
218    }
219    ExprFields(SmallVec<[ast::ExprField; 1]>) {
220        "field expression";
221        many fn flat_map_expr_field; fn visit_expr_field();
222        fn make_expr_fields;
223    }
224    PatFields(SmallVec<[ast::PatField; 1]>) {
225        "field pattern";
226        many fn flat_map_pat_field; fn visit_pat_field();
227        fn make_pat_fields;
228    }
229    GenericParams(SmallVec<[ast::GenericParam; 1]>) {
230        "generic parameter";
231        many fn flat_map_generic_param; fn visit_generic_param();
232        fn make_generic_params;
233    }
234    Params(SmallVec<[ast::Param; 1]>) {
235        "function parameter";
236        many fn flat_map_param; fn visit_param();
237        fn make_params;
238    }
239    FieldDefs(SmallVec<[ast::FieldDef; 1]>) {
240        "field";
241        many fn flat_map_field_def; fn visit_field_def();
242        fn make_field_defs;
243    }
244    Variants(SmallVec<[ast::Variant; 1]>) {
245        "variant";
246        many fn flat_map_variant; fn visit_variant();
247        fn make_variants;
248    }
249    WherePredicates(SmallVec<[ast::WherePredicate; 1]>) {
250        "where predicate";
251        many fn flat_map_where_predicate; fn visit_where_predicate();
252        fn make_where_predicates;
253    }
254    Crate(ast::Crate) {
255        "crate";
256        one fn visit_crate;
257        fn make_crate;
258    }
259}
260
261pub enum SupportsMacroExpansion {
262    No,
263    Yes { supports_inner_attrs: bool },
264}
265
266impl AstFragmentKind {
267    pub(crate) fn dummy(self, span: Span, guar: ErrorGuaranteed) -> AstFragment {
268        self.make_from(DummyResult::any(span, guar)).expect("couldn't create a dummy AST fragment")
269    }
270
271    pub fn supports_macro_expansion(self) -> SupportsMacroExpansion {
272        match self {
273            AstFragmentKind::OptExpr
274            | AstFragmentKind::Expr
275            | AstFragmentKind::MethodReceiverExpr
276            | AstFragmentKind::Stmts
277            | AstFragmentKind::Ty
278            | AstFragmentKind::Pat => SupportsMacroExpansion::Yes { supports_inner_attrs: false },
279            AstFragmentKind::Items
280            | AstFragmentKind::TraitItems
281            | AstFragmentKind::ImplItems
282            | AstFragmentKind::TraitImplItems
283            | AstFragmentKind::ForeignItems
284            | AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true },
285            AstFragmentKind::Arms
286            | AstFragmentKind::ExprFields
287            | AstFragmentKind::PatFields
288            | AstFragmentKind::GenericParams
289            | AstFragmentKind::Params
290            | AstFragmentKind::FieldDefs
291            | AstFragmentKind::Variants
292            | AstFragmentKind::WherePredicates => SupportsMacroExpansion::No,
293        }
294    }
295
296    pub(crate) fn expect_from_annotatables(
297        self,
298        items: impl IntoIterator<Item = Annotatable>,
299    ) -> AstFragment {
300        let mut items = items.into_iter();
301        match self {
302            AstFragmentKind::Arms => {
303                AstFragment::Arms(items.map(Annotatable::expect_arm).collect())
304            }
305            AstFragmentKind::ExprFields => {
306                AstFragment::ExprFields(items.map(Annotatable::expect_expr_field).collect())
307            }
308            AstFragmentKind::PatFields => {
309                AstFragment::PatFields(items.map(Annotatable::expect_pat_field).collect())
310            }
311            AstFragmentKind::GenericParams => {
312                AstFragment::GenericParams(items.map(Annotatable::expect_generic_param).collect())
313            }
314            AstFragmentKind::Params => {
315                AstFragment::Params(items.map(Annotatable::expect_param).collect())
316            }
317            AstFragmentKind::FieldDefs => {
318                AstFragment::FieldDefs(items.map(Annotatable::expect_field_def).collect())
319            }
320            AstFragmentKind::Variants => {
321                AstFragment::Variants(items.map(Annotatable::expect_variant).collect())
322            }
323            AstFragmentKind::WherePredicates => AstFragment::WherePredicates(
324                items.map(Annotatable::expect_where_predicate).collect(),
325            ),
326            AstFragmentKind::Items => {
327                AstFragment::Items(items.map(Annotatable::expect_item).collect())
328            }
329            AstFragmentKind::ImplItems => {
330                AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect())
331            }
332            AstFragmentKind::TraitImplItems => {
333                AstFragment::TraitImplItems(items.map(Annotatable::expect_impl_item).collect())
334            }
335            AstFragmentKind::TraitItems => {
336                AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect())
337            }
338            AstFragmentKind::ForeignItems => {
339                AstFragment::ForeignItems(items.map(Annotatable::expect_foreign_item).collect())
340            }
341            AstFragmentKind::Stmts => {
342                AstFragment::Stmts(items.map(Annotatable::expect_stmt).collect())
343            }
344            AstFragmentKind::Expr => AstFragment::Expr(
345                items.next().expect("expected exactly one expression").expect_expr(),
346            ),
347            AstFragmentKind::MethodReceiverExpr => AstFragment::MethodReceiverExpr(
348                items.next().expect("expected exactly one expression").expect_expr(),
349            ),
350            AstFragmentKind::OptExpr => {
351                AstFragment::OptExpr(items.next().map(Annotatable::expect_expr))
352            }
353            AstFragmentKind::Crate => {
354                AstFragment::Crate(items.next().expect("expected exactly one crate").expect_crate())
355            }
356            AstFragmentKind::Pat | AstFragmentKind::Ty => {
357                {
    ::core::panicking::panic_fmt(format_args!("patterns and types aren\'t annotatable"));
}panic!("patterns and types aren't annotatable")
358            }
359        }
360    }
361}
362
363pub struct Invocation {
364    pub kind: InvocationKind,
365    pub fragment_kind: AstFragmentKind,
366    pub expansion_data: ExpansionData,
367}
368
369pub enum InvocationKind {
370    Bang {
371        mac: Box<ast::MacCall>,
372        span: Span,
373    },
374    Attr {
375        attr: ast::Attribute,
376        /// Re-insertion position for inert attributes.
377        pos: usize,
378        item: Annotatable,
379        /// Required for resolving derive helper attributes.
380        derives: Vec<ast::Path>,
381    },
382    Derive {
383        path: ast::Path,
384        is_const: bool,
385        item: Annotatable,
386    },
387    GlobDelegation {
388        item: Box<ast::AssocItem>,
389        /// Whether this is a trait impl or an inherent impl
390        of_trait: bool,
391    },
392}
393
394impl InvocationKind {
395    fn placeholder_visibility(&self) -> Option<ast::Visibility> {
396        // HACK: For unnamed fields placeholders should have the same visibility as the actual
397        // fields because for tuple structs/variants resolve determines visibilities of their
398        // constructor using these field visibilities before attributes on them are expanded.
399        // The assumption is that the attribute expansion cannot change field visibilities,
400        // and it holds because only inert attributes are supported in this position.
401        match self {
402            InvocationKind::Attr { item: Annotatable::FieldDef(field), .. }
403            | InvocationKind::Derive { item: Annotatable::FieldDef(field), .. }
404                if field.ident.is_none() =>
405            {
406                Some(field.vis.clone())
407            }
408            _ => None,
409        }
410    }
411}
412
413impl Invocation {
414    pub fn span(&self) -> Span {
415        match &self.kind {
416            InvocationKind::Bang { span, .. } => *span,
417            InvocationKind::Attr { attr, .. } => attr.span,
418            InvocationKind::Derive { path, .. } => path.span,
419            InvocationKind::GlobDelegation { item, .. } => item.span,
420        }
421    }
422
423    fn span_mut(&mut self) -> &mut Span {
424        match &mut self.kind {
425            InvocationKind::Bang { span, .. } => span,
426            InvocationKind::Attr { attr, .. } => &mut attr.span,
427            InvocationKind::Derive { path, .. } => &mut path.span,
428            InvocationKind::GlobDelegation { item, .. } => &mut item.span,
429        }
430    }
431}
432
433pub struct MacroExpander<'a, 'b> {
434    pub cx: &'a mut ExtCtxt<'b>,
435    monotonic: bool, // cf. `cx.monotonic_expander()`
436}
437
438impl<'a, 'b> MacroExpander<'a, 'b> {
439    pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self {
440        MacroExpander { cx, monotonic }
441    }
442
443    pub fn expand_crate(&mut self, krate: ast::Crate) -> ast::Crate {
444        let file_path = match self.cx.source_map().span_to_filename(krate.spans.inner_span) {
445            FileName::Real(name) => name
446                .into_local_path()
447                .expect("attempting to resolve a file path in an external file"),
448            other => PathBuf::from(other.prefer_local_unconditionally().to_string()),
449        };
450        let dir_path = file_path.parent().unwrap_or(&file_path).to_owned();
451        self.cx.root_path = dir_path.clone();
452        self.cx.current_expansion.module = Rc::new(ModuleData {
453            mod_path: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [Ident::with_dummy_span(self.cx.ecfg.crate_name)]))vec![Ident::with_dummy_span(self.cx.ecfg.crate_name)],
454            file_path_stack: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [file_path]))vec![file_path],
455            dir_path,
456        });
457        let krate = self.fully_expand_fragment(AstFragment::Crate(krate)).make_crate();
458        match (&krate.id, &ast::CRATE_NODE_ID) {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
};assert_eq!(krate.id, ast::CRATE_NODE_ID);
459        self.cx.trace_macros_diag();
460        krate
461    }
462
463    /// Recursively expand all macro invocations in this AST fragment.
464    pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
465        let orig_expansion_data = self.cx.current_expansion.clone();
466        let orig_force_mode = self.cx.force_mode;
467
468        // Collect all macro invocations and replace them with placeholders.
469        let (mut fragment_with_placeholders, mut invocations) =
470            self.collect_invocations(input_fragment, &[]);
471
472        // Optimization: if we resolve all imports now,
473        // we'll be able to immediately resolve most of imported macros.
474        self.resolve_imports();
475
476        // Resolve paths in all invocations and produce output expanded fragments for them, but
477        // do not insert them into our input AST fragment yet, only store in `expanded_fragments`.
478        // The output fragments also go through expansion recursively until no invocations are left.
479        // Unresolved macros produce dummy outputs as a recovery measure.
480        invocations.reverse();
481        let mut expanded_fragments = Vec::new();
482        let mut expanded_fragments_len = 0;
483        let mut undetermined_invocations = Vec::new();
484        let (mut progress, mut force) = (false, !self.monotonic);
485        loop {
486            let Some((invoc, ext)) = invocations.pop() else {
487                self.resolve_imports();
488                if undetermined_invocations.is_empty() {
489                    break;
490                }
491                invocations = mem::take(&mut undetermined_invocations);
492                force = !progress;
493                progress = false;
494                if force && self.monotonic {
495                    self.cx.dcx().span_delayed_bug(
496                        invocations.last().unwrap().0.span(),
497                        "expansion entered force mode without producing any errors",
498                    );
499                }
500                continue;
501            };
502
503            let ext = match ext {
504                Some(ext) => ext,
505                None => {
506                    let eager_expansion_root = if self.monotonic {
507                        invoc.expansion_data.id
508                    } else {
509                        orig_expansion_data.id
510                    };
511                    match self.cx.resolver.resolve_macro_invocation(
512                        &invoc,
513                        eager_expansion_root,
514                        force,
515                    ) {
516                        Ok(ext) => ext,
517                        Err(Indeterminate) => {
518                            // Cannot resolve, will retry this invocation later.
519                            undetermined_invocations.push((invoc, None));
520                            continue;
521                        }
522                    }
523                }
524            };
525
526            let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
527            let depth = depth - orig_expansion_data.depth;
528            self.cx.current_expansion = invoc.expansion_data.clone();
529            self.cx.force_mode = force;
530
531            let fragment_kind = invoc.fragment_kind;
532            match self.expand_invoc(invoc, &ext.kind) {
533                ExpandResult::Ready(fragment) => {
534                    let mut derive_invocations = Vec::new();
535                    let derive_placeholders = self
536                        .cx
537                        .resolver
538                        .take_derive_resolutions(expn_id)
539                        .map(|derives| {
540                            derive_invocations.reserve(derives.len());
541                            derives
542                                .into_iter()
543                                .map(|DeriveResolution { path, item, exts: _, is_const }| {
544                                    // FIXME: Consider using the derive resolutions (`_exts`)
545                                    // instead of enqueuing the derives to be resolved again later.
546                                    // Note that this can result in duplicate diagnostics.
547                                    let expn_id = LocalExpnId::fresh_empty();
548                                    derive_invocations.push((
549                                        Invocation {
550                                            kind: InvocationKind::Derive { path, item, is_const },
551                                            fragment_kind,
552                                            expansion_data: ExpansionData {
553                                                id: expn_id,
554                                                ..self.cx.current_expansion.clone()
555                                            },
556                                        },
557                                        None,
558                                    ));
559                                    NodeId::placeholder_from_expn_id(expn_id)
560                                })
561                                .collect::<Vec<_>>()
562                        })
563                        .unwrap_or_default();
564
565                    let (expanded_fragment, collected_invocations) =
566                        self.collect_invocations(fragment, &derive_placeholders);
567                    // We choose to expand any derive invocations associated with this macro
568                    // invocation *before* any macro invocations collected from the output
569                    // fragment.
570                    derive_invocations.extend(collected_invocations);
571
572                    progress = true;
573                    if expanded_fragments.len() < depth {
574                        expanded_fragments.push(Vec::new());
575                    }
576                    expanded_fragments[depth - 1].push((expn_id, expanded_fragment));
577                    expanded_fragments_len += 1;
578                    invocations.extend(derive_invocations.into_iter().rev());
579                }
580                ExpandResult::Retry(invoc) => {
581                    if force {
582                        self.cx.dcx().span_bug(
583                            invoc.span(),
584                            "expansion entered force mode but is still stuck",
585                        );
586                    } else {
587                        // Cannot expand, will retry this invocation later.
588                        undetermined_invocations.push((invoc, Some(ext)));
589                    }
590                }
591            }
592        }
593
594        self.cx.current_expansion = orig_expansion_data;
595        self.cx.force_mode = orig_force_mode;
596
597        // Finally incorporate all the expanded macros into the input AST fragment.
598        let mut placeholder_expander = PlaceholderExpander::with_capacity(expanded_fragments_len);
599        while let Some(expanded_fragments) = expanded_fragments.pop() {
600            for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
601                placeholder_expander
602                    .add(NodeId::placeholder_from_expn_id(expn_id), expanded_fragment);
603            }
604        }
605        fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
606        fragment_with_placeholders
607    }
608
609    fn resolve_imports(&mut self) {
610        if self.monotonic {
611            self.cx.resolver.resolve_imports();
612        }
613    }
614
615    /// Collects all macro invocations reachable at this time in this AST fragment, and replace
616    /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
617    /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
618    /// prepares data for resolving paths of macro invocations.
619    fn collect_invocations(
620        &mut self,
621        mut fragment: AstFragment,
622        extra_placeholders: &[NodeId],
623    ) -> (AstFragment, Vec<(Invocation, Option<Arc<SyntaxExtension>>)>) {
624        // Resolve `$crate`s in the fragment for pretty-printing.
625        self.cx.resolver.resolve_dollar_crates();
626
627        let mut invocations = {
628            let mut collector = InvocationCollector {
629                // Non-derive macro invocations cannot see the results of cfg expansion - they
630                // will either be removed along with the item, or invoked before the cfg/cfg_attr
631                // attribute is expanded. Therefore, we don't need to configure the tokens
632                // Derive macros *can* see the results of cfg-expansion - they are handled
633                // specially in `fully_expand_fragment`
634                cx: self.cx,
635                invocations: Vec::new(),
636                monotonic: self.monotonic,
637            };
638            fragment.mut_visit_with(&mut collector);
639            fragment.add_placeholders(extra_placeholders);
640            collector.invocations
641        };
642
643        if self.monotonic {
644            self.cx
645                .resolver
646                .visit_ast_fragment_with_placeholders(self.cx.current_expansion.id, &fragment);
647
648            if self.cx.sess.opts.incremental.is_some() {
649                for (invoc, _) in invocations.iter_mut() {
650                    let expn_id = invoc.expansion_data.id;
651                    let parent_def = self.cx.resolver.invocation_parent(expn_id);
652                    let span = invoc.span_mut();
653                    *span = span.with_parent(Some(parent_def));
654                }
655            }
656        }
657
658        (fragment, invocations)
659    }
660
661    fn error_recursion_limit_reached(&mut self) -> ErrorGuaranteed {
662        let expn_data = self.cx.current_expansion.id.expn_data();
663        let suggested_limit = match self.cx.ecfg.recursion_limit {
664            Limit(0) => Limit(2),
665            limit => limit * 2,
666        };
667
668        let guar = self.cx.dcx().emit_err(RecursionLimitReached {
669            span: expn_data.call_site,
670            descr: expn_data.kind.descr(),
671            suggested_limit,
672            crate_name: self.cx.ecfg.crate_name,
673        });
674
675        self.cx.macro_error_and_trace_macros_diag();
676        guar
677    }
678
679    /// A macro's expansion does not fit in this fragment kind.
680    /// For example, a non-type macro in a type position.
681    fn error_wrong_fragment_kind(
682        &mut self,
683        kind: AstFragmentKind,
684        mac: &ast::MacCall,
685        span: Span,
686    ) -> ErrorGuaranteed {
687        let name = pprust::path_to_string(&mac.path);
688        let guar = self.cx.dcx().emit_err(WrongFragmentKind { span, kind: kind.name(), name });
689        self.cx.macro_error_and_trace_macros_diag();
690        guar
691    }
692
693    fn expand_invoc(
694        &mut self,
695        invoc: Invocation,
696        ext: &SyntaxExtensionKind,
697    ) -> ExpandResult<AstFragment, Invocation> {
698        let recursion_limit = match self.cx.reduced_recursion_limit {
699            Some((limit, _)) => limit,
700            None => self.cx.ecfg.recursion_limit,
701        };
702
703        if !recursion_limit.value_within_limit(self.cx.current_expansion.depth) {
704            let guar = match self.cx.reduced_recursion_limit {
705                Some((_, guar)) => guar,
706                None => self.error_recursion_limit_reached(),
707            };
708
709            // Reduce the recursion limit by half each time it triggers.
710            self.cx.reduced_recursion_limit = Some((recursion_limit / 2, guar));
711
712            return ExpandResult::Ready(invoc.fragment_kind.dummy(invoc.span(), guar));
713        }
714
715        let macro_stats = self.cx.sess.opts.unstable_opts.macro_stats;
716
717        let (fragment_kind, span) = (invoc.fragment_kind, invoc.span());
718        ExpandResult::Ready(match invoc.kind {
719            InvocationKind::Bang { mac, span } => {
720                if let SyntaxExtensionKind::Bang(expander) = ext {
721                    match expander.expand(self.cx, span, mac.args.tokens.clone()) {
722                        Ok(tok_result) => {
723                            let fragment =
724                                self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span);
725                            if macro_stats {
726                                update_bang_macro_stats(
727                                    self.cx,
728                                    fragment_kind,
729                                    span,
730                                    mac,
731                                    &fragment,
732                                );
733                            }
734                            fragment
735                        }
736                        Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
737                    }
738                } else if let Some(expander) = ext.as_legacy_bang() {
739                    let tok_result = match expander.expand(self.cx, span, mac.args.tokens.clone()) {
740                        ExpandResult::Ready(tok_result) => tok_result,
741                        ExpandResult::Retry(_) => {
742                            // retry the original
743                            return ExpandResult::Retry(Invocation {
744                                kind: InvocationKind::Bang { mac, span },
745                                ..invoc
746                            });
747                        }
748                    };
749                    if let Some(fragment) = fragment_kind.make_from(tok_result) {
750                        if macro_stats {
751                            update_bang_macro_stats(self.cx, fragment_kind, span, mac, &fragment);
752                        }
753                        fragment
754                    } else {
755                        let guar = self.error_wrong_fragment_kind(fragment_kind, &mac, span);
756                        fragment_kind.dummy(span, guar)
757                    }
758                } else {
759                    ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
760                }
761            }
762            InvocationKind::Attr { attr, pos, mut item, derives } => {
763                if let Some(expander) = ext.as_attr() {
764                    self.gate_proc_macro_input(&item);
765                    self.gate_proc_macro_attr_item(span, &item);
766                    let tokens = match &item {
767                        // FIXME: Collect tokens and use them instead of generating
768                        // fake ones. These are unstable, so it needs to be
769                        // fixed prior to stabilization
770                        // Fake tokens when we are invoking an inner attribute, and
771                        // we are invoking it on an out-of-line module or crate.
772                        Annotatable::Crate(krate) => {
773                            rustc_parse::fake_token_stream_for_crate(&self.cx.sess.psess, krate)
774                        }
775                        Annotatable::Item(item_inner)
776                            if #[allow(non_exhaustive_omitted_patterns)] match attr.style {
    AttrStyle::Inner => true,
    _ => false,
}matches!(attr.style, AttrStyle::Inner)
777                                && #[allow(non_exhaustive_omitted_patterns)] match item_inner.kind {
    ItemKind::Mod(_, _,
        ModKind::Unloaded | ModKind::Loaded(_, Inline::No { .. }, _)) => true,
    _ => false,
}matches!(
778                                    item_inner.kind,
779                                    ItemKind::Mod(
780                                        _,
781                                        _,
782                                        ModKind::Unloaded
783                                            | ModKind::Loaded(_, Inline::No { .. }, _),
784                                    )
785                                ) =>
786                        {
787                            rustc_parse::fake_token_stream_for_item(&self.cx.sess.psess, item_inner)
788                        }
789                        Annotatable::Item(item_inner) if item_inner.tokens.is_none() => {
790                            rustc_parse::fake_token_stream_for_item(&self.cx.sess.psess, item_inner)
791                        }
792                        // When a function has EII implementations attached (via `eii_impls`),
793                        // use fake tokens so the pretty-printer re-emits the EII attribute
794                        // (e.g. `#[hello]`) in the token stream. Without this, the EII
795                        // attribute is lost during the token roundtrip performed by
796                        // `AttrProcMacro` expanders like `contracts::requires/ensures`,
797                        // breaking the EII link on the resulting re-parsed item.
798                        Annotatable::Item(item_inner)
799                            if #[allow(non_exhaustive_omitted_patterns)] match &item_inner.kind {
    ItemKind::Fn(f) if !f.eii_impls.is_empty() => true,
    _ => false,
}matches!(&item_inner.kind,
800                                ItemKind::Fn(f) if !f.eii_impls.is_empty()) =>
801                        {
802                            rustc_parse::fake_token_stream_for_item(&self.cx.sess.psess, item_inner)
803                        }
804                        Annotatable::ForeignItem(item_inner) if item_inner.tokens.is_none() => {
805                            rustc_parse::fake_token_stream_for_foreign_item(
806                                &self.cx.sess.psess,
807                                item_inner,
808                            )
809                        }
810                        _ => item.to_tokens(),
811                    };
812                    let attr_item = attr.get_normal_item();
813                    let safety = attr_item.unsafety;
814                    if let AttrArgs::Eq { .. } = attr_item.args.unparsed_ref().unwrap() {
815                        self.cx.dcx().emit_err(UnsupportedKeyValue { span });
816                    }
817                    let inner_tokens = attr_item.args.unparsed_ref().unwrap().inner_tokens();
818                    match expander.expand_with_safety(self.cx, safety, span, inner_tokens, tokens) {
819                        Ok(tok_result) => {
820                            let fragment = self.parse_ast_fragment(
821                                tok_result,
822                                fragment_kind,
823                                &attr_item.path,
824                                span,
825                            );
826                            if macro_stats {
827                                update_attr_macro_stats(
828                                    self.cx,
829                                    fragment_kind,
830                                    span,
831                                    &attr_item.path,
832                                    &attr,
833                                    item,
834                                    &fragment,
835                                );
836                            }
837                            fragment
838                        }
839                        Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
840                    }
841                } else if let SyntaxExtensionKind::LegacyAttr(expander) = ext {
842                    // `LegacyAttr` is only used for builtin attribute macros, which have their
843                    // safety checked by `check_builtin_meta_item`, so we don't need to check
844                    // `unsafety` here.
845                    match validate_attr::parse_meta(&self.cx.sess.psess, &attr) {
846                        Ok(meta) => {
847                            let item_clone = macro_stats.then(|| item.clone());
848                            let items = match expander.expand(self.cx, span, &meta, item, false) {
849                                ExpandResult::Ready(items) => items,
850                                ExpandResult::Retry(item) => {
851                                    // Reassemble the original invocation for retrying.
852                                    return ExpandResult::Retry(Invocation {
853                                        kind: InvocationKind::Attr { attr, pos, item, derives },
854                                        ..invoc
855                                    });
856                                }
857                            };
858                            if #[allow(non_exhaustive_omitted_patterns)] match fragment_kind {
    AstFragmentKind::Expr | AstFragmentKind::MethodReceiverExpr => true,
    _ => false,
}matches!(
859                                fragment_kind,
860                                AstFragmentKind::Expr | AstFragmentKind::MethodReceiverExpr
861                            ) && items.is_empty()
862                            {
863                                let guar = self.cx.dcx().emit_err(RemoveExprNotSupported { span });
864                                fragment_kind.dummy(span, guar)
865                            } else {
866                                let fragment = fragment_kind.expect_from_annotatables(items);
867                                if macro_stats {
868                                    update_attr_macro_stats(
869                                        self.cx,
870                                        fragment_kind,
871                                        span,
872                                        &meta.path,
873                                        &attr,
874                                        item_clone.unwrap(),
875                                        &fragment,
876                                    );
877                                }
878                                fragment
879                            }
880                        }
881                        Err(err) => {
882                            let _guar = err.emit();
883                            fragment_kind.expect_from_annotatables(iter::once(item))
884                        }
885                    }
886                } else if let SyntaxExtensionKind::NonMacroAttr = ext {
887                    // `-Zmacro-stats` ignores these because they don't do any real expansion.
888                    self.cx.expanded_inert_attrs.mark(&attr);
889                    item.visit_attrs(|attrs| attrs.insert(pos, attr));
890                    fragment_kind.expect_from_annotatables(iter::once(item))
891                } else {
892                    ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
893                }
894            }
895            InvocationKind::Derive { path, item, is_const } => match ext {
896                SyntaxExtensionKind::Derive(expander)
897                | SyntaxExtensionKind::LegacyDerive(expander) => {
898                    if let SyntaxExtensionKind::Derive(..) = ext {
899                        self.gate_proc_macro_input(&item);
900                    }
901                    // The `MetaItem` representing the trait to derive can't
902                    // have an unsafe around it (as of now).
903                    let meta = ast::MetaItem {
904                        unsafety: ast::Safety::Default,
905                        kind: MetaItemKind::Word,
906                        span,
907                        path,
908                    };
909                    let items = match expander.expand(self.cx, span, &meta, item, is_const) {
910                        ExpandResult::Ready(items) => items,
911                        ExpandResult::Retry(item) => {
912                            // Reassemble the original invocation for retrying.
913                            return ExpandResult::Retry(Invocation {
914                                kind: InvocationKind::Derive { path: meta.path, item, is_const },
915                                ..invoc
916                            });
917                        }
918                    };
919                    let fragment = fragment_kind.expect_from_annotatables(items);
920                    if macro_stats {
921                        update_derive_macro_stats(
922                            self.cx,
923                            fragment_kind,
924                            span,
925                            &meta.path,
926                            &fragment,
927                        );
928                    }
929                    fragment
930                }
931                SyntaxExtensionKind::MacroRules(expander)
932                    if expander.kinds().contains(MacroKinds::DERIVE) =>
933                {
934                    if is_const {
935                        let guar = self
936                            .cx
937                            .dcx()
938                            .span_err(span, "macro `derive` does not support const derives");
939                        return ExpandResult::Ready(fragment_kind.dummy(span, guar));
940                    }
941                    let body = item.to_tokens();
942                    match expander.expand_derive(self.cx, span, &body) {
943                        Ok(tok_result) => {
944                            let fragment =
945                                self.parse_ast_fragment(tok_result, fragment_kind, &path, span);
946                            if macro_stats {
947                                update_derive_macro_stats(
948                                    self.cx,
949                                    fragment_kind,
950                                    span,
951                                    &path,
952                                    &fragment,
953                                );
954                            }
955                            fragment
956                        }
957                        Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
958                    }
959                }
960                _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
961            },
962            InvocationKind::GlobDelegation { item, of_trait } => {
963                let AssocItemKind::DelegationMac(deleg) = &item.kind else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
964                let suffixes = match ext {
965                    SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx)
966                    {
967                        ExpandResult::Ready(suffixes) => suffixes,
968                        ExpandResult::Retry(()) => {
969                            // Reassemble the original invocation for retrying.
970                            return ExpandResult::Retry(Invocation {
971                                kind: InvocationKind::GlobDelegation { item, of_trait },
972                                ..invoc
973                            });
974                        }
975                    },
976                    SyntaxExtensionKind::Bang(..) => {
977                        let msg = "expanded a dummy glob delegation";
978                        let guar = self.cx.dcx().span_delayed_bug(span, msg);
979                        return ExpandResult::Ready(fragment_kind.dummy(span, guar));
980                    }
981                    _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
982                };
983
984                type Node = AstNodeWrapper<Box<ast::AssocItem>, ImplItemTag>;
985                let single_delegations = build_single_delegations::<Node>(
986                    self.cx, deleg, &item, &suffixes, item.span, true,
987                );
988                // `-Zmacro-stats` ignores these because they don't seem important.
989                fragment_kind.expect_from_annotatables(single_delegations.map(|item| {
990                    Annotatable::AssocItem(Box::new(item), AssocCtxt::Impl { of_trait })
991                }))
992            }
993        })
994    }
995
996    fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
997        let kind = match item {
998            Annotatable::Item(_)
999            | Annotatable::AssocItem(..)
1000            | Annotatable::ForeignItem(_)
1001            | Annotatable::Crate(..) => return,
1002            Annotatable::Stmt(stmt) => {
1003                // Attributes are stable on item statements,
1004                // but unstable on all other kinds of statements
1005                if stmt.is_item() {
1006                    return;
1007                }
1008                "statements"
1009            }
1010            Annotatable::Expr(_) => "expressions",
1011            Annotatable::Arm(..)
1012            | Annotatable::ExprField(..)
1013            | Annotatable::PatField(..)
1014            | Annotatable::GenericParam(..)
1015            | Annotatable::Param(..)
1016            | Annotatable::FieldDef(..)
1017            | Annotatable::Variant(..)
1018            | Annotatable::WherePredicate(..) => { ::core::panicking::panic_fmt(format_args!("unexpected annotatable")); }panic!("unexpected annotatable"),
1019        };
1020        if self.cx.ecfg.features.proc_macro_hygiene() {
1021            return;
1022        }
1023        feature_err(
1024            self.cx.sess,
1025            sym::proc_macro_hygiene,
1026            span,
1027            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("custom attributes cannot be applied to {0}",
                kind))
    })format!("custom attributes cannot be applied to {kind}"),
1028        )
1029        .emit();
1030    }
1031
1032    fn gate_proc_macro_input(&self, annotatable: &Annotatable) {
1033        struct GateProcMacroInput<'a> {
1034            sess: &'a Session,
1035        }
1036
1037        impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
1038            fn visit_item(&mut self, item: &'ast ast::Item) {
1039                match &item.kind {
1040                    ItemKind::Mod(_, _, mod_kind)
1041                        if !#[allow(non_exhaustive_omitted_patterns)] match mod_kind {
    ModKind::Loaded(_, Inline::Yes, _) => true,
    _ => false,
}matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) =>
1042                    {
1043                        feature_err(
1044                            self.sess,
1045                            sym::proc_macro_hygiene,
1046                            item.span,
1047                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("file modules in proc macro input are unstable"))msg!("file modules in proc macro input are unstable"),
1048                        )
1049                        .emit();
1050                    }
1051                    _ => {}
1052                }
1053
1054                visit::walk_item(self, item);
1055            }
1056        }
1057
1058        if !self.cx.ecfg.features.proc_macro_hygiene() {
1059            annotatable.visit_with(&mut GateProcMacroInput { sess: self.cx.sess });
1060        }
1061    }
1062
1063    fn parse_ast_fragment(
1064        &mut self,
1065        toks: TokenStream,
1066        kind: AstFragmentKind,
1067        path: &ast::Path,
1068        span: Span,
1069    ) -> AstFragment {
1070        let mut parser = self.cx.new_parser_from_tts(toks);
1071        match parse_ast_fragment(&mut parser, kind) {
1072            Ok(fragment) => {
1073                ensure_complete_parse(&parser, path, kind.name(), span);
1074                fragment
1075            }
1076            Err(mut err) => {
1077                if err.span.is_dummy() {
1078                    err.span(span);
1079                }
1080                annotate_err_with_kind(&mut err, kind, span);
1081                let guar = err.emit();
1082                self.cx.macro_error_and_trace_macros_diag();
1083                kind.dummy(span, guar)
1084            }
1085        }
1086    }
1087}
1088
1089pub fn parse_ast_fragment<'a>(
1090    this: &mut Parser<'a>,
1091    kind: AstFragmentKind,
1092) -> PResult<'a, AstFragment> {
1093    Ok(match kind {
1094        AstFragmentKind::Items => {
1095            let mut items = SmallVec::new();
1096            while let Some(item) = this.parse_item(ForceCollect::No, AllowConstBlockItems::Yes)? {
1097                items.push(item);
1098            }
1099            AstFragment::Items(items)
1100        }
1101        AstFragmentKind::TraitItems => {
1102            let mut items = SmallVec::new();
1103            while let Some(item) = this.parse_trait_item(ForceCollect::No)? {
1104                items.extend(item);
1105            }
1106            AstFragment::TraitItems(items)
1107        }
1108        AstFragmentKind::ImplItems => {
1109            let mut items = SmallVec::new();
1110            while let Some(item) = this.parse_impl_item(ForceCollect::No)? {
1111                items.extend(item);
1112            }
1113            AstFragment::ImplItems(items)
1114        }
1115        AstFragmentKind::TraitImplItems => {
1116            let mut items = SmallVec::new();
1117            while let Some(item) = this.parse_impl_item(ForceCollect::No)? {
1118                items.extend(item);
1119            }
1120            AstFragment::TraitImplItems(items)
1121        }
1122        AstFragmentKind::ForeignItems => {
1123            let mut items = SmallVec::new();
1124            while let Some(item) = this.parse_foreign_item(ForceCollect::No)? {
1125                items.extend(item);
1126            }
1127            AstFragment::ForeignItems(items)
1128        }
1129        AstFragmentKind::Stmts => {
1130            let mut stmts = SmallVec::new();
1131            // Won't make progress on a `}`.
1132            while this.token != token::Eof && this.token != token::CloseBrace {
1133                if let Some(stmt) = this.parse_full_stmt(AttemptLocalParseRecovery::Yes)? {
1134                    stmts.push(stmt);
1135                }
1136            }
1137            AstFragment::Stmts(stmts)
1138        }
1139        AstFragmentKind::Expr => AstFragment::Expr(this.parse_expr()?),
1140        AstFragmentKind::MethodReceiverExpr => AstFragment::MethodReceiverExpr(this.parse_expr()?),
1141        AstFragmentKind::OptExpr => {
1142            if this.token != token::Eof {
1143                AstFragment::OptExpr(Some(this.parse_expr()?))
1144            } else {
1145                AstFragment::OptExpr(None)
1146            }
1147        }
1148        AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?),
1149        AstFragmentKind::Pat => AstFragment::Pat(Box::new(this.parse_pat_allow_top_guard(
1150            None,
1151            RecoverComma::No,
1152            RecoverColon::Yes,
1153            CommaRecoveryMode::LikelyTuple,
1154        )?)),
1155        AstFragmentKind::Crate => AstFragment::Crate(this.parse_crate_mod()?),
1156        AstFragmentKind::Arms
1157        | AstFragmentKind::ExprFields
1158        | AstFragmentKind::PatFields
1159        | AstFragmentKind::GenericParams
1160        | AstFragmentKind::Params
1161        | AstFragmentKind::FieldDefs
1162        | AstFragmentKind::Variants
1163        | AstFragmentKind::WherePredicates => {
    ::core::panicking::panic_fmt(format_args!("unexpected AST fragment kind"));
}panic!("unexpected AST fragment kind"),
1164    })
1165}
1166
1167pub(crate) fn ensure_complete_parse<'a>(
1168    parser: &Parser<'a>,
1169    macro_path: &ast::Path,
1170    kind_name: &str,
1171    span: Span,
1172) {
1173    if parser.token != token::Eof {
1174        let descr = token_descr(&parser.token);
1175        // Avoid emitting backtrace info twice.
1176        let def_site_span = parser.token.span.with_ctxt(SyntaxContext::root());
1177
1178        let semi_span = parser.psess.source_map().next_point(span);
1179        let add_semicolon = match &parser.psess.source_map().span_to_snippet(semi_span) {
1180            Ok(snippet) if &snippet[..] != ";" && kind_name == "expression" => {
1181                Some(span.shrink_to_hi())
1182            }
1183            _ => None,
1184        };
1185
1186        let expands_to_match_arm = kind_name == "pattern" && parser.token == token::FatArrow;
1187
1188        parser.dcx().emit_err(IncompleteParse {
1189            span: def_site_span,
1190            descr,
1191            label_span: span,
1192            macro_path: pprust::path_to_string(macro_path),
1193            kind_name,
1194            expands_to_match_arm,
1195            add_semicolon,
1196        });
1197    }
1198}
1199
1200/// Wraps a call to `walk_*` / `walk_flat_map_*`
1201/// for an AST node that supports attributes
1202/// (see the `Annotatable` enum)
1203/// This method assigns a `NodeId`, and sets that `NodeId`
1204/// as our current 'lint node id'. If a macro call is found
1205/// inside this AST node, we will use this AST node's `NodeId`
1206/// to emit lints associated with that macro (allowing
1207/// `#[allow]` / `#[deny]` to be applied close to
1208/// the macro invocation).
1209///
1210/// Do *not* call this for a macro AST node
1211/// (e.g. `ExprKind::MacCall`) - we cannot emit lints
1212/// at these AST nodes, since they are removed and
1213/// replaced with the result of macro expansion.
1214///
1215/// All other `NodeId`s are assigned by `visit_id`.
1216/// * `self` is the 'self' parameter for the current method,
1217/// * `id` is a mutable reference to the `NodeId` field
1218///    of the current AST node.
1219/// * `closure` is a closure that executes the
1220///   `walk_*` / `walk_flat_map_*` method
1221///   for the current AST node.
1222macro_rules! assign_id {
1223    ($self:ident, $id:expr, $closure:expr) => {{
1224        let old_id = $self.cx.current_expansion.lint_node_id;
1225        if $self.monotonic {
1226            debug_assert_eq!(*$id, ast::DUMMY_NODE_ID);
1227            let new_id = $self.cx.resolver.next_node_id();
1228            *$id = new_id;
1229            $self.cx.current_expansion.lint_node_id = new_id;
1230        }
1231        let ret = ($closure)();
1232        $self.cx.current_expansion.lint_node_id = old_id;
1233        ret
1234    }};
1235}
1236
1237enum AddSemicolon {
1238    Yes,
1239    No,
1240}
1241
1242/// A trait implemented for all `AstFragment` nodes and providing all pieces
1243/// of functionality used by `InvocationCollector`.
1244trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
1245    type OutputTy = SmallVec<[Self; 1]>;
1246    type ItemKind = ItemKind;
1247    const KIND: AstFragmentKind;
1248    fn to_annotatable(self) -> Annotatable;
1249    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy;
1250    fn descr() -> &'static str {
1251        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1252    }
1253    fn walk_flat_map(self, _collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1254        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1255    }
1256    fn walk(&mut self, _collector: &mut InvocationCollector<'_, '_>) {
1257        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1258    }
1259    fn is_mac_call(&self) -> bool {
1260        false
1261    }
1262    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1263        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1264    }
1265    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
1266        None
1267    }
1268    fn delegation_item_kind(_deleg: Box<ast::Delegation>) -> Self::ItemKind {
1269        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1270    }
1271    fn from_item(_item: ast::Item<Self::ItemKind>) -> Self {
1272        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1273    }
1274    fn flatten_outputs(_outputs: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
1275        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1276    }
1277    fn pre_flat_map_node_collect_attr(_cfg: &StripUnconfigured<'_>, _attr: &ast::Attribute) {}
1278    fn post_flat_map_node_collect_bang(_output: &mut Self::OutputTy, _add_semicolon: AddSemicolon) {
1279    }
1280    fn wrap_flat_map_node_walk_flat_map(
1281        node: Self,
1282        collector: &mut InvocationCollector<'_, '_>,
1283        walk_flat_map: impl FnOnce(Self, &mut InvocationCollector<'_, '_>) -> Self::OutputTy,
1284    ) -> Result<Self::OutputTy, Self> {
1285        Ok(walk_flat_map(node, collector))
1286    }
1287    fn expand_cfg_false(
1288        &mut self,
1289        collector: &mut InvocationCollector<'_, '_>,
1290        _pos: usize,
1291        span: Span,
1292    ) {
1293        collector.cx.dcx().emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
1294    }
1295
1296    /// All of the identifiers (items) declared by this node.
1297    /// This is an approximation and should only be used for diagnostics.
1298    fn declared_idents(&self) -> Vec<Ident> {
1299        ::alloc::vec::Vec::new()vec![]
1300    }
1301
1302    fn as_target(&self) -> Target;
1303}
1304
1305impl InvocationCollectorNode for Box<ast::Item> {
1306    const KIND: AstFragmentKind = AstFragmentKind::Items;
1307    fn to_annotatable(self) -> Annotatable {
1308        Annotatable::Item(self)
1309    }
1310    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1311        fragment.make_items()
1312    }
1313    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1314        walk_flat_map_item(collector, self)
1315    }
1316    fn is_mac_call(&self) -> bool {
1317        #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    ItemKind::MacCall(..) => true,
    _ => false,
}matches!(self.kind, ItemKind::MacCall(..))
1318    }
1319    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1320        match self.kind {
1321            ItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
1322            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1323        }
1324    }
1325    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
1326        match &self.kind {
1327            ItemKind::DelegationMac(deleg) => Some((deleg, self)),
1328            _ => None,
1329        }
1330    }
1331    fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
1332        ItemKind::Delegation(deleg)
1333    }
1334    fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
1335        Box::new(item)
1336    }
1337    fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
1338        items.flatten().collect()
1339    }
1340    fn wrap_flat_map_node_walk_flat_map(
1341        mut node: Self,
1342        collector: &mut InvocationCollector<'_, '_>,
1343        walk_flat_map: impl FnOnce(Self, &mut InvocationCollector<'_, '_>) -> Self::OutputTy,
1344    ) -> Result<Self::OutputTy, Self> {
1345        if !#[allow(non_exhaustive_omitted_patterns)] match node.kind {
    ItemKind::Mod(..) => true,
    _ => false,
}matches!(node.kind, ItemKind::Mod(..)) {
1346            return Ok(walk_flat_map(node, collector));
1347        }
1348
1349        // Work around borrow checker not seeing through `P`'s deref.
1350        let (span, mut attrs) = (node.span, mem::take(&mut node.attrs));
1351        let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { ::core::panicking::panic("internal error: entered unreachable code")unreachable!() };
1352        let ecx = &mut collector.cx;
1353        let (file_path, dir_path, dir_ownership) = match mod_kind {
1354            ModKind::Loaded(_, inline, _) => {
1355                // Inline `mod foo { ... }`, but we still need to push directories.
1356                let (dir_path, dir_ownership) = mod_dir_path(
1357                    ecx.sess,
1358                    ident,
1359                    &attrs,
1360                    &ecx.current_expansion.module,
1361                    ecx.current_expansion.dir_ownership,
1362                    *inline,
1363                );
1364                // If the module was parsed from an external file, recover its path.
1365                // This lets `parse_external_mod` catch cycles if it's self-referential.
1366                let file_path = match inline {
1367                    Inline::Yes => None,
1368                    Inline::No { .. } => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path),
1369                };
1370                node.attrs = attrs;
1371                (file_path, dir_path, dir_ownership)
1372            }
1373            ModKind::Unloaded => {
1374                // We have an outline `mod foo;` so we need to parse the file.
1375                let old_attrs_len = attrs.len();
1376                let ParsedExternalMod {
1377                    items,
1378                    spans,
1379                    file_path,
1380                    dir_path,
1381                    dir_ownership,
1382                    had_parse_error,
1383                } = parse_external_mod(
1384                    ecx.sess,
1385                    ident,
1386                    span,
1387                    &ecx.current_expansion.module,
1388                    ecx.current_expansion.dir_ownership,
1389                    &mut attrs,
1390                );
1391
1392                if let Some(lint_store) = ecx.lint_store {
1393                    lint_store.pre_expansion_lint(
1394                        ecx.sess,
1395                        ecx.ecfg.features,
1396                        ecx.resolver.registered_tools(),
1397                        ecx.current_expansion.lint_node_id,
1398                        &attrs,
1399                        &items,
1400                        ident.name,
1401                    );
1402                }
1403
1404                *mod_kind = ModKind::Loaded(items, Inline::No { had_parse_error }, spans);
1405                node.attrs = attrs;
1406                if node.attrs.len() > old_attrs_len {
1407                    // If we loaded an out-of-line module and added some inner attributes,
1408                    // then we need to re-configure it and re-collect attributes for
1409                    // resolution and expansion.
1410                    return Err(node);
1411                }
1412                (Some(file_path), dir_path, dir_ownership)
1413            }
1414        };
1415
1416        // Set the module info before we flat map.
1417        let mut module = ecx.current_expansion.module.with_dir_path(dir_path);
1418        module.mod_path.push(ident);
1419        if let Some(file_path) = file_path {
1420            module.file_path_stack.push(file_path);
1421        }
1422
1423        let orig_module = mem::replace(&mut ecx.current_expansion.module, Rc::new(module));
1424        let orig_dir_ownership =
1425            mem::replace(&mut ecx.current_expansion.dir_ownership, dir_ownership);
1426
1427        let res = Ok(walk_flat_map(node, collector));
1428
1429        collector.cx.current_expansion.dir_ownership = orig_dir_ownership;
1430        collector.cx.current_expansion.module = orig_module;
1431        res
1432    }
1433
1434    fn declared_idents(&self) -> Vec<Ident> {
1435        if let ItemKind::Use(ut) = &self.kind {
1436            fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
1437                match &ut.kind {
1438                    ast::UseTreeKind::Glob(_) => {}
1439                    ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
1440                    ast::UseTreeKind::Nested { items, .. } => {
1441                        for (ut, _) in items {
1442                            collect_use_tree_leaves(ut, idents);
1443                        }
1444                    }
1445                }
1446            }
1447            let mut idents = Vec::new();
1448            collect_use_tree_leaves(ut, &mut idents);
1449            idents
1450        } else {
1451            self.kind.ident().into_iter().collect()
1452        }
1453    }
1454
1455    fn as_target(&self) -> Target {
1456        Target::from_ast_item(self)
1457    }
1458}
1459
1460struct TraitItemTag;
1461impl InvocationCollectorNode for AstNodeWrapper<Box<ast::AssocItem>, TraitItemTag> {
1462    type OutputTy = SmallVec<[Box<ast::AssocItem>; 1]>;
1463    type ItemKind = AssocItemKind;
1464    const KIND: AstFragmentKind = AstFragmentKind::TraitItems;
1465    fn to_annotatable(self) -> Annotatable {
1466        Annotatable::AssocItem(self.wrapped, AssocCtxt::Trait)
1467    }
1468    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1469        fragment.make_trait_items()
1470    }
1471    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1472        walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Trait)
1473    }
1474    fn is_mac_call(&self) -> bool {
1475        #[allow(non_exhaustive_omitted_patterns)] match self.wrapped.kind {
    AssocItemKind::MacCall(..) => true,
    _ => false,
}matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
1476    }
1477    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1478        let item = self.wrapped;
1479        match item.kind {
1480            AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
1481            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1482        }
1483    }
1484    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
1485        match &self.wrapped.kind {
1486            AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
1487            _ => None,
1488        }
1489    }
1490    fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
1491        AssocItemKind::Delegation(deleg)
1492    }
1493    fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
1494        AstNodeWrapper::new(Box::new(item), TraitItemTag)
1495    }
1496    fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
1497        items.flatten().collect()
1498    }
1499    fn as_target(&self) -> Target {
1500        Target::from_assoc_item_kind(&self.wrapped.kind, AssocCtxt::Trait)
1501    }
1502}
1503
1504struct ImplItemTag;
1505impl InvocationCollectorNode for AstNodeWrapper<Box<ast::AssocItem>, ImplItemTag> {
1506    type OutputTy = SmallVec<[Box<ast::AssocItem>; 1]>;
1507    type ItemKind = AssocItemKind;
1508    const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
1509    fn to_annotatable(self) -> Annotatable {
1510        Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: false })
1511    }
1512    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1513        fragment.make_impl_items()
1514    }
1515    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1516        walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Impl { of_trait: false })
1517    }
1518    fn is_mac_call(&self) -> bool {
1519        #[allow(non_exhaustive_omitted_patterns)] match self.wrapped.kind {
    AssocItemKind::MacCall(..) => true,
    _ => false,
}matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
1520    }
1521    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1522        let item = self.wrapped;
1523        match item.kind {
1524            AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
1525            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1526        }
1527    }
1528    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
1529        match &self.wrapped.kind {
1530            AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
1531            _ => None,
1532        }
1533    }
1534    fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
1535        AssocItemKind::Delegation(deleg)
1536    }
1537    fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
1538        AstNodeWrapper::new(Box::new(item), ImplItemTag)
1539    }
1540    fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
1541        items.flatten().collect()
1542    }
1543    fn as_target(&self) -> Target {
1544        Target::from_assoc_item_kind(&self.wrapped.kind, AssocCtxt::Impl { of_trait: false })
1545    }
1546}
1547
1548struct TraitImplItemTag;
1549impl InvocationCollectorNode for AstNodeWrapper<Box<ast::AssocItem>, TraitImplItemTag> {
1550    type OutputTy = SmallVec<[Box<ast::AssocItem>; 1]>;
1551    type ItemKind = AssocItemKind;
1552    const KIND: AstFragmentKind = AstFragmentKind::TraitImplItems;
1553    fn to_annotatable(self) -> Annotatable {
1554        Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: true })
1555    }
1556    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1557        fragment.make_trait_impl_items()
1558    }
1559    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1560        walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Impl { of_trait: true })
1561    }
1562    fn is_mac_call(&self) -> bool {
1563        #[allow(non_exhaustive_omitted_patterns)] match self.wrapped.kind {
    AssocItemKind::MacCall(..) => true,
    _ => false,
}matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
1564    }
1565    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1566        let item = self.wrapped;
1567        match item.kind {
1568            AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
1569            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1570        }
1571    }
1572    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
1573        match &self.wrapped.kind {
1574            AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
1575            _ => None,
1576        }
1577    }
1578    fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
1579        AssocItemKind::Delegation(deleg)
1580    }
1581    fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
1582        AstNodeWrapper::new(Box::new(item), TraitImplItemTag)
1583    }
1584    fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
1585        items.flatten().collect()
1586    }
1587    fn as_target(&self) -> Target {
1588        Target::from_assoc_item_kind(&self.wrapped.kind, AssocCtxt::Impl { of_trait: true })
1589    }
1590}
1591
1592impl InvocationCollectorNode for Box<ast::ForeignItem> {
1593    const KIND: AstFragmentKind = AstFragmentKind::ForeignItems;
1594    fn to_annotatable(self) -> Annotatable {
1595        Annotatable::ForeignItem(self)
1596    }
1597    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1598        fragment.make_foreign_items()
1599    }
1600    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1601        walk_flat_map_foreign_item(collector, self)
1602    }
1603    fn is_mac_call(&self) -> bool {
1604        #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    ForeignItemKind::MacCall(..) => true,
    _ => false,
}matches!(self.kind, ForeignItemKind::MacCall(..))
1605    }
1606    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1607        match self.kind {
1608            ForeignItemKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
1609            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1610        }
1611    }
1612    fn as_target(&self) -> Target {
1613        match &self.kind {
1614            ForeignItemKind::Static(_) => Target::ForeignStatic,
1615            ForeignItemKind::Fn(_) => Target::ForeignFn,
1616            ForeignItemKind::TyAlias(_) => Target::ForeignTy,
1617            ForeignItemKind::MacCall(_) => Target::MacroCall,
1618        }
1619    }
1620}
1621
1622impl InvocationCollectorNode for ast::Variant {
1623    const KIND: AstFragmentKind = AstFragmentKind::Variants;
1624    fn to_annotatable(self) -> Annotatable {
1625        Annotatable::Variant(self)
1626    }
1627    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1628        fragment.make_variants()
1629    }
1630    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1631        walk_flat_map_variant(collector, self)
1632    }
1633    fn as_target(&self) -> Target {
1634        Target::Variant
1635    }
1636}
1637
1638impl InvocationCollectorNode for ast::WherePredicate {
1639    const KIND: AstFragmentKind = AstFragmentKind::WherePredicates;
1640    fn to_annotatable(self) -> Annotatable {
1641        Annotatable::WherePredicate(self)
1642    }
1643    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1644        fragment.make_where_predicates()
1645    }
1646    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1647        walk_flat_map_where_predicate(collector, self)
1648    }
1649    fn as_target(&self) -> Target {
1650        Target::WherePredicate
1651    }
1652}
1653
1654impl InvocationCollectorNode for ast::FieldDef {
1655    const KIND: AstFragmentKind = AstFragmentKind::FieldDefs;
1656    fn to_annotatable(self) -> Annotatable {
1657        Annotatable::FieldDef(self)
1658    }
1659    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1660        fragment.make_field_defs()
1661    }
1662    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1663        walk_flat_map_field_def(collector, self)
1664    }
1665    fn as_target(&self) -> Target {
1666        Target::Field
1667    }
1668}
1669
1670impl InvocationCollectorNode for ast::PatField {
1671    const KIND: AstFragmentKind = AstFragmentKind::PatFields;
1672    fn to_annotatable(self) -> Annotatable {
1673        Annotatable::PatField(self)
1674    }
1675    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1676        fragment.make_pat_fields()
1677    }
1678    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1679        walk_flat_map_pat_field(collector, self)
1680    }
1681    fn as_target(&self) -> Target {
1682        Target::PatField
1683    }
1684}
1685
1686impl InvocationCollectorNode for ast::ExprField {
1687    const KIND: AstFragmentKind = AstFragmentKind::ExprFields;
1688    fn to_annotatable(self) -> Annotatable {
1689        Annotatable::ExprField(self)
1690    }
1691    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1692        fragment.make_expr_fields()
1693    }
1694    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1695        walk_flat_map_expr_field(collector, self)
1696    }
1697    fn as_target(&self) -> Target {
1698        Target::ExprField
1699    }
1700}
1701
1702impl InvocationCollectorNode for ast::Param {
1703    const KIND: AstFragmentKind = AstFragmentKind::Params;
1704    fn to_annotatable(self) -> Annotatable {
1705        Annotatable::Param(self)
1706    }
1707    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1708        fragment.make_params()
1709    }
1710    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1711        walk_flat_map_param(collector, self)
1712    }
1713    fn as_target(&self) -> Target {
1714        Target::Param
1715    }
1716}
1717
1718impl InvocationCollectorNode for ast::GenericParam {
1719    const KIND: AstFragmentKind = AstFragmentKind::GenericParams;
1720    fn to_annotatable(self) -> Annotatable {
1721        Annotatable::GenericParam(self)
1722    }
1723    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1724        fragment.make_generic_params()
1725    }
1726    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1727        walk_flat_map_generic_param(collector, self)
1728    }
1729    fn as_target(&self) -> Target {
1730        let mut has_default = false;
1731        Target::GenericParam {
1732            kind: match &self.kind {
1733                rustc_ast::GenericParamKind::Lifetime => {
1734                    rustc_hir::target::GenericParamKind::Lifetime
1735                }
1736                rustc_ast::GenericParamKind::Type { default } => {
1737                    has_default = default.is_some();
1738                    rustc_hir::target::GenericParamKind::Type
1739                }
1740                rustc_ast::GenericParamKind::Const { default, .. } => {
1741                    has_default = default.is_some();
1742                    rustc_hir::target::GenericParamKind::Const
1743                }
1744            },
1745            has_default,
1746        }
1747    }
1748}
1749
1750impl InvocationCollectorNode for ast::Arm {
1751    const KIND: AstFragmentKind = AstFragmentKind::Arms;
1752    fn to_annotatable(self) -> Annotatable {
1753        Annotatable::Arm(self)
1754    }
1755    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1756        fragment.make_arms()
1757    }
1758    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1759        walk_flat_map_arm(collector, self)
1760    }
1761    fn as_target(&self) -> Target {
1762        Target::Arm
1763    }
1764}
1765
1766impl InvocationCollectorNode for ast::Stmt {
1767    const KIND: AstFragmentKind = AstFragmentKind::Stmts;
1768    fn to_annotatable(self) -> Annotatable {
1769        Annotatable::Stmt(Box::new(self))
1770    }
1771    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1772        fragment.make_stmts()
1773    }
1774    fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1775        walk_flat_map_stmt(collector, self)
1776    }
1777    fn is_mac_call(&self) -> bool {
1778        match &self.kind {
1779            StmtKind::MacCall(..) => true,
1780            StmtKind::Item(item) => #[allow(non_exhaustive_omitted_patterns)] match item.kind {
    ItemKind::MacCall(..) => true,
    _ => false,
}matches!(item.kind, ItemKind::MacCall(..)),
1781            StmtKind::Semi(expr) => #[allow(non_exhaustive_omitted_patterns)] match expr.kind {
    ExprKind::MacCall(..) => true,
    _ => false,
}matches!(expr.kind, ExprKind::MacCall(..)),
1782            StmtKind::Expr(..) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1783            StmtKind::Let(..) | StmtKind::Empty => false,
1784        }
1785    }
1786    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1787        // We pull macro invocations (both attributes and fn-like macro calls) out of their
1788        // `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
1789        let (add_semicolon, mac, attrs) = match self.kind {
1790            StmtKind::MacCall(mac) => {
1791                let ast::MacCallStmt { mac, style, attrs, .. } = *mac;
1792                (style == MacStmtStyle::Semicolon, mac, attrs)
1793            }
1794            StmtKind::Item(item) => match *item {
1795                ast::Item { kind: ItemKind::MacCall(mac), attrs, .. } => {
1796                    (mac.args.need_semicolon(), mac, attrs)
1797                }
1798                _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1799            },
1800            StmtKind::Semi(expr) => match *expr {
1801                ast::Expr { kind: ExprKind::MacCall(mac), attrs, .. } => {
1802                    (mac.args.need_semicolon(), mac, attrs)
1803                }
1804                _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1805            },
1806            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1807        };
1808        (mac, attrs, if add_semicolon { AddSemicolon::Yes } else { AddSemicolon::No })
1809    }
1810    fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
1811        match &self.kind {
1812            StmtKind::Item(item) => match &item.kind {
1813                ItemKind::DelegationMac(deleg) => Some((deleg, item)),
1814                _ => None,
1815            },
1816            _ => None,
1817        }
1818    }
1819    fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
1820        ItemKind::Delegation(deleg)
1821    }
1822    fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
1823        ast::Stmt { id: ast::DUMMY_NODE_ID, span: item.span, kind: StmtKind::Item(Box::new(item)) }
1824    }
1825    fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
1826        items.flatten().collect()
1827    }
1828    fn post_flat_map_node_collect_bang(stmts: &mut Self::OutputTy, add_semicolon: AddSemicolon) {
1829        // If this is a macro invocation with a semicolon, then apply that
1830        // semicolon to the final statement produced by expansion.
1831        if #[allow(non_exhaustive_omitted_patterns)] match add_semicolon {
    AddSemicolon::Yes => true,
    _ => false,
}matches!(add_semicolon, AddSemicolon::Yes) {
1832            if let Some(stmt) = stmts.pop() {
1833                stmts.push(stmt.add_trailing_semicolon());
1834            }
1835        }
1836    }
1837    fn as_target(&self) -> Target {
1838        Target::Statement
1839    }
1840}
1841
1842impl InvocationCollectorNode for ast::Crate {
1843    type OutputTy = ast::Crate;
1844    const KIND: AstFragmentKind = AstFragmentKind::Crate;
1845    fn to_annotatable(self) -> Annotatable {
1846        Annotatable::Crate(self)
1847    }
1848    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1849        fragment.make_crate()
1850    }
1851    fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1852        walk_crate(collector, self)
1853    }
1854    fn expand_cfg_false(
1855        &mut self,
1856        collector: &mut InvocationCollector<'_, '_>,
1857        pos: usize,
1858        _span: Span,
1859    ) {
1860        // Attributes above `cfg(FALSE)` are left in place, because we may want to configure
1861        // some global crate properties even on fully unconfigured crates.
1862        self.attrs.truncate(pos);
1863        // Standard prelude imports are left in the crate for backward compatibility.
1864        self.items.truncate(collector.cx.num_standard_library_imports);
1865    }
1866    fn as_target(&self) -> Target {
1867        Target::Crate
1868    }
1869}
1870
1871impl InvocationCollectorNode for ast::Ty {
1872    type OutputTy = Box<ast::Ty>;
1873    const KIND: AstFragmentKind = AstFragmentKind::Ty;
1874    fn to_annotatable(self) -> Annotatable {
1875        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1876    }
1877    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1878        fragment.make_ty()
1879    }
1880    fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1881        // Save the pre-expanded name of this `ImplTrait`, so that later when defining
1882        // an APIT we use a name that doesn't have any placeholder fragments in it.
1883        if let ast::TyKind::ImplTrait(..) = self.kind {
1884            // HACK: pprust breaks strings with newlines when the type
1885            // gets too long. We don't want these to show up in compiler
1886            // output or built artifacts, so replace them here...
1887            // Perhaps we should instead format APITs more robustly.
1888            let name = Symbol::intern(&pprust::ty_to_string(self).replace('\n', " "));
1889            collector.cx.resolver.insert_impl_trait_name(self.id, name);
1890        }
1891        walk_ty(collector, self)
1892    }
1893    fn is_mac_call(&self) -> bool {
1894        #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    ast::TyKind::MacCall(..) => true,
    _ => false,
}matches!(self.kind, ast::TyKind::MacCall(..))
1895    }
1896    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1897        match self.kind {
1898            TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
1899            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1900        }
1901    }
1902    fn as_target(&self) -> Target {
1903        // This is only used for attribute parsing, which are not allowed on types.
1904        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1905    }
1906}
1907
1908impl InvocationCollectorNode for ast::Pat {
1909    type OutputTy = Box<ast::Pat>;
1910    const KIND: AstFragmentKind = AstFragmentKind::Pat;
1911    fn to_annotatable(self) -> Annotatable {
1912        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1913    }
1914    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1915        fragment.make_pat()
1916    }
1917    fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1918        walk_pat(collector, self)
1919    }
1920    fn is_mac_call(&self) -> bool {
1921        #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    PatKind::MacCall(..) => true,
    _ => false,
}matches!(self.kind, PatKind::MacCall(..))
1922    }
1923    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1924        match self.kind {
1925            PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
1926            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1927        }
1928    }
1929    fn as_target(&self) -> Target {
1930        ::core::panicking::panic("not yet implemented");todo!();
1931    }
1932}
1933
1934impl InvocationCollectorNode for ast::Expr {
1935    type OutputTy = Box<ast::Expr>;
1936    const KIND: AstFragmentKind = AstFragmentKind::Expr;
1937    fn to_annotatable(self) -> Annotatable {
1938        Annotatable::Expr(Box::new(self))
1939    }
1940    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1941        fragment.make_expr()
1942    }
1943    fn descr() -> &'static str {
1944        "an expression"
1945    }
1946    fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
1947        walk_expr(collector, self)
1948    }
1949    fn is_mac_call(&self) -> bool {
1950        #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    ExprKind::MacCall(..) => true,
    _ => false,
}matches!(self.kind, ExprKind::MacCall(..))
1951    }
1952    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1953        match self.kind {
1954            ExprKind::MacCall(mac) => (mac, self.attrs, AddSemicolon::No),
1955            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1956        }
1957    }
1958    fn as_target(&self) -> Target {
1959        Target::Expression
1960    }
1961}
1962
1963struct OptExprTag;
1964impl InvocationCollectorNode for AstNodeWrapper<Box<ast::Expr>, OptExprTag> {
1965    type OutputTy = Option<Box<ast::Expr>>;
1966    const KIND: AstFragmentKind = AstFragmentKind::OptExpr;
1967    fn to_annotatable(self) -> Annotatable {
1968        Annotatable::Expr(self.wrapped)
1969    }
1970    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
1971        fragment.make_opt_expr()
1972    }
1973    fn walk_flat_map(mut self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy {
1974        walk_expr(collector, &mut self.wrapped);
1975        Some(self.wrapped)
1976    }
1977    fn is_mac_call(&self) -> bool {
1978        #[allow(non_exhaustive_omitted_patterns)] match self.wrapped.kind {
    ast::ExprKind::MacCall(..) => true,
    _ => false,
}matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
1979    }
1980    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
1981        let node = self.wrapped;
1982        match node.kind {
1983            ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
1984            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
1985        }
1986    }
1987    fn pre_flat_map_node_collect_attr(cfg: &StripUnconfigured<'_>, attr: &ast::Attribute) {
1988        cfg.maybe_emit_expr_attr_err(attr);
1989    }
1990    fn as_target(&self) -> Target {
1991        Target::Expression
1992    }
1993}
1994
1995/// This struct is a hack to workaround unstable of `stmt_expr_attributes`.
1996/// It can be removed once that feature is stabilized.
1997struct MethodReceiverTag;
1998
1999impl InvocationCollectorNode for AstNodeWrapper<ast::Expr, MethodReceiverTag> {
2000    type OutputTy = AstNodeWrapper<Box<ast::Expr>, MethodReceiverTag>;
2001    const KIND: AstFragmentKind = AstFragmentKind::MethodReceiverExpr;
2002    fn descr() -> &'static str {
2003        "an expression"
2004    }
2005    fn to_annotatable(self) -> Annotatable {
2006        Annotatable::Expr(Box::new(self.wrapped))
2007    }
2008    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
2009        AstNodeWrapper::new(fragment.make_method_receiver_expr(), MethodReceiverTag)
2010    }
2011    fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) {
2012        walk_expr(collector, &mut self.wrapped)
2013    }
2014    fn is_mac_call(&self) -> bool {
2015        #[allow(non_exhaustive_omitted_patterns)] match self.wrapped.kind {
    ast::ExprKind::MacCall(..) => true,
    _ => false,
}matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
2016    }
2017    fn take_mac_call(self) -> (Box<ast::MacCall>, ast::AttrVec, AddSemicolon) {
2018        let node = self.wrapped;
2019        match node.kind {
2020            ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
2021            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
2022        }
2023    }
2024    fn as_target(&self) -> Target {
2025        Target::Expression
2026    }
2027}
2028
2029fn build_single_delegations<'a, Node: InvocationCollectorNode>(
2030    ecx: &ExtCtxt<'_>,
2031    deleg: &'a ast::DelegationMac,
2032    item: &'a ast::Item<Node::ItemKind>,
2033    suffixes: &'a [(Ident, Option<Ident>)],
2034    item_span: Span,
2035    from_glob: bool,
2036) -> impl Iterator<Item = ast::Item<Node::ItemKind>> + 'a {
2037    if suffixes.is_empty() {
2038        // Report an error for now, to avoid keeping stem for resolution and
2039        // stability checks.
2040        let kind = String::from(if from_glob { "glob" } else { "list" });
2041        ecx.dcx().emit_err(EmptyDelegationMac { span: item.span, kind });
2042    }
2043
2044    suffixes.iter().map(move |&(ident, rename)| {
2045        let mut path = deleg.prefix.clone();
2046        path.segments.push(ast::PathSegment { ident, id: ast::DUMMY_NODE_ID, args: None });
2047
2048        ast::Item {
2049            attrs: item.attrs.clone(),
2050            id: ast::DUMMY_NODE_ID,
2051            span: if from_glob { item_span } else { ident.span },
2052            vis: item.vis.clone(),
2053            kind: Node::delegation_item_kind(Box::new(ast::Delegation {
2054                id: ast::DUMMY_NODE_ID,
2055                qself: deleg.qself.clone(),
2056                path,
2057                ident: rename.unwrap_or(ident),
2058                rename,
2059                body: deleg.body.clone(),
2060                from_glob,
2061            })),
2062            tokens: None,
2063        }
2064    })
2065}
2066
2067/// Required for `visit_node` obtained an owned `Node` from `&mut Node`.
2068trait DummyAstNode {
2069    fn dummy() -> Self;
2070}
2071
2072impl DummyAstNode for ast::Crate {
2073    fn dummy() -> Self {
2074        ast::Crate {
2075            attrs: Default::default(),
2076            items: Default::default(),
2077            spans: Default::default(),
2078            id: DUMMY_NODE_ID,
2079            is_placeholder: Default::default(),
2080        }
2081    }
2082}
2083
2084impl DummyAstNode for ast::Ty {
2085    fn dummy() -> Self {
2086        ast::Ty {
2087            id: DUMMY_NODE_ID,
2088            kind: TyKind::Dummy,
2089            span: Default::default(),
2090            tokens: Default::default(),
2091        }
2092    }
2093}
2094
2095impl DummyAstNode for ast::Pat {
2096    fn dummy() -> Self {
2097        ast::Pat {
2098            id: DUMMY_NODE_ID,
2099            kind: PatKind::Wild,
2100            span: Default::default(),
2101            tokens: Default::default(),
2102        }
2103    }
2104}
2105
2106impl DummyAstNode for ast::Expr {
2107    fn dummy() -> Self {
2108        ast::Expr::dummy()
2109    }
2110}
2111
2112impl DummyAstNode for AstNodeWrapper<ast::Expr, MethodReceiverTag> {
2113    fn dummy() -> Self {
2114        AstNodeWrapper::new(ast::Expr::dummy(), MethodReceiverTag)
2115    }
2116}
2117
2118struct InvocationCollector<'a, 'b> {
2119    cx: &'a mut ExtCtxt<'b>,
2120    invocations: Vec<(Invocation, Option<Arc<SyntaxExtension>>)>,
2121    monotonic: bool,
2122}
2123
2124impl<'a, 'b> InvocationCollector<'a, 'b> {
2125    fn cfg(&self) -> StripUnconfigured<'_> {
2126        StripUnconfigured {
2127            sess: self.cx.sess,
2128            features: Some(self.cx.ecfg.features),
2129            config_tokens: false,
2130            lint_node_id: self.cx.current_expansion.lint_node_id,
2131        }
2132    }
2133
2134    fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
2135        let expn_id = LocalExpnId::fresh_empty();
2136        if #[allow(non_exhaustive_omitted_patterns)] match kind {
    InvocationKind::GlobDelegation { .. } => true,
    _ => false,
}matches!(kind, InvocationKind::GlobDelegation { .. }) {
2137            // In resolver we need to know which invocation ids are delegations early,
2138            // before their `ExpnData` is filled.
2139            self.cx.resolver.register_glob_delegation(expn_id);
2140        }
2141        let vis = kind.placeholder_visibility();
2142        self.invocations.push((
2143            Invocation {
2144                kind,
2145                fragment_kind,
2146                expansion_data: ExpansionData {
2147                    id: expn_id,
2148                    depth: self.cx.current_expansion.depth + 1,
2149                    ..self.cx.current_expansion.clone()
2150                },
2151            },
2152            None,
2153        ));
2154        placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
2155    }
2156
2157    fn collect_bang(&mut self, mac: Box<ast::MacCall>, kind: AstFragmentKind) -> AstFragment {
2158        // cache the macro call span so that it can be
2159        // easily adjusted for incremental compilation
2160        let span = mac.span();
2161        self.collect(kind, InvocationKind::Bang { mac, span })
2162    }
2163
2164    fn collect_attr(
2165        &mut self,
2166        (attr, pos, derives): (ast::Attribute, usize, Vec<ast::Path>),
2167        item: Annotatable,
2168        kind: AstFragmentKind,
2169    ) -> AstFragment {
2170        self.collect(kind, InvocationKind::Attr { attr, pos, item, derives })
2171    }
2172
2173    fn collect_glob_delegation(
2174        &mut self,
2175        item: Box<ast::AssocItem>,
2176        of_trait: bool,
2177        kind: AstFragmentKind,
2178    ) -> AstFragment {
2179        self.collect(kind, InvocationKind::GlobDelegation { item, of_trait })
2180    }
2181
2182    /// If `item` is an attribute invocation, remove the attribute and return it together with
2183    /// its position and derives following it. We have to collect the derives in order to resolve
2184    /// legacy derive helpers (helpers written before derives that introduce them).
2185    fn take_first_attr(
2186        &self,
2187        item: &mut impl HasAttrs,
2188    ) -> Option<(ast::Attribute, usize, Vec<ast::Path>)> {
2189        let mut attr = None;
2190
2191        let mut cfg_pos = None;
2192        let mut attr_pos = None;
2193        for (pos, attr) in item.attrs().iter().enumerate() {
2194            if !attr.is_doc_comment() && !self.cx.expanded_inert_attrs.is_marked(attr) {
2195                let name = attr.name();
2196                if name == Some(sym::cfg) || name == Some(sym::cfg_attr) {
2197                    cfg_pos = Some(pos); // a cfg attr found, no need to search anymore
2198                    break;
2199                } else if attr_pos.is_none()
2200                    && !name.is_some_and(rustc_feature::is_builtin_attr_name)
2201                {
2202                    attr_pos = Some(pos); // a non-cfg attr found, still may find a cfg attr
2203                }
2204            }
2205        }
2206
2207        item.visit_attrs(|attrs| {
2208            attr = Some(match (cfg_pos, attr_pos) {
2209                (Some(pos), _) => (attrs.remove(pos), pos, Vec::new()),
2210                (_, Some(pos)) => {
2211                    let attr = attrs.remove(pos);
2212                    let following_derives = attrs[pos..]
2213                        .iter()
2214                        .filter(|a| a.has_name(sym::derive))
2215                        .flat_map(|a| a.meta_item_list().unwrap_or_default())
2216                        .filter_map(|meta_item_inner| match meta_item_inner {
2217                            MetaItemInner::MetaItem(ast::MetaItem {
2218                                kind: MetaItemKind::Word,
2219                                path,
2220                                ..
2221                            }) => Some(path),
2222                            _ => None,
2223                        })
2224                        .collect();
2225
2226                    (attr, pos, following_derives)
2227                }
2228                _ => return,
2229            });
2230        });
2231
2232        attr
2233    }
2234
2235    // Detect use of feature-gated or invalid attributes on macro invocations
2236    // since they will not be detected after macro expansion.
2237    fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
2238        let features = self.cx.ecfg.features;
2239        let mut attrs = attrs.iter().peekable();
2240        let mut span: Option<Span> = None;
2241        while let Some(attr) = attrs.next() {
2242            rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
2243            validate_attr::check_attr(&self.cx.sess.psess, attr);
2244            AttributeParser::parse_limited_all(
2245                self.cx.sess,
2246                slice::from_ref(attr),
2247                None,
2248                Target::MacroCall,
2249                call.span(),
2250                self.cx.current_expansion.lint_node_id,
2251                Some(self.cx.ecfg.features),
2252                ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
2253                Some(self.cx.resolver.registered_tools()),
2254            );
2255
2256            let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
2257            span = Some(current_span);
2258
2259            if attrs.peek().is_some_and(|next_attr| next_attr.doc_str().is_some()) {
2260                continue;
2261            }
2262
2263            if attr.doc_str_and_fragment_kind().is_some() {
2264                self.cx.sess.psess.buffer_lint(
2265                    UNUSED_DOC_COMMENTS,
2266                    current_span,
2267                    self.cx.current_expansion.lint_node_id,
2268                    crate::errors::MacroCallUnusedDocComment { span: attr.span },
2269                );
2270            } else if rustc_attr_parsing::is_builtin_attr(attr)
2271                && !AttributeParser::is_parsed_attribute(&attr.path())
2272            {
2273                let attr_name = attr.name().unwrap();
2274                self.cx.sess.psess.buffer_lint(
2275                    UNUSED_ATTRIBUTES,
2276                    attr.span,
2277                    self.cx.current_expansion.lint_node_id,
2278                    crate::errors::UnusedBuiltinAttribute {
2279                        attr_name,
2280                        macro_name: pprust::path_to_string(&call.path),
2281                        invoc_span: call.path.span,
2282                        attr_span: attr.span,
2283                    },
2284                );
2285            }
2286        }
2287    }
2288
2289    fn expand_cfg_true(
2290        &mut self,
2291        node: &mut impl InvocationCollectorNode,
2292        attr: ast::Attribute,
2293        pos: usize,
2294    ) -> EvalConfigResult {
2295        let Some(cfg) = AttributeParser::parse_single(
2296            self.cfg().sess,
2297            &attr,
2298            attr.span,
2299            self.cfg().lint_node_id,
2300            node.as_target(),
2301            self.cfg().features,
2302            ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },
2303            parse_cfg,
2304            &CFG_TEMPLATE,
2305            AllowExprMetavar::Yes,
2306            AttributeSafety::Normal,
2307        ) else {
2308            // Cfg attribute was not parsable, give up
2309            return EvalConfigResult::True;
2310        };
2311
2312        let res = eval_config_entry(self.cfg().sess, &cfg);
2313        if res.as_bool() {
2314            // A trace attribute left in AST in place of the original `cfg` attribute.
2315            // It can later be used by lints or other diagnostics.
2316            let mut trace_attr = attr_into_trace(attr, sym::cfg_trace);
2317            trace_attr.replace_args(AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg)));
2318            node.visit_attrs(|attrs| attrs.insert(pos, trace_attr));
2319        }
2320
2321        res
2322    }
2323
2324    fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: &ast::Attribute, pos: usize) {
2325        node.visit_attrs(|attrs| {
2326            // Repeated `insert` calls is inefficient, but the number of
2327            // insertions is almost always 0 or 1 in practice.
2328            for cfg in self.cfg().expand_cfg_attr(attr, false).into_iter().rev() {
2329                attrs.insert(pos, cfg)
2330            }
2331        });
2332    }
2333
2334    fn flat_map_node<Node: InvocationCollectorNode<OutputTy: Default>>(
2335        &mut self,
2336        mut node: Node,
2337    ) -> Node::OutputTy {
2338        loop {
2339            return match self.take_first_attr(&mut node) {
2340                Some((attr, pos, derives)) => match attr.name() {
2341                    Some(sym::cfg) => {
2342                        let res = self.expand_cfg_true(&mut node, attr, pos);
2343                        match res {
2344                            EvalConfigResult::True => continue,
2345                            EvalConfigResult::False { reason, reason_span } => {
2346                                for ident in node.declared_idents() {
2347                                    self.cx.resolver.append_stripped_cfg_item(
2348                                        self.cx.current_expansion.lint_node_id,
2349                                        ident,
2350                                        reason.clone(),
2351                                        reason_span,
2352                                    )
2353                                }
2354                            }
2355                        }
2356
2357                        Default::default()
2358                    }
2359                    Some(sym::cfg_attr) => {
2360                        self.expand_cfg_attr(&mut node, &attr, pos);
2361                        continue;
2362                    }
2363                    _ => {
2364                        Node::pre_flat_map_node_collect_attr(&self.cfg(), &attr);
2365                        self.collect_attr((attr, pos, derives), node.to_annotatable(), Node::KIND)
2366                            .make_ast::<Node>()
2367                    }
2368                },
2369                None if node.is_mac_call() => {
2370                    let (mac, attrs, add_semicolon) = node.take_mac_call();
2371                    self.check_attributes(&attrs, &mac);
2372                    let mut res = self.collect_bang(mac, Node::KIND).make_ast::<Node>();
2373                    Node::post_flat_map_node_collect_bang(&mut res, add_semicolon);
2374                    res
2375                }
2376                None if let Some((deleg, item)) = node.delegation() => {
2377                    let DelegationSuffixes::List(suffixes) = &deleg.suffixes else {
2378                        let traitless_qself =
2379                            #[allow(non_exhaustive_omitted_patterns)] match &deleg.qself {
    Some(qself) if qself.position == 0 => true,
    _ => false,
}matches!(&deleg.qself, Some(qself) if qself.position == 0);
2380                        let (item, of_trait) = match node.to_annotatable() {
2381                            Annotatable::AssocItem(item, AssocCtxt::Impl { of_trait }) => {
2382                                (item, of_trait)
2383                            }
2384                            ann @ (Annotatable::Item(_)
2385                            | Annotatable::AssocItem(..)
2386                            | Annotatable::Stmt(_)) => {
2387                                let span = ann.span();
2388                                self.cx.dcx().emit_err(GlobDelegationOutsideImpls { span });
2389                                return Default::default();
2390                            }
2391                            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
2392                        };
2393                        if traitless_qself {
2394                            let span = item.span;
2395                            self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
2396                            return Default::default();
2397                        }
2398                        return self
2399                            .collect_glob_delegation(item, of_trait, Node::KIND)
2400                            .make_ast::<Node>();
2401                    };
2402
2403                    let single_delegations = build_single_delegations::<Node>(
2404                        self.cx, deleg, item, suffixes, item.span, false,
2405                    );
2406                    Node::flatten_outputs(single_delegations.map(|item| {
2407                        let mut item = Node::from_item(item);
2408                        {
    let old_id = self.cx.current_expansion.lint_node_id;
    if self.monotonic {
        if true {
            match (&*item.node_id_mut(), &ast::DUMMY_NODE_ID) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        let kind = ::core::panicking::AssertKind::Eq;
                        ::core::panicking::assert_failed(kind, &*left_val,
                            &*right_val, ::core::option::Option::None);
                    }
                }
            };
        };
        let new_id = self.cx.resolver.next_node_id();
        *item.node_id_mut() = new_id;
        self.cx.current_expansion.lint_node_id = new_id;
    }
    let ret = (|| item.walk_flat_map(self))();
    self.cx.current_expansion.lint_node_id = old_id;
    ret
}assign_id!(self, item.node_id_mut(), || item.walk_flat_map(self))
2409                    }))
2410                }
2411                None => {
2412                    match Node::wrap_flat_map_node_walk_flat_map(node, self, |mut node, this| {
2413                        {
    let old_id = this.cx.current_expansion.lint_node_id;
    if this.monotonic {
        if true {
            match (&*node.node_id_mut(), &ast::DUMMY_NODE_ID) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        let kind = ::core::panicking::AssertKind::Eq;
                        ::core::panicking::assert_failed(kind, &*left_val,
                            &*right_val, ::core::option::Option::None);
                    }
                }
            };
        };
        let new_id = this.cx.resolver.next_node_id();
        *node.node_id_mut() = new_id;
        this.cx.current_expansion.lint_node_id = new_id;
    }
    let ret = (|| node.walk_flat_map(this))();
    this.cx.current_expansion.lint_node_id = old_id;
    ret
}assign_id!(this, node.node_id_mut(), || node.walk_flat_map(this))
2414                    }) {
2415                        Ok(output) => output,
2416                        Err(returned_node) => {
2417                            node = returned_node;
2418                            continue;
2419                        }
2420                    }
2421                }
2422            };
2423        }
2424    }
2425
2426    fn visit_node<Node: InvocationCollectorNode<OutputTy: Into<Node>> + DummyAstNode>(
2427        &mut self,
2428        node: &mut Node,
2429    ) {
2430        loop {
2431            return match self.take_first_attr(node) {
2432                Some((attr, pos, derives)) => match attr.name() {
2433                    Some(sym::cfg) => {
2434                        let span = attr.span;
2435                        if self.expand_cfg_true(node, attr, pos).as_bool() {
2436                            continue;
2437                        }
2438
2439                        node.expand_cfg_false(self, pos, span);
2440                        continue;
2441                    }
2442                    Some(sym::cfg_attr) => {
2443                        self.expand_cfg_attr(node, &attr, pos);
2444                        continue;
2445                    }
2446                    _ => {
2447                        let n = mem::replace(node, Node::dummy());
2448                        *node = self
2449                            .collect_attr((attr, pos, derives), n.to_annotatable(), Node::KIND)
2450                            .make_ast::<Node>()
2451                            .into()
2452                    }
2453                },
2454                None if node.is_mac_call() => {
2455                    let n = mem::replace(node, Node::dummy());
2456                    let (mac, attrs, _) = n.take_mac_call();
2457                    self.check_attributes(&attrs, &mac);
2458
2459                    *node = self.collect_bang(mac, Node::KIND).make_ast::<Node>().into()
2460                }
2461                None if node.delegation().is_some() => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
2462                None => {
2463                    {
    let old_id = self.cx.current_expansion.lint_node_id;
    if self.monotonic {
        if true {
            match (&*node.node_id_mut(), &ast::DUMMY_NODE_ID) {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        let kind = ::core::panicking::AssertKind::Eq;
                        ::core::panicking::assert_failed(kind, &*left_val,
                            &*right_val, ::core::option::Option::None);
                    }
                }
            };
        };
        let new_id = self.cx.resolver.next_node_id();
        *node.node_id_mut() = new_id;
        self.cx.current_expansion.lint_node_id = new_id;
    }
    let ret = (|| node.walk(self))();
    self.cx.current_expansion.lint_node_id = old_id;
    ret
}assign_id!(self, node.node_id_mut(), || node.walk(self))
2464                }
2465            };
2466        }
2467    }
2468}
2469
2470impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
2471    fn flat_map_item(&mut self, node: Box<ast::Item>) -> SmallVec<[Box<ast::Item>; 1]> {
2472        self.flat_map_node(node)
2473    }
2474
2475    fn flat_map_assoc_item(
2476        &mut self,
2477        node: Box<ast::AssocItem>,
2478        ctxt: AssocCtxt,
2479    ) -> SmallVec<[Box<ast::AssocItem>; 1]> {
2480        match ctxt {
2481            AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
2482            AssocCtxt::Impl { of_trait: false, .. } => {
2483                self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
2484            }
2485            AssocCtxt::Impl { of_trait: true, .. } => {
2486                self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
2487            }
2488        }
2489    }
2490
2491    fn flat_map_foreign_item(
2492        &mut self,
2493        node: Box<ast::ForeignItem>,
2494    ) -> SmallVec<[Box<ast::ForeignItem>; 1]> {
2495        self.flat_map_node(node)
2496    }
2497
2498    fn flat_map_variant(&mut self, node: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
2499        self.flat_map_node(node)
2500    }
2501
2502    fn flat_map_where_predicate(
2503        &mut self,
2504        node: ast::WherePredicate,
2505    ) -> SmallVec<[ast::WherePredicate; 1]> {
2506        self.flat_map_node(node)
2507    }
2508
2509    fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> {
2510        self.flat_map_node(node)
2511    }
2512
2513    fn flat_map_pat_field(&mut self, node: ast::PatField) -> SmallVec<[ast::PatField; 1]> {
2514        self.flat_map_node(node)
2515    }
2516
2517    fn flat_map_expr_field(&mut self, node: ast::ExprField) -> SmallVec<[ast::ExprField; 1]> {
2518        self.flat_map_node(node)
2519    }
2520
2521    fn flat_map_param(&mut self, node: ast::Param) -> SmallVec<[ast::Param; 1]> {
2522        self.flat_map_node(node)
2523    }
2524
2525    fn flat_map_generic_param(
2526        &mut self,
2527        node: ast::GenericParam,
2528    ) -> SmallVec<[ast::GenericParam; 1]> {
2529        self.flat_map_node(node)
2530    }
2531
2532    fn flat_map_arm(&mut self, node: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
2533        self.flat_map_node(node)
2534    }
2535
2536    fn flat_map_stmt(&mut self, node: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> {
2537        // FIXME: invocations in semicolon-less expressions positions are expanded as expressions,
2538        // changing that requires some compatibility measures.
2539        if node.is_expr() {
2540            // The only way that we can end up with a `MacCall` expression statement,
2541            // (as opposed to a `StmtKind::MacCall`) is if we have a macro as the
2542            // trailing expression in a block (e.g. `fn foo() { my_macro!() }`).
2543            // Record this information, so that we can report a more specific
2544            // `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` lint if needed.
2545            // See #78991 for an investigation of treating macros in this position
2546            // as statements, rather than expressions, during parsing.
2547            return match &node.kind {
2548                StmtKind::Expr(expr)
2549                    if #[allow(non_exhaustive_omitted_patterns)] match **expr {
    ast::Expr { kind: ExprKind::MacCall(..), .. } => true,
    _ => false,
}matches!(**expr, ast::Expr { kind: ExprKind::MacCall(..), .. }) =>
2550                {
2551                    self.cx.current_expansion.is_trailing_mac = true;
2552                    // Don't use `assign_id` for this statement - it may get removed
2553                    // entirely due to a `#[cfg]` on the contained expression
2554                    let res = walk_flat_map_stmt(self, node);
2555                    self.cx.current_expansion.is_trailing_mac = false;
2556                    res
2557                }
2558                _ => walk_flat_map_stmt(self, node),
2559            };
2560        }
2561
2562        self.flat_map_node(node)
2563    }
2564
2565    fn visit_crate(&mut self, node: &mut ast::Crate) {
2566        self.visit_node(node)
2567    }
2568
2569    fn visit_ty(&mut self, node: &mut ast::Ty) {
2570        self.visit_node(node)
2571    }
2572
2573    fn visit_pat(&mut self, node: &mut ast::Pat) {
2574        self.visit_node(node)
2575    }
2576
2577    fn visit_expr(&mut self, node: &mut ast::Expr) {
2578        // FIXME: Feature gating is performed inconsistently between `Expr` and `OptExpr`.
2579        if let Some(attr) = node.attrs.first() {
2580            self.cfg().maybe_emit_expr_attr_err(attr);
2581        }
2582        ensure_sufficient_stack(|| self.visit_node(node))
2583    }
2584
2585    fn visit_method_receiver_expr(&mut self, node: &mut ast::Expr) {
2586        self.visit_node(AstNodeWrapper::from_mut(node, MethodReceiverTag))
2587    }
2588
2589    fn filter_map_expr(&mut self, node: Box<ast::Expr>) -> Option<Box<ast::Expr>> {
2590        self.flat_map_node(AstNodeWrapper::new(node, OptExprTag))
2591    }
2592
2593    fn visit_block(&mut self, node: &mut ast::Block) {
2594        let orig_dir_ownership = mem::replace(
2595            &mut self.cx.current_expansion.dir_ownership,
2596            DirOwnership::UnownedViaBlock,
2597        );
2598        walk_block(self, node);
2599        self.cx.current_expansion.dir_ownership = orig_dir_ownership;
2600    }
2601
2602    fn visit_id(&mut self, id: &mut NodeId) {
2603        // We may have already assigned a `NodeId`
2604        // by calling `assign_id`
2605        if self.monotonic && *id == ast::DUMMY_NODE_ID {
2606            *id = self.cx.resolver.next_node_id();
2607        }
2608    }
2609}
2610
2611pub struct ExpansionConfig<'feat> {
2612    pub crate_name: Symbol,
2613    pub features: &'feat Features,
2614    pub recursion_limit: Limit,
2615    pub trace_mac: bool,
2616    /// If false, strip `#[test]` nodes
2617    pub should_test: bool,
2618    /// If true, use verbose debugging for `proc_macro::Span`
2619    pub span_debug: bool,
2620    /// If true, show backtraces for proc-macro panics
2621    pub proc_macro_backtrace: bool,
2622}
2623
2624impl ExpansionConfig<'_> {
2625    pub fn default(crate_name: Symbol, features: &Features) -> ExpansionConfig<'_> {
2626        ExpansionConfig {
2627            crate_name,
2628            features,
2629            // FIXME should this limit be configurable?
2630            recursion_limit: Limit::new(1024),
2631            trace_mac: false,
2632            should_test: false,
2633            span_debug: false,
2634            proc_macro_backtrace: false,
2635        }
2636    }
2637}