use std::any::Any;
use std::default::Default;
use std::iter;
use std::path::Component::Prefix;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;

use rustc_ast::attr::{AttributeExt, MarkedAttrs};
use rustc_ast::token::MetaVarKind;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::sync;
use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation};
use rustc_hir::def::MacroKinds;
use rustc_hir::limit::Limit;
use rustc_hir::{Stability, find_attr};
use rustc_lint_defs::RegisteredTools;
use rustc_parse::MACRO_ARGUMENTS;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_session::Session;
use rustc_session::config::CollapseMacroDebuginfo;
use rustc_session::parse::ParseSess;
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym};
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;

use crate::base::ast::MetaItemInner;
use crate::errors;
use crate::expand::{self, AstFragment, Invocation};
use crate::mbe::macro_rules::ParserAnyMacro;
use crate::module::DirOwnership;
use crate::stats::MacroStat;

// When adding new variants, make sure to
// adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
// to use `assign_id!`
#[derive(Debug, Clone)]
pub enum Annotatable {
    Item(Box<ast::Item>),
    AssocItem(Box<ast::AssocItem>, AssocCtxt),
    ForeignItem(Box<ast::ForeignItem>),
    Stmt(Box<ast::Stmt>),
    Expr(Box<ast::Expr>),
    Arm(ast::Arm),
    ExprField(ast::ExprField),
    PatField(ast::PatField),
    GenericParam(ast::GenericParam),
    Param(ast::Param),
    FieldDef(ast::FieldDef),
    Variant(ast::Variant),
    WherePredicate(ast::WherePredicate),
    Crate(ast::Crate),
}

impl Annotatable {
    pub fn span(&self) -> Span {
        match self {
            Annotatable::Item(item) => item.span,
            Annotatable::AssocItem(assoc_item, _) => assoc_item.span,
            Annotatable::ForeignItem(foreign_item) => foreign_item.span,
            Annotatable::Stmt(stmt) => stmt.span,
            Annotatable::Expr(expr) => expr.span,
            Annotatable::Arm(arm) => arm.span,
            Annotatable::ExprField(field) => field.span,
            Annotatable::PatField(fp) => fp.pat.span,
            Annotatable::GenericParam(gp) => gp.ident.span,
            Annotatable::Param(p) => p.span,
            Annotatable::FieldDef(sf) => sf.span,
            Annotatable::Variant(v) => v.span,
            Annotatable::WherePredicate(wp) => wp.span,
            Annotatable::Crate(c) => c.spans.inner_span,
        }
    }

    pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
        match self {
            Annotatable::Item(item) => item.visit_attrs(f),
            Annotatable::AssocItem(assoc_item, _) => assoc_item.visit_attrs(f),
            Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
            Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
            Annotatable::Expr(expr) => expr.visit_attrs(f),
            Annotatable::Arm(arm) => arm.visit_attrs(f),
            Annotatable::ExprField(field) => field.visit_attrs(f),
            Annotatable::PatField(fp) => fp.visit_attrs(f),
            Annotatable::GenericParam(gp) => gp.visit_attrs(f),
            Annotatable::Param(p) => p.visit_attrs(f),
            Annotatable::FieldDef(sf) => sf.visit_attrs(f),
            Annotatable::Variant(v) => v.visit_attrs(f),
            Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
            Annotatable::Crate(c) => c.visit_attrs(f),
        }
    }

    pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
        match self {
            Annotatable::Item(item) => visitor.visit_item(item),
            Annotatable::AssocItem(item, ctxt) => visitor.visit_assoc_item(item, *ctxt),
            Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
            Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
            Annotatable::Expr(expr) => visitor.visit_expr(expr),
            Annotatable::Arm(arm) => visitor.visit_arm(arm),
            Annotatable::ExprField(field) => visitor.visit_expr_field(field),
            Annotatable::PatField(fp) => visitor.visit_pat_field(fp),
            Annotatable::GenericParam(gp) => visitor.visit_generic_param(gp),
            Annotatable::Param(p) => visitor.visit_param(p),
            Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
            Annotatable::Variant(v) => visitor.visit_variant(v),
            Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
            Annotatable::Crate(c) => visitor.visit_crate(c),
        }
    }

    pub fn to_tokens(&self) -> TokenStream {
        match self {
            Annotatable::Item(node) => TokenStream::from_ast(node),
            Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
            Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
            Annotatable::Stmt(node) => {
                assert!(!matches!(node.kind, ast::StmtKind::Empty));
                TokenStream::from_ast(node)
            }
            Annotatable::Expr(node) => TokenStream::from_ast(node),
            Annotatable::Arm(..)
            | Annotatable::ExprField(..)
            | Annotatable::PatField(..)
            | Annotatable::GenericParam(..)
            | Annotatable::Param(..)
            | Annotatable::FieldDef(..)
            | Annotatable::Variant(..)
            | Annotatable::WherePredicate(..)
            | Annotatable::Crate(..) => panic!("unexpected annotatable"),
        }
    }

    pub fn expect_item(self) -> Box<ast::Item> {
        match self {
            Annotatable::Item(i) => i,
            _ => panic!("expected Item"),
        }
    }

    pub fn expect_trait_item(self) -> Box<ast::AssocItem> {
        match self {
            Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
            _ => panic!("expected Item"),
        }
    }

    pub fn expect_impl_item(self) -> Box<ast::AssocItem> {
        match self {
            Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
            _ => panic!("expected Item"),
        }
    }

    pub fn expect_foreign_item(self) -> Box<ast::ForeignItem> {
        match self {
            Annotatable::ForeignItem(i) => i,
            _ => panic!("expected foreign item"),
        }
    }

    pub fn expect_stmt(self) -> ast::Stmt {
        match self {
            Annotatable::Stmt(stmt) => *stmt,
            _ => panic!("expected statement"),
        }
    }

    pub fn expect_expr(self) -> Box<ast::Expr> {
        match self {
            Annotatable::Expr(expr) => expr,
            _ => panic!("expected expression"),
        }
    }

    pub fn expect_arm(self) -> ast::Arm {
        match self {
            Annotatable::Arm(arm) => arm,
            _ => panic!("expected match arm"),
        }
    }

    pub fn expect_expr_field(self) -> ast::ExprField {
        match self {
            Annotatable::ExprField(field) => field,
            _ => panic!("expected field"),
        }
    }

    pub fn expect_pat_field(self) -> ast::PatField {
        match self {
            Annotatable::PatField(fp) => fp,
            _ => panic!("expected field pattern"),
        }
    }

    pub fn expect_generic_param(self) -> ast::GenericParam {
        match self {
            Annotatable::GenericParam(gp) => gp,
            _ => panic!("expected generic parameter"),
        }
    }

    pub fn expect_param(self) -> ast::Param {
        match self {
            Annotatable::Param(param) => param,
            _ => panic!("expected parameter"),
        }
    }

    pub fn expect_field_def(self) -> ast::FieldDef {
        match self {
            Annotatable::FieldDef(sf) => sf,
            _ => panic!("expected struct field"),
        }
    }

    pub fn expect_variant(self) -> ast::Variant {
        match self {
            Annotatable::Variant(v) => v,
            _ => panic!("expected variant"),
        }
    }

    pub fn expect_where_predicate(self) -> ast::WherePredicate {
        match self {
            Annotatable::WherePredicate(wp) => wp,
            _ => panic!("expected where predicate"),
        }
    }

    pub fn expect_crate(self) -> ast::Crate {
        match self {
            Annotatable::Crate(krate) => krate,
            _ => panic!("expected krate"),
        }
    }
}

