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