Skip to main content

rustc_expand/
base.rs

1use std::any::Any;
2use std::default::Default;
3use std::iter;
4use std::path::Component::Prefix;
5use std::path::PathBuf;
6use std::rc::Rc;
7use std::sync::Arc;
8
9use rustc_ast::attr::MarkedAttrs;
10use rustc_ast::tokenstream::TokenStream;
11use rustc_ast::visit::{AssocCtxt, Visitor};
12use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind, Safety};
13use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
14use rustc_data_structures::sync;
15use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult};
16use rustc_feature::Features;
17use rustc_hir as hir;
18use rustc_hir::attrs::{CfgEntry, CollapseMacroDebuginfo, Deprecation};
19use rustc_hir::def::MacroKinds;
20use rustc_hir::limit::Limit;
21use rustc_hir::{Stability, find_attr};
22use rustc_lint_defs::RegisteredTools;
23use rustc_parse::MACRO_ARGUMENTS;
24use rustc_parse::parser::Parser;
25use rustc_session::Session;
26use rustc_session::parse::ParseSess;
27use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
28use rustc_span::edition::Edition;
29use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
30use rustc_span::source_map::SourceMap;
31use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
32use smallvec::{SmallVec, smallvec};
33use thin_vec::ThinVec;
34
35use crate::errors;
36use crate::expand::{self, AstFragment, Invocation};
37use crate::mbe::macro_rules::ParserAnyMacro;
38use crate::module::DirOwnership;
39use crate::stats::MacroStat;
40
41// When adding new variants, make sure to
42// adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
43// to use `assign_id!`
44#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Annotatable {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Annotatable::Item(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Item",
                    &__self_0),
            Annotatable::AssocItem(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "AssocItem", __self_0, &__self_1),
            Annotatable::ForeignItem(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ForeignItem", &__self_0),
            Annotatable::Stmt(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Stmt",
                    &__self_0),
            Annotatable::Expr(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Expr",
                    &__self_0),
            Annotatable::Arm(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Arm",
                    &__self_0),
            Annotatable::ExprField(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ExprField", &__self_0),
            Annotatable::PatField(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "PatField", &__self_0),
            Annotatable::GenericParam(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "GenericParam", &__self_0),
            Annotatable::Param(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Param",
                    &__self_0),
            Annotatable::FieldDef(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FieldDef", &__self_0),
            Annotatable::Variant(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Variant", &__self_0),
            Annotatable::WherePredicate(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "WherePredicate", &__self_0),
            Annotatable::Crate(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Crate",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Annotatable {
    #[inline]
    fn clone(&self) -> Annotatable {
        match self {
            Annotatable::Item(__self_0) =>
                Annotatable::Item(::core::clone::Clone::clone(__self_0)),
            Annotatable::AssocItem(__self_0, __self_1) =>
                Annotatable::AssocItem(::core::clone::Clone::clone(__self_0),
                    ::core::clone::Clone::clone(__self_1)),
            Annotatable::ForeignItem(__self_0) =>
                Annotatable::ForeignItem(::core::clone::Clone::clone(__self_0)),
            Annotatable::Stmt(__self_0) =>
                Annotatable::Stmt(::core::clone::Clone::clone(__self_0)),
            Annotatable::Expr(__self_0) =>
                Annotatable::Expr(::core::clone::Clone::clone(__self_0)),
            Annotatable::Arm(__self_0) =>
                Annotatable::Arm(::core::clone::Clone::clone(__self_0)),
            Annotatable::ExprField(__self_0) =>
                Annotatable::ExprField(::core::clone::Clone::clone(__self_0)),
            Annotatable::PatField(__self_0) =>
                Annotatable::PatField(::core::clone::Clone::clone(__self_0)),
            Annotatable::GenericParam(__self_0) =>
                Annotatable::GenericParam(::core::clone::Clone::clone(__self_0)),
            Annotatable::Param(__self_0) =>
                Annotatable::Param(::core::clone::Clone::clone(__self_0)),
            Annotatable::FieldDef(__self_0) =>
                Annotatable::FieldDef(::core::clone::Clone::clone(__self_0)),
            Annotatable::Variant(__self_0) =>
                Annotatable::Variant(::core::clone::Clone::clone(__self_0)),
            Annotatable::WherePredicate(__self_0) =>
                Annotatable::WherePredicate(::core::clone::Clone::clone(__self_0)),
            Annotatable::Crate(__self_0) =>
                Annotatable::Crate(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
45pub enum Annotatable {
46    Item(Box<ast::Item>),
47    AssocItem(Box<ast::AssocItem>, AssocCtxt),
48    ForeignItem(Box<ast::ForeignItem>),
49    Stmt(Box<ast::Stmt>),
50    Expr(Box<ast::Expr>),
51    Arm(ast::Arm),
52    ExprField(ast::ExprField),
53    PatField(ast::PatField),
54    GenericParam(ast::GenericParam),
55    Param(ast::Param),
56    FieldDef(ast::FieldDef),
57    Variant(ast::Variant),
58    WherePredicate(ast::WherePredicate),
59    Crate(ast::Crate),
60}
61
62impl Annotatable {
63    pub fn span(&self) -> Span {
64        match self {
65            Annotatable::Item(item) => item.span,
66            Annotatable::AssocItem(assoc_item, _) => assoc_item.span,
67            Annotatable::ForeignItem(foreign_item) => foreign_item.span,
68            Annotatable::Stmt(stmt) => stmt.span,
69            Annotatable::Expr(expr) => expr.span,
70            Annotatable::Arm(arm) => arm.span,
71            Annotatable::ExprField(field) => field.span,
72            Annotatable::PatField(fp) => fp.pat.span,
73            Annotatable::GenericParam(gp) => gp.ident.span,
74            Annotatable::Param(p) => p.span,
75            Annotatable::FieldDef(sf) => sf.span,
76            Annotatable::Variant(v) => v.span,
77            Annotatable::WherePredicate(wp) => wp.span,
78            Annotatable::Crate(c) => c.spans.inner_span,
79        }
80    }
81
82    pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
83        match self {
84            Annotatable::Item(item) => item.visit_attrs(f),
85            Annotatable::AssocItem(assoc_item, _) => assoc_item.visit_attrs(f),
86            Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
87            Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
88            Annotatable::Expr(expr) => expr.visit_attrs(f),
89            Annotatable::Arm(arm) => arm.visit_attrs(f),
90            Annotatable::ExprField(field) => field.visit_attrs(f),
91            Annotatable::PatField(fp) => fp.visit_attrs(f),
92            Annotatable::GenericParam(gp) => gp.visit_attrs(f),
93            Annotatable::Param(p) => p.visit_attrs(f),
94            Annotatable::FieldDef(sf) => sf.visit_attrs(f),
95            Annotatable::Variant(v) => v.visit_attrs(f),
96            Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
97            Annotatable::Crate(c) => c.visit_attrs(f),
98        }
99    }
100
101    pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
102        match self {
103            Annotatable::Item(item) => visitor.visit_item(item),
104            Annotatable::AssocItem(item, ctxt) => visitor.visit_assoc_item(item, *ctxt),
105            Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
106            Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
107            Annotatable::Expr(expr) => visitor.visit_expr(expr),
108            Annotatable::Arm(arm) => visitor.visit_arm(arm),
109            Annotatable::ExprField(field) => visitor.visit_expr_field(field),
110            Annotatable::PatField(fp) => visitor.visit_pat_field(fp),
111            Annotatable::GenericParam(gp) => visitor.visit_generic_param(gp),
112            Annotatable::Param(p) => visitor.visit_param(p),
113            Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
114            Annotatable::Variant(v) => visitor.visit_variant(v),
115            Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
116            Annotatable::Crate(c) => visitor.visit_crate(c),
117        }
118    }
119
120    pub fn to_tokens(&self) -> TokenStream {
121        match self {
122            Annotatable::Item(node) => TokenStream::from_ast(node),
123            Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
124            Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
125            Annotatable::Stmt(node) => {
126                if !!#[allow(non_exhaustive_omitted_patterns)] match node.kind {
                ast::StmtKind::Empty => true,
                _ => false,
            } {
    ::core::panicking::panic("assertion failed: !matches!(node.kind, ast::StmtKind::Empty)")
};assert!(!matches!(node.kind, ast::StmtKind::Empty));
127                TokenStream::from_ast(node)
128            }
129            Annotatable::Expr(node) => TokenStream::from_ast(node),
130            Annotatable::Arm(..)
131            | Annotatable::ExprField(..)
132            | Annotatable::PatField(..)
133            | Annotatable::GenericParam(..)
134            | Annotatable::Param(..)
135            | Annotatable::FieldDef(..)
136            | Annotatable::Variant(..)
137            | Annotatable::WherePredicate(..)
138            | Annotatable::Crate(..) => { ::core::panicking::panic_fmt(format_args!("unexpected annotatable")); }panic!("unexpected annotatable"),
139        }
140    }
141
142    pub fn expect_item(self) -> Box<ast::Item> {
143        match self {
144            Annotatable::Item(i) => i,
145            _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
146        }
147    }
148
149    pub fn expect_trait_item(self) -> Box<ast::AssocItem> {
150        match self {
151            Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
152            _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
153        }
154    }
155
156    pub fn expect_impl_item(self) -> Box<ast::AssocItem> {
157        match self {
158            Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
159            _ => { ::core::panicking::panic_fmt(format_args!("expected Item")); }panic!("expected Item"),
160        }
161    }
162
163    pub fn expect_foreign_item(self) -> Box<ast::ForeignItem> {
164        match self {
165            Annotatable::ForeignItem(i) => i,
166            _ => { ::core::panicking::panic_fmt(format_args!("expected foreign item")); }panic!("expected foreign item"),
167        }
168    }
169
170    pub fn expect_stmt(self) -> ast::Stmt {
171        match self {
172            Annotatable::Stmt(stmt) => *stmt,
173            _ => { ::core::panicking::panic_fmt(format_args!("expected statement")); }panic!("expected statement"),
174        }
175    }
176
177    pub fn expect_expr(self) -> Box<ast::Expr> {
178        match self {
179            Annotatable::Expr(expr) => expr,
180            _ => { ::core::panicking::panic_fmt(format_args!("expected expression")); }panic!("expected expression"),
181        }
182    }
183
184    pub fn expect_arm(self) -> ast::Arm {
185        match self {
186            Annotatable::Arm(arm) => arm,
187            _ => { ::core::panicking::panic_fmt(format_args!("expected match arm")); }panic!("expected match arm"),
188        }
189    }
190
191    pub fn expect_expr_field(self) -> ast::ExprField {
192        match self {
193            Annotatable::ExprField(field) => field,
194            _ => { ::core::panicking::panic_fmt(format_args!("expected field")); }panic!("expected field"),
195        }
196    }
197
198    pub fn expect_pat_field(self) -> ast::PatField {
199        match self {
200            Annotatable::PatField(fp) => fp,
201            _ => { ::core::panicking::panic_fmt(format_args!("expected field pattern")); }panic!("expected field pattern"),
202        }
203    }
204
205    pub fn expect_generic_param(self) -> ast::GenericParam {
206        match self {
207            Annotatable::GenericParam(gp) => gp,
208            _ => { ::core::panicking::panic_fmt(format_args!("expected generic parameter")); }panic!("expected generic parameter"),
209        }
210    }
211
212    pub fn expect_param(self) -> ast::Param {
213        match self {
214            Annotatable::Param(param) => param,
215            _ => { ::core::panicking::panic_fmt(format_args!("expected parameter")); }panic!("expected parameter"),
216        }
217    }
218
219    pub fn expect_field_def(self) -> ast::FieldDef {
220        match self {
221            Annotatable::FieldDef(sf) => sf,
222            _ => { ::core::panicking::panic_fmt(format_args!("expected struct field")); }panic!("expected struct field"),
223        }
224    }
225
226    pub fn expect_variant(self) -> ast::Variant {
227        match self {
228            Annotatable::Variant(v) => v,
229            _ => { ::core::panicking::panic_fmt(format_args!("expected variant")); }panic!("expected variant"),
230        }
231    }
232
233    pub fn expect_where_predicate(self) -> ast::WherePredicate {
234        match self {
235            Annotatable::WherePredicate(wp) => wp,
236            _ => { ::core::panicking::panic_fmt(format_args!("expected where predicate")); }panic!("expected where predicate"),
237        }
238    }
239
240    pub fn expect_crate(self) -> ast::Crate {
241        match self {
242            Annotatable::Crate(krate) => krate,
243            _ => { ::core::panicking::panic_fmt(format_args!("expected krate")); }panic!("expected krate"),
244        }
245    }
246}
247
248/// Result of an expansion that may need to be retried.
249/// Consider using this for non-`MultiItemModifier` expanders as well.
250pub enum ExpandResult<T, U> {
251    /// Expansion produced a result (possibly dummy).
252    Ready(T),
253    /// Expansion could not produce a result and needs to be retried.
254    Retry(U),
255}
256
257impl<T, U> ExpandResult<T, U> {
258    pub fn map<E, F: FnOnce(T) -> E>(self, f: F) -> ExpandResult<E, U> {
259        match self {
260            ExpandResult::Ready(t) => ExpandResult::Ready(f(t)),
261            ExpandResult::Retry(u) => ExpandResult::Retry(u),
262        }
263    }
264}
265
266impl<'cx> MacroExpanderResult<'cx> {
267    /// Creates a [`MacroExpanderResult::Ready`] from a [`TokenStream`].
268    ///
269    /// The `TokenStream` is forwarded without any expansion.
270    pub fn from_tts(
271        cx: &'cx mut ExtCtxt<'_>,
272        tts: TokenStream,
273        site_span: Span,
274        arm_span: Span,
275        macro_ident: Ident,
276    ) -> Self {
277        // Emit the SEMICOLON_IN_EXPRESSIONS_FROM_MACROS deprecation lint.
278        let is_local = true;
279
280        let parser = ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident);
281        ExpandResult::Ready(Box::new(parser))
282    }
283}
284
285pub trait MultiItemModifier {
286    /// `meta_item` is the attribute, and `item` is the item being modified.
287    fn expand(
288        &self,
289        ecx: &mut ExtCtxt<'_>,
290        span: Span,
291        meta_item: &ast::MetaItem,
292        item: Annotatable,
293        is_derive_const: bool,
294    ) -> ExpandResult<Vec<Annotatable>, Annotatable>;
295}
296
297impl<F> MultiItemModifier for F
298where
299    F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> Vec<Annotatable>,
300{
301    fn expand(
302        &self,
303        ecx: &mut ExtCtxt<'_>,
304        span: Span,
305        meta_item: &ast::MetaItem,
306        item: Annotatable,
307        _is_derive_const: bool,
308    ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
309        ExpandResult::Ready(self(ecx, span, meta_item, item))
310    }
311}
312
313pub trait BangProcMacro {
314    fn expand<'cx>(
315        &self,
316        ecx: &'cx mut ExtCtxt<'_>,
317        span: Span,
318        ts: TokenStream,
319    ) -> Result<TokenStream, ErrorGuaranteed>;
320}
321
322impl<F> BangProcMacro for F
323where
324    F: Fn(&mut ExtCtxt<'_>, Span, TokenStream) -> Result<TokenStream, ErrorGuaranteed>,
325{
326    fn expand<'cx>(
327        &self,
328        ecx: &'cx mut ExtCtxt<'_>,
329        span: Span,
330        ts: TokenStream,
331    ) -> Result<TokenStream, ErrorGuaranteed> {
332        // FIXME setup implicit context in TLS before calling self.
333        self(ecx, span, ts)
334    }
335}
336
337pub trait AttrProcMacro {
338    fn expand<'cx>(
339        &self,
340        ecx: &'cx mut ExtCtxt<'_>,
341        span: Span,
342        annotation: TokenStream,
343        annotated: TokenStream,
344    ) -> Result<TokenStream, ErrorGuaranteed>;
345
346    // Default implementation for safe attributes; override if the attribute can be unsafe.
347    fn expand_with_safety<'cx>(
348        &self,
349        ecx: &'cx mut ExtCtxt<'_>,
350        safety: Safety,
351        span: Span,
352        annotation: TokenStream,
353        annotated: TokenStream,
354    ) -> Result<TokenStream, ErrorGuaranteed> {
355        if let Safety::Unsafe(span) = safety {
356            ecx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
357        }
358        self.expand(ecx, span, annotation, annotated)
359    }
360}
361
362impl<F> AttrProcMacro for F
363where
364    F: Fn(TokenStream, TokenStream) -> TokenStream,
365{
366    fn expand<'cx>(
367        &self,
368        _ecx: &'cx mut ExtCtxt<'_>,
369        _span: Span,
370        annotation: TokenStream,
371        annotated: TokenStream,
372    ) -> Result<TokenStream, ErrorGuaranteed> {
373        // FIXME setup implicit context in TLS before calling self.
374        Ok(self(annotation, annotated))
375    }
376}
377
378/// Represents a thing that maps token trees to Macro Results
379pub trait TTMacroExpander: Any {
380    fn expand<'cx>(
381        &self,
382        ecx: &'cx mut ExtCtxt<'_>,
383        span: Span,
384        input: TokenStream,
385    ) -> MacroExpanderResult<'cx>;
386}
387
388pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
389
390pub type MacroExpanderFn =
391    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;
392
393impl<F: 'static> TTMacroExpander for F
394where
395    F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
396{
397    fn expand<'cx>(
398        &self,
399        ecx: &'cx mut ExtCtxt<'_>,
400        span: Span,
401        input: TokenStream,
402    ) -> MacroExpanderResult<'cx> {
403        self(ecx, span, input)
404    }
405}
406
407pub trait GlobDelegationExpander {
408    fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()>;
409}
410
411// Use a macro because forwarding to a simple function has type system issues
412macro_rules! make_stmts_default {
413    ($me:expr) => {
414        $me.make_expr().map(|e| {
415            smallvec![ast::Stmt {
416                id: ast::DUMMY_NODE_ID,
417                span: e.span,
418                kind: ast::StmtKind::Expr(e),
419            }]
420        })
421    };
422}
423
424/// The result of a macro expansion. The return values of the various
425/// methods are spliced into the AST at the callsite of the macro.
426pub trait MacResult {
427    /// Creates an expression.
428    fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
429        None
430    }
431
432    /// Creates zero or more items.
433    fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
434        None
435    }
436
437    /// Creates zero or more impl items.
438    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
439        None
440    }
441
442    /// Creates zero or more impl items.
443    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
444        None
445    }
446
447    /// Creates zero or more trait items.
448    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
449        None
450    }
451
452    /// Creates zero or more items in an `extern {}` block
453    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
454        None
455    }
456
457    /// Creates a pattern.
458    fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
459        None
460    }
461
462    /// Creates zero or more statements.
463    ///
464    /// By default this attempts to create an expression statement,
465    /// returning None if that fails.
466    fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
467        self.make_expr().map(|e|
        {
            {
                let count = 0usize + 1usize;
                let mut vec = ::smallvec::SmallVec::new();
                if count <= vec.inline_size() {
                    vec.push(ast::Stmt {
                            id: ast::DUMMY_NODE_ID,
                            span: e.span,
                            kind: ast::StmtKind::Expr(e),
                        });
                    vec
                } else {
                    ::smallvec::SmallVec::from_vec(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                                [ast::Stmt {
                                            id: ast::DUMMY_NODE_ID,
                                            span: e.span,
                                            kind: ast::StmtKind::Expr(e),
                                        }])))
                }
            }
        })make_stmts_default!(self)