/// Result of an expansion that may need to be retried.
/// Consider using this for non-`MultiItemModifier` expanders as well.
pub enum ExpandResult<T, U> {
    /// Expansion produced a result (possibly dummy).
    Ready(T),
    /// Expansion could not produce a result and needs to be retried.
    Retry(U),
}

impl<T, U> ExpandResult<T, U> {
    pub fn map<E, F: FnOnce(T) -> E>(self, f: F) -> ExpandResult<E, U> {
        match self {
            ExpandResult::Ready(t) => ExpandResult::Ready(f(t)),
            ExpandResult::Retry(u) => ExpandResult::Retry(u),
        }
    }
}

impl<'cx> MacroExpanderResult<'cx> {
    /// Creates a [`MacroExpanderResult::Ready`] from a [`TokenStream`].
    ///
    /// The `TokenStream` is forwarded without any expansion.
    pub fn from_tts(
        cx: &'cx mut ExtCtxt<'_>,
        tts: TokenStream,
        site_span: Span,
        arm_span: Span,
        macro_ident: Ident,
    ) -> Self {
        // Emit the SEMICOLON_IN_EXPRESSIONS_FROM_MACROS deprecation lint.
        let is_local = true;

        let parser = ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident);
        ExpandResult::Ready(Box::new(parser))
    }
}

pub trait MultiItemModifier {
    /// `meta_item` is the attribute, and `item` is the item being modified.
    fn expand(
        &self,
        ecx: &mut ExtCtxt<'_>,
        span: Span,
        meta_item: &ast::MetaItem,
        item: Annotatable,
        is_derive_const: bool,
    ) -> ExpandResult<Vec<Annotatable>, Annotatable>;
}

impl<F> MultiItemModifier for F
where
    F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> Vec<Annotatable>,
{
    fn expand(
        &self,
        ecx: &mut ExtCtxt<'_>,
        span: Span,
        meta_item: &ast::MetaItem,
        item: Annotatable,
        _is_derive_const: bool,
    ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
        ExpandResult::Ready(self(ecx, span, meta_item, item))
    }
}

pub trait BangProcMacro {
    fn expand<'cx>(
        &self,
        ecx: &'cx mut ExtCtxt<'_>,
        span: Span,
        ts: TokenStream,
    ) -> Result<TokenStream, ErrorGuaranteed>;
}

impl<F> BangProcMacro for F
where
    F: Fn(TokenStream) -> TokenStream,
{
    fn expand<'cx>(
        &self,
        _ecx: &'cx mut ExtCtxt<'_>,
        _span: Span,
        ts: TokenStream,
    ) -> Result<TokenStream, ErrorGuaranteed> {
        // FIXME setup implicit context in TLS before calling self.
        Ok(self(ts))
    }
}

pub trait AttrProcMacro {
    fn expand<'cx>(
        &self,
        ecx: &'cx mut ExtCtxt<'_>,
        span: Span,
        annotation: TokenStream,
        annotated: TokenStream,
    ) -> Result<TokenStream, ErrorGuaranteed>;
}

impl<F> AttrProcMacro for F
where
    F: Fn(TokenStream, TokenStream) -> TokenStream,
{
    fn expand<'cx>(
        &self,
        _ecx: &'cx mut ExtCtxt<'_>,
        _span: Span,
        annotation: TokenStream,
        annotated: TokenStream,
    ) -> Result<TokenStream, ErrorGuaranteed> {
        // FIXME setup implicit context in TLS before calling self.
        Ok(self(annotation, annotated))
    }
}

