// ignore-tidy-filelength
use std::borrow::Cow;
use std::fmt;

use rustc_abi::ExternAbi;
use rustc_ast::attr::AttributeExt;
use rustc_ast::token::CommentKind;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{
    self as ast, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitIntType,
    LitKind, TraitObjectSyntax, UintTy, UnsafeBinderCastKind, join_path_idents,
};
pub use rustc_ast::{
    AssignOp, AssignOpKind, AttrId, AttrStyle, BinOp, BinOpKind, BindingMode, BorrowKind,
    BoundConstness, BoundPolarity, ByRef, CaptureBy, DelimArgs, ImplPolarity, IsAuto,
    MetaItemInner, MetaItemLit, Movability, Mutability, Pinnedness, UnOp,
};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::tagged_ptr::TaggedRef;
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
use rustc_index::IndexVec;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::def_id::LocalDefId;
use rustc_span::source_map::Spanned;
use rustc_span::{
    BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Symbol, kw, sym,
};
use rustc_target::asm::InlineAsmRegOrRegClass;
use smallvec::SmallVec;
use thin_vec::ThinVec;
use tracing::debug;

use crate::attrs::AttributeKind;
use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res};
use crate::def_id::{DefId, LocalDefIdMap};
pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
use crate::intravisit::{FnKind, VisitorExt};
use crate::lints::DelayedLints;

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
pub enum AngleBrackets {
    /// E.g. `Path`.
    Missing,
    /// E.g. `Path<>`.
    Empty,
    /// E.g. `Path<T>`.
    Full,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
pub enum LifetimeSource {
    /// E.g. `&Type`, `&'_ Type`, `&'a Type`, `&mut Type`, `&'_ mut Type`, `&'a mut Type`
    Reference,

    /// E.g. `ContainsLifetime`, `ContainsLifetime<>`, `ContainsLifetime<'_>`,
    /// `ContainsLifetime<'a>`
    Path { angle_brackets: AngleBrackets },

    /// E.g. `impl Trait + '_`, `impl Trait + 'a`
    OutlivesBound,

    /// E.g. `impl Trait + use<'_>`, `impl Trait + use<'a>`
    PreciseCapturing,

    /// Other usages which have not yet been categorized. Feel free to
    /// add new sources that you find useful.
    ///
    /// Some non-exhaustive examples:
    /// - `where T: 'a`
    /// - `fn(_: dyn Trait + 'a)`
    Other,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
pub enum LifetimeSyntax {
    /// E.g. `&Type`, `ContainsLifetime`
    Implicit,

    /// E.g. `&'_ Type`, `ContainsLifetime<'_>`, `impl Trait + '_`, `impl Trait + use<'_>`
    ExplicitAnonymous,

    /// E.g. `&'a Type`, `ContainsLifetime<'a>`, `impl Trait + 'a`, `impl Trait + use<'a>`
    ExplicitBound,
}

impl From<Ident> for LifetimeSyntax {
    fn from(ident: Ident) -> Self {
        let name = ident.name;

        if name == sym::empty {
            unreachable!("A lifetime name should never be empty");
        } else if name == kw::UnderscoreLifetime {
            LifetimeSyntax::ExplicitAnonymous
        } else {
            debug_assert!(name.as_str().starts_with('\''));
            LifetimeSyntax::ExplicitBound
        }
    }
}

/// A lifetime. The valid field combinations are non-obvious and not all
/// combinations are possible. The following example shows some of
/// them. See also the comments on `LifetimeKind` and `LifetimeSource`.
///
/// ```
/// #[repr(C)]
/// struct S<'a>(&'a u32);       // res=Param, name='a, source=Reference, syntax=ExplicitBound
/// unsafe extern "C" {
///     fn f1(s: S);             // res=Param, name='_, source=Path, syntax=Implicit
///     fn f2(s: S<'_>);         // res=Param, name='_, source=Path, syntax=ExplicitAnonymous
///     fn f3<'a>(s: S<'a>);     // res=Param, name='a, source=Path, syntax=ExplicitBound
/// }
///
/// struct St<'a> { x: &'a u32 } // res=Param, name='a, source=Reference, syntax=ExplicitBound
/// fn f() {
///     _ = St { x: &0 };        // res=Infer, name='_, source=Path, syntax=Implicit
///     _ = St::<'_> { x: &0 };  // res=Infer, name='_, source=Path, syntax=ExplicitAnonymous
/// }
///
/// struct Name<'a>(&'a str);    // res=Param,  name='a, source=Reference, syntax=ExplicitBound
/// const A: Name = Name("a");   // res=Static, name='_, source=Path, syntax=Implicit
/// const B: &str = "";          // res=Static, name='_, source=Reference, syntax=Implicit
/// static C: &'_ str = "";      // res=Static, name='_, source=Reference, syntax=ExplicitAnonymous
/// static D: &'static str = ""; // res=Static, name='static, source=Reference, syntax=ExplicitBound
///
/// trait Tr {}
/// fn tr(_: Box<dyn Tr>) {}     // res=ImplicitObjectLifetimeDefault, name='_, source=Other, syntax=Implicit
///
/// fn capture_outlives<'a>() ->
///     impl FnOnce() + 'a       // res=Param, ident='a, source=OutlivesBound, syntax=ExplicitBound
/// {
///     || {}
/// }
///
/// fn capture_precise<'a>() ->
///     impl FnOnce() + use<'a>  // res=Param, ident='a, source=PreciseCapturing, syntax=ExplicitBound
/// {
///     || {}
/// }
///
/// // (commented out because these cases trigger errors)
/// // struct S1<'a>(&'a str);   // res=Param, name='a, source=Reference, syntax=ExplicitBound
/// // struct S2(S1);            // res=Error, name='_, source=Path, syntax=Implicit
/// // struct S3(S1<'_>);        // res=Error, name='_, source=Path, syntax=ExplicitAnonymous
/// // struct S4(S1<'a>);        // res=Error, name='a, source=Path, syntax=ExplicitBound
/// ```
///
/// Some combinations that cannot occur are `LifetimeSyntax::Implicit` with
/// `LifetimeSource::OutlivesBound` or `LifetimeSource::PreciseCapturing`
/// — there's no way to "elide" these lifetimes.
#[derive(Debug, Copy, Clone, HashStable_Generic)]
// Raise the aligement to at least 4 bytes - this is relied on in other parts of the compiler(for pointer tagging):
// https://github.com/rust-lang/rust/blob/ce5fdd7d42aba9a2925692e11af2bd39cf37798a/compiler/rustc_data_structures/src/tagged_ptr.rs#L163
// Removing this `repr(4)` will cause the compiler to not build on platforms like `m68k` Linux, where the aligement of u32 and usize is only 2.
// Since `repr(align)` may only raise aligement, this has no effect on platforms where the aligement is already sufficient.
#[repr(align(4))]
pub struct Lifetime {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,

    /// Either a named lifetime definition (e.g. `'a`, `'static`) or an
    /// anonymous lifetime (`'_`, either explicitly written, or inserted for
    /// things like `&type`).
    pub ident: Ident,

    /// Semantics of this lifetime.
    pub kind: LifetimeKind,

    /// The context in which the lifetime occurred. See `Lifetime::suggestion`
    /// for example use.
    pub source: LifetimeSource,

    /// The syntax that the user used to declare this lifetime. See
    /// `Lifetime::suggestion` for example use.
    pub syntax: LifetimeSyntax,
}

#[derive(Debug, Copy, Clone, HashStable_Generic)]
pub enum ParamName {
    /// Some user-given name like `T` or `'x`.
    Plain(Ident),

    /// Indicates an illegal name was given and an error has been
    /// reported (so we should squelch other derived errors).
    ///
    /// Occurs when, e.g., `'_` is used in the wrong place, or a
    /// lifetime name is duplicated.
    Error(Ident),

    /// Synthetic name generated when user elided a lifetime in an impl header.
    ///
    /// E.g., the lifetimes in cases like these:
    /// ```ignore (fragment)
    /// impl Foo for &u32
    /// impl Foo<'_> for u32
    /// ```
    /// in that case, we rewrite to
    /// ```ignore (fragment)
    /// impl<'f> Foo for &'f u32
    /// impl<'f> Foo<'f> for u32
    /// ```
    /// where `'f` is something like `Fresh(0)`. The indices are
    /// unique per impl, but not necessarily continuous.
    Fresh,
}

impl ParamName {
    pub fn ident(&self) -> Ident {
        match *self {
            ParamName::Plain(ident) | ParamName::Error(ident) => ident,
            ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
pub enum LifetimeKind {
    /// User-given names or fresh (synthetic) names.
    Param(LocalDefId),

    /// Implicit lifetime in a context like `dyn Foo`. This is
    /// distinguished from implicit lifetimes elsewhere because the
    /// lifetime that they default to must appear elsewhere within the
    /// enclosing type. This means that, in an `impl Trait` context, we
    /// don't have to create a parameter for them. That is, `impl
    /// Trait<Item = &u32>` expands to an opaque type like `type
    /// Foo<'a> = impl Trait<Item = &'a u32>`, but `impl Trait<item =
    /// dyn Bar>` expands to `type Foo = impl Trait<Item = dyn Bar +
    /// 'static>`. The latter uses `ImplicitObjectLifetimeDefault` so
    /// that surrounding code knows not to create a lifetime
    /// parameter.
    ImplicitObjectLifetimeDefault,

    /// Indicates an error during lowering (usually `'_` in wrong place)
    /// that was already reported.
    Error,

    /// User wrote an anonymous lifetime, either `'_` or nothing (which gets
    /// converted to `'_`). The semantics of this lifetime should be inferred
    /// by typechecking code.
    Infer,

    /// User wrote `'static` or nothing (which gets converted to `'_`).
    Static,
}

impl LifetimeKind {
    fn is_elided(&self) -> bool {
        match self {
            LifetimeKind::ImplicitObjectLifetimeDefault | LifetimeKind::Infer => true,

            // It might seem surprising that `Fresh` counts as not *elided*
            // -- but this is because, as far as the code in the compiler is
            // concerned -- `Fresh` variants act equivalently to "some fresh name".
            // They correspond to early-bound regions on an impl, in other words.
            LifetimeKind::Error | LifetimeKind::Param(..) | LifetimeKind::Static => false,
        }
    }
}

impl fmt::Display for Lifetime {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.ident.name.fmt(f)
    }
}

impl Lifetime {
    pub fn new(
        hir_id: HirId,
        ident: Ident,
        kind: LifetimeKind,
        source: LifetimeSource,
        syntax: LifetimeSyntax,
    ) -> Lifetime {
        let lifetime = Lifetime { hir_id, ident, kind, source, syntax };

        // Sanity check: elided lifetimes form a strict subset of anonymous lifetimes.
        #[cfg(debug_assertions)]
        match (lifetime.is_elided(), lifetime.is_anonymous()) {
            (false, false) => {} // e.g. `'a`
            (false, true) => {}  // e.g. explicit `'_`
            (true, true) => {}   // e.g. `&x`
            (true, false) => panic!("bad Lifetime"),
        }

        lifetime
    }

    pub fn is_elided(&self) -> bool {
        self.kind.is_elided()
    }

    pub fn is_anonymous(&self) -> bool {
        self.ident.name == kw::UnderscoreLifetime
    }

    pub fn is_implicit(&self) -> bool {
        matches!(self.syntax, LifetimeSyntax::Implicit)
    }

    pub fn is_static(&self) -> bool {
        self.kind == LifetimeKind::Static
    }

    pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
        use LifetimeSource::*;
        use LifetimeSyntax::*;

        debug_assert!(new_lifetime.starts_with('\''));

        match (self.syntax, self.source) {
            // The user wrote `'a` or `'_`.
            (ExplicitBound | ExplicitAnonymous, _) => (self.ident.span, format!("{new_lifetime}")),

            // The user wrote `Path<T>`, and omitted the `'_,`.
            (Implicit, Path { angle_brackets: AngleBrackets::Full }) => {
                (self.ident.span, format!("{new_lifetime}, "))
            }

            // The user wrote `Path<>`, and omitted the `'_`..
            (Implicit, Path { angle_brackets: AngleBrackets::Empty }) => {
                (self.ident.span, format!("{new_lifetime}"))
            }

            // The user wrote `Path` and omitted the `<'_>`.
            (Implicit, Path { angle_brackets: AngleBrackets::Missing }) => {
                (self.ident.span.shrink_to_hi(), format!("<{new_lifetime}>"))
            }

            // The user wrote `&type` or `&mut type`.
            (Implicit, Reference) => (self.ident.span, format!("{new_lifetime} ")),

            (Implicit, source) => {
                unreachable!("can't suggest for a implicit lifetime of {source:?}")
            }
        }
    }
}

/// A `Path` is essentially Rust's notion of a name; for instance,
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Path<'hir, R = Res> {
    pub span: Span,
    /// The resolution for the path.
    pub res: R,
    /// The segments in the path: the things separated by `::`.
    pub segments: &'hir [PathSegment<'hir>],
}

/// Up to three resolutions for type, value and macro namespaces.
pub type UsePath<'hir> = Path<'hir, PerNS<Option<Res>>>;

impl Path<'_> {
    pub fn is_global(&self) -> bool {
        self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
    }
}

/// A segment of a path: an identifier, an optional lifetime, and a set of
/// types.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct PathSegment<'hir> {
    /// The identifier portion of this path segment.
    pub ident: Ident,
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub res: Res,

    /// Type/lifetime parameters attached to this path. They come in
    /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
    /// this is more than just simple syntactic sugar; the use of
    /// parens affects the region binding rules, so we preserve the
    /// distinction.
    pub args: Option<&'hir GenericArgs<'hir>>,

    /// Whether to infer remaining type parameters, if any.
    /// This only applies to expression and pattern paths, and
    /// out of those only the segments with no type parameters
    /// to begin with, e.g., `Vec::new` is `<Vec<..>>::new::<..>`.
    pub infer_args: bool,
}

impl<'hir> PathSegment<'hir> {
    /// Converts an identifier to the corresponding segment.
    pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
        PathSegment { ident, hir_id, res, infer_args: true, args: None }
    }

    pub fn invalid() -> Self {
        Self::new(Ident::dummy(), HirId::INVALID, Res::Err)
    }

    pub fn args(&self) -> &GenericArgs<'hir> {
        if let Some(ref args) = self.args {
            args
        } else {
            const DUMMY: &GenericArgs<'_> = &GenericArgs::none();
            DUMMY
        }
    }
}

#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub enum ConstItemRhs<'hir> {
    Body(BodyId),
    TypeConst(&'hir ConstArg<'hir>),
}

impl<'hir> ConstItemRhs<'hir> {
    pub fn hir_id(&self) -> HirId {
        match self {
            ConstItemRhs::Body(body_id) => body_id.hir_id,
            ConstItemRhs::TypeConst(ct_arg) => ct_arg.hir_id,
        }
    }

    pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span {
        match self {
            ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span,
            ConstItemRhs::TypeConst(ct_arg) => ct_arg.span(),
        }
    }
}

/// A constant that enters the type system, used for arguments to const generics (e.g. array lengths).
///
/// These are distinct from [`AnonConst`] as anon consts in the type system are not allowed
/// to use any generic parameters, therefore we must represent `N` differently. Additionally
/// future designs for supporting generic parameters in const arguments will likely not use
/// an anon const based design.
///
/// So, `ConstArg` (specifically, [`ConstArgKind`]) distinguishes between const args
/// that are [just paths](ConstArgKind::Path) (currently just bare const params)
/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
///
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// <https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html>
#[derive(Clone, Copy, Debug, HashStable_Generic)]
#[repr(C)]
pub struct ConstArg<'hir, Unambig = ()> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub kind: ConstArgKind<'hir, Unambig>,
}

impl<'hir> ConstArg<'hir, AmbigArg> {
    /// Converts a `ConstArg` in an ambiguous position to one in an unambiguous position.
    ///
    /// Functions accepting unambiguous consts may expect the [`ConstArgKind::Infer`] variant
    /// to be used. Care should be taken to separately handle infer consts when calling this
    /// function as it cannot be handled by downstream code making use of the returned const.
    ///
    /// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
    /// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
    ///
    /// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
    pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
        // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the
        // layout is the same across different ZST type arguments.
        let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
        unsafe { &*ptr }
    }
}

impl<'hir> ConstArg<'hir> {
    /// Converts a `ConstArg` in an unambiguous position to one in an ambiguous position. This is
    /// fallible as the [`ConstArgKind::Infer`] variant is not present in ambiguous positions.
    ///
    /// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
    /// infer consts are relevant to you then care should be taken to handle them separately.
    pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
        if let ConstArgKind::Infer(_, ()) = self.kind {
            return None;
        }

        // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
        // the same across different ZST type arguments. We also asserted that the `self` is
        // not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
        let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
        Some(unsafe { &*ptr })
    }
}

impl<'hir, Unambig> ConstArg<'hir, Unambig> {
    pub fn anon_const_hir_id(&self) -> Option<HirId> {
        match self.kind {
            ConstArgKind::Anon(ac) => Some(ac.hir_id),
            _ => None,
        }
    }

    pub fn span(&self) -> Span {
        match self.kind {
            ConstArgKind::Path(path) => path.span(),
            ConstArgKind::Anon(anon) => anon.span,
            ConstArgKind::Error(span, _) => span,
            ConstArgKind::Infer(span, _) => span,
        }
    }
}

/// See [`ConstArg`].
#[derive(Clone, Copy, Debug, HashStable_Generic)]
#[repr(u8, C)]
pub enum ConstArgKind<'hir, Unambig = ()> {
    /// **Note:** Currently this is only used for bare const params
    /// (`N` where `fn foo<const N: usize>(...)`),
    /// not paths to any const (`N` where `const N: usize = ...`).
    ///
    /// However, in the future, we'll be using it for all of those.
    Path(QPath<'hir>),
    Anon(&'hir AnonConst),
    /// Error const
    Error(Span, ErrorGuaranteed),
    /// This variant is not always used to represent inference consts, sometimes
    /// [`GenericArg::Infer`] is used instead.
    Infer(Span, Unambig),
}

#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub struct InferArg {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub span: Span,
}