468    }
469
470    fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
471        None
472    }
473
474    fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
475        None
476    }
477
478    fn make_expr_fields(self: Box<Self>) -> Option<SmallVec<[ast::ExprField; 1]>> {
479        None
480    }
481
482    fn make_pat_fields(self: Box<Self>) -> Option<SmallVec<[ast::PatField; 1]>> {
483        None
484    }
485
486    fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
487        None
488    }
489
490    fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
491        None
492    }
493
494    fn make_field_defs(self: Box<Self>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
495        None
496    }
497
498    fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
499        None
500    }
501
502    fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
503        None
504    }
505
506    fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
507        // Fn-like macros cannot produce a crate.
508        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
509    }
510}
511
512macro_rules! make_MacEager {
513    ( $( $fld:ident: $t:ty, )* ) => {
514        /// `MacResult` implementation for the common case where you've already
515        /// built each form of AST that you might return.
516        #[derive(Default)]
517        pub struct MacEager {
518            $(
519                pub $fld: Option<$t>,
520            )*
521        }
522
523        impl MacEager {
524            $(
525                pub fn $fld(v: $t) -> Box<dyn MacResult> {
526                    Box::new(MacEager {
527                        $fld: Some(v),
528                        ..Default::default()
529                    })
530                }
531            )*
532        }
533    }
534}
535
536/// `MacResult` implementation for the common case where you've already
/// built each form of AST that you might return.
pub struct MacEager {
    pub expr: Option<Box<ast::Expr>>,
    pub pat: Option<Box<ast::Pat>>,
    pub items: Option<SmallVec<[Box<ast::Item>; 1]>>,
    pub impl_items: Option<SmallVec<[Box<ast::AssocItem>; 1]>>,
    pub trait_items: Option<SmallVec<[Box<ast::AssocItem>; 1]>>,
    pub foreign_items: Option<SmallVec<[Box<ast::ForeignItem>; 1]>>,
    pub stmts: Option<SmallVec<[ast::Stmt; 1]>>,
    pub ty: Option<Box<ast::Ty>>,
}
#[automatically_derived]
impl ::core::default::Default for MacEager {
    #[inline]
    fn default() -> MacEager {
        MacEager {
            expr: ::core::default::Default::default(),
            pat: ::core::default::Default::default(),
            items: ::core::default::Default::default(),
            impl_items: ::core::default::Default::default(),
            trait_items: ::core::default::Default::default(),
            foreign_items: ::core::default::Default::default(),
            stmts: ::core::default::Default::default(),
            ty: ::core::default::Default::default(),
        }
    }
}
impl MacEager {
    pub fn expr(v: Box<ast::Expr>) -> Box<dyn MacResult> {
        Box::new(MacEager { expr: Some(v), ..Default::default() })
    }
    pub fn pat(v: Box<ast::Pat>) -> Box<dyn MacResult> {
        Box::new(MacEager { pat: Some(v), ..Default::default() })
    }
    pub fn items(v: SmallVec<[Box<ast::Item>; 1]>) -> Box<dyn MacResult> {
        Box::new(MacEager { items: Some(v), ..Default::default() })
    }
    pub fn impl_items(v: SmallVec<[Box<ast::AssocItem>; 1]>)
        -> Box<dyn MacResult> {
        Box::new(MacEager { impl_items: Some(v), ..Default::default() })
    }
    pub fn trait_items(v: SmallVec<[Box<ast::AssocItem>; 1]>)
        -> Box<dyn MacResult> {
        Box::new(MacEager { trait_items: Some(v), ..Default::default() })
    }
    pub fn foreign_items(v: SmallVec<[Box<ast::ForeignItem>; 1]>)
        -> Box<dyn MacResult> {
        Box::new(MacEager { foreign_items: Some(v), ..Default::default() })
    }
    pub fn stmts(v: SmallVec<[ast::Stmt; 1]>) -> Box<dyn MacResult> {
        Box::new(MacEager { stmts: Some(v), ..Default::default() })
    }
    pub fn ty(v: Box<ast::Ty>) -> Box<dyn MacResult> {
        Box::new(MacEager { ty: Some(v), ..Default::default() })
    }
}make_MacEager! {
537    expr: Box<ast::Expr>,
538    pat: Box<ast::Pat>,
539    items: SmallVec<[Box<ast::Item>; 1]>,
540    impl_items: SmallVec<[Box<ast::AssocItem>; 1]>,
541    trait_items: SmallVec<[Box<ast::AssocItem>; 1]>,
542    foreign_items: SmallVec<[Box<ast::ForeignItem>; 1]>,
543    stmts: SmallVec<[ast::Stmt; 1]>,
544    ty: Box<ast::Ty>,
545}
546
547impl MacResult for MacEager {
548    fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
549        self.expr
550    }
551
552    fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
553        self.items
554    }
555
556    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
557        self.impl_items
558    }
559
560    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
561        self.impl_items
562    }
563
564    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
565        self.trait_items
566    }
567
568    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
569        self.foreign_items
570    }
571
572    fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
573        match self.stmts.as_ref().map_or(0, |s| s.len()) {
574            0 => self.make_expr().map(|e|
        {
            {
                let count = 0usize + 1usize;
                let mut vec = ::smallvec::SmallVec::new();
                if count <= vec.inline_size() {
                    vec.push(ast::Stmt {
                            id: ast::DUMMY_NODE_ID,
                            span: e.span,
                            kind: ast::StmtKind::Expr(e),
                        });
                    vec
                } else {
                    ::smallvec::SmallVec::from_vec(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                                [ast::Stmt {
                                            id: ast::DUMMY_NODE_ID,
                                            span: e.span,
                                            kind: ast::StmtKind::Expr(e),
                                        }])))
                }
            }
        })make_stmts_default!(self),