/// Represents a thing that maps token trees to Macro Results
pub trait TTMacroExpander: Any {
    fn expand<'cx>(
        &self,
        ecx: &'cx mut ExtCtxt<'_>,
        span: Span,
        input: TokenStream,
    ) -> MacroExpanderResult<'cx>;
}

pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;

pub type MacroExpanderFn =
    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;

impl<F: 'static> TTMacroExpander for F
where
    F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
{
    fn expand<'cx>(
        &self,
        ecx: &'cx mut ExtCtxt<'_>,
        span: Span,
        input: TokenStream,
    ) -> MacroExpanderResult<'cx> {
        self(ecx, span, input)
    }
}

pub trait GlobDelegationExpander {
    fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()>;
}

// Use a macro because forwarding to a simple function has type system issues
macro_rules! make_stmts_default {
    ($me:expr) => {
        $me.make_expr().map(|e| {
            smallvec![ast::Stmt {
                id: ast::DUMMY_NODE_ID,
                span: e.span,
                kind: ast::StmtKind::Expr(e),
            }]
        })
    };
}

/// The result of a macro expansion. The return values of the various
/// methods are spliced into the AST at the callsite of the macro.
pub trait MacResult {
    /// Creates an expression.
    fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
        None
    }

    /// Creates zero or more items.
    fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
        None
    }

    /// Creates zero or more impl items.
    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        None
    }

    /// Creates zero or more impl items.
    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        None
    }

    /// Creates zero or more trait items.
    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        None
    }

    /// Creates zero or more items in an `extern {}` block
    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
        None
    }

    /// Creates a pattern.
    fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
        None
    }

    /// Creates zero or more statements.
    ///
    /// By default this attempts to create an expression statement,
    /// returning None if that fails.
    fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
        make_stmts_default!(self)
    }

    fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
        None
    }

    fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
        None
    }

    fn make_expr_fields(self: Box<Self>) -> Option<SmallVec<[ast::ExprField; 1]>> {
        None
    }

    fn make_pat_fields(self: Box<Self>) -> Option<SmallVec<[ast::PatField; 1]>> {
        None
    }

    fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
        None
    }

    fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
        None
    }

    fn make_field_defs(self: Box<Self>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
        None
    }

    fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
        None
    }

    fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
        None
    }

    fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
        // Fn-like macros cannot produce a crate.
        unreachable!()
    }
}

macro_rules! make_MacEager {
    ( $( $fld:ident: $t:ty, )* ) => {
        /// `MacResult` implementation for the common case where you've already
        /// built each form of AST that you might return.
        #[derive(Default)]
        pub struct MacEager {
            $(
                pub $fld: Option<$t>,
            )*
        }

        impl MacEager {
            $(
                pub fn $fld(v: $t) -> Box<dyn MacResult> {
                    Box::new(MacEager {
                        $fld: Some(v),
                        ..Default::default()
                    })
                }
            )*
        }
    }
}

make_MacEager! {
    expr: Box<ast::Expr>,
    pat: Box<ast::Pat>,
    items: SmallVec<[Box<ast::Item>; 1]>,
    impl_items: SmallVec<[Box<ast::AssocItem>; 1]>,
    trait_items: SmallVec<[Box<ast::AssocItem>; 1]>,
    foreign_items: SmallVec<[Box<ast::ForeignItem>; 1]>,
    stmts: SmallVec<[ast::Stmt; 1]>,
    ty: Box<ast::Ty>,
}

impl MacResult for MacEager {
    fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
        self.expr
    }

    fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
        self.items
    }

    fn make_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        self.impl_items
    }

    fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        self.impl_items
    }

    fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        self.trait_items
    }

    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
        self.foreign_items
    }

    fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
        match self.stmts.as_ref().map_or(0, |s| s.len()) {
            0 => make_stmts_default!(self),
            _ => self.stmts,
        }
    }

    fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
        if let Some(p) = self.pat {
            return Some(p);
        }
        if let Some(e) = self.expr {
            if matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) {
                return Some(Box::new(ast::Pat {
                    id: ast::DUMMY_NODE_ID,
                    span: e.span,
                    kind: PatKind::Expr(e),
                    tokens: None,
                }));
            }
        }
        None
    }

    fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
        self.ty
    }
}

/// Fill-in macro expansion result, to allow compilation to continue
/// after hitting errors.
#[derive(Copy, Clone)]
pub struct DummyResult {
    guar: Option<ErrorGuaranteed>,
    span: Span,
}

impl DummyResult {
    /// Creates a default MacResult that can be anything.
    ///
    /// Use this as a return value after hitting any errors and
    /// calling `span_err`.
    pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
        Box::new(DummyResult { guar: Some(guar), span })
    }

    /// Same as `any`, but must be a valid fragment, not error.
    pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
        Box::new(DummyResult { guar: None, span })
    }

    /// A plain dummy expression.
    pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> Box<ast::Expr> {
        Box::new(ast::Expr {
            id: ast::DUMMY_NODE_ID,
            kind: if let Some(guar) = guar {
                ast::ExprKind::Err(guar)
            } else {
                ast::ExprKind::Tup(ThinVec::new())
            },
            span: sp,
            attrs: ast::AttrVec::new(),
            tokens: None,
        })
    }
}