impl InferArg {
    pub fn to_ty(&self) -> Ty<'static> {
        Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum GenericArg<'hir> {
    Lifetime(&'hir Lifetime),
    Type(&'hir Ty<'hir, AmbigArg>),
    Const(&'hir ConstArg<'hir, AmbigArg>),
    /// Inference variables in [`GenericArg`] are always represented by
    /// `GenericArg::Infer` instead of the `Infer` variants on [`TyKind`] and
    /// [`ConstArgKind`] as it is not clear until hir ty lowering whether a
    /// `_` argument is a type or const argument.
    ///
    /// However, some builtin types' generic arguments are represented by [`TyKind`]
    /// without a [`GenericArg`], instead directly storing a [`Ty`] or [`ConstArg`]. In
    /// such cases they *are* represented by the `Infer` variants on [`TyKind`] and
    /// [`ConstArgKind`] as it is not ambiguous whether the argument is a type or const.
    Infer(InferArg),
}

impl GenericArg<'_> {
    pub fn span(&self) -> Span {
        match self {
            GenericArg::Lifetime(l) => l.ident.span,
            GenericArg::Type(t) => t.span,
            GenericArg::Const(c) => c.span(),
            GenericArg::Infer(i) => i.span,
        }
    }

    pub fn hir_id(&self) -> HirId {
        match self {
            GenericArg::Lifetime(l) => l.hir_id,
            GenericArg::Type(t) => t.hir_id,
            GenericArg::Const(c) => c.hir_id,
            GenericArg::Infer(i) => i.hir_id,
        }
    }

    pub fn descr(&self) -> &'static str {
        match self {
            GenericArg::Lifetime(_) => "lifetime",
            GenericArg::Type(_) => "type",
            GenericArg::Const(_) => "constant",
            GenericArg::Infer(_) => "placeholder",
        }
    }

    pub fn to_ord(&self) -> ast::ParamKindOrd {
        match self {
            GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
            GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
                ast::ParamKindOrd::TypeOrConst
            }
        }
    }

    pub fn is_ty_or_const(&self) -> bool {
        match self {
            GenericArg::Lifetime(_) => false,
            GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
        }
    }
}

/// The generic arguments and associated item constraints of a path segment.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct GenericArgs<'hir> {
    /// The generic arguments for this path segment.
    pub args: &'hir [GenericArg<'hir>],
    /// The associated item constraints for this path segment.
    pub constraints: &'hir [AssocItemConstraint<'hir>],
    /// Whether the arguments were written in parenthesized form (e.g., `Fn(T) -> U`).
    ///
    /// This is required mostly for pretty-printing and diagnostics,
    /// but also for changing lifetime elision rules to be "function-like".
    pub parenthesized: GenericArgsParentheses,
    /// The span encompassing the arguments, constraints and the surrounding brackets (`<>` or `()`).
    ///
    /// For example:
    ///
    /// ```ignore (illustrative)
    ///       Foo<A, B, AssocTy = D>           Fn(T, U, V) -> W
    ///          ^^^^^^^^^^^^^^^^^^^             ^^^^^^^^^
    /// ```
    ///
    /// Note that this may be:
    /// - empty, if there are no generic brackets (but there may be hidden lifetimes)
    /// - dummy, if this was generated during desugaring
    pub span_ext: Span,
}

impl<'hir> GenericArgs<'hir> {
    pub const fn none() -> Self {
        Self {
            args: &[],
            constraints: &[],
            parenthesized: GenericArgsParentheses::No,
            span_ext: DUMMY_SP,
        }
    }

    /// Obtain the list of input types and the output type if the generic arguments are parenthesized.
    ///
    /// Returns the `Ty0, Ty1, ...` and the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
    /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
    pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
        if self.parenthesized != GenericArgsParentheses::ParenSugar {
            return None;
        }

        let inputs = self
            .args
            .iter()
            .find_map(|arg| {
                let GenericArg::Type(ty) = arg else { return None };
                let TyKind::Tup(tys) = &ty.kind else { return None };
                Some(tys)
            })
            .unwrap();

        Some((inputs, self.paren_sugar_output_inner()))
    }

    /// Obtain the output type if the generic arguments are parenthesized.
    ///
    /// Returns the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
    /// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
    pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
        (self.parenthesized == GenericArgsParentheses::ParenSugar)
            .then(|| self.paren_sugar_output_inner())
    }

    fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
        let [constraint] = self.constraints.try_into().unwrap();
        debug_assert_eq!(constraint.ident.name, sym::Output);
        constraint.ty().unwrap()
    }

    pub fn has_err(&self) -> Option<ErrorGuaranteed> {
        self.args
            .iter()
            .find_map(|arg| {
                let GenericArg::Type(ty) = arg else { return None };
                let TyKind::Err(guar) = ty.kind else { return None };
                Some(guar)
            })
            .or_else(|| {
                self.constraints.iter().find_map(|constraint| {
                    let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
                    Some(guar)
                })
            })
    }

    #[inline]
    pub fn num_lifetime_params(&self) -> usize {
        self.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(_))).count()
    }

    #[inline]
    pub fn has_lifetime_params(&self) -> bool {
        self.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
    }

    #[inline]
    /// This function returns the number of type and const generic params.
    /// It should only be used for diagnostics.
    pub fn num_generic_params(&self) -> usize {
        self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
    }

    /// The span encompassing the arguments and constraints[^1] inside the surrounding brackets.
    ///
    /// Returns `None` if the span is empty (i.e., no brackets) or dummy.
    ///
    /// [^1]: Unless of the form `-> Ty` (see [`GenericArgsParentheses`]).
    pub fn span(&self) -> Option<Span> {
        let span_ext = self.span_ext()?;
        Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
    }

    /// Returns span encompassing arguments and their surrounding `<>` or `()`
    pub fn span_ext(&self) -> Option<Span> {
        Some(self.span_ext).filter(|span| !span.is_empty())
    }

    pub fn is_empty(&self) -> bool {
        self.args.is_empty()
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
pub enum GenericArgsParentheses {
    No,
    /// Bounds for `feature(return_type_notation)`, like `T: Trait<method(..): Send>`,
    /// where the args are explicitly elided with `..`
    ReturnTypeNotation,
    /// parenthesized function-family traits, like `T: Fn(u32) -> i32`
    ParenSugar,
}

/// The modifiers on a trait bound.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct TraitBoundModifiers {
    pub constness: BoundConstness,
    pub polarity: BoundPolarity,
}

impl TraitBoundModifiers {
    pub const NONE: Self =
        TraitBoundModifiers { constness: BoundConstness::Never, polarity: BoundPolarity::Positive };
}

#[derive(Clone, Copy, Debug, HashStable_Generic)]
pub enum GenericBound<'hir> {
    Trait(PolyTraitRef<'hir>),
    Outlives(&'hir Lifetime),
    Use(&'hir [PreciseCapturingArg<'hir>], Span),
}

impl GenericBound<'_> {
    pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
        match self {
            GenericBound::Trait(data) => Some(&data.trait_ref),
            _ => None,
        }
    }

    pub fn span(&self) -> Span {
        match self {
            GenericBound::Trait(t, ..) => t.span,
            GenericBound::Outlives(l) => l.ident.span,
            GenericBound::Use(_, span) => *span,
        }
    }
}

pub type GenericBounds<'hir> = &'hir [GenericBound<'hir>];

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic, Debug)]
pub enum MissingLifetimeKind {
    /// An explicit `'_`.
    Underscore,
    /// An elided lifetime `&' ty`.
    Ampersand,
    /// An elided lifetime in brackets with written brackets.
    Comma,
    /// An elided lifetime with elided brackets.
    Brackets,
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum LifetimeParamKind {
    // Indicates that the lifetime definition was explicitly declared (e.g., in
    // `fn foo<'a>(x: &'a u8) -> &'a u8 { x }`).
    Explicit,

    // Indication that the lifetime was elided (e.g., in both cases in
    // `fn foo(x: &u8) -> &'_ u8 { x }`).
    Elided(MissingLifetimeKind),

    // Indication that the lifetime name was somehow in error.
    Error,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum GenericParamKind<'hir> {
    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
    Lifetime {
        kind: LifetimeParamKind,
    },
    Type {
        default: Option<&'hir Ty<'hir>>,
        synthetic: bool,
    },
    Const {
        ty: &'hir Ty<'hir>,
        /// Optional default value for the const generic param
        default: Option<&'hir ConstArg<'hir>>,
    },
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct GenericParam<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub def_id: LocalDefId,
    pub name: ParamName,
    pub span: Span,
    pub pure_wrt_drop: bool,
    pub kind: GenericParamKind<'hir>,
    pub colon_span: Option<Span>,
    pub source: GenericParamSource,
}

impl<'hir> GenericParam<'hir> {
    /// Synthetic type-parameters are inserted after normal ones.
    /// In order for normal parameters to be able to refer to synthetic ones,
    /// scans them first.
    pub fn is_impl_trait(&self) -> bool {
        matches!(self.kind, GenericParamKind::Type { synthetic: true, .. })
    }

    /// This can happen for `async fn`, e.g. `async fn f<'_>(&'_ self)`.
    ///
    /// See `lifetime_to_generic_param` in `rustc_ast_lowering` for more information.
    pub fn is_elided_lifetime(&self) -> bool {
        matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) })
    }
}

/// Records where the generic parameter originated from.
///
/// This can either be from an item's generics, in which case it's typically
/// early-bound (but can be a late-bound lifetime in functions, for example),
/// or from a `for<...>` binder, in which case it's late-bound (and notably,
/// does not show up in the parent item's generics).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum GenericParamSource {
    // Early or late-bound parameters defined on an item
    Generics,
    // Late-bound parameters defined via a `for<...>`
    Binder,
}

#[derive(Default)]
pub struct GenericParamCount {
    pub lifetimes: usize,
    pub types: usize,
    pub consts: usize,
    pub infer: usize,
}

/// Represents lifetimes and type parameters attached to a declaration
/// of a function, enum, trait, etc.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Generics<'hir> {
    pub params: &'hir [GenericParam<'hir>],
    pub predicates: &'hir [WherePredicate<'hir>],
    pub has_where_clause_predicates: bool,
    pub where_clause_span: Span,
    pub span: Span,
}

impl<'hir> Generics<'hir> {
    pub const fn empty() -> &'hir Generics<'hir> {
        const NOPE: Generics<'_> = Generics {
            params: &[],
            predicates: &[],
            has_where_clause_predicates: false,
            where_clause_span: DUMMY_SP,
            span: DUMMY_SP,
        };
        &NOPE
    }

    pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
        self.params.iter().find(|&param| name == param.name.ident().name)
    }

    /// If there are generic parameters, return where to introduce a new one.
    pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
        if let Some(first) = self.params.first()
            && self.span.contains(first.span)
        {
            // `fn foo<A>(t: impl Trait)`
            //         ^ suggest `'a, ` here
            Some(first.span.shrink_to_lo())
        } else {
            None
        }
    }

    /// If there are generic parameters, return where to introduce a new one.
    pub fn span_for_param_suggestion(&self) -> Option<Span> {
        self.params.iter().any(|p| self.span.contains(p.span)).then(|| {
            // `fn foo<A>(t: impl Trait)`
            //          ^ suggest `, T: Trait` here
            self.span.with_lo(self.span.hi() - BytePos(1)).shrink_to_lo()
        })
    }

    /// `Span` where further predicates would be suggested, accounting for trailing commas, like
    ///  in `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
    pub fn tail_span_for_predicate_suggestion(&self) -> Span {
        let end = self.where_clause_span.shrink_to_hi();
        if self.has_where_clause_predicates {
            self.predicates
                .iter()
                .rfind(|&p| p.kind.in_where_clause())
                .map_or(end, |p| p.span)
                .shrink_to_hi()
                .to(end)
        } else {
            end
        }
    }

    pub fn add_where_or_trailing_comma(&self) -> &'static str {
        if self.has_where_clause_predicates {
            ","
        } else if self.where_clause_span.is_empty() {
            " where"
        } else {
            // No where clause predicates, but we have `where` token
            ""
        }
    }

    pub fn bounds_for_param(
        &self,
        param_def_id: LocalDefId,
    ) -> impl Iterator<Item = &WhereBoundPredicate<'hir>> {
        self.predicates.iter().filter_map(move |pred| match pred.kind {
            WherePredicateKind::BoundPredicate(bp)
                if bp.is_param_bound(param_def_id.to_def_id()) =>
            {
                Some(bp)
            }
            _ => None,
        })
    }

    pub fn outlives_for_param(
        &self,
        param_def_id: LocalDefId,
    ) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
        self.predicates.iter().filter_map(move |pred| match pred.kind {
            WherePredicateKind::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
            _ => None,
        })
    }

    /// Returns a suggestable empty span right after the "final" bound of the generic parameter.
    ///
    /// If that bound needs to be wrapped in parentheses to avoid ambiguity with
    /// subsequent bounds, it also returns an empty span for an open parenthesis
    /// as the second component.
    ///
    /// E.g., adding `+ 'static` after `Fn() -> dyn Future<Output = ()>` or
    /// `Fn() -> &'static dyn Debug` requires parentheses:
    /// `Fn() -> (dyn Future<Output = ()>) + 'static` and
    /// `Fn() -> &'static (dyn Debug) + 'static`, respectively.
    pub fn bounds_span_for_suggestions(
        &self,
        param_def_id: LocalDefId,
    ) -> Option<(Span, Option<Span>)> {
        self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
            |bound| {
                let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
                    && let [.., segment] = trait_ref.path.segments
                    && let Some(ret_ty) = segment.args().paren_sugar_output()
                    && let ret_ty = ret_ty.peel_refs()
                    && let TyKind::TraitObject(_, tagged_ptr) = ret_ty.kind
                    && let TraitObjectSyntax::Dyn = tagged_ptr.tag()
                    && ret_ty.span.can_be_used_for_suggestions()
                {
                    Some(ret_ty.span)
                } else {
                    None
                };

                span_for_parentheses.map_or_else(
                    || {
                        // We include bounds that come from a `#[derive(_)]` but point at the user's code,
                        // as we use this method to get a span appropriate for suggestions.
                        let bs = bound.span();
                        bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
                    },
                    |span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
                )
            },
        )
    }

    pub fn span_for_predicate_removal(&self, pos: usize) -> Span {
        let predicate = &self.predicates[pos];
        let span = predicate.span;

        if !predicate.kind.in_where_clause() {
            // <T: ?Sized, U>
            //   ^^^^^^^^
            return span;
        }

        // We need to find out which comma to remove.
        if pos < self.predicates.len() - 1 {
            let next_pred = &self.predicates[pos + 1];
            if next_pred.kind.in_where_clause() {
                // where T: ?Sized, Foo: Bar,
                //       ^^^^^^^^^^^
                return span.until(next_pred.span);
            }
        }

        if pos > 0 {
            let prev_pred = &self.predicates[pos - 1];
            if prev_pred.kind.in_where_clause() {
                // where Foo: Bar, T: ?Sized,
                //               ^^^^^^^^^^^
                return prev_pred.span.shrink_to_hi().to(span);
            }
        }

        // This is the only predicate in the where clause.
        // where T: ?Sized
        // ^^^^^^^^^^^^^^^
        self.where_clause_span
    }

    pub fn span_for_bound_removal(&self, predicate_pos: usize, bound_pos: usize) -> Span {
        let predicate = &self.predicates[predicate_pos];
        let bounds = predicate.kind.bounds();

        if bounds.len() == 1 {
            return self.span_for_predicate_removal(predicate_pos);
        }

        let bound_span = bounds[bound_pos].span();
        if bound_pos < bounds.len() - 1 {
            // If there's another bound after the current bound
            // include the following '+' e.g.:
            //
            //  `T: Foo + CurrentBound + Bar`
            //            ^^^^^^^^^^^^^^^
            bound_span.to(bounds[bound_pos + 1].span().shrink_to_lo())
        } else {
            // If the current bound is the last bound
            // include the preceding '+' E.g.:
            //
            //  `T: Foo + Bar + CurrentBound`
            //               ^^^^^^^^^^^^^^^
            bound_span.with_lo(bounds[bound_pos - 1].span().hi())
        }
    }
}

/// A single predicate in a where-clause.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WherePredicate<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub span: Span,
    pub kind: &'hir WherePredicateKind<'hir>,
}

/// The kind of a single predicate in a where-clause.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum WherePredicateKind<'hir> {
    /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
    BoundPredicate(WhereBoundPredicate<'hir>),
    /// A lifetime predicate (e.g., `'a: 'b + 'c`).
    RegionPredicate(WhereRegionPredicate<'hir>),
    /// An equality predicate (unsupported).
    EqPredicate(WhereEqPredicate<'hir>),
}

impl<'hir> WherePredicateKind<'hir> {
    pub fn in_where_clause(&self) -> bool {
        match self {
            WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause,
            WherePredicateKind::RegionPredicate(p) => p.in_where_clause,
            WherePredicateKind::EqPredicate(_) => false,
        }
    }

    pub fn bounds(&self) -> GenericBounds<'hir> {
        match self {
            WherePredicateKind::BoundPredicate(p) => p.bounds,
            WherePredicateKind::RegionPredicate(p) => p.bounds,
            WherePredicateKind::EqPredicate(_) => &[],
        }
    }
}

#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
pub enum PredicateOrigin {
    WhereClause,
    GenericParam,
    ImplTrait,
}

/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WhereBoundPredicate<'hir> {
    /// Origin of the predicate.
    pub origin: PredicateOrigin,
    /// Any generics from a `for` binding.
    pub bound_generic_params: &'hir [GenericParam<'hir>],
    /// The type being bounded.
    pub bounded_ty: &'hir Ty<'hir>,
    /// Trait and lifetime bounds (e.g., `Clone + Send + 'static`).
    pub bounds: GenericBounds<'hir>,
}

impl<'hir> WhereBoundPredicate<'hir> {
    /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
    pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
        self.bounded_ty.as_generic_param().is_some_and(|(def_id, _)| def_id == param_def_id)
    }
}

/// A lifetime predicate (e.g., `'a: 'b + 'c`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WhereRegionPredicate<'hir> {
    pub in_where_clause: bool,
    pub lifetime: &'hir Lifetime,
    pub bounds: GenericBounds<'hir>,
}

impl<'hir> WhereRegionPredicate<'hir> {
    /// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
    fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
        self.lifetime.kind == LifetimeKind::Param(param_def_id)
    }
}

/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct WhereEqPredicate<'hir> {
    pub lhs_ty: &'hir Ty<'hir>,
    pub rhs_ty: &'hir Ty<'hir>,
}

/// HIR node coupled with its parent's id in the same HIR owner.
///
/// The parent is trash when the node is a HIR owner.
#[derive(Clone, Copy, Debug)]
pub struct ParentedNode<'tcx> {
    pub parent: ItemLocalId,
    pub node: Node<'tcx>,
}

