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