impl MacResult for DummyResult {
    fn make_expr(self: Box<DummyResult>) -> Option<Box<ast::Expr>> {
        Some(DummyResult::raw_expr(self.span, self.guar))
    }

    fn make_pat(self: Box<DummyResult>) -> Option<Box<ast::Pat>> {
        Some(Box::new(ast::Pat {
            id: ast::DUMMY_NODE_ID,
            kind: PatKind::Wild,
            span: self.span,
            tokens: None,
        }))
    }

    fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
        Some(SmallVec::new())
    }

    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        Some(SmallVec::new())
    }

    fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        Some(SmallVec::new())
    }

    fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[Box<ast::AssocItem>; 1]>> {
        Some(SmallVec::new())
    }

    fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::ForeignItem>; 1]>> {
        Some(SmallVec::new())
    }

    fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
        Some(smallvec![ast::Stmt {
            id: ast::DUMMY_NODE_ID,
            kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
            span: self.span,
        }])
    }

    fn make_ty(self: Box<DummyResult>) -> Option<Box<ast::Ty>> {
        // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
        // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
        // support, so we use an empty tuple instead.
        Some(Box::new(ast::Ty {
            id: ast::DUMMY_NODE_ID,
            kind: ast::TyKind::Tup(ThinVec::new()),
            span: self.span,
            tokens: None,
        }))
    }

    fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
        Some(SmallVec::new())
    }

    fn make_expr_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::ExprField; 1]>> {
        Some(SmallVec::new())
    }

    fn make_pat_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::PatField; 1]>> {
        Some(SmallVec::new())
    }

    fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
        Some(SmallVec::new())
    }

    fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
        Some(SmallVec::new())
    }

    fn make_field_defs(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldDef; 1]>> {
        Some(SmallVec::new())
    }

    fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
        Some(SmallVec::new())
    }

    fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> {
        Some(ast::Crate {
            attrs: Default::default(),
            items: Default::default(),
            spans: Default::default(),
            id: ast::DUMMY_NODE_ID,
            is_placeholder: Default::default(),
        })
    }
}

/// A syntax extension kind.
#[derive(Clone)]
pub enum SyntaxExtensionKind {
    /// A `macro_rules!` macro that can work as any `MacroKind`
    MacroRules(Arc<crate::MacroRulesMacroExpander>),

    /// A token-based function-like macro.
    Bang(
        /// An expander with signature TokenStream -> TokenStream.
        Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
    ),

    /// An AST-based function-like macro.
    LegacyBang(
        /// An expander with signature TokenStream -> AST.
        Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
    ),

    /// A token-based attribute macro.
    Attr(
        /// An expander with signature (TokenStream, TokenStream) -> TokenStream.
        /// The first TokenStream is the attribute itself, the second is the annotated item.
        /// The produced TokenStream replaces the input TokenStream.
        Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
    ),

    /// An AST-based attribute macro.
    LegacyAttr(
        /// An expander with signature (AST, AST) -> AST.
        /// The first AST fragment is the attribute itself, the second is the annotated item.
        /// The produced AST fragment replaces the input AST fragment.
        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
    ),

    /// A trivial attribute "macro" that does nothing,
    /// only keeps the attribute and marks it as inert,
    /// thus making it ineligible for further expansion.
    /// E.g. `#[default]`, `#[rustfmt::skip]`.
    NonMacroAttr,

    /// A token-based derive macro.
    Derive(
        /// An expander with signature TokenStream -> TokenStream.
        /// The produced TokenStream is appended to the input TokenStream.
        ///
        /// FIXME: The text above describes how this should work. Currently it
        /// is handled identically to `LegacyDerive`. It should be migrated to
        /// a token-based representation like `Bang` and `Attr`, instead of
        /// using `MultiItemModifier`.
        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
    ),

    /// An AST-based derive macro.
    LegacyDerive(
        /// An expander with signature AST -> AST.
        /// The produced AST fragment is appended to the input AST fragment.
        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
    ),

    /// A glob delegation.
    ///
    /// This is for delegated function implementations, and has nothing to do with glob imports.
    GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
}

impl SyntaxExtensionKind {
    /// Returns `Some(expander)` for a macro usable as a `LegacyBang`; otherwise returns `None`
    ///
    /// This includes a `MacroRules` with function-like rules.
    pub fn as_legacy_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> {
        match self {
            SyntaxExtensionKind::LegacyBang(exp) => Some(exp.as_ref()),
            SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::BANG) => {
                Some(exp.as_ref())
            }
            _ => None,
        }
    }

    /// Returns `Some(expander)` for a macro usable as an `Attr`; otherwise returns `None`
    ///
    /// This includes a `MacroRules` with `attr` rules.
    pub fn as_attr(&self) -> Option<&(dyn AttrProcMacro + sync::DynSync + sync::DynSend)> {
        match self {
            SyntaxExtensionKind::Attr(exp) => Some(exp.as_ref()),
            SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::ATTR) => {
                Some(exp.as_ref())
            }
            _ => None,
        }
    }
}