/// Arguments passed to an attribute macro.
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
pub enum AttrArgs {
    /// No arguments: `#[attr]`.
    Empty,
    /// Delimited arguments: `#[attr()/[]/{}]`.
    Delimited(DelimArgs),
    /// Arguments of a key-value attribute: `#[attr = "value"]`.
    Eq {
        /// Span of the `=` token.
        eq_span: Span,
        /// The "value".
        expr: MetaItemLit,
    },
}

#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
pub struct AttrPath {
    pub segments: Box<[Ident]>,
    pub span: Span,
}

impl IntoDiagArg for AttrPath {
    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
        self.to_string().into_diag_arg(path)
    }
}

impl AttrPath {
    pub fn from_ast(path: &ast::Path) -> Self {
        AttrPath {
            segments: path.segments.iter().map(|i| i.ident).collect::<Vec<_>>().into_boxed_slice(),
            span: path.span,
        }
    }
}

impl fmt::Display for AttrPath {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", join_path_idents(&self.segments))
    }
}

#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
pub struct AttrItem {
    // Not lowered to hir::Path because we have no NodeId to resolve to.
    pub path: AttrPath,
    pub args: AttrArgs,
    pub id: HashIgnoredAttrId,
    /// Denotes if the attribute decorates the following construct (outer)
    /// or the construct this attribute is contained within (inner).
    pub style: AttrStyle,
    /// Span of the entire attribute
    pub span: Span,
}

/// The derived implementation of [`HashStable_Generic`] on [`Attribute`]s shouldn't hash
/// [`AttrId`]s. By wrapping them in this, we make sure we never do.
#[derive(Copy, Debug, Encodable, Decodable, Clone)]
pub struct HashIgnoredAttrId {
    pub attr_id: AttrId,
}

#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum Attribute {
    /// A parsed built-in attribute.
    ///
    /// Each attribute has a span connected to it. However, you must be somewhat careful using it.
    /// That's because sometimes we merge multiple attributes together, like when an item has
    /// multiple `repr` attributes. In this case the span might not be very useful.
    Parsed(AttributeKind),

    /// An attribute that could not be parsed, out of a token-like representation.
    /// This is the case for custom tool attributes.
    Unparsed(Box<AttrItem>),
}

impl Attribute {
    pub fn get_normal_item(&self) -> &AttrItem {
        match &self {
            Attribute::Unparsed(normal) => &normal,
            _ => panic!("unexpected parsed attribute"),
        }
    }

    pub fn unwrap_normal_item(self) -> AttrItem {
        match self {
            Attribute::Unparsed(normal) => *normal,
            _ => panic!("unexpected parsed attribute"),
        }
    }

    pub fn value_lit(&self) -> Option<&MetaItemLit> {
        match &self {
            Attribute::Unparsed(n) => match n.as_ref() {
                AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
                _ => None,
            },
            _ => None,
        }
    }

    pub fn is_parsed_attr(&self) -> bool {
        match self {
            Attribute::Parsed(_) => true,
            Attribute::Unparsed(_) => false,
        }
    }
}

impl AttributeExt for Attribute {
    #[inline]
    fn id(&self) -> AttrId {
        match &self {
            Attribute::Unparsed(u) => u.id.attr_id,
            _ => panic!(),
        }
    }

    #[inline]
    fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
        match &self {
            Attribute::Unparsed(n) => match n.as_ref() {
                AttrItem { args: AttrArgs::Delimited(d), .. } => {
                    ast::MetaItemKind::list_from_tokens(d.tokens.clone())
                }
                _ => None,
            },
            _ => None,
        }
    }

    #[inline]
    fn value_str(&self) -> Option<Symbol> {
        self.value_lit().and_then(|x| x.value_str())
    }

    #[inline]
    fn value_span(&self) -> Option<Span> {
        self.value_lit().map(|i| i.span)
    }

    /// For a single-segment attribute, returns its name; otherwise, returns `None`.
    #[inline]
    fn ident(&self) -> Option<Ident> {
        match &self {
            Attribute::Unparsed(n) => {
                if let [ident] = n.path.segments.as_ref() {
                    Some(*ident)
                } else {
                    None
                }
            }
            _ => None,
        }
    }

    #[inline]
    fn path_matches(&self, name: &[Symbol]) -> bool {
        match &self {
            Attribute::Unparsed(n) => n.path.segments.iter().map(|ident| &ident.name).eq(name),
            _ => false,
        }
    }

    #[inline]
    fn is_doc_comment(&self) -> Option<Span> {
        if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self {
            Some(*span)
        } else {
            None
        }
    }

    #[inline]
    fn span(&self) -> Span {
        match &self {
            Attribute::Unparsed(u) => u.span,
            // FIXME: should not be needed anymore when all attrs are parsed
            Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
            Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
            a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
        }
    }

    #[inline]
    fn is_word(&self) -> bool {
        match &self {
            Attribute::Unparsed(n) => {
                matches!(n.args, AttrArgs::Empty)
            }
            _ => false,
        }
    }

    #[inline]
    fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
        match &self {
            Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
            _ => None,
        }
    }

    #[inline]
    fn doc_str(&self) -> Option<Symbol> {
        match &self {
            Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
            Attribute::Unparsed(_) if self.has_name(sym::doc) => self.value_str(),
            _ => None,
        }
    }

    fn is_automatically_derived_attr(&self) -> bool {
        matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..)))
    }

    #[inline]
    fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
        match &self {
            Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
                Some((*comment, *kind))
            }
            Attribute::Unparsed(_) if self.has_name(sym::doc) => {
                self.value_str().map(|s| (s, CommentKind::Line))
            }
            _ => None,
        }
    }

    fn doc_resolution_scope(&self) -> Option<AttrStyle> {
        match self {
            Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
            Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
                Some(attr.style)
            }
            _ => None,
        }
    }

    fn is_proc_macro_attr(&self) -> bool {
        matches!(
            self,
            Attribute::Parsed(
                AttributeKind::ProcMacro(..)
                    | AttributeKind::ProcMacroAttribute(..)
                    | AttributeKind::ProcMacroDerive { .. }
            )
        )
    }
}

// FIXME(fn_delegation): use function delegation instead of manually forwarding
impl Attribute {
    #[inline]
    pub fn id(&self) -> AttrId {
        AttributeExt::id(self)
    }

    #[inline]
    pub fn name(&self) -> Option<Symbol> {
        AttributeExt::name(self)
    }

    #[inline]
    pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
        AttributeExt::meta_item_list(self)
    }

    #[inline]
    pub fn value_str(&self) -> Option<Symbol> {
        AttributeExt::value_str(self)
    }

    #[inline]
    pub fn value_span(&self) -> Option<Span> {
        AttributeExt::value_span(self)
    }

    #[inline]
    pub fn ident(&self) -> Option<Ident> {
        AttributeExt::ident(self)
    }

    #[inline]
    pub fn path_matches(&self, name: &[Symbol]) -> bool {
        AttributeExt::path_matches(self, name)
    }

    #[inline]
    pub fn is_doc_comment(&self) -> Option<Span> {
        AttributeExt::is_doc_comment(self)
    }

    #[inline]
    pub fn has_name(&self, name: Symbol) -> bool {
        AttributeExt::has_name(self, name)
    }

    #[inline]
    pub fn has_any_name(&self, names: &[Symbol]) -> bool {
        AttributeExt::has_any_name(self, names)
    }

    #[inline]
    pub fn span(&self) -> Span {
        AttributeExt::span(self)
    }

    #[inline]
    pub fn is_word(&self) -> bool {
        AttributeExt::is_word(self)
    }

    #[inline]
    pub fn path(&self) -> SmallVec<[Symbol; 1]> {
        AttributeExt::path(self)
    }

    #[inline]
    pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
        AttributeExt::ident_path(self)
    }

    #[inline]
    pub fn doc_str(&self) -> Option<Symbol> {
        AttributeExt::doc_str(self)
    }

    #[inline]
    pub fn is_proc_macro_attr(&self) -> bool {
        AttributeExt::is_proc_macro_attr(self)
    }

    #[inline]
    pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
        AttributeExt::doc_str_and_comment_kind(self)
    }
}

/// Attributes owned by a HIR owner.
#[derive(Debug)]
pub struct AttributeMap<'tcx> {
    pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
    /// Preprocessed `#[define_opaque]` attribute.
    pub define_opaque: Option<&'tcx [(Span, LocalDefId)]>,
    // Only present when the crate hash is needed.
    pub opt_hash: Option<Fingerprint>,
}

impl<'tcx> AttributeMap<'tcx> {
    pub const EMPTY: &'static AttributeMap<'static> = &AttributeMap {
        map: SortedMap::new(),
        opt_hash: Some(Fingerprint::ZERO),
        define_opaque: None,
    };

    #[inline]
    pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
        self.map.get(&id).copied().unwrap_or(&[])
    }
}

/// Map of all HIR nodes inside the current owner.
/// These nodes are mapped by `ItemLocalId` alongside the index of their parent node.
/// The HIR tree, including bodies, is pre-hashed.
pub struct OwnerNodes<'tcx> {
    /// Pre-computed hash of the full HIR. Used in the crate hash. Only present
    /// when incr. comp. is enabled.
    pub opt_hash_including_bodies: Option<Fingerprint>,
    /// Full HIR for the current owner.
    // The zeroth node's parent should never be accessed: the owner's parent is computed by the
    // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
    // used.
    pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
    /// Content of local bodies.
    pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
}

impl<'tcx> OwnerNodes<'tcx> {
    pub fn node(&self) -> OwnerNode<'tcx> {
        // Indexing must ensure it is an OwnerNode.
        self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
    }
}

impl fmt::Debug for OwnerNodes<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("OwnerNodes")
            // Do not print all the pointers to all the nodes, as it would be unreadable.
            .field("node", &self.nodes[ItemLocalId::ZERO])
            .field(
                "parents",
                &fmt::from_fn(|f| {
                    f.debug_list()
                        .entries(self.nodes.iter_enumerated().map(|(id, parented_node)| {
                            fmt::from_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
                        }))
                        .finish()
                }),
            )
            .field("bodies", &self.bodies)
            .field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
            .finish()
    }
}

/// Full information resulting from lowering an AST node.
#[derive(Debug, HashStable_Generic)]
pub struct OwnerInfo<'hir> {
    /// Contents of the HIR.
    pub nodes: OwnerNodes<'hir>,
    /// Map from each nested owner to its parent's local id.
    pub parenting: LocalDefIdMap<ItemLocalId>,
    /// Collected attributes of the HIR nodes.
    pub attrs: AttributeMap<'hir>,
    /// Map indicating what traits are in scope for places where this
    /// is relevant; generated by resolve.
    pub trait_map: ItemLocalMap<Box<[TraitCandidate]>>,

    /// Lints delayed during ast lowering to be emitted
    /// after hir has completely built
    pub delayed_lints: DelayedLints,
}

impl<'tcx> OwnerInfo<'tcx> {
    #[inline]
    pub fn node(&self) -> OwnerNode<'tcx> {
        self.nodes.node()
    }
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum MaybeOwner<'tcx> {
    Owner(&'tcx OwnerInfo<'tcx>),
    NonOwner(HirId),
    /// Used as a placeholder for unused LocalDefId.
    Phantom,
}

impl<'tcx> MaybeOwner<'tcx> {
    pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> {
        match self {
            MaybeOwner::Owner(i) => Some(i),
            MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
        }
    }

    pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> {
        self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner"))
    }
}

/// The top-level data structure that stores the entire contents of
/// the crate currently being compiled.
///
/// For more details, see the [rustc dev guide].
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
#[derive(Debug)]
pub struct Crate<'hir> {
    pub owners: IndexVec<LocalDefId, MaybeOwner<'hir>>,
    // Only present when incr. comp. is enabled.
    pub opt_hir_hash: Option<Fingerprint>,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Closure<'hir> {
    pub def_id: LocalDefId,
    pub binder: ClosureBinder,
    pub constness: Constness,
    pub capture_clause: CaptureBy,
    pub bound_generic_params: &'hir [GenericParam<'hir>],
    pub fn_decl: &'hir FnDecl<'hir>,
    pub body: BodyId,
    /// The span of the declaration block: 'move |...| -> ...'
    pub fn_decl_span: Span,
    /// The span of the argument block `|...|`
    pub fn_arg_span: Option<Span>,
    pub kind: ClosureKind,
}

#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
pub enum ClosureKind {
    /// This is a plain closure expression.
    Closure,
    /// This is a coroutine expression -- i.e. a closure expression in which
    /// we've found a `yield`. These can arise either from "plain" coroutine
    ///  usage (e.g. `let x = || { yield (); }`) or from a desugared expression
    /// (e.g. `async` and `gen` blocks).
    Coroutine(CoroutineKind),
    /// This is a coroutine-closure, which is a special sugared closure that
    /// returns one of the sugared coroutine (`async`/`gen`/`async gen`). It
    /// additionally allows capturing the coroutine's upvars by ref, and therefore
    /// needs to be specially treated during analysis and borrowck.
    CoroutineClosure(CoroutineDesugaring),
}

/// A block of statements `{ .. }`, which may have a label (in this case the
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
/// the `rules` being anything but `DefaultBlock`.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Block<'hir> {
    /// Statements in a block.
    pub stmts: &'hir [Stmt<'hir>],
    /// An expression at the end of the block
    /// without a semicolon, if any.
    pub expr: Option<&'hir Expr<'hir>>,
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    /// Distinguishes between `unsafe { ... }` and `{ ... }`.
    pub rules: BlockCheckMode,
    /// The span includes the curly braces `{` and `}` around the block.
    pub span: Span,
    /// If true, then there may exist `break 'a` values that aim to
    /// break out of this block early.
    /// Used by `'label: {}` blocks and by `try {}` blocks.
    pub targeted_by_break: bool,
}

impl<'hir> Block<'hir> {
    pub fn innermost_block(&self) -> &Block<'hir> {
        let mut block = self;
        while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
            block = inner_block;
        }
        block
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TyPat<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub kind: TyPatKind<'hir>,
    pub span: Span,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Pat<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub kind: PatKind<'hir>,
    pub span: Span,
    /// Whether to use default binding modes.
    /// At present, this is false only for destructuring assignment.
    pub default_binding_modes: bool,
}

impl<'hir> Pat<'hir> {
    fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
        if !it(self) {
            return false;
        }

        use PatKind::*;
        match self.kind {
            Missing => unreachable!(),
            Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => true,
            Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => {
                s.walk_short_(it)
            }
            Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
            TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
            Slice(before, slice, after) => {
                before.iter().chain(slice).chain(after.iter()).all(|p| p.walk_short_(it))
            }
        }
    }

    /// Walk the pattern in left-to-right order,
    /// short circuiting (with `.all(..)`) if `false` is returned.
    ///
    /// Note that when visiting e.g. `Tuple(ps)`,
    /// if visiting `ps[0]` returns `false`,
    /// then `ps[1]` will not be visited.
    pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
        self.walk_short_(&mut it)
    }

    fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
        if !it(self) {
            return;
        }

        use PatKind::*;
        match self.kind {
            Missing | Wild | Never | Expr(_) | Range(..) | Binding(.., None) | Err(_) => {}
            Box(s) | Deref(s) | Ref(s, _, _) | Binding(.., Some(s)) | Guard(s, _) => s.walk_(it),
            Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
            TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
            Slice(before, slice, after) => {
                before.iter().chain(slice).chain(after.iter()).for_each(|p| p.walk_(it))
            }
        }
    }

    /// Walk the pattern in left-to-right order.
    ///
    /// If `it(pat)` returns `false`, the children are not visited.
    pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
        self.walk_(&mut it)
    }

    /// Walk the pattern in left-to-right order.
    ///
    /// If you always want to recurse, prefer this method over `walk`.
    pub fn walk_always(&self, mut it: impl FnMut(&Pat<'_>)) {
        self.walk(|p| {
            it(p);
            true
        })
    }

    /// Whether this a never pattern.
    pub fn is_never_pattern(&self) -> bool {
        let mut is_never_pattern = false;
        self.walk(|pat| match &pat.kind {
            PatKind::Never => {
                is_never_pattern = true;
                false
            }
            PatKind::Or(s) => {
                is_never_pattern = s.iter().all(|p| p.is_never_pattern());
                false
            }
            _ => true,
        });
        is_never_pattern
    }
}

/// A single field in a struct pattern.
///
/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
/// are treated the same as` x: x, y: ref y, z: ref mut z`,
/// except `is_shorthand` is true.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct PatField<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    /// The identifier for the field.
    pub ident: Ident,
    /// The pattern the field is destructured to.
    pub pat: &'hir Pat<'hir>,
    pub is_shorthand: bool,
    pub span: Span,
}

#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
pub enum RangeEnd {
    Included,
    Excluded,
}

impl fmt::Display for RangeEnd {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            RangeEnd::Included => "..=",
            RangeEnd::Excluded => "..",
        })
    }
}

// Equivalent to `Option<usize>`. That type takes up 16 bytes on 64-bit, but
// this type only takes up 4 bytes, at the cost of being restricted to a
// maximum value of `u32::MAX - 1`. In practice, this is more than enough.
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
pub struct DotDotPos(u32);

impl DotDotPos {
    /// Panics if n >= u32::MAX.
    pub fn new(n: Option<usize>) -> Self {
        match n {
            Some(n) => {
                assert!(n < u32::MAX as usize);
                Self(n as u32)
            }
            None => Self(u32::MAX),
        }
    }

    pub fn as_opt_usize(&self) -> Option<usize> {
        if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
    }
}

impl fmt::Debug for DotDotPos {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.as_opt_usize().fmt(f)
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct PatExpr<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub span: Span,
    pub kind: PatExprKind<'hir>,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum PatExprKind<'hir> {
    Lit {
        lit: Lit,
        // FIXME: move this into `Lit` and handle negated literal expressions
        // once instead of matching on unop neg expressions everywhere.
        negated: bool,
    },
    ConstBlock(ConstBlock),
    /// A path pattern for a unit struct/variant or a (maybe-associated) constant.
    Path(QPath<'hir>),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum TyPatKind<'hir> {
    /// A range pattern (e.g., `1..=2` or `1..2`).
    Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),

    /// A pattern that excludes null pointers
    NotNull,

    /// A list of patterns where only one needs to be satisfied
    Or(&'hir [TyPat<'hir>]),

    /// A placeholder for a pattern that wasn't well formed in some way.
    Err(ErrorGuaranteed),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum PatKind<'hir> {
    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
    Missing,

    /// Represents a wildcard pattern (i.e., `_`).
    Wild,

    /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
    /// The `HirId` is the canonical ID for the variable being bound,
    /// (e.g., in `Ok(x) | Err(x)`, both `x` use the same canonical ID),
    /// which is the pattern ID of the first `x`.
    ///
    /// The `BindingMode` is what's provided by the user, before match
    /// ergonomics are applied. For the binding mode actually in use,
    /// see [`TypeckResults::extract_binding_mode`].
    ///
    /// [`TypeckResults::extract_binding_mode`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.extract_binding_mode
    Binding(BindingMode, HirId, Ident, Option<&'hir Pat<'hir>>),

    /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
    /// The `Option` contains the span of a possible `..`.
    Struct(QPath<'hir>, &'hir [PatField<'hir>], Option<Span>),

    /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
    /// If the `..` pattern fragment is present, then `DotDotPos` denotes its position.
    /// `0 <= position <= subpats.len()`
    TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),

    /// An or-pattern `A | B | C`.
    /// Invariant: `pats.len() >= 2`.
    Or(&'hir [Pat<'hir>]),

    /// A never pattern `!`.
    Never,

    /// A tuple pattern (e.g., `(a, b)`).
    /// If the `..` pattern fragment is present, then `DotDotPos` denotes its position.
    /// `0 <= position <= subpats.len()`
    Tuple(&'hir [Pat<'hir>], DotDotPos),