575            _ => self.stmts,
576        }
577    }
578
579    fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
580        if let Some(p) = self.pat {
581            return Some(p);
582        }
583        if let Some(e) = self.expr {
584            if #[allow(non_exhaustive_omitted_patterns)] match e.kind {
    ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_) => true,
    _ => false,
}matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
585                return Some(Box::new(ast::Pat {
586                    id: ast::DUMMY_NODE_ID,
587                    span: e.span,
588                    kind: PatKind::Expr(e),
589                    tokens: None,
590                }));
591            }
592        }
593        None
594    }
595
596    fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
597        self.ty
598    }
599}
600
601/// Fill-in macro expansion result, to allow compilation to continue
602/// after hitting errors.
603#[derive(#[automatically_derived]
impl ::core::marker::Copy for DummyResult { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DummyResult {
    #[inline]
    fn clone(&self) -> DummyResult {
        let _: ::core::clone::AssertParamIsClone<Option<ErrorGuaranteed>>;
        let _: ::core::clone::AssertParamIsClone<Span>;
        *self
    }
}Clone)]
604pub struct DummyResult {
605    guar: Option<ErrorGuaranteed>,
606    span: Span,
607}
608
609impl DummyResult {
610    /// Creates a default MacResult that can be anything.
611    ///
612    /// Use this as a return value after hitting any errors and
613    /// calling `span_err`.
614    pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
615        Box::new(DummyResult { guar: Some(guar), span })
616    }
617
618    /// Same as `any`, but must be a valid fragment, not error.
619    pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
620        Box::new(DummyResult { guar: None, span })
621    }
622
623    /// A plain dummy expression.
624    pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> Box<ast::Expr> {
625        Box::new(ast::Expr {
626            id: ast::DUMMY_NODE_ID,
627            kind: if let Some(guar) = guar {
628                ast::ExprKind::Err(guar)
629            } else {
630                ast::ExprKind::Tup(ThinVec::new())
631            },
632            span: sp,
633            attrs: ast::AttrVec::new(),
634            tokens: None,
635        })
636    }
637}
638
639impl MacResult for DummyResult {
640    fn make_expr(self: Box<DummyResult>) -> Option<Box<ast::Expr>> {
641        Some(DummyResult::raw_expr(self.span, self.guar))
642    }
643
644    fn make_pat(self: Box<DummyResult>) -> Option<Box<ast::Pat>> {
645        Some(Box::new(ast::Pat {
646            id: ast::DUMMY_NODE_ID,
647            kind: PatKind::Wild,
648            span: self.span,
649            tokens: None,
650        }))
651    }
652
653    fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
654        Some(SmallVec::new())
655    }
656
657    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
658        Some(SmallVec::new())
659    }
660
661    fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
662        Some(SmallVec::new())
663    }
664
665    fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
666        Some(SmallVec::new())
667    }
668
669    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
670        Some(SmallVec::new())
671    }
672
673    fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
674        Some({
    let count = 0usize + 1usize;
    let mut vec = ::smallvec::SmallVec::new();
    if count <= vec.inline_size() {
        vec.push(ast::Stmt {
                id: ast::DUMMY_NODE_ID,
                kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span,
                        self.guar)),
                span: self.span,
            });
        vec
    } else {
        ::smallvec::SmallVec::from_vec(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                    [ast::Stmt {
                                id: ast::DUMMY_NODE_ID,
                                kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span,
                                        self.guar)),
                                span: self.span,
                            }])))
    }
}smallvec![ast::Stmt {
675            id: ast::DUMMY_NODE_ID,
676            kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
677            span: self.span,
678        }])
679    }
680
681    fn make_ty(self: Box<DummyResult>) -> Option<Box<ast::Ty>> {
682        // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
683        // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
684        // support, so we use an empty tuple instead.
685        Some(Box::new(ast::Ty {
686            id: ast::DUMMY_NODE_ID,
687            kind: ast::TyKind::Tup(ThinVec::new()),
688            span: self.span,
689            tokens: None,
690        }))
691    }
692
693    fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
694        Some(SmallVec::new())
695    }
696
697    fn make_expr_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::ExprField; 1]>> {
698        Some(SmallVec::new())
699    }
700
701    fn make_pat_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::PatField; 1]>> {
702        Some(SmallVec::new())
703    }
704
705    fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
706        Some(SmallVec::new())
707    }
708
709    fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
710        Some(SmallVec::new())
711    }
712
713    fn make_field_defs(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
714        Some(SmallVec::new())
715    }
716
717    fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
718        Some(SmallVec::new())
719    }
720
721    fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
722        Some(ast::Crate {
723            attrs: Default::default(),
724            items: Default::default(),
725            spans: Default::default(),
726            id: ast::DUMMY_NODE_ID,
727            is_placeholder: Default::default(),
728        })
729    }
730}
731
732/// A syntax extension kind.
733#[derive(#[automatically_derived]
impl ::core::clone::Clone for SyntaxExtensionKind {
    #[inline]
    fn clone(&self) -> SyntaxExtensionKind {
        match self {
            SyntaxExtensionKind::MacroRules(__self_0) =>
                SyntaxExtensionKind::MacroRules(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::Bang(__self_0) =>
                SyntaxExtensionKind::Bang(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::LegacyBang(__self_0) =>
                SyntaxExtensionKind::LegacyBang(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::Attr(__self_0) =>
                SyntaxExtensionKind::Attr(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::LegacyAttr(__self_0) =>
                SyntaxExtensionKind::LegacyAttr(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::NonMacroAttr =>
                SyntaxExtensionKind::NonMacroAttr,
            SyntaxExtensionKind::Derive(__self_0) =>
                SyntaxExtensionKind::Derive(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::LegacyDerive(__self_0) =>
                SyntaxExtensionKind::LegacyDerive(::core::clone::Clone::clone(__self_0)),
            SyntaxExtensionKind::GlobDelegation(__self_0) =>
                SyntaxExtensionKind::GlobDelegation(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
734pub enum SyntaxExtensionKind {
735    /// A `macro_rules!` macro that can work as any `MacroKind`
736    MacroRules(Arc<crate::MacroRulesMacroExpander>),
737
738    /// A token-based function-like macro.
739    Bang(
740        /// An expander with signature TokenStream -> TokenStream.
741        Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
742    ),
743
744    /// An AST-based function-like macro.
745    LegacyBang(
746        /// An expander with signature TokenStream -> AST.
747        Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
748    ),
749
750    /// A token-based attribute macro.
751    Attr(
752        /// An expander with signature (TokenStream, TokenStream) -> TokenStream.
753        /// The first TokenStream is the attribute itself, the second is the annotated item.
754        /// The produced TokenStream replaces the input TokenStream.
755        Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
756    ),
757
758    /// An AST-based attribute macro.
759    LegacyAttr(
760        /// An expander with signature (AST, AST) -> AST.
761        /// The first AST fragment is the attribute itself, the second is the annotated item.
762        /// The produced AST fragment replaces the input AST fragment.
763        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
764    ),
765
766    /// A trivial attribute "macro" that does nothing,
767    /// only keeps the attribute and marks it as inert,
768    /// thus making it ineligible for further expansion.
769    /// E.g. `#[default]`, `#[rustfmt::skip]`.
770    NonMacroAttr,
771
772    /// A token-based derive macro.
773    Derive(
774        /// An expander with signature TokenStream -> TokenStream.
775        /// The produced TokenStream is appended to the input TokenStream.
776        ///
777        /// FIXME: The text above describes how this should work. Currently it
778        /// is handled identically to `LegacyDerive`. It should be migrated to
779        /// a token-based representation like `Bang` and `Attr`, instead of
780        /// using `MultiItemModifier`.
781        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
782    ),
783
784    /// An AST-based derive macro.
785    LegacyDerive(
786        /// An expander with signature AST -> AST.
787        /// The produced AST fragment is appended to the input AST fragment.
788        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
789    ),
790
791    /// A glob delegation.
792    ///
793    /// This is for delegated function implementations, and has nothing to do with glob imports.
794    GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
795}
796
797impl SyntaxExtensionKind {
798    /// Returns `Some(expander)` for a macro usable as a `LegacyBang`; otherwise returns `None`
799    ///
800    /// This includes a `MacroRules` with function-like rules.
801    pub fn as_legacy_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> {
802        match self {
803            SyntaxExtensionKind::LegacyBang(exp) => Some(exp.as_ref()),
804            SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::BANG) => {
805                Some(exp.as_ref())
806            }
807            _ => None,
808        }
809    }
810
811    /// Returns `Some(expander)` for a macro usable as an `Attr`; otherwise returns `None`
812    ///
813    /// This includes a `MacroRules` with `attr` rules.
814    pub fn as_attr(&self) -> Option<&(dyn AttrProcMacro + sync::DynSync + sync::DynSend)> {
815        match self {
816            SyntaxExtensionKind::Attr(exp) => Some(exp.as_ref()),
817            SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::ATTR) => {
818                Some(exp.as_ref())
819            }
820            _ => None,
821        }
822    }
823}
824
825/// A struct representing a macro definition in "lowered" form ready for expansion.
826pub struct SyntaxExtension {
827    /// A syntax extension kind.
828    pub kind: SyntaxExtensionKind,
829    /// Span of the macro definition.
830    pub span: Span,
831    /// List of unstable features that are treated as stable inside this macro.
832    pub allow_internal_unstable: Option<Arc<[Symbol]>>,
833    /// The macro's stability info.
834    pub stability: Option<Stability>,
835    /// The macro's deprecation info.
836    pub deprecation: Option<Deprecation>,
837    /// Names of helper attributes registered by this macro.
838    pub helper_attrs: Vec<Symbol>,
839    /// Edition of the crate in which this macro is defined.
840    pub edition: Edition,
841    /// Built-in macros have a couple of special properties like availability
842    /// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
843    pub builtin_name: Option<Symbol>,
844    /// Suppresses the `unsafe_code` lint for code produced by this macro.
845    pub allow_internal_unsafe: bool,
846    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
847    pub local_inner_macros: bool,
848    /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other
849    /// words, was the macro definition annotated with `#[collapse_debuginfo]`)?
850    pub collapse_debuginfo: bool,
851    /// Suppresses the "this error originates in the macro" note when a diagnostic points at this
852    /// macro.
853    pub hide_backtrace: bool,
854}
855
856impl SyntaxExtension {
857    /// Returns which kinds of macro call this syntax extension.
858    pub fn macro_kinds(&self) -> MacroKinds {
859        match self.kind {
860            SyntaxExtensionKind::Bang(..)
861            | SyntaxExtensionKind::LegacyBang(..)
862            | SyntaxExtensionKind::GlobDelegation(..) => MacroKinds::BANG,
863            SyntaxExtensionKind::Attr(..)
864            | SyntaxExtensionKind::LegacyAttr(..)
865            | SyntaxExtensionKind::NonMacroAttr => MacroKinds::ATTR,
866            SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
867                MacroKinds::DERIVE
868            }
869            SyntaxExtensionKind::MacroRules(ref m) => m.kinds(),
870        }
871    }
872
873    /// Constructs a syntax extension with default properties.
874    pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
875        SyntaxExtension {
876            span: DUMMY_SP,
877            allow_internal_unstable: None,
878            stability: None,
879            deprecation: None,
880            helper_attrs: Vec::new(),
881            edition,
882            builtin_name: None,
883            kind,
884            allow_internal_unsafe: false,
885            local_inner_macros: false,
886            collapse_debuginfo: false,
887            hide_backtrace: false,
888        }
889    }
890
891    /// if-ext - if macro from different crate (related to callsite code)
892    /// | cmd \ attr    | no  | (unspecified) | external | yes |
893    /// | no            | no  | no            | no       | no  |
894    /// | (unspecified) | no  | if-ext        | if-ext   | yes |
895    /// | external      | no  | if-ext        | if-ext   | yes |
896    /// | yes           | yes | yes           | yes      | yes |
897    fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
898        let flag = sess.opts.cg.collapse_macro_debuginfo;
899        let attr = if let Some(info) = {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(CollapseDebugInfo(info)) => {
                    break 'done Some(info);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, CollapseDebugInfo(info) => info) {
900            info.clone()
901        } else if {
    {
            'done:
                {
                for i in attrs {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(RustcBuiltinMacro { .. }) => {
                            break 'done Some(());
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }.is_some()
}find_attr!(attrs, RustcBuiltinMacro { .. }) {
902            CollapseMacroDebuginfo::Yes
903        } else {
904            CollapseMacroDebuginfo::Unspecified
905        };
906
907        #[rustfmt::skip]
908        let collapse_table = [
909            [false, false, false, false],
910            [false, ext,   ext,   true],
911            [false, ext,   ext,   true],
912            [true,  true,  true,  true],
913        ];
914        collapse_table[flag as usize][attr as usize]
915    }
916
917    fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool {
918        // FIXME(estebank): instead of reusing `#[rustc_diagnostic_item]` as a proxy, introduce a
919        // new attribute purely for this under the `#[diagnostic]` namespace.
920        {
    {
            'done:
                {
                for i in attrs {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(RustcDiagnosticItem(..)) => {
                            break 'done Some(());
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }.is_some()
}find_attr!(attrs, RustcDiagnosticItem(..))
921    }
922
923    /// Constructs a syntax extension with the given properties
924    /// and other properties converted from attributes.
925    pub fn new(
926        sess: &Session,
927        kind: SyntaxExtensionKind,
928        span: Span,
929        helper_attrs: Vec<Symbol>,
930        edition: Edition,
931        name: Symbol,
932        attrs: &[hir::Attribute],
933        is_local: bool,
934    ) -> SyntaxExtension {
935        let allow_internal_unstable = {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(AllowInternalUnstable(i, _)) => {
                    break 'done Some(i);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, AllowInternalUnstable(i, _) => i)
936            .map(|i| i.as_slice())
937            .unwrap_or_default();
938        let allow_internal_unsafe = {
    {
            'done:
                {
                for i in attrs {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(AllowInternalUnsafe(_)) => {
                            break 'done Some(());
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }.is_some()
}find_attr!(attrs, AllowInternalUnsafe(_));
939
940        let local_inner_macros =
941            *{
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(MacroExport {
                    local_inner_macros: l, .. }) => {
                    break 'done Some(l);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, MacroExport {local_inner_macros: l, ..} => l).unwrap_or(&false);
942        let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
943        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_expand/src/base.rs:943",
                        "rustc_expand::base", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_expand/src/base.rs"),
                        ::tracing_core::__macro_support::Option::Some(943u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_expand::base"),
                        ::tracing_core::field::FieldSet::new(&["name",
                                        "local_inner_macros", "collapse_debuginfo",
                                        "allow_internal_unsafe"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&name) as
                                            &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&local_inner_macros)
                                            as &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&collapse_debuginfo)
                                            as &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&allow_internal_unsafe)
                                            as &dyn Value))])
            });
    } else { ; }
};tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
944
945        let (builtin_name, helper_attrs) = match {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(RustcBuiltinMacro {
                    builtin_name, helper_attrs, .. }) => {
                    break 'done Some((builtin_name, helper_attrs));
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, RustcBuiltinMacro { builtin_name, helper_attrs, .. } => (builtin_name, helper_attrs))
946        {
947            // Override `helper_attrs` passed above if it's a built-in macro,
948            // marking `proc_macro_derive` macros as built-in is not a realistic use case.
949            Some((Some(name), helper_attrs)) => {
950                (Some(*name), helper_attrs.iter().copied().collect())
951            }
952            Some((None, _)) => (Some(name), Vec::new()),
953
954            // Not a built-in macro
955            None => (None, helper_attrs),
956        };
957        let hide_backtrace = builtin_name.is_some() || Self::get_hide_backtrace(attrs);
958
959        let stability = {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(Stability { stability, .. }) => {
                    break 'done Some(*stability);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, Stability { stability, .. } => *stability);
960
961        if let Some(sp) = {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(RustcBodyStability { span, .. })
                    => {
                    break 'done Some(*span);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(attrs, RustcBodyStability{ span, .. } => *span) {
962            sess.dcx().emit_err(errors::MacroBodyStability {
963                span: sp,
964                head_span: sess.source_map().guess_head_span(span),
965            });
966        }
967
968        SyntaxExtension {
969            kind,
970            span,
971            allow_internal_unstable: (!allow_internal_unstable.is_empty())
972                // FIXME(jdonszelmann): avoid the into_iter/collect?
973                .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
974            stability,
975            deprecation: {
    'done:
        {
        for i in attrs {
            #[allow(unused_imports)]
            use rustc_hir::attrs::AttributeKind::*;
            let i: &rustc_hir::Attribute = i;
            match i {
                rustc_hir::Attribute::Parsed(Deprecated { deprecation, .. })
                    => {
                    break 'done Some(*deprecation);
                }
                rustc_hir::Attribute::Unparsed(..) =>
                    {}
                    #[deny(unreachable_patterns)]
                    _ => {}
            }
        }
        None
    }
}find_attr!(
976                attrs,
977                Deprecated { deprecation, .. } => *deprecation
978            ),
979            helper_attrs,
980            edition,
981            builtin_name,
982            allow_internal_unsafe,
983            local_inner_macros,
984            collapse_debuginfo,
985            hide_backtrace,
986        }
987    }
988
989    /// A dummy bang macro `foo!()`.
990    pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
991        fn expand(
992            ecx: &mut ExtCtxt<'_>,
993            span: Span,
994            _ts: TokenStream,
995        ) -> Result<TokenStream, ErrorGuaranteed> {
996            Err(ecx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"))
997        }
998        SyntaxExtension::default(SyntaxExtensionKind::Bang(Arc::new(expand)), edition)
999    }
1000
1001    /// A dummy derive macro `#[derive(Foo)]`.
1002    pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
1003        fn expander(
1004            _: &mut ExtCtxt<'_>,
1005            _: Span,
1006            _: &ast::MetaItem,
1007            _: Annotatable,
1008        ) -> Vec<Annotatable> {
1009            Vec::new()
1010        }
1011        SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
1012    }
1013
1014    pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
1015        SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr, edition)
1016    }
1017
1018    pub fn glob_delegation(
1019        trait_def_id: DefId,
1020        impl_def_id: LocalDefId,
1021        edition: Edition,
1022    ) -> SyntaxExtension {
1023        struct GlobDelegationExpanderImpl {
1024            trait_def_id: DefId,
1025            impl_def_id: LocalDefId,
1026        }
1027        impl GlobDelegationExpander for GlobDelegationExpanderImpl {
1028            fn expand(
1029                &self,
1030                ecx: &mut ExtCtxt<'_>,
1031            ) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
1032                match ecx.resolver.glob_delegation_suffixes(self.trait_def_id, self.impl_def_id) {
1033                    Ok(suffixes) => ExpandResult::Ready(suffixes),
1034                    Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
1035                    Err(Indeterminate) => ExpandResult::Retry(()),
1036                }
1037            }
1038        }
1039
1040        let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
1041        SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
1042    }
1043
1044    pub fn expn_data(
1045        &self,
1046        parent: LocalExpnId,
1047        call_site: Span,
1048        descr: Symbol,
1049        kind: MacroKind,
1050        macro_def_id: Option<DefId>,
1051        parent_module: Option<DefId>,
1052    ) -> ExpnData {
1053        ExpnData::new(
1054            ExpnKind::Macro(kind, descr),
1055            parent.to_expn_id(),
1056            call_site,
1057            self.span,
1058            self.allow_internal_unstable.clone(),
1059            self.edition,
1060            macro_def_id,
1061            parent_module,
1062            self.allow_internal_unsafe,
1063            self.local_inner_macros,
1064            self.collapse_debuginfo,
1065            self.hide_backtrace,
1066        )
1067    }
1068}
1069
1070/// Error type that denotes indeterminacy.
1071pub struct Indeterminate;
1072
1073pub struct DeriveResolution {
1074    pub path: ast::Path,
1075    pub item: Annotatable,
1076    // FIXME: currently this field is only used in `is_none`/`is_some` conditions. However, the
1077    // `Arc<SyntaxExtension>` will be used if the FIXME in `MacroExpander::fully_expand_fragment`
1078    // is completed.
1079    pub exts: Option<Arc<SyntaxExtension>>,
1080    pub is_const: bool,
1081}
1082
1083pub trait ResolverExpand {
1084    fn next_node_id(&mut self) -> NodeId;
1085    fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;
1086
1087    fn resolve_dollar_crates(&self);
1088    fn visit_ast_fragment_with_placeholders(
1089        &mut self,
1090        expn_id: LocalExpnId,
1091        fragment: &AstFragment,
1092    );
1093    fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind);
1094
1095    fn expansion_for_ast_pass(
1096        &mut self,
1097        call_site: Span,
1098        pass: AstPass,
1099        features: &[Symbol],
1100        parent_module_id: Option<NodeId>,
1101    ) -> LocalExpnId;
1102
1103    fn resolve_imports(&mut self);
1104
1105    fn resolve_macro_invocation(
1106        &mut self,
1107        invoc: &Invocation,
1108        eager_expansion_root: LocalExpnId,
1109        force: bool,
1110    ) -> Result<Arc<SyntaxExtension>, Indeterminate>;
1111
1112    fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);
1113
1114    fn check_unused_macros(&mut self);
1115
1116    // Resolver interfaces for specific built-in macros.
1117    /// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
1118    fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
1119    /// Resolve paths inside the `#[derive(...)]` attribute with the given `ExpnId`.
1120    fn resolve_derives(
1121        &mut self,
1122        expn_id: LocalExpnId,
1123        force: bool,
1124        derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
1125    ) -> Result<(), Indeterminate>;
1126    /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`
1127    /// back from resolver.
1128    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
1129    /// Path resolution logic for `#[cfg_accessible(path)]`.
1130    fn cfg_accessible(
1131        &mut self,
1132        expn_id: LocalExpnId,
1133        path: &ast::Path,
1134    ) -> Result<bool, Indeterminate>;
1135    fn macro_accessible(
1136        &mut self,
1137        expn_id: LocalExpnId,
1138        path: &ast::Path,
1139    ) -> Result<bool, Indeterminate>;
1140
1141    /// Decodes the proc-macro quoted span in the specified crate, with the specified id.
1142    /// No caching is performed.
1143    fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1144
1145    /// The order of items in the HIR is unrelated to the order of
1146    /// items in the AST. However, we generate proc macro harnesses
1147    /// based on the AST order, and later refer to these harnesses
1148    /// from the HIR. This field keeps track of the order in which
1149    /// we generated proc macros harnesses, so that we can map
1150    /// HIR proc macros items back to their harness items.
1151    fn declare_proc_macro(&mut self, id: NodeId);
1152
1153    fn append_stripped_cfg_item(
1154        &mut self,
1155        parent_node: NodeId,
1156        ident: Ident,
1157        cfg: CfgEntry,
1158        cfg_span: Span,
1159    );
1160
1161    /// Tools registered with `#![register_tool]` and used by tool attributes and lints.
1162    fn registered_tools(&self) -> &RegisteredTools;
1163
1164    /// Mark this invocation id as a glob delegation.
1165    fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
1166
1167    /// Names of specific methods to which glob delegation expands.
1168    fn glob_delegation_suffixes(
1169        &self,
1170        trait_def_id: DefId,
1171        impl_def_id: LocalDefId,
1172    ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
1173
1174    /// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used
1175    /// to generate an item name later that does not reference placeholder macros.
1176    fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
1177
1178    /// Mark the scope as having a compile error so that error for lookup in this scope
1179    /// should be suppressed
1180    fn mark_scope_with_compile_error(&mut self, parent_node: NodeId);
1181}
1182
1183pub trait LintStoreExpand {
1184    fn pre_expansion_lint(
1185        &self,
1186        sess: &Session,
1187        features: &Features,
1188        registered_tools: &RegisteredTools,
1189        node_id: NodeId,
1190        attrs: &[Attribute],
1191        items: &[Box<Item>],
1192        name: Symbol,
1193    );
1194}
1195
1196type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
1197
1198#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ModuleData {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "ModuleData",
            "mod_path", &self.mod_path, "file_path_stack",
            &self.file_path_stack, "dir_path", &&self.dir_path)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for ModuleData {
    #[inline]
    fn clone(&self) -> ModuleData {
        ModuleData {
            mod_path: ::core::clone::Clone::clone(&self.mod_path),
            file_path_stack: ::core::clone::Clone::clone(&self.file_path_stack),
            dir_path: ::core::clone::Clone::clone(&self.dir_path),
        }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for ModuleData {
    #[inline]
    fn default() -> ModuleData {
        ModuleData {
            mod_path: ::core::default::Default::default(),
            file_path_stack: ::core::default::Default::default(),
            dir_path: ::core::default::Default::default(),
        }
    }
}Default)]
1199pub struct ModuleData {
1200    /// Path to the module starting from the crate name, like `my_crate::foo::bar`.
1201    pub mod_path: Vec<Ident>,
1202    /// Stack of paths to files loaded by out-of-line module items,
1203    /// used to detect and report recursive module inclusions.
1204    pub file_path_stack: Vec<PathBuf>,
1205    /// Directory to search child module files in,
1206    /// often (but not necessarily) the parent of the top file path on the `file_path_stack`.
1207    pub dir_path: PathBuf,
1208}
1209
1210impl ModuleData {
1211    pub fn with_dir_path(&self, dir_path: PathBuf) -> ModuleData {
1212        ModuleData {
1213            mod_path: self.mod_path.clone(),
1214            file_path_stack: self.file_path_stack.clone(),
1215            dir_path,
1216        }
1217    }
1218}
1219
1220#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExpansionData {
    #[inline]
    fn clone(&self) -> ExpansionData {
        ExpansionData {
            id: ::core::clone::Clone::clone(&self.id),
            depth: ::core::clone::Clone::clone(&self.depth),
            module: ::core::clone::Clone::clone(&self.module),
            dir_ownership: ::core::clone::Clone::clone(&self.dir_ownership),
            lint_node_id: ::core::clone::Clone::clone(&self.lint_node_id),
            is_trailing_mac: ::core::clone::Clone::clone(&self.is_trailing_mac),
        }
    }
}Clone)]
1221pub struct ExpansionData {
1222    pub id: LocalExpnId,
1223    pub depth: usize,
1224    pub module: Rc<ModuleData>,
1225    pub dir_ownership: DirOwnership,
1226    /// Some parent node that is close to this macro call
1227    pub lint_node_id: NodeId,
1228    pub is_trailing_mac: bool,
1229}
1230
1231/// One of these is made during expansion and incrementally updated as we go;
1232/// when a macro expansion occurs, the resulting nodes have the `backtrace()
1233/// -> expn_data` of their expansion context stored into their span.
1234pub struct ExtCtxt<'a> {
1235    pub sess: &'a Session,
1236    pub ecfg: expand::ExpansionConfig<'a>,
1237    pub num_standard_library_imports: usize,
1238    pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
1239    pub root_path: PathBuf,
1240    pub resolver: &'a mut dyn ResolverExpand,
1241    pub current_expansion: ExpansionData,
1242    /// Error recovery mode entered when expansion is stuck
1243    /// (or during eager expansion, but that's a hack).
1244    pub force_mode: bool,
1245    pub expansions: FxIndexMap<Span, Vec<String>>,
1246    /// Used for running pre-expansion lints on freshly loaded modules.
1247    pub(super) lint_store: LintStoreExpandDyn<'a>,
1248    /// Used for storing lints generated during expansion, like `NAMED_ARGUMENTS_USED_POSITIONALLY`
1249    pub buffered_early_lint: Vec<BufferedEarlyLint>,
1250    /// When we 'expand' an inert attribute, we leave it
1251    /// in the AST, but insert it here so that we know
1252    /// not to expand it again.
1253    pub(super) expanded_inert_attrs: MarkedAttrs,
1254    /// `-Zmacro-stats` data.
1255    pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1256    pub nb_macro_errors: usize,
1257}
1258
1259impl<'a> ExtCtxt<'a> {
1260    pub fn new(
1261        sess: &'a Session,
1262        ecfg: expand::ExpansionConfig<'a>,
1263        resolver: &'a mut dyn ResolverExpand,
1264        lint_store: LintStoreExpandDyn<'a>,
1265    ) -> ExtCtxt<'a> {
1266        ExtCtxt {
1267            sess,
1268            ecfg,
1269            num_standard_library_imports: 0,
1270            reduced_recursion_limit: None,
1271            resolver,
1272            lint_store,
1273            root_path: PathBuf::new(),
1274            current_expansion: ExpansionData {
1275                id: LocalExpnId::ROOT,
1276                depth: 0,
1277                module: Default::default(),
1278                dir_ownership: DirOwnership::Owned { relative: None },
1279                lint_node_id: ast::CRATE_NODE_ID,
1280                is_trailing_mac: false,
1281            },
1282            force_mode: false,
1283            expansions: FxIndexMap::default(),
1284            expanded_inert_attrs: MarkedAttrs::new(),
1285            buffered_early_lint: ::alloc::vec::Vec::new()vec![],
1286            macro_stats: Default::default(),
1287            nb_macro_errors: 0,
1288        }
1289    }
1290
1291    pub fn dcx(&self) -> DiagCtxtHandle<'a> {
1292        self.sess.dcx()
1293    }
1294
1295    /// Returns a `Folder` for deeply expanding all macros in an AST node.
1296    pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1297        expand::MacroExpander::new(self, false)
1298    }
1299
1300    /// Returns a `Folder` that deeply expands all macros and assigns all `NodeId`s in an AST node.
1301    /// Once `NodeId`s are assigned, the node may not be expanded, removed, or otherwise modified.
1302    pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
1303        expand::MacroExpander::new(self, true)
1304    }
1305    pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
1306        Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
1307    }
1308    pub fn source_map(&self) -> &'a SourceMap {
1309        self.sess.psess.source_map()
1310    }
1311    pub fn psess(&self) -> &'a ParseSess {
1312        &self.sess.psess
1313    }
1314    pub fn call_site(&self) -> Span {
1315        self.current_expansion.id.expn_data().call_site
1316    }
1317
1318    /// Returns the current expansion kind's description.
1319    pub(crate) fn expansion_descr(&self) -> String {
1320        let expn_data = self.current_expansion.id.expn_data();
1321        expn_data.kind.descr()
1322    }
1323
1324    /// Equivalent of `Span::def_site` from the proc macro API,
1325    /// except that the location is taken from the span passed as an argument.
1326    pub fn with_def_site_ctxt(&self, span: Span) -> Span {
1327        span.with_def_site_ctxt(self.current_expansion.id.to_expn_id())
1328    }
1329
1330    /// Equivalent of `Span::call_site` from the proc macro API,
1331    /// except that the location is taken from the span passed as an argument.
1332    pub fn with_call_site_ctxt(&self, span: Span) -> Span {
1333        span.with_call_site_ctxt(self.current_expansion.id.to_expn_id())
1334    }
1335
1336    /// Equivalent of `Span::mixed_site` from the proc macro API,
1337    /// except that the location is taken from the span passed as an argument.
1338    pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
1339        span.with_mixed_site_ctxt(self.current_expansion.id.to_expn_id())
1340    }
1341
1342    /// Returns span for the macro which originally caused the current expansion to happen.
1343    ///
1344    /// Stops backtracing at include! boundary.
1345    pub fn expansion_cause(&self) -> Option<Span> {
1346        self.current_expansion.id.expansion_cause()
1347    }
1348
1349    /// This method increases the internal macro errors count and then call `trace_macros_diag`.
1350    pub fn macro_error_and_trace_macros_diag(&mut self) {
1351        self.nb_macro_errors += 1;
1352        self.trace_macros_diag();
1353    }
1354
1355    pub fn trace_macros_diag(&mut self) {
1356        for (span, notes) in self.expansions.iter() {
1357            let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
1358            for note in notes {
1359                db.note(note.clone());
1360            }
1361            db.emit();
1362        }
1363        // Fixme: does this result in errors?
1364        self.expansions.clear();
1365    }
1366    pub fn trace_macros(&self) -> bool {
1367        self.ecfg.trace_mac
1368    }
1369    pub fn set_trace_macros(&mut self, x: bool) {
1370        self.ecfg.trace_mac = x
1371    }
1372    pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
1373        let def_site = self.with_def_site_ctxt(DUMMY_SP);
1374        iter::once(Ident::new(kw::DollarCrate, def_site))
1375            .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
1376            .collect()
1377    }
1378    pub fn def_site_path(&self, components: &[Symbol]) -> Vec<Ident> {
1379        let def_site = self.with_def_site_ctxt(DUMMY_SP);
1380        components.iter().map(|&s| Ident::new(s, def_site)).collect()
1381    }
1382
1383    pub fn check_unused_macros(&mut self) {
1384        self.resolver.check_unused_macros();
1385    }
1386}
1387
1388/// Resolves a `path` mentioned inside Rust code, returning an absolute path.
1389///
1390/// This unifies the logic used for resolving `include_X!`.
1391pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PResult<'_, PathBuf> {
1392    let path = path.into();
1393
1394    // Relative paths are resolved relative to the file in which they are found
1395    // after macro expansion (that is, they are unhygienic).
1396    if !path.is_absolute() {
1397        let callsite = span.source_callsite();
1398        let source_map = sess.source_map();
1399        let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
1400            return Err(sess.dcx().create_err(errors::ResolveRelativePath {
1401                span,
1402                path: source_map
1403                    .filename_for_diagnostics(&source_map.span_to_filename(callsite))
1404                    .to_string(),
1405            }));
1406        };
1407        base_path.pop();
1408        base_path.push(path);
1409        Ok(base_path)
1410    } else {
1411        // This ensures that Windows verbatim paths are fixed if mixed path separators are used,
1412        // which can happen when `concat!` is used to join paths.
1413        match path.components().next() {
1414            Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
1415            _ => Ok(path),
1416        }
1417    }
1418}