/// A struct representing a macro definition in "lowered" form ready for expansion.
pub struct SyntaxExtension {
    /// A syntax extension kind.
    pub kind: SyntaxExtensionKind,
    /// Span of the macro definition.
    pub span: Span,
    /// List of unstable features that are treated as stable inside this macro.
    pub allow_internal_unstable: Option<Arc<[Symbol]>>,
    /// The macro's stability info.
    pub stability: Option<Stability>,
    /// The macro's deprecation info.
    pub deprecation: Option<Deprecation>,
    /// Names of helper attributes registered by this macro.
    pub helper_attrs: Vec<Symbol>,
    /// Edition of the crate in which this macro is defined.
    pub edition: Edition,
    /// Built-in macros have a couple of special properties like availability
    /// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
    pub builtin_name: Option<Symbol>,
    /// Suppresses the `unsafe_code` lint for code produced by this macro.
    pub allow_internal_unsafe: bool,
    /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro.
    pub local_inner_macros: bool,
    /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other
    /// words, was the macro definition annotated with `#[collapse_debuginfo]`)?
    pub collapse_debuginfo: bool,
}

impl SyntaxExtension {
    /// Returns which kinds of macro call this syntax extension.
    pub fn macro_kinds(&self) -> MacroKinds {
        match self.kind {
            SyntaxExtensionKind::Bang(..)
            | SyntaxExtensionKind::LegacyBang(..)
            | SyntaxExtensionKind::GlobDelegation(..) => MacroKinds::BANG,
            SyntaxExtensionKind::Attr(..)
            | SyntaxExtensionKind::LegacyAttr(..)
            | SyntaxExtensionKind::NonMacroAttr => MacroKinds::ATTR,
            SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => {
                MacroKinds::DERIVE
            }
            SyntaxExtensionKind::MacroRules(ref m) => m.kinds(),
        }
    }

    /// Constructs a syntax extension with default properties.
    pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
        SyntaxExtension {
            span: DUMMY_SP,
            allow_internal_unstable: None,
            stability: None,
            deprecation: None,
            helper_attrs: Vec::new(),
            edition,
            builtin_name: None,
            kind,
            allow_internal_unsafe: false,
            local_inner_macros: false,
            collapse_debuginfo: false,
        }
    }

    fn collapse_debuginfo_by_name(
        attr: &impl AttributeExt,
    ) -> Result<CollapseMacroDebuginfo, Span> {
        let list = attr.meta_item_list();
        let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else {
            return Err(attr.span());
        };
        if !item.is_word() {
            return Err(item.span);
        }

        match item.name() {
            Some(sym::no) => Ok(CollapseMacroDebuginfo::No),
            Some(sym::external) => Ok(CollapseMacroDebuginfo::External),
            Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes),
            _ => Err(item.path.span),
        }
    }

    /// if-ext - if macro from different crate (related to callsite code)
    /// | cmd \ attr    | no  | (unspecified) | external | yes |
    /// | no            | no  | no            | no       | no  |
    /// | (unspecified) | no  | if-ext        | if-ext   | yes |
    /// | external      | no  | if-ext        | if-ext   | yes |
    /// | yes           | yes | yes           | yes      | yes |
    fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
        let flag = sess.opts.cg.collapse_macro_debuginfo;
        let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo)
            .and_then(|attr| {
                Self::collapse_debuginfo_by_name(attr)
                    .map_err(|span| {
                        sess.dcx().emit_err(errors::CollapseMacroDebuginfoIllegal { span })
                    })
                    .ok()
            })
            .unwrap_or_else(|| {
                if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) {
                    CollapseMacroDebuginfo::Yes
                } else {
                    CollapseMacroDebuginfo::Unspecified
                }
            });
        #[rustfmt::skip]
        let collapse_table = [
            [false, false, false, false],
            [false, ext,   ext,   true],
            [false, ext,   ext,   true],
            [true,  true,  true,  true],
        ];
        collapse_table[flag as usize][attr as usize]
    }

    /// Constructs a syntax extension with the given properties
    /// and other properties converted from attributes.
    pub fn new(
        sess: &Session,
        kind: SyntaxExtensionKind,
        span: Span,
        helper_attrs: Vec<Symbol>,
        edition: Edition,
        name: Symbol,
        attrs: &[hir::Attribute],
        is_local: bool,
    ) -> SyntaxExtension {
        let allow_internal_unstable =
            find_attr!(attrs, AttributeKind::AllowInternalUnstable(i, _) => i)
                .map(|i| i.as_slice())
                .unwrap_or_default();
        let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe(_));

        let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
            .and_then(|macro_export| macro_export.meta_item_list())
            .is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
        let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
        tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);

        let (builtin_name, helper_attrs) = match find_attr!(attrs, AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, .. } => (builtin_name, helper_attrs))
        {
            // Override `helper_attrs` passed above if it's a built-in macro,
            // marking `proc_macro_derive` macros as built-in is not a realistic use case.
            Some((Some(name), helper_attrs)) => {
                (Some(*name), helper_attrs.iter().copied().collect())
            }
            Some((None, _)) => (Some(name), Vec::new()),

            // Not a built-in macro
            None => (None, helper_attrs),
        };

        let stability = find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability);

        // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
        if let Some(sp) = find_attr!(attrs, AttributeKind::ConstStability { span, .. } => *span) {
            sess.dcx().emit_err(errors::MacroConstStability {
                span: sp,
                head_span: sess.source_map().guess_head_span(span),
            });
        }
        if let Some(sp) = find_attr!(attrs, AttributeKind::BodyStability{ span, .. } => *span) {
            sess.dcx().emit_err(errors::MacroBodyStability {
                span: sp,
                head_span: sess.source_map().guess_head_span(span),
            });
        }

        SyntaxExtension {
            kind,
            span,
            allow_internal_unstable: (!allow_internal_unstable.is_empty())
                // FIXME(jdonszelmann): avoid the into_iter/collect?
                .then(|| allow_internal_unstable.iter().map(|i| i.0).collect::<Vec<_>>().into()),
            stability,
            deprecation: find_attr!(
                attrs,
                AttributeKind::Deprecation { deprecation, .. } => *deprecation
            ),
            helper_attrs,
            edition,
            builtin_name,
            allow_internal_unsafe,
            local_inner_macros,
            collapse_debuginfo,
        }
    }

    /// A dummy bang macro `foo!()`.
    pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
        fn expander<'cx>(
            cx: &'cx mut ExtCtxt<'_>,
            span: Span,
            _: TokenStream,
        ) -> MacroExpanderResult<'cx> {
            ExpandResult::Ready(DummyResult::any(
                span,
                cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"),
            ))
        }
        SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition)
    }

    /// A dummy derive macro `#[derive(Foo)]`.
    pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
        fn expander(
            _: &mut ExtCtxt<'_>,
            _: Span,
            _: &ast::MetaItem,
            _: Annotatable,
        ) -> Vec<Annotatable> {
            Vec::new()
        }
        SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
    }

    pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
        SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr, edition)
    }

    pub fn glob_delegation(
        trait_def_id: DefId,
        impl_def_id: LocalDefId,
        edition: Edition,
    ) -> SyntaxExtension {
        struct GlobDelegationExpanderImpl {
            trait_def_id: DefId,
            impl_def_id: LocalDefId,
        }
        impl GlobDelegationExpander for GlobDelegationExpanderImpl {
            fn expand(
                &self,
                ecx: &mut ExtCtxt<'_>,
            ) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
                match ecx.resolver.glob_delegation_suffixes(self.trait_def_id, self.impl_def_id) {
                    Ok(suffixes) => ExpandResult::Ready(suffixes),
                    Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
                    Err(Indeterminate) => ExpandResult::Retry(()),
                }
            }
        }

        let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
        SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
    }

    pub fn expn_data(
        &self,
        parent: LocalExpnId,
        call_site: Span,
        descr: Symbol,
        kind: MacroKind,
        macro_def_id: Option<DefId>,
        parent_module: Option<DefId>,
    ) -> ExpnData {
        ExpnData::new(
            ExpnKind::Macro(kind, descr),
            parent.to_expn_id(),
            call_site,
            self.span,
            self.allow_internal_unstable.clone(),
            self.edition,
            macro_def_id,
            parent_module,
            self.allow_internal_unsafe,
            self.local_inner_macros,
            self.collapse_debuginfo,
            self.builtin_name.is_some(),
        )
    }
}