    /// A `box` pattern.
    Box(&'hir Pat<'hir>),

    /// A `deref` pattern (currently `deref!()` macro-based syntax).
    Deref(&'hir Pat<'hir>),

    /// A reference pattern (e.g., `&mut (a, b)`).
    Ref(&'hir Pat<'hir>, Pinnedness, Mutability),

    /// A literal, const block or path.
    Expr(&'hir PatExpr<'hir>),

    /// A guard pattern (e.g., `x if guard(x)`).
    Guard(&'hir Pat<'hir>, &'hir Expr<'hir>),

    /// A range pattern (e.g., `1..=2` or `1..2`).
    Range(Option<&'hir PatExpr<'hir>>, Option<&'hir PatExpr<'hir>>, RangeEnd),

    /// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`.
    ///
    /// Here, `slice` is lowered from the syntax `($binding_mode $ident @)? ..`.
    /// If `slice` exists, then `after` can be non-empty.
    ///
    /// The representation for e.g., `[a, b, .., c, d]` is:
    /// ```ignore (illustrative)
    /// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)])
    /// ```
    Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),

    /// A placeholder for a pattern that wasn't well formed in some way.
    Err(ErrorGuaranteed),
}

/// A statement.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Stmt<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub kind: StmtKind<'hir>,
    pub span: Span,
}

/// The contents of a statement.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum StmtKind<'hir> {
    /// A local (`let`) binding.
    Let(&'hir LetStmt<'hir>),

    /// An item binding.
    Item(ItemId),

    /// An expression without a trailing semi-colon (must have unit type).
    Expr(&'hir Expr<'hir>),

    /// An expression with a trailing semi-colon (may have any type).
    Semi(&'hir Expr<'hir>),
}

/// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct LetStmt<'hir> {
    /// Span of `super` in `super let`.
    pub super_: Option<Span>,
    pub pat: &'hir Pat<'hir>,
    /// Type annotation, if any (otherwise the type will be inferred).
    pub ty: Option<&'hir Ty<'hir>>,
    /// Initializer expression to set the value, if any.
    pub init: Option<&'hir Expr<'hir>>,
    /// Else block for a `let...else` binding.
    pub els: Option<&'hir Block<'hir>>,
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub span: Span,
    /// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
    /// desugaring, or `AssignDesugar` if it is the result of a complex
    /// assignment desugaring. Otherwise will be `Normal`.
    pub source: LocalSource,
}

/// Represents a single arm of a `match` expression, e.g.
/// `<pat> (if <guard>) => <body>`.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Arm<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub span: Span,
    /// If this pattern and the optional guard matches, then `body` is evaluated.
    pub pat: &'hir Pat<'hir>,
    /// Optional guard clause.
    pub guard: Option<&'hir Expr<'hir>>,
    /// The expression the arm evaluates to if this arm matches.
    pub body: &'hir Expr<'hir>,
}

/// Represents a `let <pat>[: <ty>] = <expr>` expression (not a [`LetStmt`]), occurring in an `if-let`
/// or `let-else`, evaluating to a boolean. Typically the pattern is refutable.
///
/// In an `if let`, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of
/// the desugaring to if-let. Only let-else supports the type annotation at present.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct LetExpr<'hir> {
    pub span: Span,
    pub pat: &'hir Pat<'hir>,
    pub ty: Option<&'hir Ty<'hir>>,
    pub init: &'hir Expr<'hir>,
    /// `Recovered::Yes` when this let expressions is not in a syntactically valid location.
    /// Used to prevent building MIR in such situations.
    pub recovered: ast::Recovered,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ExprField<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub ident: Ident,
    pub expr: &'hir Expr<'hir>,
    pub span: Span,
    pub is_shorthand: bool,
}

#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
pub enum BlockCheckMode {
    DefaultBlock,
    UnsafeBlock(UnsafeSource),
}

#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
pub enum UnsafeSource {
    CompilerGenerated,
    UserProvided,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
pub struct BodyId {
    pub hir_id: HirId,
}

/// The body of a function, closure, or constant value. In the case of
/// a function, the body contains not only the function body itself
/// (which is an expression), but also the argument patterns, since
/// those are something that the caller doesn't really care about.
///
/// # Examples
///
/// ```
/// fn foo((x, y): (u32, u32)) -> u32 {
///     x + y
/// }
/// ```
///
/// Here, the `Body` associated with `foo()` would contain:
///
/// - an `params` array containing the `(x, y)` pattern
/// - a `value` containing the `x + y` expression (maybe wrapped in a block)
/// - `coroutine_kind` would be `None`
///
/// All bodies have an **owner**, which can be accessed via the HIR
/// map using `body_owner_def_id()`.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Body<'hir> {
    pub params: &'hir [Param<'hir>],
    pub value: &'hir Expr<'hir>,
}

impl<'hir> Body<'hir> {
    pub fn id(&self) -> BodyId {
        BodyId { hir_id: self.value.hir_id }
    }
}

/// The type of source expression that caused this coroutine to be created.
#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
pub enum CoroutineKind {
    /// A coroutine that comes from a desugaring.
    Desugared(CoroutineDesugaring, CoroutineSource),

    /// A coroutine literal created via a `yield` inside a closure.
    Coroutine(Movability),
}

impl CoroutineKind {
    pub fn movability(self) -> Movability {
        match self {
            CoroutineKind::Desugared(CoroutineDesugaring::Async, _)
            | CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => Movability::Static,
            CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => Movability::Movable,
            CoroutineKind::Coroutine(mov) => mov,
        }
    }

    pub fn is_fn_like(self) -> bool {
        matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
    }

    pub fn to_plural_string(&self) -> String {
        match self {
            CoroutineKind::Desugared(d, CoroutineSource::Fn) => format!("{d:#}fn bodies"),
            CoroutineKind::Desugared(d, CoroutineSource::Block) => format!("{d:#}blocks"),
            CoroutineKind::Desugared(d, CoroutineSource::Closure) => format!("{d:#}closure bodies"),
            CoroutineKind::Coroutine(_) => "coroutines".to_string(),
        }
    }
}

impl fmt::Display for CoroutineKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CoroutineKind::Desugared(d, k) => {
                d.fmt(f)?;
                k.fmt(f)
            }
            CoroutineKind::Coroutine(_) => f.write_str("coroutine"),
        }
    }
}

/// In the case of a coroutine created as part of an async/gen construct,
/// which kind of async/gen construct caused it to be created?
///
/// This helps error messages but is also used to drive coercions in
/// type-checking (see #60424).
#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy, HashStable_Generic, Encodable, Decodable)]
pub enum CoroutineSource {
    /// An explicit `async`/`gen` block written by the user.
    Block,

    /// An explicit `async`/`gen` closure written by the user.
    Closure,

    /// The `async`/`gen` block generated as the body of an async/gen function.
    Fn,
}

impl fmt::Display for CoroutineSource {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CoroutineSource::Block => "block",
            CoroutineSource::Closure => "closure body",
            CoroutineSource::Fn => "fn body",
        }
        .fmt(f)
    }
}

#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash, HashStable_Generic, Encodable, Decodable)]
pub enum CoroutineDesugaring {
    /// An explicit `async` block or the body of an `async` function.
    Async,

    /// An explicit `gen` block or the body of a `gen` function.
    Gen,

    /// An explicit `async gen` block or the body of an `async gen` function,
    /// which is able to both `yield` and `.await`.
    AsyncGen,
}

impl fmt::Display for CoroutineDesugaring {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CoroutineDesugaring::Async => {
                if f.alternate() {
                    f.write_str("`async` ")?;
                } else {
                    f.write_str("async ")?
                }
            }
            CoroutineDesugaring::Gen => {
                if f.alternate() {
                    f.write_str("`gen` ")?;
                } else {
                    f.write_str("gen ")?
                }
            }
            CoroutineDesugaring::AsyncGen => {
                if f.alternate() {
                    f.write_str("`async gen` ")?;
                } else {
                    f.write_str("async gen ")?
                }
            }
        }

        Ok(())
    }
}

#[derive(Copy, Clone, Debug)]
pub enum BodyOwnerKind {
    /// Functions and methods.
    Fn,

    /// Closures
    Closure,

    /// Constants and associated constants, also including inline constants.
    Const { inline: bool },

    /// Initializer of a `static` item.
    Static(Mutability),

    /// Fake body for a global asm to store its const-like value types.
    GlobalAsm,
}

impl BodyOwnerKind {
    pub fn is_fn_or_closure(self) -> bool {
        match self {
            BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
            BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
                false
            }
        }
    }
}

/// The kind of an item that requires const-checking.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ConstContext {
    /// A `const fn`.
    ConstFn,

    /// A `static` or `static mut`.
    Static(Mutability),

    /// A `const`, associated `const`, or other const context.
    ///
    /// Other contexts include:
    /// - Array length expressions
    /// - Enum discriminants
    /// - Const generics
    ///
    /// For the most part, other contexts are treated just like a regular `const`, so they are
    /// lumped into the same category.
    Const { inline: bool },
}

impl ConstContext {
    /// A description of this const context that can appear between backticks in an error message.
    ///
    /// E.g. `const` or `static mut`.
    pub fn keyword_name(self) -> &'static str {
        match self {
            Self::Const { .. } => "const",
            Self::Static(Mutability::Not) => "static",
            Self::Static(Mutability::Mut) => "static mut",
            Self::ConstFn => "const fn",
        }
    }
}

/// A colloquial, trivially pluralizable description of this const context for use in error
/// messages.
impl fmt::Display for ConstContext {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            Self::Const { .. } => write!(f, "constant"),
            Self::Static(_) => write!(f, "static"),
            Self::ConstFn => write!(f, "constant function"),
        }
    }
}

impl IntoDiagArg for ConstContext {
    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
        DiagArgValue::Str(Cow::Borrowed(match self {
            ConstContext::ConstFn => "const_fn",
            ConstContext::Static(_) => "static",
            ConstContext::Const { .. } => "const",
        }))
    }
}

/// A literal.
pub type Lit = Spanned<LitKind>;

/// A constant (expression) that's not an item or associated item,
/// but needs its own `DefId` for type-checking, const-eval, etc.
/// These are usually found nested inside types (e.g., array lengths)
/// or expressions (e.g., repeat counts), and also used to define
/// explicit discriminant values for enum variants.
///
/// You can check if this anon const is a default in a const param
/// `const N: usize = { ... }` with `tcx.hir_opt_const_param_default_param_def_id(..)`
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub struct AnonConst {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub def_id: LocalDefId,
    pub body: BodyId,
    pub span: Span,
}

/// An inline constant expression `const { something }`.
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub struct ConstBlock {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub def_id: LocalDefId,
    pub body: BodyId,
}

/// An expression.
///
/// For more details, see the [rust lang reference].
/// Note that the reference does not document nightly-only features.
/// There may be also slight differences in the names and representation of AST nodes between
/// the compiler and the reference.
///
/// [rust lang reference]: https://doc.rust-lang.org/reference/expressions.html
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Expr<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub kind: ExprKind<'hir>,
    pub span: Span,
}

impl Expr<'_> {
    pub fn precedence(&self, has_attr: &dyn Fn(HirId) -> bool) -> ExprPrecedence {
        let prefix_attrs_precedence = || -> ExprPrecedence {
            if has_attr(self.hir_id) { ExprPrecedence::Prefix } else { ExprPrecedence::Unambiguous }
        };

        match &self.kind {
            ExprKind::Closure(closure) => {
                match closure.fn_decl.output {
                    FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
                    FnRetTy::Return(_) => prefix_attrs_precedence(),
                }
            }

            ExprKind::Break(..)
            | ExprKind::Ret(..)
            | ExprKind::Yield(..)
            | ExprKind::Become(..) => ExprPrecedence::Jump,

            // Binop-like expr kinds, handled by `AssocOp`.
            ExprKind::Binary(op, ..) => op.node.precedence(),
            ExprKind::Cast(..) => ExprPrecedence::Cast,

            ExprKind::Assign(..) |
            ExprKind::AssignOp(..) => ExprPrecedence::Assign,

            // Unary, prefix
            ExprKind::AddrOf(..)
            // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
            // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
            // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
            // but we need to print `(let _ = a) < b` as-is with parens.
            | ExprKind::Let(..)
            | ExprKind::Unary(..) => ExprPrecedence::Prefix,

            // Need parens if and only if there are prefix attributes.
            ExprKind::Array(_)
            | ExprKind::Block(..)
            | ExprKind::Call(..)
            | ExprKind::ConstBlock(_)
            | ExprKind::Continue(..)
            | ExprKind::Field(..)
            | ExprKind::If(..)
            | ExprKind::Index(..)
            | ExprKind::InlineAsm(..)
            | ExprKind::Lit(_)
            | ExprKind::Loop(..)
            | ExprKind::Match(..)
            | ExprKind::MethodCall(..)
            | ExprKind::OffsetOf(..)
            | ExprKind::Path(..)
            | ExprKind::Repeat(..)
            | ExprKind::Struct(..)
            | ExprKind::Tup(_)
            | ExprKind::Type(..)
            | ExprKind::UnsafeBinderCast(..)
            | ExprKind::Use(..)
            | ExprKind::Err(_) => prefix_attrs_precedence(),

            ExprKind::DropTemps(expr, ..) => expr.precedence(has_attr),
        }
    }

    /// Whether this looks like a place expr, without checking for deref
    /// adjustments.
    /// This will return `true` in some potentially surprising cases such as
    /// `CONSTANT.field`.
    pub fn is_syntactic_place_expr(&self) -> bool {
        self.is_place_expr(|_| true)
    }

    /// Whether this is a place expression.
    ///
    /// `allow_projections_from` should return `true` if indexing a field or index expression based
    /// on the given expression should be considered a place expression.
    pub fn is_place_expr(&self, mut allow_projections_from: impl FnMut(&Self) -> bool) -> bool {
        match self.kind {
            ExprKind::Path(QPath::Resolved(_, ref path)) => {
                matches!(path.res, Res::Local(..) | Res::Def(DefKind::Static { .. }, _) | Res::Err)
            }

            // Type ascription inherits its place expression kind from its
            // operand. See:
            // https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
            ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from),

            // Unsafe binder cast preserves place-ness of the sub-expression.
            ExprKind::UnsafeBinderCast(_, e, _) => e.is_place_expr(allow_projections_from),

            ExprKind::Unary(UnOp::Deref, _) => true,

            ExprKind::Field(ref base, _) | ExprKind::Index(ref base, _, _) => {
                allow_projections_from(base) || base.is_place_expr(allow_projections_from)
            }

            // Suppress errors for bad expressions.
            ExprKind::Err(_guar)
            | ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,

            // Partially qualified paths in expressions can only legally
            // refer to associated items which are always rvalues.
            ExprKind::Path(QPath::TypeRelative(..))
            | ExprKind::Call(..)
            | ExprKind::MethodCall(..)
            | ExprKind::Use(..)
            | ExprKind::Struct(..)
            | ExprKind::Tup(..)
            | ExprKind::If(..)
            | ExprKind::Match(..)
            | ExprKind::Closure { .. }
            | ExprKind::Block(..)
            | ExprKind::Repeat(..)
            | ExprKind::Array(..)
            | ExprKind::Break(..)
            | ExprKind::Continue(..)
            | ExprKind::Ret(..)
            | ExprKind::Become(..)
            | ExprKind::Let(..)
            | ExprKind::Loop(..)
            | ExprKind::Assign(..)
            | ExprKind::InlineAsm(..)
            | ExprKind::OffsetOf(..)
            | ExprKind::AssignOp(..)
            | ExprKind::Lit(_)
            | ExprKind::ConstBlock(..)
            | ExprKind::Unary(..)
            | ExprKind::AddrOf(..)
            | ExprKind::Binary(..)
            | ExprKind::Yield(..)
            | ExprKind::Cast(..)
            | ExprKind::DropTemps(..) => false,
        }
    }

    /// If this is a desugared range expression,
    /// returns the span of the range without desugaring context.
    pub fn range_span(&self) -> Option<Span> {
        is_range_literal(self).then(|| self.span.parent_callsite().unwrap())
    }

    /// Check if expression is an integer literal that can be used
    /// where `usize` is expected.
    pub fn is_size_lit(&self) -> bool {
        matches!(
            self.kind,
            ExprKind::Lit(Lit {
                node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
                ..
            })
        )
    }

    /// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
    /// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
    /// silent, only signaling the ownership system. By doing this, suggestions that check the
    /// `ExprKind` of any given `Expr` for presentation don't have to care about `DropTemps`
    /// beyond remembering to call this function before doing analysis on it.
    pub fn peel_drop_temps(&self) -> &Self {
        let mut expr = self;
        while let ExprKind::DropTemps(inner) = &expr.kind {
            expr = inner;
        }
        expr
    }

    pub fn peel_blocks(&self) -> &Self {
        let mut expr = self;
        while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
            expr = inner;
        }
        expr
    }

    pub fn peel_borrows(&self) -> &Self {
        let mut expr = self;
        while let ExprKind::AddrOf(.., inner) = &expr.kind {
            expr = inner;
        }
        expr
    }

    pub fn can_have_side_effects(&self) -> bool {
        match self.peel_drop_temps().kind {
            ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
                false
            }
            ExprKind::Type(base, _)
            | ExprKind::Unary(_, base)
            | ExprKind::Field(base, _)
            | ExprKind::Index(base, _, _)
            | ExprKind::AddrOf(.., base)
            | ExprKind::Cast(base, _)
            | ExprKind::UnsafeBinderCast(_, base, _) => {
                // This isn't exactly true for `Index` and all `Unary`, but we are using this
                // method exclusively for diagnostics and there's a *cultural* pressure against
                // them being used only for its side-effects.
                base.can_have_side_effects()
            }
            ExprKind::Struct(_, fields, init) => {
                let init_side_effects = match init {
                    StructTailExpr::Base(init) => init.can_have_side_effects(),
                    StructTailExpr::DefaultFields(_) | StructTailExpr::None => false,
                };
                fields.iter().map(|field| field.expr).any(|e| e.can_have_side_effects())
                    || init_side_effects
            }

            ExprKind::Array(args)
            | ExprKind::Tup(args)
            | ExprKind::Call(
                Expr {
                    kind:
                        ExprKind::Path(QPath::Resolved(
                            None,
                            Path { res: Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), .. },
                        )),
                    ..
                },
                args,
            ) => args.iter().any(|arg| arg.can_have_side_effects()),
            ExprKind::If(..)
            | ExprKind::Match(..)
            | ExprKind::MethodCall(..)
            | ExprKind::Call(..)
            | ExprKind::Closure { .. }
            | ExprKind::Block(..)
            | ExprKind::Repeat(..)
            | ExprKind::Break(..)
            | ExprKind::Continue(..)
            | ExprKind::Ret(..)
            | ExprKind::Become(..)
            | ExprKind::Let(..)
            | ExprKind::Loop(..)
            | ExprKind::Assign(..)
            | ExprKind::InlineAsm(..)
            | ExprKind::AssignOp(..)
            | ExprKind::ConstBlock(..)
            | ExprKind::Binary(..)
            | ExprKind::Yield(..)
            | ExprKind::DropTemps(..)
            | ExprKind::Err(_) => true,
        }
    }

    /// To a first-order approximation, is this a pattern?
    pub fn is_approximately_pattern(&self) -> bool {
        match &self.kind {
            ExprKind::Array(_)
            | ExprKind::Call(..)
            | ExprKind::Tup(_)
            | ExprKind::Lit(_)
            | ExprKind::Path(_)
            | ExprKind::Struct(..) => true,
            _ => false,
        }
    }

    /// Whether this and the `other` expression are the same for purposes of an indexing operation.
    ///
    /// This is only used for diagnostics to see if we have things like `foo[i]` where `foo` is
    /// borrowed multiple times with `i`.
    pub fn equivalent_for_indexing(&self, other: &Expr<'_>) -> bool {
        match (self.kind, other.kind) {
            (ExprKind::Lit(lit1), ExprKind::Lit(lit2)) => lit1.node == lit2.node,
            (
                ExprKind::Path(QPath::Resolved(None, path1)),
                ExprKind::Path(QPath::Resolved(None, path2)),
            ) => path1.res == path2.res,
            (
                ExprKind::Struct(
                    &QPath::Resolved(None, &Path { res: Res::Def(_, path1_def_id), .. }),
                    args1,
                    StructTailExpr::None,
                ),
                ExprKind::Struct(
                    &QPath::Resolved(None, &Path { res: Res::Def(_, path2_def_id), .. }),
                    args2,
                    StructTailExpr::None,
                ),
            ) => {
                path2_def_id == path1_def_id
                    && is_range_literal(self)
                    && is_range_literal(other)
                    && std::iter::zip(args1, args2)
                        .all(|(a, b)| a.expr.equivalent_for_indexing(b.expr))
            }
            _ => false,
        }
    }

    pub fn method_ident(&self) -> Option<Ident> {
        match self.kind {
            ExprKind::MethodCall(receiver_method, ..) => Some(receiver_method.ident),
            ExprKind::Unary(_, expr) | ExprKind::AddrOf(.., expr) => expr.method_ident(),
            _ => None,
        }
    }
}

