rustc_expand/
expand.rs

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