/// Error type that denotes indeterminacy.
pub struct Indeterminate;

pub struct DeriveResolution {
    pub path: ast::Path,
    pub item: Annotatable,
    pub exts: Option<Arc<SyntaxExtension>>,
    pub is_const: bool,
}

pub trait ResolverExpand {
    fn next_node_id(&mut self) -> NodeId;
    fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId;

    fn resolve_dollar_crates(&self);
    fn visit_ast_fragment_with_placeholders(
        &mut self,
        expn_id: LocalExpnId,
        fragment: &AstFragment,
    );
    fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind);

    fn expansion_for_ast_pass(
        &mut self,
        call_site: Span,
        pass: AstPass,
        features: &[Symbol],
        parent_module_id: Option<NodeId>,
    ) -> LocalExpnId;

    fn resolve_imports(&mut self);

    fn resolve_macro_invocation(
        &mut self,
        invoc: &Invocation,
        eager_expansion_root: LocalExpnId,
        force: bool,
    ) -> Result<Arc<SyntaxExtension>, Indeterminate>;

    fn record_macro_rule_usage(&mut self, mac_id: NodeId, rule_index: usize);

    fn check_unused_macros(&mut self);

    // Resolver interfaces for specific built-in macros.
    /// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
    fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool;
    /// Resolve paths inside the `#[derive(...)]` attribute with the given `ExpnId`.
    fn resolve_derives(
        &mut self,
        expn_id: LocalExpnId,
        force: bool,
        derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
    ) -> Result<(), Indeterminate>;
    /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`
    /// back from resolver.
    fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
    /// Path resolution logic for `#[cfg_accessible(path)]`.
    fn cfg_accessible(
        &mut self,
        expn_id: LocalExpnId,
        path: &ast::Path,
    ) -> Result<bool, Indeterminate>;
    fn macro_accessible(
        &mut self,
        expn_id: LocalExpnId,
        path: &ast::Path,
    ) -> Result<bool, Indeterminate>;

    /// Decodes the proc-macro quoted span in the specified crate, with the specified id.
    /// No caching is performed.
    fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;

    /// The order of items in the HIR is unrelated to the order of
    /// items in the AST. However, we generate proc macro harnesses
    /// based on the AST order, and later refer to these harnesses
    /// from the HIR. This field keeps track of the order in which
    /// we generated proc macros harnesses, so that we can map
    /// HIR proc macros items back to their harness items.
    fn declare_proc_macro(&mut self, id: NodeId);

    fn append_stripped_cfg_item(
        &mut self,
        parent_node: NodeId,
        ident: Ident,
        cfg: CfgEntry,
        cfg_span: Span,
    );

    /// Tools registered with `#![register_tool]` and used by tool attributes and lints.
    fn registered_tools(&self) -> &RegisteredTools;

    /// Mark this invocation id as a glob delegation.
    fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);

    /// Names of specific methods to which glob delegation expands.
    fn glob_delegation_suffixes(
        &self,
        trait_def_id: DefId,
        impl_def_id: LocalDefId,
    ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;

    /// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used
    /// to generate an item name later that does not reference placeholder macros.
    fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol);
}