/// Checks if the specified expression is a built-in range literal.
/// (See: `LoweringContext::lower_expr()`).
pub fn is_range_literal(expr: &Expr<'_>) -> bool {
    if let ExprKind::Struct(QPath::Resolved(None, path), _, StructTailExpr::None) = expr.kind
        && let [.., segment] = path.segments
        && let sym::RangeFrom
        | sym::RangeFull
        | sym::Range
        | sym::RangeToInclusive
        | sym::RangeTo
        | sym::RangeFromCopy
        | sym::RangeCopy
        | sym::RangeInclusiveCopy
        | sym::RangeToInclusiveCopy = segment.ident.name
        && expr.span.is_desugaring(DesugaringKind::RangeExpr)
    {
        true
    } else if let ExprKind::Call(func, _) = &expr.kind
        && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
        && let [.., segment] = path.segments
        && let sym::range_inclusive_new = segment.ident.name
        && expr.span.is_desugaring(DesugaringKind::RangeExpr)
    {
        true
    } else {
        false
    }
}

/// Checks if the specified expression needs parentheses for prefix
/// or postfix suggestions to be valid.
/// For example, `a + b` requires parentheses to suggest `&(a + b)`,
/// but just `a` does not.
/// Similarly, `(a + b).c()` also requires parentheses.
/// This should not be used for other types of suggestions.
pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
    match expr.kind {
        // parenthesize if needed (Issue #46756)
        ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
        // parenthesize borrows of range literals (Issue #54505)
        _ if is_range_literal(expr) => true,
        _ => false,
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ExprKind<'hir> {
    /// Allow anonymous constants from an inline `const` block
    ConstBlock(ConstBlock),
    /// An array (e.g., `[a, b, c, d]`).
    Array(&'hir [Expr<'hir>]),
    /// A function call.
    ///
    /// The first field resolves to the function itself (usually an `ExprKind::Path`),
    /// and the second field is the list of arguments.
    /// This also represents calling the constructor of
    /// tuple-like ADTs such as tuple structs and enum variants.
    Call(&'hir Expr<'hir>, &'hir [Expr<'hir>]),
    /// A method call (e.g., `x.foo::<'static, Bar, Baz>(a, b, c, d)`).
    ///
    /// The `PathSegment` represents the method name and its generic arguments
    /// (within the angle brackets).
    /// The `&Expr` is the expression that evaluates
    /// to the object on which the method is being called on (the receiver),
    /// and the `&[Expr]` is the rest of the arguments.
    /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
    /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d], span)`.
    /// The final `Span` represents the span of the function and arguments
    /// (e.g. `foo::<Bar, Baz>(a, b, c, d)` in `x.foo::<Bar, Baz>(a, b, c, d)`
    ///
    /// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with
    /// the `hir_id` of the `MethodCall` node itself.
    ///
    /// [`type_dependent_def_id`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.type_dependent_def_id
    MethodCall(&'hir PathSegment<'hir>, &'hir Expr<'hir>, &'hir [Expr<'hir>], Span),
    /// An use expression (e.g., `var.use`).
    Use(&'hir Expr<'hir>, Span),
    /// A tuple (e.g., `(a, b, c, d)`).
    Tup(&'hir [Expr<'hir>]),
    /// A binary operation (e.g., `a + b`, `a * b`).
    Binary(BinOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
    /// A unary operation (e.g., `!x`, `*x`).
    Unary(UnOp, &'hir Expr<'hir>),
    /// A literal (e.g., `1`, `"foo"`).
    Lit(Lit),
    /// A cast (e.g., `foo as f64`).
    Cast(&'hir Expr<'hir>, &'hir Ty<'hir>),
    /// A type ascription (e.g., `x: Foo`). See RFC 3307.
    Type(&'hir Expr<'hir>, &'hir Ty<'hir>),
    /// Wraps the expression in a terminating scope.
    /// This makes it semantically equivalent to `{ let _t = expr; _t }`.
    ///
    /// This construct only exists to tweak the drop order in AST lowering.
    /// An example of that is the desugaring of `for` loops.
    DropTemps(&'hir Expr<'hir>),
    /// A `let $pat = $expr` expression.
    ///
    /// These are not [`LetStmt`] and only occur as expressions.
    /// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`.
    Let(&'hir LetExpr<'hir>),
    /// An `if` block, with an optional else block.
    ///
    /// I.e., `if <expr> { <expr> } else { <expr> }`.
    ///
    /// The "then" expr is always `ExprKind::Block`. If present, the "else" expr is always
    /// `ExprKind::Block` (for `else`) or `ExprKind::If` (for `else if`).
    /// Note that using an `Expr` instead of a `Block` for the "then" part is intentional,
    /// as it simplifies the type coercion machinery.
    If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
    /// A conditionless loop (can be exited with `break`, `continue`, or `return`).
    ///
    /// I.e., `'label: loop { <block> }`.
    ///
    /// The `Span` is the loop header (`for x in y`/`while let pat = expr`).
    Loop(&'hir Block<'hir>, Option<Label>, LoopSource, Span),
    /// A `match` block, with a source that indicates whether or not it is
    /// the result of a desugaring, and if so, which kind.
    Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),
    /// A closure (e.g., `move |a, b, c| {a + b + c}`).
    ///
    /// The `Span` is the argument block `|...|`.
    ///
    /// This may also be a coroutine literal or an `async block` as indicated by the
    /// `Option<Movability>`.
    Closure(&'hir Closure<'hir>),
    /// A block (e.g., `'label: { ... }`).
    Block(&'hir Block<'hir>, Option<Label>),

    /// An assignment (e.g., `a = foo()`).
    Assign(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),
    /// An assignment with an operator.
    ///
    /// E.g., `a += 1`.
    AssignOp(AssignOp, &'hir Expr<'hir>, &'hir Expr<'hir>),
    /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct or tuple field.
    Field(&'hir Expr<'hir>, Ident),
    /// An indexing operation (`foo[2]`).
    /// Similar to [`ExprKind::MethodCall`], the final `Span` represents the span of the brackets
    /// and index.
    Index(&'hir Expr<'hir>, &'hir Expr<'hir>, Span),

    /// Path to a definition, possibly containing lifetime or type parameters.
    Path(QPath<'hir>),

    /// A referencing operation (i.e., `&a` or `&mut a`).
    AddrOf(BorrowKind, Mutability, &'hir Expr<'hir>),
    /// A `break`, with an optional label to break.
    Break(Destination, Option<&'hir Expr<'hir>>),
    /// A `continue`, with an optional label.
    Continue(Destination),
    /// A `return`, with an optional value to be returned.
    Ret(Option<&'hir Expr<'hir>>),
    /// A `become`, with the value to be returned.
    Become(&'hir Expr<'hir>),

    /// Inline assembly (from `asm!`), with its outputs and inputs.
    InlineAsm(&'hir InlineAsm<'hir>),

    /// Field offset (`offset_of!`)
    OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),

    /// A struct or struct-like variant literal expression.
    ///
    /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
    /// where `base` is the `Option<Expr>`.
    Struct(&'hir QPath<'hir>, &'hir [ExprField<'hir>], StructTailExpr<'hir>),

    /// An array literal constructed from one repeated element.
    ///
    /// E.g., `[1; 5]`. The first expression is the element
    /// to be repeated; the second is the number of times to repeat it.
    Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>),

    /// A suspension point for coroutines (i.e., `yield <expr>`).
    Yield(&'hir Expr<'hir>, YieldSource),

    /// Operators which can be used to interconvert `unsafe` binder types.
    /// e.g. `unsafe<'a> &'a i32` <=> `&i32`.
    UnsafeBinderCast(UnsafeBinderCastKind, &'hir Expr<'hir>, Option<&'hir Ty<'hir>>),

    /// A placeholder for an expression that wasn't syntactically well formed in some way.
    Err(rustc_span::ErrorGuaranteed),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum StructTailExpr<'hir> {
    /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
    None,
    /// A struct expression with a "base", an expression of the same type as the outer struct that
    /// will be used to populate any fields not explicitly mentioned: `Foo { ..base }`
    Base(&'hir Expr<'hir>),
    /// A struct expression with a `..` tail but no "base" expression. The values from the struct
    /// fields' default values will be used to populate any fields not explicitly mentioned:
    /// `Foo { .. }`.
    DefaultFields(Span),
}

/// Represents an optionally `Self`-qualified value/type path or associated extension.
///
/// To resolve the path to a `DefId`, call [`qpath_res`].
///
/// [`qpath_res`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum QPath<'hir> {
    /// Path to a definition, optionally "fully-qualified" with a `Self`
    /// type, if the path points to an associated item in a trait.
    ///
    /// E.g., an unqualified path like `Clone::clone` has `None` for `Self`,
    /// while `<Vec<T> as Clone>::clone` has `Some(Vec<T>)` for `Self`,
    /// even though they both have the same two-segment `Clone::clone` `Path`.
    Resolved(Option<&'hir Ty<'hir>>, &'hir Path<'hir>),

    /// Type-related paths (e.g., `<T>::default` or `<T>::Output`).
    /// Will be resolved by type-checking to an associated item.
    ///
    /// UFCS source paths can desugar into this, with `Vec::new` turning into
    /// `<Vec>::new`, and `T::X::Y::method` into `<<<T>::X>::Y>::method`,
    /// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
    TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
}

impl<'hir> QPath<'hir> {
    /// Returns the span of this `QPath`.
    pub fn span(&self) -> Span {
        match *self {
            QPath::Resolved(_, path) => path.span,
            QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
        }
    }

    /// Returns the span of the qself of this `QPath`. For example, `()` in
    /// `<() as Trait>::method`.
    pub fn qself_span(&self) -> Span {
        match *self {
            QPath::Resolved(_, path) => path.span,
            QPath::TypeRelative(qself, _) => qself.span,
        }
    }
}

/// Hints at the original code for a let statement.
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum LocalSource {
    /// A `match _ { .. }`.
    Normal,
    /// When lowering async functions, we create locals within the `async move` so that
    /// all parameters are dropped after the future is polled.
    ///
    /// ```ignore (pseudo-Rust)
    /// async fn foo(<pattern> @ x: Type) {
    ///     async move {
    ///         let <pattern> = x;
    ///     }
    /// }
    /// ```
    AsyncFn,
    /// A desugared `<expr>.await`.
    AwaitDesugar,
    /// A desugared `expr = expr`, where the LHS is a tuple, struct, array or underscore expression.
    AssignDesugar,
    /// A contract `#[ensures(..)]` attribute injects a let binding for the check that runs at point of return.
    Contract,
}

/// Hints at the original code for a `match _ { .. }`.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
pub enum MatchSource {
    /// A `match _ { .. }`.
    Normal,
    /// A `expr.match { .. }`.
    Postfix,
    /// A desugared `for _ in _ { .. }` loop.
    ForLoopDesugar,
    /// A desugared `?` operator.
    TryDesugar(HirId),
    /// A desugared `<expr>.await`.
    AwaitDesugar,
    /// A desugared `format_args!()`.
    FormatArgs,
}

impl MatchSource {
    #[inline]
    pub const fn name(self) -> &'static str {
        use MatchSource::*;
        match self {
            Normal => "match",
            Postfix => ".match",
            ForLoopDesugar => "for",
            TryDesugar(_) => "?",
            AwaitDesugar => ".await",
            FormatArgs => "format_args!()",
        }
    }
}

/// The loop type that yielded an `ExprKind::Loop`.
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
pub enum LoopSource {
    /// A `loop { .. }` loop.
    Loop,
    /// A `while _ { .. }` loop.
    While,
    /// A `for _ in _ { .. }` loop.
    ForLoop,
}

impl LoopSource {
    pub fn name(self) -> &'static str {
        match self {
            LoopSource::Loop => "loop",
            LoopSource::While => "while",
            LoopSource::ForLoop => "for",
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
pub enum LoopIdError {
    OutsideLoopScope,
    UnlabeledCfInWhileCondition,
    UnresolvedLabel,
}

impl fmt::Display for LoopIdError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            LoopIdError::OutsideLoopScope => "not inside loop scope",
            LoopIdError::UnlabeledCfInWhileCondition => {
                "unlabeled control flow (break or continue) in while condition"
            }
            LoopIdError::UnresolvedLabel => "label not found",
        })
    }
}

#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
pub struct Destination {
    /// This is `Some(_)` iff there is an explicit user-specified 'label
    pub label: Option<Label>,

    /// These errors are caught and then reported during the diagnostics pass in
    /// `librustc_passes/loops.rs`
    pub target_id: Result<HirId, LoopIdError>,
}

/// The yield kind that caused an `ExprKind::Yield`.
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum YieldSource {
    /// An `<expr>.await`.
    Await { expr: Option<HirId> },
    /// A plain `yield`.
    Yield,
}

impl fmt::Display for YieldSource {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            YieldSource::Await { .. } => "`await`",
            YieldSource::Yield => "`yield`",
        })
    }
}

// N.B., if you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct MutTy<'hir> {
    pub ty: &'hir Ty<'hir>,
    pub mutbl: Mutability,
}

/// Represents a function's signature in a trait declaration,
/// trait implementation, or a free function.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct FnSig<'hir> {
    pub header: FnHeader,
    pub decl: &'hir FnDecl<'hir>,
    pub span: Span,
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct TraitItemId {
    pub owner_id: OwnerId,
}

impl TraitItemId {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }
}

/// Represents an item declaration within a trait declaration,
/// possibly including a default implementation. A trait item is
/// either required (meaning it doesn't have an implementation, just a
/// signature) or provided (meaning it has a default implementation).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TraitItem<'hir> {
    pub ident: Ident,
    pub owner_id: OwnerId,
    pub generics: &'hir Generics<'hir>,
    pub kind: TraitItemKind<'hir>,
    pub span: Span,
    pub defaultness: Defaultness,
    pub has_delayed_lints: bool,
}

macro_rules! expect_methods_self_kind {
    ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
        $(
            #[track_caller]
            pub fn $name(&self) -> $ret_ty {
                let $pat = &self.kind else { expect_failed(stringify!($name), self) };
                $ret_val
            }
        )*
    }
}

macro_rules! expect_methods_self {
    ( $( $name:ident, $ret_ty:ty, $pat:pat, $ret_val:expr; )* ) => {
        $(
            #[track_caller]
            pub fn $name(&self) -> $ret_ty {
                let $pat = self else { expect_failed(stringify!($name), self) };
                $ret_val
            }
        )*
    }
}

#[track_caller]
fn expect_failed<T: fmt::Debug>(ident: &'static str, found: T) -> ! {
    panic!("{ident}: found {found:?}")
}