pub trait LintStoreExpand {
    fn pre_expansion_lint(
        &self,
        sess: &Session,
        features: &Features,
        registered_tools: &RegisteredTools,
        node_id: NodeId,
        attrs: &[Attribute],
        items: &[Box<Item>],
        name: Symbol,
    );
}

type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;

#[derive(Debug, Clone, Default)]
pub struct ModuleData {
    /// Path to the module starting from the crate name, like `my_crate::foo::bar`.
    pub mod_path: Vec<Ident>,
    /// Stack of paths to files loaded by out-of-line module items,
    /// used to detect and report recursive module inclusions.
    pub file_path_stack: Vec<PathBuf>,
    /// Directory to search child module files in,
    /// often (but not necessarily) the parent of the top file path on the `file_path_stack`.
    pub dir_path: PathBuf,
}

impl ModuleData {
    pub fn with_dir_path(&self, dir_path: PathBuf) -> ModuleData {
        ModuleData {
            mod_path: self.mod_path.clone(),
            file_path_stack: self.file_path_stack.clone(),
            dir_path,
        }
    }
}

#[derive(Clone)]
pub struct ExpansionData {
    pub id: LocalExpnId,
    pub depth: usize,
    pub module: Rc<ModuleData>,
    pub dir_ownership: DirOwnership,
    /// Some parent node that is close to this macro call
    pub lint_node_id: NodeId,
    pub is_trailing_mac: bool,
}

/// One of these is made during expansion and incrementally updated as we go;
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
/// -> expn_data` of their expansion context stored into their span.
pub struct ExtCtxt<'a> {
    pub sess: &'a Session,
    pub ecfg: expand::ExpansionConfig<'a>,
    pub num_standard_library_imports: usize,
    pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
    pub root_path: PathBuf,
    pub resolver: &'a mut dyn ResolverExpand,
    pub current_expansion: ExpansionData,
    /// Error recovery mode entered when expansion is stuck
    /// (or during eager expansion, but that's a hack).
    pub force_mode: bool,
    pub expansions: FxIndexMap<Span, Vec<String>>,
    /// Used for running pre-expansion lints on freshly loaded modules.
    pub(super) lint_store: LintStoreExpandDyn<'a>,
    /// Used for storing lints generated during expansion, like `NAMED_ARGUMENTS_USED_POSITIONALLY`
    pub buffered_early_lint: Vec<BufferedEarlyLint>,
    /// When we 'expand' an inert attribute, we leave it
    /// in the AST, but insert it here so that we know
    /// not to expand it again.
    pub(super) expanded_inert_attrs: MarkedAttrs,
    /// `-Zmacro-stats` data.
    pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
    pub nb_macro_errors: usize,
}

impl<'a> ExtCtxt<'a> {
    pub fn new(
        sess: &'a Session,
        ecfg: expand::ExpansionConfig<'a>,
        resolver: &'a mut dyn ResolverExpand,
        lint_store: LintStoreExpandDyn<'a>,
    ) -> ExtCtxt<'a> {
        ExtCtxt {
            sess,
            ecfg,
            num_standard_library_imports: 0,
            reduced_recursion_limit: None,
            resolver,
            lint_store,
            root_path: PathBuf::new(),
            current_expansion: ExpansionData {
                id: LocalExpnId::ROOT,
                depth: 0,
                module: Default::default(),
                dir_ownership: DirOwnership::Owned { relative: None },
                lint_node_id: ast::CRATE_NODE_ID,
                is_trailing_mac: false,
            },
            force_mode: false,
            expansions: FxIndexMap::default(),
            expanded_inert_attrs: MarkedAttrs::new(),
            buffered_early_lint: vec![],
            macro_stats: Default::default(),
            nb_macro_errors: 0,
        }
    }

    pub fn dcx(&self) -> DiagCtxtHandle<'a> {
        self.sess.dcx()
    }

    /// Returns a `Folder` for deeply expanding all macros in an AST node.
    pub fn expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
        expand::MacroExpander::new(self, false)
    }

    /// Returns a `Folder` that deeply expands all macros and assigns all `NodeId`s in an AST node.
    /// Once `NodeId`s are assigned, the node may not be expanded, removed, or otherwise modified.
    pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
        expand::MacroExpander::new(self, true)
    }
    pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
        Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
    }
    pub fn source_map(&self) -> &'a SourceMap {
        self.sess.psess.source_map()
    }
    pub fn psess(&self) -> &'a ParseSess {
        &self.sess.psess
    }
    pub fn call_site(&self) -> Span {
        self.current_expansion.id.expn_data().call_site
    }

    /// Returns the current expansion kind's description.
    pub(crate) fn expansion_descr(&self) -> String {
        let expn_data = self.current_expansion.id.expn_data();
        expn_data.kind.descr()
    }

    /// Equivalent of `Span::def_site` from the proc macro API,
    /// except that the location is taken from the span passed as an argument.
    pub fn with_def_site_ctxt(&self, span: Span) -> Span {
        span.with_def_site_ctxt(self.current_expansion.id.to_expn_id())
    }

    /// Equivalent of `Span::call_site` from the proc macro API,
    /// except that the location is taken from the span passed as an argument.
    pub fn with_call_site_ctxt(&self, span: Span) -> Span {
        span.with_call_site_ctxt(self.current_expansion.id.to_expn_id())
    }

    /// Equivalent of `Span::mixed_site` from the proc macro API,
    /// except that the location is taken from the span passed as an argument.
    pub fn with_mixed_site_ctxt(&self, span: Span) -> Span {
        span.with_mixed_site_ctxt(self.current_expansion.id.to_expn_id())
    }

    /// Returns span for the macro which originally caused the current expansion to happen.
    ///
    /// Stops backtracing at include! boundary.
    pub fn expansion_cause(&self) -> Option<Span> {
        self.current_expansion.id.expansion_cause()
    }

    /// This method increases the internal macro errors count and then call `trace_macros_diag`.
    pub fn macro_error_and_trace_macros_diag(&mut self) {
        self.nb_macro_errors += 1;
        self.trace_macros_diag();
    }

    pub fn trace_macros_diag(&mut self) {
        for (span, notes) in self.expansions.iter() {
            let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
            for note in notes {
                // FIXME: make this translatable
                #[allow(rustc::untranslatable_diagnostic)]
                db.note(note.clone());
            }
            db.emit();
        }
        // Fixme: does this result in errors?
        self.expansions.clear();
    }
    pub fn trace_macros(&self) -> bool {
        self.ecfg.trace_mac
    }
    pub fn set_trace_macros(&mut self, x: bool) {
        self.ecfg.trace_mac = x
    }
    pub fn std_path(&self, components: &[Symbol]) -> Vec<Ident> {
        let def_site = self.with_def_site_ctxt(DUMMY_SP);
        iter::once(Ident::new(kw::DollarCrate, def_site))
            .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
            .collect()
    }
    pub fn def_site_path(&self, components: &[Symbol]) -> Vec<Ident> {
        let def_site = self.with_def_site_ctxt(DUMMY_SP);
        components.iter().map(|&s| Ident::new(s, def_site)).collect()
    }

    pub fn check_unused_macros(&mut self) {
        self.resolver.check_unused_macros();
    }
}