impl<'hir> TraitItem<'hir> {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }

    pub fn trait_item_id(&self) -> TraitItemId {
        TraitItemId { owner_id: self.owner_id }
    }

    expect_methods_self_kind! {
        expect_const, (&'hir Ty<'hir>, Option<ConstItemRhs<'hir>>),
            TraitItemKind::Const(ty, rhs), (ty, *rhs);

        expect_fn, (&FnSig<'hir>, &TraitFn<'hir>),
            TraitItemKind::Fn(ty, trfn), (ty, trfn);

        expect_type, (GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
            TraitItemKind::Type(bounds, ty), (bounds, *ty);
    }
}

/// Represents a trait method's body (or just argument names).
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum TraitFn<'hir> {
    /// No default body in the trait, just a signature.
    Required(&'hir [Option<Ident>]),

    /// Both signature and body are provided in the trait.
    Provided(BodyId),
}

/// Represents a trait method or associated constant or type
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum TraitItemKind<'hir> {
    /// An associated constant with an optional value (otherwise `impl`s must contain a value).
    Const(&'hir Ty<'hir>, Option<ConstItemRhs<'hir>>),
    /// An associated function with an optional body.
    Fn(FnSig<'hir>, TraitFn<'hir>),
    /// An associated type with (possibly empty) bounds and optional concrete
    /// type.
    Type(GenericBounds<'hir>, Option<&'hir Ty<'hir>>),
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct ImplItemId {
    pub owner_id: OwnerId,
}

impl ImplItemId {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }
}

/// Represents an associated item within an impl block.
///
/// Refer to [`Impl`] for an impl block declaration.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ImplItem<'hir> {
    pub ident: Ident,
    pub owner_id: OwnerId,
    pub generics: &'hir Generics<'hir>,
    pub kind: ImplItemKind<'hir>,
    pub impl_kind: ImplItemImplKind,
    pub span: Span,
    pub has_delayed_lints: bool,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ImplItemImplKind {
    Inherent {
        vis_span: Span,
    },
    Trait {
        defaultness: Defaultness,
        /// Item in the trait that this item implements
        trait_item_def_id: Result<DefId, ErrorGuaranteed>,
    },
}

impl<'hir> ImplItem<'hir> {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }

    pub fn impl_item_id(&self) -> ImplItemId {
        ImplItemId { owner_id: self.owner_id }
    }

    pub fn vis_span(&self) -> Option<Span> {
        match self.impl_kind {
            ImplItemImplKind::Trait { .. } => None,
            ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
        }
    }

    expect_methods_self_kind! {
        expect_const, (&'hir Ty<'hir>, ConstItemRhs<'hir>), ImplItemKind::Const(ty, rhs), (ty, *rhs);
        expect_fn,    (&FnSig<'hir>, BodyId),               ImplItemKind::Fn(ty, body),   (ty, *body);
        expect_type,  &'hir Ty<'hir>,                       ImplItemKind::Type(ty),       ty;
    }
}

/// Represents various kinds of content within an `impl`.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ImplItemKind<'hir> {
    /// An associated constant of the given type, set to the constant result
    /// of the expression.
    Const(&'hir Ty<'hir>, ConstItemRhs<'hir>),
    /// An associated function implementation with the given signature and body.
    Fn(FnSig<'hir>, BodyId),
    /// An associated type.
    Type(&'hir Ty<'hir>),
}

/// A constraint on an associated item.
///
/// ### Examples
///
/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
/// * the `A: Bound` in `Trait<A: Bound>`
/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
/// * the `f(..): Bound` in `Trait<f(..): Bound>` (feature `return_type_notation`)
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct AssocItemConstraint<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub ident: Ident,
    pub gen_args: &'hir GenericArgs<'hir>,
    pub kind: AssocItemConstraintKind<'hir>,
    pub span: Span,
}

impl<'hir> AssocItemConstraint<'hir> {
    /// Obtain the type on the RHS of an assoc ty equality constraint if applicable.
    pub fn ty(self) -> Option<&'hir Ty<'hir>> {
        match self.kind {
            AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
            _ => None,
        }
    }

    /// Obtain the const on the RHS of an assoc const equality constraint if applicable.
    pub fn ct(self) -> Option<&'hir ConstArg<'hir>> {
        match self.kind {
            AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
            _ => None,
        }
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum Term<'hir> {
    Ty(&'hir Ty<'hir>),
    Const(&'hir ConstArg<'hir>),
}

impl<'hir> From<&'hir Ty<'hir>> for Term<'hir> {
    fn from(ty: &'hir Ty<'hir>) -> Self {
        Term::Ty(ty)
    }
}

impl<'hir> From<&'hir ConstArg<'hir>> for Term<'hir> {
    fn from(c: &'hir ConstArg<'hir>) -> Self {
        Term::Const(c)
    }
}

/// The kind of [associated item constraint][AssocItemConstraint].
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum AssocItemConstraintKind<'hir> {
    /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
    ///
    /// Also known as an *associated item binding* (we *bind* an associated item to a term).
    ///
    /// Furthermore, associated type equality constraints can also be referred to as *associated type
    /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
    Equality { term: Term<'hir> },
    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
    Bound { bounds: &'hir [GenericBound<'hir>] },
}

impl<'hir> AssocItemConstraintKind<'hir> {
    pub fn descr(&self) -> &'static str {
        match self {
            AssocItemConstraintKind::Equality { .. } => "binding",
            AssocItemConstraintKind::Bound { .. } => "constraint",
        }
    }
}

/// An uninhabited enum used to make `Infer` variants on [`Ty`] and [`ConstArg`] be
/// unreachable. Zero-Variant enums are guaranteed to have the same layout as the never
/// type.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum AmbigArg {}

/// Represents a type in the `HIR`.
///
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// <https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html>
#[derive(Debug, Clone, Copy, HashStable_Generic)]
#[repr(C)]
pub struct Ty<'hir, Unambig = ()> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub span: Span,
    pub kind: TyKind<'hir, Unambig>,
}

impl<'hir> Ty<'hir, AmbigArg> {
    /// Converts a `Ty` in an ambiguous position to one in an unambiguous position.
    ///
    /// Functions accepting an unambiguous types may expect the [`TyKind::Infer`] variant
    /// to be used. Care should be taken to separately handle infer types when calling this
    /// function as it cannot be handled by downstream code making use of the returned ty.
    ///
    /// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
    /// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
    ///
    /// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
    pub fn as_unambig_ty(&self) -> &Ty<'hir> {
        // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
        // the same across different ZST type arguments.
        let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
        unsafe { &*ptr }
    }
}

impl<'hir> Ty<'hir> {
    /// Converts a `Ty` in an unambiguous position to one in an ambiguous position. This is
    /// fallible as the [`TyKind::Infer`] variant is not present in ambiguous positions.
    ///
    /// Functions accepting ambiguous types will not handle the [`TyKind::Infer`] variant, if
    /// infer types are relevant to you then care should be taken to handle them separately.
    pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
        if let TyKind::Infer(()) = self.kind {
            return None;
        }

        // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
        // the same across different ZST type arguments. We also asserted that the `self` is
        // not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
        let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
        Some(unsafe { &*ptr })
    }
}

impl<'hir> Ty<'hir, AmbigArg> {
    pub fn peel_refs(&self) -> &Ty<'hir> {
        let mut final_ty = self.as_unambig_ty();
        while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
            final_ty = ty;
        }
        final_ty
    }
}

impl<'hir> Ty<'hir> {
    pub fn peel_refs(&self) -> &Self {
        let mut final_ty = self;
        while let TyKind::Ref(_, MutTy { ty, .. }) = &final_ty.kind {
            final_ty = ty;
        }
        final_ty
    }

    /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
    pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
        let TyKind::Path(QPath::Resolved(None, path)) = self.kind else {
            return None;
        };
        let [segment] = &path.segments else {
            return None;
        };
        match path.res {
            Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
                Some((def_id, segment.ident))
            }
            _ => None,
        }
    }

    pub fn find_self_aliases(&self) -> Vec<Span> {
        use crate::intravisit::Visitor;
        struct MyVisitor(Vec<Span>);
        impl<'v> Visitor<'v> for MyVisitor {
            fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
                if matches!(
                    &t.kind,
                    TyKind::Path(QPath::Resolved(
                        _,
                        Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
                    ))
                ) {
                    self.0.push(t.span);
                    return;
                }
                crate::intravisit::walk_ty(self, t);
            }
        }

        let mut my_visitor = MyVisitor(vec![]);
        my_visitor.visit_ty_unambig(self);
        my_visitor.0
    }

    /// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
    /// use inference to provide suggestions for the appropriate type if possible.
    pub fn is_suggestable_infer_ty(&self) -> bool {
        fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
            generic_args.iter().any(|arg| match arg {
                GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
                GenericArg::Infer(_) => true,
                _ => false,
            })
        }
        debug!(?self);
        match &self.kind {
            TyKind::Infer(()) => true,
            TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
            TyKind::Array(ty, length) => {
                ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
            }
            TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty),
            TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(),
            TyKind::Path(QPath::TypeRelative(ty, segment)) => {
                ty.is_suggestable_infer_ty() || are_suggestable_generic_args(segment.args().args)
            }
            TyKind::Path(QPath::Resolved(ty_opt, Path { segments, .. })) => {
                ty_opt.is_some_and(Self::is_suggestable_infer_ty)
                    || segments
                        .iter()
                        .any(|segment| are_suggestable_generic_args(segment.args().args))
            }
            _ => false,
        }
    }
}

/// Not represented directly in the AST; referred to by name through a `ty_path`.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum PrimTy {
    Int(IntTy),
    Uint(UintTy),
    Float(FloatTy),
    Str,
    Bool,
    Char,
}

impl PrimTy {
    /// All of the primitive types
    pub const ALL: [Self; 19] = [
        // any changes here should also be reflected in `PrimTy::from_name`
        Self::Int(IntTy::I8),
        Self::Int(IntTy::I16),
        Self::Int(IntTy::I32),
        Self::Int(IntTy::I64),
        Self::Int(IntTy::I128),
        Self::Int(IntTy::Isize),
        Self::Uint(UintTy::U8),
        Self::Uint(UintTy::U16),
        Self::Uint(UintTy::U32),
        Self::Uint(UintTy::U64),
        Self::Uint(UintTy::U128),
        Self::Uint(UintTy::Usize),
        Self::Float(FloatTy::F16),
        Self::Float(FloatTy::F32),
        Self::Float(FloatTy::F64),
        Self::Float(FloatTy::F128),
        Self::Bool,
        Self::Char,
        Self::Str,
    ];

    /// Like [`PrimTy::name`], but returns a &str instead of a symbol.
    ///
    /// Used by clippy.
    pub fn name_str(self) -> &'static str {
        match self {
            PrimTy::Int(i) => i.name_str(),
            PrimTy::Uint(u) => u.name_str(),
            PrimTy::Float(f) => f.name_str(),
            PrimTy::Str => "str",
            PrimTy::Bool => "bool",
            PrimTy::Char => "char",
        }
    }

    pub fn name(self) -> Symbol {
        match self {
            PrimTy::Int(i) => i.name(),
            PrimTy::Uint(u) => u.name(),
            PrimTy::Float(f) => f.name(),
            PrimTy::Str => sym::str,
            PrimTy::Bool => sym::bool,
            PrimTy::Char => sym::char,
        }
    }

    /// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32".
    /// Returns `None` if no matching type is found.
    pub fn from_name(name: Symbol) -> Option<Self> {
        let ty = match name {
            // any changes here should also be reflected in `PrimTy::ALL`
            sym::i8 => Self::Int(IntTy::I8),
            sym::i16 => Self::Int(IntTy::I16),
            sym::i32 => Self::Int(IntTy::I32),
            sym::i64 => Self::Int(IntTy::I64),
            sym::i128 => Self::Int(IntTy::I128),
            sym::isize => Self::Int(IntTy::Isize),
            sym::u8 => Self::Uint(UintTy::U8),
            sym::u16 => Self::Uint(UintTy::U16),
            sym::u32 => Self::Uint(UintTy::U32),
            sym::u64 => Self::Uint(UintTy::U64),
            sym::u128 => Self::Uint(UintTy::U128),
            sym::usize => Self::Uint(UintTy::Usize),
            sym::f16 => Self::Float(FloatTy::F16),
            sym::f32 => Self::Float(FloatTy::F32),
            sym::f64 => Self::Float(FloatTy::F64),
            sym::f128 => Self::Float(FloatTy::F128),
            sym::bool => Self::Bool,
            sym::char => Self::Char,
            sym::str => Self::Str,
            _ => return None,
        };
        Some(ty)
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct FnPtrTy<'hir> {
    pub safety: Safety,
    pub abi: ExternAbi,
    pub generic_params: &'hir [GenericParam<'hir>],
    pub decl: &'hir FnDecl<'hir>,
    // `Option` because bare fn parameter identifiers are optional. We also end up
    // with `None` in some error cases, e.g. invalid parameter patterns.
    pub param_idents: &'hir [Option<Ident>],
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct UnsafeBinderTy<'hir> {
    pub generic_params: &'hir [GenericParam<'hir>],
    pub inner_ty: &'hir Ty<'hir>,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct OpaqueTy<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub def_id: LocalDefId,
    pub bounds: GenericBounds<'hir>,
    pub origin: OpaqueTyOrigin<LocalDefId>,
    pub span: Span,
}

#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)]
pub enum PreciseCapturingArgKind<T, U> {
    Lifetime(T),
    /// Non-lifetime argument (type or const)
    Param(U),
}

pub type PreciseCapturingArg<'hir> =
    PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>;

impl PreciseCapturingArg<'_> {
    pub fn hir_id(self) -> HirId {
        match self {
            PreciseCapturingArg::Lifetime(lt) => lt.hir_id,
            PreciseCapturingArg::Param(param) => param.hir_id,
        }
    }

    pub fn name(self) -> Symbol {
        match self {
            PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
            PreciseCapturingArg::Param(param) => param.ident.name,
        }
    }
}

/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param
/// resolution to. Lifetimes don't have this problem, and for them, it's actually
/// kind of detrimental to use a custom node type versus just using [`Lifetime`],
/// since resolve_bound_vars operates on `Lifetime`s.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct PreciseCapturingNonLifetimeArg {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub ident: Ident,
    pub res: Res,
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[derive(HashStable_Generic, Encodable, Decodable)]
pub enum RpitContext {
    Trait,
    TraitImpl,
}

/// From whence the opaque type came.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[derive(HashStable_Generic, Encodable, Decodable)]
pub enum OpaqueTyOrigin<D> {
    /// `-> impl Trait`
    FnReturn {
        /// The defining function.
        parent: D,
        // Whether this is an RPITIT (return position impl trait in trait)
        in_trait_or_impl: Option<RpitContext>,
    },
    /// `async fn`
    AsyncFn {
        /// The defining function.
        parent: D,
        // Whether this is an AFIT (async fn in trait)
        in_trait_or_impl: Option<RpitContext>,
    },
    /// type aliases: `type Foo = impl Trait;`
    TyAlias {
        /// The type alias or associated type parent of the TAIT/ATPIT
        parent: D,
        /// associated types in impl blocks for traits.
        in_assoc_ty: bool,
    },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable_Generic)]
pub enum InferDelegationKind {
    Input(usize),
    Output,
}

/// The various kinds of types recognized by the compiler.
///
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// <https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html>
// SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
#[repr(u8, C)]
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum TyKind<'hir, Unambig = ()> {
    /// Actual type should be inherited from `DefId` signature
    InferDelegation(DefId, InferDelegationKind),
    /// A variable length slice (i.e., `[T]`).
    Slice(&'hir Ty<'hir>),
    /// A fixed length array (i.e., `[T; n]`).
    Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>),
    /// A raw pointer (i.e., `*const T` or `*mut T`).
    Ptr(MutTy<'hir>),
    /// A reference (i.e., `&'a T` or `&'a mut T`).
    Ref(&'hir Lifetime, MutTy<'hir>),
    /// A function pointer (e.g., `fn(usize) -> bool`).
    FnPtr(&'hir FnPtrTy<'hir>),
    /// An unsafe binder type (e.g. `unsafe<'a> Foo<'a>`).
    UnsafeBinder(&'hir UnsafeBinderTy<'hir>),
    /// The never type (`!`).
    Never,
    /// A tuple (`(A, B, C, D, ...)`).
    Tup(&'hir [Ty<'hir>]),
    /// A path to a type definition (`module::module::...::Type`), or an
    /// associated type (e.g., `<Vec<T> as Trait>::Type` or `<T>::Target`).
    ///
    /// Type parameters may be stored in each `PathSegment`.
    Path(QPath<'hir>),
    /// An opaque type definition itself. This is only used for `impl Trait`.
    OpaqueDef(&'hir OpaqueTy<'hir>),
    /// A trait ascription type, which is `impl Trait` within a local binding.
    TraitAscription(GenericBounds<'hir>),
    /// A trait object type `Bound1 + Bound2 + Bound3`
    /// where `Bound` is a trait or a lifetime.
    ///
    /// We use pointer tagging to represent a `&'hir Lifetime` and `TraitObjectSyntax` pair
    /// as otherwise this type being `repr(C)` would result in `TyKind` increasing in size.
    TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
    /// Unused for now.
    Typeof(&'hir AnonConst),
    /// Placeholder for a type that has failed to be defined.
    Err(rustc_span::ErrorGuaranteed),
    /// Pattern types (`pattern_type!(u32 is 1..)`)
    Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
    /// `TyKind::Infer` means the type should be inferred instead of it having been
    /// specified. This can appear anywhere in a type.
    ///
    /// This variant is not always used to represent inference types, sometimes
    /// [`GenericArg::Infer`] is used instead.
    Infer(Unambig),
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum InlineAsmOperand<'hir> {
    In {
        reg: InlineAsmRegOrRegClass,
        expr: &'hir Expr<'hir>,
    },
    Out {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        expr: Option<&'hir Expr<'hir>>,
    },
    InOut {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        expr: &'hir Expr<'hir>,
    },
    SplitInOut {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        in_expr: &'hir Expr<'hir>,
        out_expr: Option<&'hir Expr<'hir>>,
    },
    Const {
        anon_const: ConstBlock,
    },
    SymFn {
        expr: &'hir Expr<'hir>,
    },
    SymStatic {
        path: QPath<'hir>,
        def_id: DefId,
    },
    Label {
        block: &'hir Block<'hir>,
    },
}

impl<'hir> InlineAsmOperand<'hir> {
    pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
        match *self {
            Self::In { reg, .. }
            | Self::Out { reg, .. }
            | Self::InOut { reg, .. }
            | Self::SplitInOut { reg, .. } => Some(reg),
            Self::Const { .. }
            | Self::SymFn { .. }
            | Self::SymStatic { .. }
            | Self::Label { .. } => None,
        }
    }

    pub fn is_clobber(&self) -> bool {
        matches!(
            self,
            InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
        )
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct InlineAsm<'hir> {
    pub asm_macro: ast::AsmMacro,
    pub template: &'hir [InlineAsmTemplatePiece],
    pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)],
    pub operands: &'hir [(InlineAsmOperand<'hir>, Span)],
    pub options: InlineAsmOptions,
    pub line_spans: &'hir [Span],
}

impl InlineAsm<'_> {
    pub fn contains_label(&self) -> bool {
        self.operands.iter().any(|x| matches!(x.0, InlineAsmOperand::Label { .. }))
    }
}

/// Represents a parameter in a function header.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Param<'hir> {
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub pat: &'hir Pat<'hir>,
    pub ty_span: Span,
    pub span: Span,
}

/// Represents the header (not the body) of a function declaration.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct FnDecl<'hir> {
    /// The types of the function's parameters.
    ///
    /// Additional argument data is stored in the function's [body](Body::params).
    pub inputs: &'hir [Ty<'hir>],
    pub output: FnRetTy<'hir>,
    pub c_variadic: bool,
    /// Does the function have an implicit self?
    pub implicit_self: ImplicitSelfKind,
    /// Is lifetime elision allowed.
    pub lifetime_elision_allowed: bool,
}

impl<'hir> FnDecl<'hir> {
    pub fn opt_delegation_sig_id(&self) -> Option<DefId> {
        if let FnRetTy::Return(ty) = self.output
            && let TyKind::InferDelegation(sig_id, _) = ty.kind
        {
            return Some(sig_id);
        }
        None
    }
}

/// Represents what type of implicit self a function has, if any.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum ImplicitSelfKind {
    /// Represents a `fn x(self);`.
    Imm,
    /// Represents a `fn x(mut self);`.
    Mut,
    /// Represents a `fn x(&self);`.
    RefImm,
    /// Represents a `fn x(&mut self);`.
    RefMut,
    /// Represents when a function does not have a self argument or
    /// when a function has a `self: X` argument.
    None,
}

impl ImplicitSelfKind {
    /// Does this represent an implicit self?
    pub fn has_implicit_self(&self) -> bool {
        !matches!(*self, ImplicitSelfKind::None)
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum IsAsync {
    Async(Span),
    NotAsync,
}

impl IsAsync {
    pub fn is_async(self) -> bool {
        matches!(self, IsAsync::Async(_))
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum Defaultness {
    Default { has_value: bool },
    Final,
}

impl Defaultness {
    pub fn has_value(&self) -> bool {
        match *self {
            Defaultness::Default { has_value } => has_value,
            Defaultness::Final => true,
        }
    }

    pub fn is_final(&self) -> bool {
        *self == Defaultness::Final
    }

    pub fn is_default(&self) -> bool {
        matches!(*self, Defaultness::Default { .. })
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum FnRetTy<'hir> {
    /// Return type is not specified.
    ///
    /// Functions default to `()` and
    /// closures default to inference. Span points to where return
    /// type would be inserted.
    DefaultReturn(Span),
    /// Everything else.
    Return(&'hir Ty<'hir>),
}

impl<'hir> FnRetTy<'hir> {
    #[inline]
    pub fn span(&self) -> Span {
        match *self {
            Self::DefaultReturn(span) => span,
            Self::Return(ref ty) => ty.span,
        }
    }

    pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
        if let Self::Return(ty) = self
            && ty.is_suggestable_infer_ty()
        {
            return Some(*ty);
        }
        None
    }
}

/// Represents `for<...>` binder before a closure
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum ClosureBinder {
    /// Binder is not specified.
    Default,
    /// Binder is specified.
    ///
    /// Span points to the whole `for<...>`.
    For { span: Span },
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Mod<'hir> {
    pub spans: ModSpans,
    pub item_ids: &'hir [ItemId],
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub struct ModSpans {
    /// A span from the first token past `{` to the last token until `}`.
    /// For `mod foo;`, the inner span ranges from the first token
    /// to the last token in the external file.
    pub inner_span: Span,
    pub inject_use_span: Span,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct EnumDef<'hir> {
    pub variants: &'hir [Variant<'hir>],
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Variant<'hir> {
    /// Name of the variant.
    pub ident: Ident,
    /// Id of the variant (not the constructor, see `VariantData::ctor_hir_id()`).
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub def_id: LocalDefId,
    /// Fields and constructor id of the variant.
    pub data: VariantData<'hir>,
    /// Explicit discriminant (e.g., `Foo = 1`).
    pub disr_expr: Option<&'hir AnonConst>,
    /// Span
    pub span: Span,
}

#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
pub enum UseKind {
    /// One import, e.g., `use foo::bar` or `use foo::bar as baz`.
    /// Also produced for each element of a list `use`, e.g.
    /// `use foo::{a, b}` lowers to `use foo::a; use foo::b;`.
    ///
    /// The identifier is the name defined by the import. E.g. for `use
    /// foo::bar` it is `bar`, for `use foo::bar as baz` it is `baz`.
    Single(Ident),

    /// Glob import, e.g., `use foo::*`.
    Glob,

    /// Degenerate list import, e.g., `use foo::{a, b}` produces
    /// an additional `use foo::{}` for performing checks such as
    /// unstable feature gating. May be removed in the future.
    ListStem,
}

/// References to traits in impls.
///
/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all
/// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
/// trait being referred to but just a unique `HirId` that serves as a key
/// within the resolution map.
#[derive(Clone, Debug, Copy, HashStable_Generic)]
pub struct TraitRef<'hir> {
    pub path: &'hir Path<'hir>,
    // Don't hash the `ref_id`. It is tracked via the thing it is used to access.
    #[stable_hasher(ignore)]
    pub hir_ref_id: HirId,
}

impl TraitRef<'_> {
    /// Gets the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias.
    pub fn trait_def_id(&self) -> Option<DefId> {
        match self.path.res {
            Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did),
            Res::Err => None,
            res => panic!("{res:?} did not resolve to a trait or trait alias"),
        }
    }
}

#[derive(Clone, Debug, Copy, HashStable_Generic)]
pub struct PolyTraitRef<'hir> {
    /// The `'a` in `for<'a> Foo<&'a T>`.
    pub bound_generic_params: &'hir [GenericParam<'hir>],

    /// The constness and polarity of the trait ref.
    ///
    /// The `async` modifier is lowered directly into a different trait for now.
    pub modifiers: TraitBoundModifiers,

    /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`.
    pub trait_ref: TraitRef<'hir>,

    pub span: Span,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct FieldDef<'hir> {
    pub span: Span,
    pub vis_span: Span,
    pub ident: Ident,
    #[stable_hasher(ignore)]
    pub hir_id: HirId,
    pub def_id: LocalDefId,
    pub ty: &'hir Ty<'hir>,
    pub safety: Safety,
    pub default: Option<&'hir AnonConst>,
}

impl FieldDef<'_> {
    // Still necessary in couple of places
    pub fn is_positional(&self) -> bool {
        self.ident.as_str().as_bytes()[0].is_ascii_digit()
    }
}

/// Fields and constructor IDs of enum variants and structs.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum VariantData<'hir> {
    /// A struct variant.
    ///
    /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
    Struct { fields: &'hir [FieldDef<'hir>], recovered: ast::Recovered },
    /// A tuple variant.
    ///
    /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
    Tuple(&'hir [FieldDef<'hir>], #[stable_hasher(ignore)] HirId, LocalDefId),
    /// A unit variant.
    ///
    /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
    Unit(#[stable_hasher(ignore)] HirId, LocalDefId),
}

impl<'hir> VariantData<'hir> {
    /// Return the fields of this variant.
    pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
        match *self {
            VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
            _ => &[],
        }
    }

    pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
        match *self {
            VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
            VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
            VariantData::Struct { .. } => None,
        }
    }

    #[inline]
    pub fn ctor_kind(&self) -> Option<CtorKind> {
        self.ctor().map(|(kind, ..)| kind)
    }

    /// Return the `HirId` of this variant's constructor, if it has one.
    #[inline]
    pub fn ctor_hir_id(&self) -> Option<HirId> {
        self.ctor().map(|(_, hir_id, _)| hir_id)
    }

    /// Return the `LocalDefId` of this variant's constructor, if it has one.
    #[inline]
    pub fn ctor_def_id(&self) -> Option<LocalDefId> {
        self.ctor().map(|(.., def_id)| def_id)
    }
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
pub struct ItemId {
    pub owner_id: OwnerId,
}

impl ItemId {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }
}

/// An item
///
/// For more details, see the [rust lang reference].
/// Note that the reference does not document nightly-only features.
/// There may be also slight differences in the names and representation of AST nodes between
/// the compiler and the reference.
///
/// [rust lang reference]: https://doc.rust-lang.org/reference/items.html
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Item<'hir> {
    pub owner_id: OwnerId,
    pub kind: ItemKind<'hir>,
    pub span: Span,
    pub vis_span: Span,
    pub has_delayed_lints: bool,
}

impl<'hir> Item<'hir> {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }

    pub fn item_id(&self) -> ItemId {
        ItemId { owner_id: self.owner_id }
    }

    /// Check if this is an [`ItemKind::Enum`], [`ItemKind::Struct`] or
    /// [`ItemKind::Union`].
    pub fn is_adt(&self) -> bool {
        matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
    }

    /// Check if this is an [`ItemKind::Struct`] or [`ItemKind::Union`].
    pub fn is_struct_or_union(&self) -> bool {
        matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
    }

    expect_methods_self_kind! {
        expect_extern_crate, (Option<Symbol>, Ident),
            ItemKind::ExternCrate(s, ident), (*s, *ident);

        expect_use, (&'hir UsePath<'hir>, UseKind), ItemKind::Use(p, uk), (p, *uk);

        expect_static, (Mutability, Ident, &'hir Ty<'hir>, BodyId),
            ItemKind::Static(mutbl, ident, ty, body), (*mutbl, *ident, ty, *body);

        expect_const, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>),
            ItemKind::Const(ident, generics, ty, rhs), (*ident, generics, ty, *rhs);

        expect_fn, (Ident, &FnSig<'hir>, &'hir Generics<'hir>, BodyId),
            ItemKind::Fn { ident, sig, generics, body, .. }, (*ident, sig, generics, *body);

        expect_macro, (Ident, &ast::MacroDef, MacroKinds),
            ItemKind::Macro(ident, def, mk), (*ident, def, *mk);

        expect_mod, (Ident, &'hir Mod<'hir>), ItemKind::Mod(ident, m), (*ident, m);

        expect_foreign_mod, (ExternAbi, &'hir [ForeignItemId]),
            ItemKind::ForeignMod { abi, items }, (*abi, items);

        expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;

        expect_ty_alias, (Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
            ItemKind::TyAlias(ident, generics, ty), (*ident, generics, ty);

        expect_enum, (Ident, &'hir Generics<'hir>, &EnumDef<'hir>),
            ItemKind::Enum(ident, generics, def), (*ident, generics, def);

        expect_struct, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
            ItemKind::Struct(ident, generics, data), (*ident, generics, data);

        expect_union, (Ident, &'hir Generics<'hir>, &VariantData<'hir>),
            ItemKind::Union(ident, generics, data), (*ident, generics, data);

        expect_trait,
            (
                Constness,
                IsAuto,
                Safety,
                Ident,
                &'hir Generics<'hir>,
                GenericBounds<'hir>,
                &'hir [TraitItemId]
            ),
            ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
            (*constness, *is_auto, *safety, *ident, generics, bounds, items);

        expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
            ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds);

        expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum Safety {
    Unsafe,
    Safe,
}

impl Safety {
    pub fn prefix_str(self) -> &'static str {
        match self {
            Self::Unsafe => "unsafe ",
            Self::Safe => "",
        }
    }

    #[inline]
    pub fn is_unsafe(self) -> bool {
        !self.is_safe()
    }

    #[inline]
    pub fn is_safe(self) -> bool {
        match self {
            Self::Unsafe => false,
            Self::Safe => true,
        }
    }
}

impl fmt::Display for Safety {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match *self {
            Self::Unsafe => "unsafe",
            Self::Safe => "safe",
        })
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum Constness {
    Const,
    NotConst,
}

impl fmt::Display for Constness {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match *self {
            Self::Const => "const",
            Self::NotConst => "non-const",
        })
    }
}

/// The actual safety specified in syntax. We may treat
/// its safety different within the type system to create a
/// "sound by default" system that needs checking this enum
/// explicitly to allow unsafe operations.
#[derive(Copy, Clone, Debug, HashStable_Generic, PartialEq, Eq)]
pub enum HeaderSafety {
    /// A safe function annotated with `#[target_features]`.
    /// The type system treats this function as an unsafe function,
    /// but safety checking will check this enum to treat it as safe
    /// and allowing calling other safe target feature functions with
    /// the same features without requiring an additional unsafe block.
    SafeTargetFeatures,
    Normal(Safety),
}

impl From<Safety> for HeaderSafety {
    fn from(v: Safety) -> Self {
        Self::Normal(v)
    }
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub struct FnHeader {
    pub safety: HeaderSafety,
    pub constness: Constness,
    pub asyncness: IsAsync,
    pub abi: ExternAbi,
}

impl FnHeader {
    pub fn is_async(&self) -> bool {
        matches!(self.asyncness, IsAsync::Async(_))
    }

    pub fn is_const(&self) -> bool {
        matches!(self.constness, Constness::Const)
    }

    pub fn is_unsafe(&self) -> bool {
        self.safety().is_unsafe()
    }

    pub fn is_safe(&self) -> bool {
        self.safety().is_safe()
    }

    pub fn safety(&self) -> Safety {
        match self.safety {
            HeaderSafety::SafeTargetFeatures => Safety::Unsafe,
            HeaderSafety::Normal(safety) => safety,
        }
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ItemKind<'hir> {
    /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
    ///
    /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
    ExternCrate(Option<Symbol>, Ident),

    /// `use foo::bar::*;` or `use foo::bar::baz as quux;`
    ///
    /// or just
    ///
    /// `use foo::bar::baz;` (with `as baz` implicitly on the right).
    Use(&'hir UsePath<'hir>, UseKind),

    /// A `static` item.
    Static(Mutability, Ident, &'hir Ty<'hir>, BodyId),
    /// A `const` item.
    Const(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>, ConstItemRhs<'hir>),
    /// A function declaration.
    Fn {
        sig: FnSig<'hir>,
        ident: Ident,
        generics: &'hir Generics<'hir>,
        body: BodyId,
        /// Whether this function actually has a body.
        /// For functions without a body, `body` is synthesized (to avoid ICEs all over the
        /// compiler), but that code should never be translated.
        has_body: bool,
    },
    /// A MBE macro definition (`macro_rules!` or `macro`).
    Macro(Ident, &'hir ast::MacroDef, MacroKinds),
    /// A module.
    Mod(Ident, &'hir Mod<'hir>),
    /// An external module, e.g. `extern { .. }`.
    ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemId] },
    /// Module-level inline assembly (from `global_asm!`).
    GlobalAsm {
        asm: &'hir InlineAsm<'hir>,
        /// A fake body which stores typeck results for the global asm's sym_fn
        /// operands, which are represented as path expressions. This body contains
        /// a single [`ExprKind::InlineAsm`] which points to the asm in the field
        /// above, and which is typechecked like a inline asm expr just for the
        /// typeck results.
        fake_body: BodyId,
    },
    /// A type alias, e.g., `type Foo = Bar<u8>`.
    TyAlias(Ident, &'hir Generics<'hir>, &'hir Ty<'hir>),
    /// An enum definition, e.g., `enum Foo<A, B> { C<A>, D<B> }`.
    Enum(Ident, &'hir Generics<'hir>, EnumDef<'hir>),
    /// A struct definition, e.g., `struct Foo<A> {x: A}`.
    Struct(Ident, &'hir Generics<'hir>, VariantData<'hir>),
    /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
    Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
    /// A trait definition.
    Trait(
        Constness,
        IsAuto,
        Safety,
        Ident,
        &'hir Generics<'hir>,
        GenericBounds<'hir>,
        &'hir [TraitItemId],
    ),
    /// A trait alias.
    TraitAlias(Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),

    /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
    Impl(Impl<'hir>),
}

/// Represents an impl block declaration.
///
/// E.g., `impl $Type { .. }` or `impl $Trait for $Type { .. }`
/// Refer to [`ImplItem`] for an associated item within an impl block.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Impl<'hir> {
    pub generics: &'hir Generics<'hir>,
    pub of_trait: Option<&'hir TraitImplHeader<'hir>>,
    pub self_ty: &'hir Ty<'hir>,
    pub items: &'hir [ImplItemId],
    pub constness: Constness,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TraitImplHeader<'hir> {
    pub safety: Safety,
    pub polarity: ImplPolarity,
    pub defaultness: Defaultness,
    // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
    // decoding as `Span`s cannot be decoded when a `Session` is not available.
    pub defaultness_span: Option<Span>,
    pub trait_ref: TraitRef<'hir>,
}

impl ItemKind<'_> {
    pub fn ident(&self) -> Option<Ident> {
        match *self {
            ItemKind::ExternCrate(_, ident)
            | ItemKind::Use(_, UseKind::Single(ident))
            | ItemKind::Static(_, ident, ..)
            | ItemKind::Const(ident, ..)
            | ItemKind::Fn { ident, .. }
            | ItemKind::Macro(ident, ..)
            | ItemKind::Mod(ident, ..)
            | ItemKind::TyAlias(ident, ..)
            | ItemKind::Enum(ident, ..)
            | ItemKind::Struct(ident, ..)
            | ItemKind::Union(ident, ..)
            | ItemKind::Trait(_, _, _, ident, ..)
            | ItemKind::TraitAlias(_, ident, ..) => Some(ident),

            ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
            | ItemKind::ForeignMod { .. }
            | ItemKind::GlobalAsm { .. }
            | ItemKind::Impl(_) => None,
        }
    }

    pub fn generics(&self) -> Option<&Generics<'_>> {
        Some(match self {
            ItemKind::Fn { generics, .. }
            | ItemKind::TyAlias(_, generics, _)
            | ItemKind::Const(_, generics, _, _)
            | ItemKind::Enum(_, generics, _)
            | ItemKind::Struct(_, generics, _)
            | ItemKind::Union(_, generics, _)
            | ItemKind::Trait(_, _, _, _, generics, _, _)
            | ItemKind::TraitAlias(_, _, generics, _)
            | ItemKind::Impl(Impl { generics, .. }) => generics,
            _ => return None,
        })
    }
}

// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct ForeignItemId {
    pub owner_id: OwnerId,
}

impl ForeignItemId {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ForeignItem<'hir> {
    pub ident: Ident,
    pub kind: ForeignItemKind<'hir>,
    pub owner_id: OwnerId,
    pub span: Span,
    pub vis_span: Span,
    pub has_delayed_lints: bool,
}

impl ForeignItem<'_> {
    #[inline]
    pub fn hir_id(&self) -> HirId {
        // Items are always HIR owners.
        HirId::make_owner(self.owner_id.def_id)
    }