/// Resolves a `path` mentioned inside Rust code, returning an absolute path.
///
/// This unifies the logic used for resolving `include_X!`.
pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PResult<'_, PathBuf> {
    let path = path.into();

    // Relative paths are resolved relative to the file in which they are found
    // after macro expansion (that is, they are unhygienic).
    if !path.is_absolute() {
        let callsite = span.source_callsite();
        let source_map = sess.source_map();
        let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
            return Err(sess.dcx().create_err(errors::ResolveRelativePath {
                span,
                path: source_map
                    .filename_for_diagnostics(&source_map.span_to_filename(callsite))
                    .to_string(),
            }));
        };
        base_path.pop();
        base_path.push(path);
        Ok(base_path)
    } else {
        // This ensures that Windows verbatim paths are fixed if mixed path separators are used,
        // which can happen when `concat!` is used to join paths.
        match path.components().next() {
            Some(Prefix(prefix)) if prefix.kind().is_verbatim() => Ok(path.components().collect()),
            _ => Ok(path),
        }
    }
}

/// If this item looks like a specific enums from `rental`, emit a fatal error.
/// See #73345 and #83125 for more details.
/// FIXME(#73933): Remove this eventually.
fn pretty_printing_compatibility_hack(item: &Item, psess: &ParseSess) {
    if let ast::ItemKind::Enum(ident, _, enum_def) = &item.kind
        && ident.name == sym::ProceduralMasqueradeDummyType
        && let [variant] = &*enum_def.variants
        && variant.ident.name == sym::Input
        && let FileName::Real(real) = psess.source_map().span_to_filename(ident.span)
        && let Some(c) = real
            .local_path()
            .unwrap_or(Path::new(""))
            .components()
            .flat_map(|c| c.as_os_str().to_str())
            .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental"))
    {
        let crate_matches = if c.starts_with("allsorts-rental") {
            true
        } else {
            let mut version = c.trim_start_matches("rental-").split('.');
            version.next() == Some("0")
                && version.next() == Some("5")
                && version.next().and_then(|c| c.parse::<u32>().ok()).is_some_and(|v| v < 6)
        };

        if crate_matches {
            psess.dcx().emit_fatal(errors::ProcMacroBackCompat {
                crate_name: "rental".to_string(),
                fixed_version: "0.5.6".to_string(),
            });
        }
    }
}

pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, psess: &ParseSess) {
    let item = match ann {
        Annotatable::Item(item) => item,
        Annotatable::Stmt(stmt) => match &stmt.kind {
            ast::StmtKind::Item(item) => item,
            _ => return,
        },
        _ => return,
    };
    pretty_printing_compatibility_hack(item, psess)
}

pub(crate) fn stream_pretty_printing_compatibility_hack(
    kind: MetaVarKind,
    stream: &TokenStream,
    psess: &ParseSess,
) {
    let item = match kind {
        MetaVarKind::Item => {
            let mut parser = Parser::new(psess, stream.clone(), None);
            // No need to collect tokens for this simple check.
            parser
                .parse_item(ForceCollect::No)
                .expect("failed to reparse item")
                .expect("an actual item")
        }
        MetaVarKind::Stmt => {
            let mut parser = Parser::new(psess, stream.clone(), None);
            // No need to collect tokens for this simple check.
            let stmt = parser
                .parse_stmt(ForceCollect::No)
                .expect("failed to reparse")
                .expect("an actual stmt");
            match &stmt.kind {
                ast::StmtKind::Item(item) => item.clone(),
                _ => return,
            }
        }
        _ => return,
    };
    pretty_printing_compatibility_hack(&item, psess)
}