    pub fn foreign_item_id(&self) -> ForeignItemId {
        ForeignItemId { owner_id: self.owner_id }
    }
}

/// An item within an `extern` block.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ForeignItemKind<'hir> {
    /// A foreign function.
    ///
    /// All argument idents are actually always present (i.e. `Some`), but
    /// `&[Option<Ident>]` is used because of code paths shared with `TraitFn`
    /// and `FnPtrTy`. The sharing is due to all of these cases not allowing
    /// arbitrary patterns for parameters.
    Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
    /// A foreign static item (`static ext: u8`).
    Static(&'hir Ty<'hir>, Mutability, Safety),
    /// A foreign type.
    Type,
}

/// A variable captured by a closure.
#[derive(Debug, Copy, Clone, HashStable_Generic)]
pub struct Upvar {
    /// First span where it is accessed (there can be multiple).
    pub span: Span,
}

// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
// has length > 0 if the trait is found through an chain of imports, starting with the
// import/use statement in the scope where the trait is used.
#[derive(Debug, Clone, HashStable_Generic)]
pub struct TraitCandidate {
    pub def_id: DefId,
    pub import_ids: SmallVec<[LocalDefId; 1]>,
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum OwnerNode<'hir> {
    Item(&'hir Item<'hir>),
    ForeignItem(&'hir ForeignItem<'hir>),
    TraitItem(&'hir TraitItem<'hir>),
    ImplItem(&'hir ImplItem<'hir>),
    Crate(&'hir Mod<'hir>),
    Synthetic,
}

impl<'hir> OwnerNode<'hir> {
    pub fn span(&self) -> Span {
        match self {
            OwnerNode::Item(Item { span, .. })
            | OwnerNode::ForeignItem(ForeignItem { span, .. })
            | OwnerNode::ImplItem(ImplItem { span, .. })
            | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
            OwnerNode::Synthetic => unreachable!(),
        }
    }

    pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
        match self {
            OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
            | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
            | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
            | OwnerNode::ForeignItem(ForeignItem {
                kind: ForeignItemKind::Fn(fn_sig, _, _), ..
            }) => Some(fn_sig),
            _ => None,
        }
    }

    pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
        match self {
            OwnerNode::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
            | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
            | OwnerNode::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
            | OwnerNode::ForeignItem(ForeignItem {
                kind: ForeignItemKind::Fn(fn_sig, _, _), ..
            }) => Some(fn_sig.decl),
            _ => None,
        }
    }

    pub fn body_id(&self) -> Option<BodyId> {
        match self {
            OwnerNode::Item(Item {
                kind:
                    ItemKind::Static(_, _, _, body)
                    | ItemKind::Const(.., ConstItemRhs::Body(body))
                    | ItemKind::Fn { body, .. },
                ..
            })
            | OwnerNode::TraitItem(TraitItem {
                kind:
                    TraitItemKind::Fn(_, TraitFn::Provided(body))
                    | TraitItemKind::Const(_, Some(ConstItemRhs::Body(body))),
                ..
            })
            | OwnerNode::ImplItem(ImplItem {
                kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, ConstItemRhs::Body(body)),
                ..
            }) => Some(*body),
            _ => None,
        }
    }

    pub fn generics(self) -> Option<&'hir Generics<'hir>> {
        Node::generics(self.into())
    }

    pub fn def_id(self) -> OwnerId {
        match self {
            OwnerNode::Item(Item { owner_id, .. })
            | OwnerNode::TraitItem(TraitItem { owner_id, .. })
            | OwnerNode::ImplItem(ImplItem { owner_id, .. })
            | OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
            OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
            OwnerNode::Synthetic => unreachable!(),
        }
    }

    /// Check if node is an impl block.
    pub fn is_impl_block(&self) -> bool {
        matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
    }

    expect_methods_self! {
        expect_item,         &'hir Item<'hir>,        OwnerNode::Item(n),        n;
        expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
        expect_impl_item,    &'hir ImplItem<'hir>,    OwnerNode::ImplItem(n),    n;
        expect_trait_item,   &'hir TraitItem<'hir>,   OwnerNode::TraitItem(n),   n;
    }
}

impl<'hir> From<&'hir Item<'hir>> for OwnerNode<'hir> {
    fn from(val: &'hir Item<'hir>) -> Self {
        OwnerNode::Item(val)
    }
}

impl<'hir> From<&'hir ForeignItem<'hir>> for OwnerNode<'hir> {
    fn from(val: &'hir ForeignItem<'hir>) -> Self {
        OwnerNode::ForeignItem(val)
    }
}

impl<'hir> From<&'hir ImplItem<'hir>> for OwnerNode<'hir> {
    fn from(val: &'hir ImplItem<'hir>) -> Self {
        OwnerNode::ImplItem(val)
    }
}

impl<'hir> From<&'hir TraitItem<'hir>> for OwnerNode<'hir> {
    fn from(val: &'hir TraitItem<'hir>) -> Self {
        OwnerNode::TraitItem(val)
    }
}

impl<'hir> From<OwnerNode<'hir>> for Node<'hir> {
    fn from(val: OwnerNode<'hir>) -> Self {
        match val {
            OwnerNode::Item(n) => Node::Item(n),
            OwnerNode::ForeignItem(n) => Node::ForeignItem(n),
            OwnerNode::ImplItem(n) => Node::ImplItem(n),
            OwnerNode::TraitItem(n) => Node::TraitItem(n),
            OwnerNode::Crate(n) => Node::Crate(n),
            OwnerNode::Synthetic => Node::Synthetic,
        }
    }
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum Node<'hir> {
    Param(&'hir Param<'hir>),
    Item(&'hir Item<'hir>),
    ForeignItem(&'hir ForeignItem<'hir>),
    TraitItem(&'hir TraitItem<'hir>),
    ImplItem(&'hir ImplItem<'hir>),
    Variant(&'hir Variant<'hir>),
    Field(&'hir FieldDef<'hir>),
    AnonConst(&'hir AnonConst),
    ConstBlock(&'hir ConstBlock),
    ConstArg(&'hir ConstArg<'hir>),
    Expr(&'hir Expr<'hir>),
    ExprField(&'hir ExprField<'hir>),
    Stmt(&'hir Stmt<'hir>),
    PathSegment(&'hir PathSegment<'hir>),
    Ty(&'hir Ty<'hir>),
    AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
    TraitRef(&'hir TraitRef<'hir>),
    OpaqueTy(&'hir OpaqueTy<'hir>),
    TyPat(&'hir TyPat<'hir>),
    Pat(&'hir Pat<'hir>),
    PatField(&'hir PatField<'hir>),
    /// Needed as its own node with its own HirId for tracking
    /// the unadjusted type of literals within patterns
    /// (e.g. byte str literals not being of slice type).
    PatExpr(&'hir PatExpr<'hir>),
    Arm(&'hir Arm<'hir>),
    Block(&'hir Block<'hir>),
    LetStmt(&'hir LetStmt<'hir>),
    /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
    /// with synthesized constructors.
    Ctor(&'hir VariantData<'hir>),
    Lifetime(&'hir Lifetime),
    GenericParam(&'hir GenericParam<'hir>),
    Crate(&'hir Mod<'hir>),
    Infer(&'hir InferArg),
    WherePredicate(&'hir WherePredicate<'hir>),
    PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
    // Created by query feeding
    Synthetic,
    Err(Span),
}

impl<'hir> Node<'hir> {
    /// Get the identifier of this `Node`, if applicable.
    ///
    /// # Edge cases
    ///
    /// Calling `.ident()` on a [`Node::Ctor`] will return `None`
    /// because `Ctor`s do not have identifiers themselves.
    /// Instead, call `.ident()` on the parent struct/variant, like so:
    ///
    /// ```ignore (illustrative)
    /// ctor
    ///     .ctor_hir_id()
    ///     .map(|ctor_id| tcx.parent_hir_node(ctor_id))
    ///     .and_then(|parent| parent.ident())
    /// ```
    pub fn ident(&self) -> Option<Ident> {
        match self {
            Node::Item(item) => item.kind.ident(),
            Node::TraitItem(TraitItem { ident, .. })
            | Node::ImplItem(ImplItem { ident, .. })
            | Node::ForeignItem(ForeignItem { ident, .. })
            | Node::Field(FieldDef { ident, .. })
            | Node::Variant(Variant { ident, .. })
            | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
            Node::Lifetime(lt) => Some(lt.ident),
            Node::GenericParam(p) => Some(p.name.ident()),
            Node::AssocItemConstraint(c) => Some(c.ident),
            Node::PatField(f) => Some(f.ident),
            Node::ExprField(f) => Some(f.ident),
            Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
            Node::Param(..)
            | Node::AnonConst(..)
            | Node::ConstBlock(..)
            | Node::ConstArg(..)
            | Node::Expr(..)
            | Node::Stmt(..)
            | Node::Block(..)
            | Node::Ctor(..)
            | Node::Pat(..)
            | Node::TyPat(..)
            | Node::PatExpr(..)
            | Node::Arm(..)
            | Node::LetStmt(..)
            | Node::Crate(..)
            | Node::Ty(..)
            | Node::TraitRef(..)
            | Node::OpaqueTy(..)
            | Node::Infer(..)
            | Node::WherePredicate(..)
            | Node::Synthetic
            | Node::Err(..) => None,
        }
    }

    pub fn fn_decl(self) -> Option<&'hir FnDecl<'hir>> {
        match self {
            Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
            | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
            | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
            | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
                Some(fn_sig.decl)
            }
            Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. }) => {
                Some(fn_decl)
            }
            _ => None,
        }
    }

    /// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`.
    pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
        if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
            && let Some(of_trait) = impl_block.of_trait
            && let Some(trait_id) = of_trait.trait_ref.trait_def_id()
            && trait_id == trait_def_id
        {
            Some(impl_block)
        } else {
            None
        }
    }

    pub fn fn_sig(self) -> Option<&'hir FnSig<'hir>> {
        match self {
            Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. })
            | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
            | Node::Item(Item { kind: ItemKind::Fn { sig: fn_sig, .. }, .. })
            | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_sig, _, _), .. }) => {
                Some(fn_sig)
            }
            _ => None,
        }
    }

    /// Get the type for constants, assoc types, type aliases and statics.
    pub fn ty(self) -> Option<&'hir Ty<'hir>> {
        match self {
            Node::Item(it) => match it.kind {
                ItemKind::TyAlias(_, _, ty)
                | ItemKind::Static(_, _, ty, _)
                | ItemKind::Const(_, _, ty, _) => Some(ty),
                ItemKind::Impl(impl_item) => Some(&impl_item.self_ty),
                _ => None,
            },
            Node::TraitItem(it) => match it.kind {
                TraitItemKind::Const(ty, _) => Some(ty),
                TraitItemKind::Type(_, ty) => ty,
                _ => None,
            },
            Node::ImplItem(it) => match it.kind {
                ImplItemKind::Const(ty, _) => Some(ty),
                ImplItemKind::Type(ty) => Some(ty),
                _ => None,
            },
            Node::ForeignItem(it) => match it.kind {
                ForeignItemKind::Static(ty, ..) => Some(ty),
                _ => None,
            },
            Node::GenericParam(param) => match param.kind {
                GenericParamKind::Lifetime { .. } => None,
                GenericParamKind::Type { default, .. } => default,
                GenericParamKind::Const { ty, .. } => Some(ty),
            },
            _ => None,
        }
    }

    pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
        match self {
            Node::Item(Item { kind: ItemKind::TyAlias(_, _, ty), .. }) => Some(ty),
            _ => None,
        }
    }

    #[inline]
    pub fn associated_body(&self) -> Option<(LocalDefId, BodyId)> {
        match self {
            Node::Item(Item {
                owner_id,
                kind:
                    ItemKind::Const(.., ConstItemRhs::Body(body))
                    | ItemKind::Static(.., body)
                    | ItemKind::Fn { body, .. },
                ..
            })
            | Node::TraitItem(TraitItem {
                owner_id,
                kind:
                    TraitItemKind::Const(.., Some(ConstItemRhs::Body(body)))
                    | TraitItemKind::Fn(_, TraitFn::Provided(body)),
                ..
            })
            | Node::ImplItem(ImplItem {
                owner_id,
                kind: ImplItemKind::Const(.., ConstItemRhs::Body(body)) | ImplItemKind::Fn(_, body),
                ..
            }) => Some((owner_id.def_id, *body)),

            Node::Item(Item {
                owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
            }) => Some((owner_id.def_id, *fake_body)),

            Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
                Some((*def_id, *body))
            }

            Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
            Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),

            _ => None,
        }
    }

    pub fn body_id(&self) -> Option<BodyId> {
        Some(self.associated_body()?.1)
    }

    pub fn generics(self) -> Option<&'hir Generics<'hir>> {
        match self {
            Node::ForeignItem(ForeignItem {
                kind: ForeignItemKind::Fn(_, _, generics), ..
            })
            | Node::TraitItem(TraitItem { generics, .. })
            | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
            Node::Item(item) => item.kind.generics(),
            _ => None,
        }
    }

    pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
        match self {
            Node::Item(i) => Some(OwnerNode::Item(i)),
            Node::ForeignItem(i) => Some(OwnerNode::ForeignItem(i)),
            Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
            Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
            Node::Crate(i) => Some(OwnerNode::Crate(i)),
            Node::Synthetic => Some(OwnerNode::Synthetic),
            _ => None,
        }
    }

    pub fn fn_kind(self) -> Option<FnKind<'hir>> {
        match self {
            Node::Item(i) => match i.kind {
                ItemKind::Fn { ident, sig, generics, .. } => {
                    Some(FnKind::ItemFn(ident, generics, sig.header))
                }
                _ => None,
            },
            Node::TraitItem(ti) => match ti.kind {
                TraitItemKind::Fn(ref sig, _) => Some(FnKind::Method(ti.ident, sig)),
                _ => None,
            },
            Node::ImplItem(ii) => match ii.kind {
                ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig)),
                _ => None,
            },
            Node::Expr(e) => match e.kind {
                ExprKind::Closure { .. } => Some(FnKind::Closure),
                _ => None,
            },
            _ => None,
        }
    }

    expect_methods_self! {
        expect_param,         &'hir Param<'hir>,        Node::Param(n),        n;
        expect_item,          &'hir Item<'hir>,         Node::Item(n),         n;
        expect_foreign_item,  &'hir ForeignItem<'hir>,  Node::ForeignItem(n),  n;
        expect_trait_item,    &'hir TraitItem<'hir>,    Node::TraitItem(n),    n;
        expect_impl_item,     &'hir ImplItem<'hir>,     Node::ImplItem(n),     n;
        expect_variant,       &'hir Variant<'hir>,      Node::Variant(n),      n;
        expect_field,         &'hir FieldDef<'hir>,     Node::Field(n),        n;
        expect_anon_const,    &'hir AnonConst,          Node::AnonConst(n),    n;
        expect_inline_const,  &'hir ConstBlock,         Node::ConstBlock(n),   n;
        expect_expr,          &'hir Expr<'hir>,         Node::Expr(n),         n;
        expect_expr_field,    &'hir ExprField<'hir>,    Node::ExprField(n),    n;
        expect_stmt,          &'hir Stmt<'hir>,         Node::Stmt(n),         n;
        expect_path_segment,  &'hir PathSegment<'hir>,  Node::PathSegment(n),  n;
        expect_ty,            &'hir Ty<'hir>,           Node::Ty(n),           n;
        expect_assoc_item_constraint,  &'hir AssocItemConstraint<'hir>,  Node::AssocItemConstraint(n),  n;
        expect_trait_ref,     &'hir TraitRef<'hir>,     Node::TraitRef(n),     n;
        expect_opaque_ty,     &'hir OpaqueTy<'hir>,     Node::OpaqueTy(n),     n;
        expect_pat,           &'hir Pat<'hir>,          Node::Pat(n),          n;
        expect_pat_field,     &'hir PatField<'hir>,     Node::PatField(n),     n;
        expect_arm,           &'hir Arm<'hir>,          Node::Arm(n),          n;
        expect_block,         &'hir Block<'hir>,        Node::Block(n),        n;
        expect_let_stmt,      &'hir LetStmt<'hir>,      Node::LetStmt(n),      n;
        expect_ctor,          &'hir VariantData<'hir>,  Node::Ctor(n),         n;
        expect_lifetime,      &'hir Lifetime,           Node::Lifetime(n),     n;
        expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
        expect_crate,         &'hir Mod<'hir>,          Node::Crate(n),        n;
        expect_infer,         &'hir InferArg,           Node::Infer(n),        n;
        expect_closure,       &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
    }
}

// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(target_pointer_width = "64")]
mod size_asserts {
    use rustc_data_structures::static_assert_size;

    use super::*;
    // tidy-alphabetical-start
    static_assert_size!(Block<'_>, 48);
    static_assert_size!(Body<'_>, 24);
    static_assert_size!(Expr<'_>, 64);
    static_assert_size!(ExprKind<'_>, 48);
    static_assert_size!(FnDecl<'_>, 40);
    static_assert_size!(ForeignItem<'_>, 96);
    static_assert_size!(ForeignItemKind<'_>, 56);
    static_assert_size!(GenericArg<'_>, 16);
    static_assert_size!(GenericBound<'_>, 64);
    static_assert_size!(Generics<'_>, 56);
    static_assert_size!(Impl<'_>, 48);
    static_assert_size!(ImplItem<'_>, 88);
    static_assert_size!(ImplItemKind<'_>, 40);
    static_assert_size!(Item<'_>, 88);
    static_assert_size!(ItemKind<'_>, 64);
    static_assert_size!(LetStmt<'_>, 64);
    static_assert_size!(Param<'_>, 32);
    static_assert_size!(Pat<'_>, 80);
    static_assert_size!(PatKind<'_>, 56);
    static_assert_size!(Path<'_>, 40);
    static_assert_size!(PathSegment<'_>, 48);
    static_assert_size!(QPath<'_>, 24);
    static_assert_size!(Res, 12);
    static_assert_size!(Stmt<'_>, 32);
    static_assert_size!(StmtKind<'_>, 16);
    static_assert_size!(TraitImplHeader<'_>, 48);
    static_assert_size!(TraitItem<'_>, 88);
    static_assert_size!(TraitItemKind<'_>, 48);
    static_assert_size!(Ty<'_>, 48);
    static_assert_size!(TyKind<'_>, 32);
    // tidy-alphabetical-end
}

#[cfg(test)]
mod tests;
