//! The Rust abstract syntax tree module.
//!
//! This module contains common structures forming the language AST.
//! Two main entities in the module are [`Item`] (which represents an AST element with
//! additional metadata), and [`ItemKind`] (which represents a concrete type and contains
//! information specific to the type of the item).
//!
//! Other module items worth mentioning:
//! - [`Ty`] and [`TyKind`]: A parsed Rust type.
//! - [`Expr`] and [`ExprKind`]: A parsed Rust expression.
//! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions.
//! - [`Stmt`] and [`StmtKind`]: An executable action that does not return a value.
//! - [`FnDecl`], [`FnHeader`] and [`Param`]: Metadata associated with a function declaration.
//! - [`Generics`], [`GenericParam`], [`WhereClause`]: Metadata associated with generic parameters.
//! - [`EnumDef`] and [`Variant`]: Enum declaration.
//! - [`MetaItemLit`] and [`LitKind`]: Literal expressions.
//! - [`MacroDef`], [`MacStmtStyle`], [`MacCall`]: Macro definition and invocation.
//! - [`Attribute`]: Metadata associated with item.
//! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators.

use std::borrow::{Borrow, Cow};
use std::{cmp, fmt};

pub use GenericArgs::*;
pub use UnsafeSource::*;
pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::tagged_ptr::Tag;
use rustc_macros::{Decodable, Encodable, HashStable_Generic, Walkable};
pub use rustc_span::AttrId;
use rustc_span::source_map::{Spanned, respan};
use rustc_span::{ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
use thin_vec::{ThinVec, thin_vec};

pub use crate::format::*;
use crate::token::{self, CommentKind, Delimiter};
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
use crate::util::parser::{ExprPrecedence, Fixity};
use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt};

/// A "Label" is an identifier of some point in sources,
/// e.g. in the following code:
///
/// ```rust
/// 'outer: loop {
///     break 'outer;
/// }
/// ```
///
/// `'outer` is a label.
#[derive(Clone, Encodable, Decodable, Copy, HashStable_Generic, Eq, PartialEq, Walkable)]
pub struct Label {
    pub ident: Ident,
}

impl fmt::Debug for Label {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "label({:?})", self.ident)
    }
}

/// A "Lifetime" is an annotation of the scope in which variable
/// can be used, e.g. `'a` in `&'a i32`.
#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash, Walkable)]
pub struct Lifetime {
    pub id: NodeId,
    pub ident: Ident,
}

impl fmt::Debug for Lifetime {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "lifetime({}: {})", self.id, self)
    }
}

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

/// A "Path" is essentially Rust's notion of a name.
///
/// It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
///
/// E.g., `std::cmp::PartialEq`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Path {
    pub span: Span,
    /// The segments in the path: the things separated by `::`.
    /// Global paths begin with `kw::PathRoot`.
    pub segments: ThinVec<PathSegment>,
    pub tokens: Option<LazyAttrTokenStream>,
}

// Succeeds if the path has a single segment that is arg-free and matches the given symbol.
impl PartialEq<Symbol> for Path {
    #[inline]
    fn eq(&self, name: &Symbol) -> bool {
        if let [segment] = self.segments.as_ref()
            && segment == name
        {
            true
        } else {
            false
        }
    }
}

// Succeeds if the path has segments that are arg-free and match the given symbols.
impl PartialEq<&[Symbol]> for Path {
    #[inline]
    fn eq(&self, names: &&[Symbol]) -> bool {
        self.segments.iter().eq(*names)
    }
}

impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
        self.segments.len().hash_stable(hcx, hasher);
        for segment in &self.segments {
            segment.ident.hash_stable(hcx, hasher);
        }
    }
}

impl Path {
    /// Convert a span and an identifier to the corresponding
    /// one-segment path.
    pub fn from_ident(ident: Ident) -> Path {
        Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None }
    }

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

    /// Check if this path is potentially a trivial const arg, i.e., one that can _potentially_
    /// be represented without an anon const in the HIR.
    ///
    /// If `allow_mgca_arg` is true (as should be the case in most situations when
    /// `#![feature(min_generic_const_args)]` is enabled), then this always returns true
    /// because all paths are valid.
    ///
    /// Otherwise, it returns true iff the path has exactly one segment, and it has no generic args
    /// (i.e., it is _potentially_ a const parameter).
    #[tracing::instrument(level = "debug", ret)]
    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
        allow_mgca_arg
            || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
    }
}

/// Joins multiple symbols with "::" into a path, e.g. "a::b::c". If the first
/// segment is `kw::PathRoot` it will be printed as empty, e.g. "::b::c".
///
/// The generics on the `path` argument mean it can accept many forms, such as:
/// - `&[Symbol]`
/// - `Vec<Symbol>`
/// - `Vec<&Symbol>`
/// - `impl Iterator<Item = Symbol>`
/// - `impl Iterator<Item = &Symbol>`
///
/// Panics if `path` is empty or a segment after the first is `kw::PathRoot`.
pub fn join_path_syms(path: impl IntoIterator<Item = impl Borrow<Symbol>>) -> String {
    // This is a guess at the needed capacity that works well in practice. It is slightly faster
    // than (a) starting with an empty string, or (b) computing the exact capacity required.
    // `8` works well because it's about the right size and jemalloc's size classes are all
    // multiples of 8.
    let mut iter = path.into_iter();
    let len_hint = iter.size_hint().1.unwrap_or(1);
    let mut s = String::with_capacity(len_hint * 8);

    let first_sym = *iter.next().unwrap().borrow();
    if first_sym != kw::PathRoot {
        s.push_str(first_sym.as_str());
    }
    for sym in iter {
        let sym = *sym.borrow();
        debug_assert_ne!(sym, kw::PathRoot);
        s.push_str("::");
        s.push_str(sym.as_str());
    }
    s
}

/// Like `join_path_syms`, but for `Ident`s. This function is necessary because
/// `Ident::to_string` does more than just print the symbol in the `name` field.
pub fn join_path_idents(path: impl IntoIterator<Item = impl Borrow<Ident>>) -> String {
    let mut iter = path.into_iter();
    let len_hint = iter.size_hint().1.unwrap_or(1);
    let mut s = String::with_capacity(len_hint * 8);

    let first_ident = *iter.next().unwrap().borrow();
    if first_ident.name != kw::PathRoot {
        s.push_str(&first_ident.to_string());
    }
    for ident in iter {
        let ident = *ident.borrow();
        debug_assert_ne!(ident.name, kw::PathRoot);
        s.push_str("::");
        s.push_str(&ident.to_string());
    }
    s
}

/// A segment of a path: an identifier, an optional lifetime, and a set of types.
///
/// E.g., `std`, `String` or `Box<T>`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct PathSegment {
    /// The identifier portion of this path segment.
    pub ident: Ident,

    pub id: NodeId,

    /// Type/lifetime parameters attached to this path. They come in
    /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
    /// `None` means that no parameter list is supplied (`Path`),
    /// `Some` means that parameter list is supplied (`Path<X, Y>`)
    /// but it can be empty (`Path<>`).
    /// `P` is used as a size optimization for the common case with no parameters.
    pub args: Option<Box<GenericArgs>>,
}

// Succeeds if the path segment is arg-free and matches the given symbol.
impl PartialEq<Symbol> for PathSegment {
    #[inline]
    fn eq(&self, name: &Symbol) -> bool {
        self.args.is_none() && self.ident.name == *name
    }
}

impl PathSegment {
    pub fn from_ident(ident: Ident) -> Self {
        PathSegment { ident, id: DUMMY_NODE_ID, args: None }
    }

    pub fn path_root(span: Span) -> Self {
        PathSegment::from_ident(Ident::new(kw::PathRoot, span))
    }

    pub fn span(&self) -> Span {
        match &self.args {
            Some(args) => self.ident.span.to(args.span()),
            None => self.ident.span,
        }
    }
}

/// The generic arguments and associated item constraints of a path segment.
///
/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum GenericArgs {
    /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`.
    AngleBracketed(AngleBracketedArgs),
    /// The `(A, B)` and `C` in `Foo(A, B) -> C`.
    Parenthesized(ParenthesizedArgs),
    /// `(..)` in return type notation.
    ParenthesizedElided(Span),
}

impl GenericArgs {
    pub fn is_angle_bracketed(&self) -> bool {
        matches!(self, AngleBracketed(..))
    }

    pub fn span(&self) -> Span {
        match self {
            AngleBracketed(data) => data.span,
            Parenthesized(data) => data.span,
            ParenthesizedElided(span) => *span,
        }
    }
}

/// Concrete argument in the sequence of generic args.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum GenericArg {
    /// `'a` in `Foo<'a>`.
    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
    /// `Bar` in `Foo<Bar>`.
    Type(Box<Ty>),
    /// `1` in `Foo<1>`.
    Const(AnonConst),
}

impl GenericArg {
    pub fn span(&self) -> Span {
        match self {
            GenericArg::Lifetime(lt) => lt.ident.span,
            GenericArg::Type(ty) => ty.span,
            GenericArg::Const(ct) => ct.value.span,
        }
    }
}

/// A path like `Foo<'a, T>`.
#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct AngleBracketedArgs {
    /// The overall span.
    pub span: Span,
    /// The comma separated parts in the `<...>`.
    pub args: ThinVec<AngleBracketedArg>,
}

/// Either an argument for a generic parameter or a constraint on an associated item.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum AngleBracketedArg {
    /// A generic argument for a generic parameter.
    Arg(GenericArg),
    /// A constraint on an associated item.
    Constraint(AssocItemConstraint),
}

impl AngleBracketedArg {
    pub fn span(&self) -> Span {
        match self {
            AngleBracketedArg::Arg(arg) => arg.span(),
            AngleBracketedArg::Constraint(constraint) => constraint.span,
        }
    }
}

impl From<AngleBracketedArgs> for Box<GenericArgs> {
    fn from(val: AngleBracketedArgs) -> Self {
        Box::new(GenericArgs::AngleBracketed(val))
    }
}

impl From<ParenthesizedArgs> for Box<GenericArgs> {
    fn from(val: ParenthesizedArgs) -> Self {
        Box::new(GenericArgs::Parenthesized(val))
    }
}

/// A path like `Foo(A, B) -> C`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct ParenthesizedArgs {
    /// ```text
    /// Foo(A, B) -> C
    /// ^^^^^^^^^^^^^^
    /// ```
    pub span: Span,

    /// `(A, B)`
    pub inputs: ThinVec<Box<Ty>>,

    /// ```text
    /// Foo(A, B) -> C
    ///    ^^^^^^
    /// ```
    pub inputs_span: Span,

    /// `C`
    pub output: FnRetTy,
}

impl ParenthesizedArgs {
    pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
        let args = self
            .inputs
            .iter()
            .cloned()
            .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
            .collect();
        AngleBracketedArgs { span: self.inputs_span, args }
    }
}

pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};

/// Modifiers on a trait bound like `[const]`, `?` and `!`.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Walkable)]
pub struct TraitBoundModifiers {
    pub constness: BoundConstness,
    pub asyncness: BoundAsyncness,
    pub polarity: BoundPolarity,
}

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

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum GenericBound {
    Trait(PolyTraitRef),
    Outlives(#[visitable(extra = LifetimeCtxt::Bound)] Lifetime),
    /// Precise capturing syntax: `impl Sized + use<'a>`
    Use(ThinVec<PreciseCapturingArg>, Span),
}

impl GenericBound {
    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 = Vec<GenericBound>;

/// Specifies the enforced ordering for generic parameters. In the future,
/// if we wanted to relax this order, we could override `PartialEq` and
/// `PartialOrd`, to allow the kinds to be unordered.
#[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum ParamKindOrd {
    Lifetime,
    TypeOrConst,
}

impl fmt::Display for ParamKindOrd {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ParamKindOrd::Lifetime => "lifetime".fmt(f),
            ParamKindOrd::TypeOrConst => "type and const".fmt(f),
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum GenericParamKind {
    /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
    Lifetime,
    Type {
        default: Option<Box<Ty>>,
    },
    Const {
        ty: Box<Ty>,
        /// Span of the whole parameter definition, including default.
        span: Span,
        /// Optional default value for the const generic param.
        default: Option<AnonConst>,
    },
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct GenericParam {
    pub id: NodeId,
    pub ident: Ident,
    pub attrs: AttrVec,
    #[visitable(extra = BoundKind::Bound)]
    pub bounds: GenericBounds,
    pub is_placeholder: bool,
    pub kind: GenericParamKind,
    pub colon_span: Option<Span>,
}

impl GenericParam {
    pub fn span(&self) -> Span {
        match &self.kind {
            GenericParamKind::Lifetime | GenericParamKind::Type { default: None } => {
                self.ident.span
            }
            GenericParamKind::Type { default: Some(ty) } => self.ident.span.to(ty.span),
            GenericParamKind::Const { span, .. } => *span,
        }
    }
}

/// Represents lifetime, type and const parameters attached to a declaration of
/// a function, enum, trait, etc.
#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct Generics {
    pub params: ThinVec<GenericParam>,
    pub where_clause: WhereClause,
    pub span: Span,
}

/// A where-clause in a definition.
#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct WhereClause {
    /// `true` if we ate a `where` token.
    ///
    /// This can happen if we parsed no predicates, e.g., `struct Foo where {}`.
    /// This allows us to pretty-print accurately and provide correct suggestion diagnostics.
    pub has_where_token: bool,
    pub predicates: ThinVec<WherePredicate>,
    pub span: Span,
}

impl WhereClause {
    pub fn is_empty(&self) -> bool {
        !self.has_where_token && self.predicates.is_empty()
    }
}

/// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct WherePredicate {
    pub attrs: AttrVec,
    pub kind: WherePredicateKind,
    pub id: NodeId,
    pub span: Span,
    pub is_placeholder: bool,
}

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

/// A type bound.
///
/// E.g., `for<'c> Foo: Send + Clone + 'c`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct WhereBoundPredicate {
    /// Any generics from a `for` binding.
    pub bound_generic_params: ThinVec<GenericParam>,
    /// The type being bounded.
    pub bounded_ty: Box<Ty>,
    /// Trait and lifetime bounds (`Clone + Send + 'static`).
    #[visitable(extra = BoundKind::Bound)]
    pub bounds: GenericBounds,
}

/// A lifetime predicate.
///
/// E.g., `'a: 'b + 'c`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct WhereRegionPredicate {
    #[visitable(extra = LifetimeCtxt::Bound)]
    pub lifetime: Lifetime,
    #[visitable(extra = BoundKind::Bound)]
    pub bounds: GenericBounds,
}

/// An equality predicate (unsupported).
///
/// E.g., `T = int`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct WhereEqPredicate {
    pub lhs_ty: Box<Ty>,
    pub rhs_ty: Box<Ty>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Crate {
    /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
    /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that.
    pub id: NodeId,
    pub attrs: AttrVec,
    pub items: ThinVec<Box<Item>>,
    pub spans: ModSpans,
    pub is_placeholder: bool,
}

/// A semantic representation of a meta item. A meta item is a slightly
/// restricted form of an attribute -- it can only contain expressions in
/// certain leaf positions, rather than arbitrary token streams -- that is used
/// for most built-in attributes.
///
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MetaItem {
    pub unsafety: Safety,
    pub path: Path,
    pub kind: MetaItemKind,
    pub span: Span,
}

/// The meta item kind, containing the data after the initial path.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MetaItemKind {
    /// Word meta item.
    ///
    /// E.g., `#[test]`, which lacks any arguments after `test`.
    Word,

    /// List meta item.
    ///
    /// E.g., `#[derive(..)]`, where the field represents the `..`.
    List(ThinVec<MetaItemInner>),

    /// Name value meta item.
    ///
    /// E.g., `#[feature = "foo"]`, where the field represents the `"foo"`.
    NameValue(MetaItemLit),
}

/// Values inside meta item lists.
///
/// E.g., each of `Clone`, `Copy` in `#[derive(Clone, Copy)]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum MetaItemInner {
    /// A full MetaItem, for recursive meta items.
    MetaItem(MetaItem),

    /// A literal.
    ///
    /// E.g., `"foo"`, `64`, `true`.
    Lit(MetaItemLit),
}

/// A block (`{ .. }`).
///
/// E.g., `{ .. }` as in `fn foo() { .. }`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Block {
    /// The statements in the block.
    pub stmts: ThinVec<Stmt>,
    pub id: NodeId,
    /// Distinguishes between `unsafe { ... }` and `{ ... }`.
    pub rules: BlockCheckMode,
    pub span: Span,
    pub tokens: Option<LazyAttrTokenStream>,
}

/// A match pattern.
///
/// Patterns appear in match statements and some other contexts, such as `let` and `if let`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Pat {
    pub id: NodeId,
    pub kind: PatKind,
    pub span: Span,
    pub tokens: Option<LazyAttrTokenStream>,
}

impl Pat {
    /// Attempt reparsing the pattern as a type.
    /// This is intended for use by diagnostics.
    pub fn to_ty(&self) -> Option<Box<Ty>> {
        let kind = match &self.kind {
            PatKind::Missing => unreachable!(),
            // In a type expression `_` is an inference variable.
            PatKind::Wild => TyKind::Infer,
            // An IDENT pattern with no binding mode would be valid as path to a type. E.g. `u32`.
            PatKind::Ident(BindingMode::NONE, ident, None) => {
                TyKind::Path(None, Path::from_ident(*ident))
            }
            PatKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
            PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
            // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
            PatKind::Ref(pat, mutbl) => {
                pat.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
            }
            // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
            // when `P` can be reparsed as a type `T`.
            PatKind::Slice(pats) if let [pat] = pats.as_slice() => {
                pat.to_ty().map(TyKind::Slice)?
            }
            // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)`
            // assuming `T0` to `Tn` are all syntactically valid as types.
            PatKind::Tuple(pats) => {
                let mut tys = ThinVec::with_capacity(pats.len());
                // FIXME(#48994) - could just be collected into an Option<Vec>
                for pat in pats {
                    tys.push(pat.to_ty()?);
                }
                TyKind::Tup(tys)
            }
            _ => return None,
        };

        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
    }

    /// Walk top-down and call `it` in each place where a pattern occurs
    /// starting with the root pattern `walk` is called on. If `it` returns
    /// false then we will descend no further but siblings will be processed.
    pub fn walk<'ast>(&'ast self, it: &mut impl FnMut(&'ast Pat) -> bool) {
        if !it(self) {
            return;
        }

        match &self.kind {
            // Walk into the pattern associated with `Ident` (if any).
            PatKind::Ident(_, _, Some(p)) => p.walk(it),

            // Walk into each field of struct.
            PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),

            // Sequence of patterns.
            PatKind::TupleStruct(_, _, s)
            | PatKind::Tuple(s)
            | PatKind::Slice(s)
            | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),

            // Trivial wrappers over inner patterns.
            PatKind::Box(s)
            | PatKind::Deref(s)
            | PatKind::Ref(s, _)
            | PatKind::Paren(s)
            | PatKind::Guard(s, _) => s.walk(it),

            // These patterns do not contain subpatterns, skip.
            PatKind::Missing
            | PatKind::Wild
            | PatKind::Rest
            | PatKind::Never
            | PatKind::Expr(_)
            | PatKind::Range(..)
            | PatKind::Ident(..)
            | PatKind::Path(..)
            | PatKind::MacCall(_)
            | PatKind::Err(_) => {}
        }
    }

    /// Is this a `..` pattern?
    pub fn is_rest(&self) -> bool {
        matches!(self.kind, PatKind::Rest)
    }

    /// Whether this could be a never pattern, taking into account that a macro invocation can
    /// return a never pattern. Used to inform errors during parsing.
    pub fn could_be_never_pattern(&self) -> bool {
        let mut could_be_never_pattern = false;
        self.walk(&mut |pat| match &pat.kind {
            PatKind::Never | PatKind::MacCall(_) => {
                could_be_never_pattern = true;
                false
            }
            PatKind::Or(s) => {
                could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern());
                false
            }
            _ => true,
        });
        could_be_never_pattern
    }

    /// Whether this contains a `!` pattern. This in particular means that a feature gate error will
    /// be raised if the feature is off. Used to avoid gating the feature twice.
    pub fn contains_never_pattern(&self) -> bool {
        let mut contains_never_pattern = false;
        self.walk(&mut |pat| {
            if matches!(pat.kind, PatKind::Never) {
                contains_never_pattern = true;
            }
            true
        });
        contains_never_pattern
    }

    /// Return a name suitable for diagnostics.
    pub fn descr(&self) -> Option<String> {
        match &self.kind {
            PatKind::Missing => unreachable!(),
            PatKind::Wild => Some("_".to_string()),
            PatKind::Ident(BindingMode::NONE, ident, None) => Some(format!("{ident}")),
            PatKind::Ref(pat, mutbl) => pat.descr().map(|d| format!("&{}{d}", mutbl.prefix_str())),
            _ => None,
        }
    }
}

impl From<Box<Pat>> for Pat {
    fn from(value: Box<Pat>) -> Self {
        *value
    }
}

/// 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 when `is_shorthand` is true.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct PatField {
    /// The identifier for the field.
    pub ident: Ident,
    /// The pattern the field is destructured to.
    pub pat: Box<Pat>,
    pub is_shorthand: bool,
    pub attrs: AttrVec,
    pub id: NodeId,
    pub span: Span,
    pub is_placeholder: bool,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum ByRef {
    Yes(Mutability),
    No,
}

impl ByRef {
    #[must_use]
    pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self {
        if let ByRef::Yes(old_mutbl) = &mut self {
            *old_mutbl = cmp::min(*old_mutbl, mutbl);
        }
        self
    }
}

/// The mode of a binding (`mut`, `ref mut`, etc).
/// Used for both the explicit binding annotations given in the HIR for a binding
/// and the final binding mode that we infer after type inference/match ergonomics.
/// `.0` is the by-reference mode (`ref`, `ref mut`, or by value),
/// `.1` is the mutability of the binding.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
pub struct BindingMode(pub ByRef, pub Mutability);

impl BindingMode {
    pub const NONE: Self = Self(ByRef::No, Mutability::Not);
    pub const REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Not);
    pub const MUT: Self = Self(ByRef::No, Mutability::Mut);
    pub const REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Not);
    pub const MUT_REF: Self = Self(ByRef::Yes(Mutability::Not), Mutability::Mut);
    pub const MUT_REF_MUT: Self = Self(ByRef::Yes(Mutability::Mut), Mutability::Mut);

    pub fn prefix_str(self) -> &'static str {
        match self {
            Self::NONE => "",
            Self::REF => "ref ",
            Self::MUT => "mut ",
            Self::REF_MUT => "ref mut ",
            Self::MUT_REF => "mut ref ",
            Self::MUT_REF_MUT => "mut ref mut ",
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum RangeEnd {
    /// `..=` or `...`
    Included(RangeSyntax),
    /// `..`
    Excluded,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum RangeSyntax {
    /// `...`
    DotDotDot,
    /// `..=`
    DotDotEq,
}

/// All the different flavors of pattern that Rust recognizes.
//
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum PatKind {
    /// A missing pattern, e.g. for an anonymous param in a bare fn like `fn f(u32)`.
    Missing,

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

    /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
    /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
    /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
    /// during name resolution.
    Ident(BindingMode, Ident, Option<Box<Pat>>),

    /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
    Struct(Option<Box<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),

    /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
    TupleStruct(Option<Box<QSelf>>, Path, ThinVec<Pat>),

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

    /// A possibly qualified path pattern.
    /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
    /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
    /// only legally refer to associated constants.
    Path(Option<Box<QSelf>>, Path),

    /// A tuple pattern (`(a, b)`).
    Tuple(ThinVec<Pat>),

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

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

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

    /// A literal, const block or path.
    Expr(Box<Expr>),

    /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
    Range(Option<Box<Expr>>, Option<Box<Expr>>, Spanned<RangeEnd>),

    /// A slice pattern `[a, b, c]`.
    Slice(ThinVec<Pat>),

    /// A rest pattern `..`.
    ///
    /// Syntactically it is valid anywhere.
    ///
    /// Semantically however, it only has meaning immediately inside:
    /// - a slice pattern: `[a, .., b]`,
    /// - a binding pattern immediately inside a slice pattern: `[a, r @ ..]`,
    /// - a tuple pattern: `(a, .., b)`,
    /// - a tuple struct/variant pattern: `$path(a, .., b)`.
    ///
    /// In all of these cases, an additional restriction applies,
    /// only one rest pattern may occur in the pattern sequences.
    Rest,

    // A never pattern `!`.
    Never,

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

    /// Parentheses in patterns used for grouping (i.e., `(PAT)`).
    Paren(Box<Pat>),

    /// A macro pattern; pre-expansion.
    MacCall(Box<MacCall>),

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

/// Whether the `..` is present in a struct fields pattern.
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
pub enum PatFieldsRest {
    /// `module::StructName { field, ..}`
    Rest(Span),
    /// `module::StructName { field, syntax error }`
    Recovered(ErrorGuaranteed),
    /// `module::StructName { field }`
    None,
}

/// The kind of borrow in an `AddrOf` expression,
/// e.g., `&place` or `&raw const place`.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum BorrowKind {
    /// A normal borrow, `&$expr` or `&mut $expr`.
    /// The resulting type is either `&'a T` or `&'a mut T`
    /// where `T = typeof($expr)` and `'a` is some lifetime.
    Ref,
    /// A raw borrow, `&raw const $expr` or `&raw mut $expr`.
    /// The resulting type is either `*const T` or `*mut T`
    /// where `T = typeof($expr)`.
    Raw,
    /// A pinned borrow, `&pin const $expr` or `&pin mut $expr`.
    /// The resulting type is either `Pin<&'a T>` or `Pin<&'a mut T>`
    /// where `T = typeof($expr)` and `'a` is some lifetime.
    Pin,
}

#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum BinOpKind {
    /// The `+` operator (addition)
    Add,
    /// The `-` operator (subtraction)
    Sub,
    /// The `*` operator (multiplication)
    Mul,
    /// The `/` operator (division)
    Div,
    /// The `%` operator (modulus)
    Rem,
    /// The `&&` operator (logical and)
    And,
    /// The `||` operator (logical or)
    Or,
    /// The `^` operator (bitwise xor)
    BitXor,
    /// The `&` operator (bitwise and)
    BitAnd,
    /// The `|` operator (bitwise or)
    BitOr,
    /// The `<<` operator (shift left)
    Shl,
    /// The `>>` operator (shift right)
    Shr,
    /// The `==` operator (equality)
    Eq,
    /// The `<` operator (less than)
    Lt,
    /// The `<=` operator (less than or equal to)
    Le,
    /// The `!=` operator (not equal to)
    Ne,
    /// The `>=` operator (greater than or equal to)
    Ge,
    /// The `>` operator (greater than)
    Gt,
}

impl BinOpKind {
    pub fn as_str(&self) -> &'static str {
        use BinOpKind::*;
        match self {
            Add => "+",
            Sub => "-",
            Mul => "*",
            Div => "/",
            Rem => "%",
            And => "&&",
            Or => "||",
            BitXor => "^",
            BitAnd => "&",
            BitOr => "|",
            Shl => "<<",
            Shr => ">>",
            Eq => "==",
            Lt => "<",
            Le => "<=",
            Ne => "!=",
            Ge => ">=",
            Gt => ">",
        }
    }

    pub fn is_lazy(&self) -> bool {
        matches!(self, BinOpKind::And | BinOpKind::Or)
    }

    pub fn precedence(&self) -> ExprPrecedence {
        use BinOpKind::*;
        match *self {
            Mul | Div | Rem => ExprPrecedence::Product,
            Add | Sub => ExprPrecedence::Sum,
            Shl | Shr => ExprPrecedence::Shift,
            BitAnd => ExprPrecedence::BitAnd,
            BitXor => ExprPrecedence::BitXor,
            BitOr => ExprPrecedence::BitOr,
            Lt | Gt | Le | Ge | Eq | Ne => ExprPrecedence::Compare,
            And => ExprPrecedence::LAnd,
            Or => ExprPrecedence::LOr,
        }
    }

    pub fn fixity(&self) -> Fixity {
        use BinOpKind::*;
        match self {
            Eq | Ne | Lt | Le | Gt | Ge => Fixity::None,
            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => {
                Fixity::Left
            }
        }
    }

    pub fn is_comparison(self) -> bool {
        use BinOpKind::*;
        match self {
            Eq | Ne | Lt | Le | Gt | Ge => true,
            Add | Sub | Mul | Div | Rem | And | Or | BitXor | BitAnd | BitOr | Shl | Shr => false,
        }
    }

    /// Returns `true` if the binary operator takes its arguments by value.
    pub fn is_by_value(self) -> bool {
        !self.is_comparison()
    }
}

pub type BinOp = Spanned<BinOpKind>;

// Sometimes `BinOpKind` and `AssignOpKind` need the same treatment. The
// operations covered by `AssignOpKind` are a subset of those covered by
// `BinOpKind`, so it makes sense to convert `AssignOpKind` to `BinOpKind`.
impl From<AssignOpKind> for BinOpKind {
    fn from(op: AssignOpKind) -> BinOpKind {
        match op {
            AssignOpKind::AddAssign => BinOpKind::Add,
            AssignOpKind::SubAssign => BinOpKind::Sub,
            AssignOpKind::MulAssign => BinOpKind::Mul,
            AssignOpKind::DivAssign => BinOpKind::Div,
            AssignOpKind::RemAssign => BinOpKind::Rem,
            AssignOpKind::BitXorAssign => BinOpKind::BitXor,
            AssignOpKind::BitAndAssign => BinOpKind::BitAnd,
            AssignOpKind::BitOrAssign => BinOpKind::BitOr,
            AssignOpKind::ShlAssign => BinOpKind::Shl,
            AssignOpKind::ShrAssign => BinOpKind::Shr,
        }
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum AssignOpKind {
    /// The `+=` operator (addition)
    AddAssign,
    /// The `-=` operator (subtraction)
    SubAssign,
    /// The `*=` operator (multiplication)
    MulAssign,
    /// The `/=` operator (division)
    DivAssign,
    /// The `%=` operator (modulus)
    RemAssign,
    /// The `^=` operator (bitwise xor)
    BitXorAssign,
    /// The `&=` operator (bitwise and)
    BitAndAssign,
    /// The `|=` operator (bitwise or)
    BitOrAssign,
    /// The `<<=` operator (shift left)
    ShlAssign,
    /// The `>>=` operator (shift right)
    ShrAssign,
}

impl AssignOpKind {
    pub fn as_str(&self) -> &'static str {
        use AssignOpKind::*;
        match self {
            AddAssign => "+=",
            SubAssign => "-=",
            MulAssign => "*=",
            DivAssign => "/=",
            RemAssign => "%=",
            BitXorAssign => "^=",
            BitAndAssign => "&=",
            BitOrAssign => "|=",
            ShlAssign => "<<=",
            ShrAssign => ">>=",
        }
    }

    /// AssignOps are always by value.
    pub fn is_by_value(self) -> bool {
        true
    }
}

pub type AssignOp = Spanned<AssignOpKind>;

/// Unary operator.
///
/// Note that `&data` is not an operator, it's an `AddrOf` expression.
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum UnOp {
    /// The `*` operator for dereferencing
    Deref,
    /// The `!` operator for logical inversion
    Not,
    /// The `-` operator for negation
    Neg,
}

impl UnOp {
    pub fn as_str(&self) -> &'static str {
        match self {
            UnOp::Deref => "*",
            UnOp::Not => "!",
            UnOp::Neg => "-",
        }
    }

    /// Returns `true` if the unary operator takes its argument by value.
    pub fn is_by_value(self) -> bool {
        matches!(self, Self::Neg | Self::Not)
    }
}

/// A statement. No `attrs` or `tokens` fields because each `StmtKind` variant
/// contains an AST node with those fields. (Except for `StmtKind::Empty`,
/// which never has attrs or tokens)
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Stmt {
    pub id: NodeId,
    pub kind: StmtKind,
    pub span: Span,
}

impl Stmt {
    pub fn has_trailing_semicolon(&self) -> bool {
        match &self.kind {
            StmtKind::Semi(_) => true,
            StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon),
            _ => false,
        }
    }

    /// Converts a parsed `Stmt` to a `Stmt` with
    /// a trailing semicolon.
    ///
    /// This only modifies the parsed AST struct, not the attached
    /// `LazyAttrTokenStream`. The parser is responsible for calling
    /// `ToAttrTokenStream::add_trailing_semi` when there is actually
    /// a semicolon in the tokenstream.
    pub fn add_trailing_semicolon(mut self) -> Self {
        self.kind = match self.kind {
            StmtKind::Expr(expr) => StmtKind::Semi(expr),
            StmtKind::MacCall(mut mac) => {
                mac.style = MacStmtStyle::Semicolon;
                StmtKind::MacCall(mac)
            }
            kind => kind,
        };

        self
    }

    pub fn is_item(&self) -> bool {
        matches!(self.kind, StmtKind::Item(_))
    }

    pub fn is_expr(&self) -> bool {
        matches!(self.kind, StmtKind::Expr(_))
    }
}

// Adding a new variant? Please update `test_stmt` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum StmtKind {
    /// A local (let) binding.
    Let(Box<Local>),
    /// An item definition.
    Item(Box<Item>),
    /// Expr without trailing semi-colon.
    Expr(Box<Expr>),
    /// Expr with a trailing semi-colon.
    Semi(Box<Expr>),
    /// Just a trailing semi-colon.
    Empty,
    /// Macro.
    MacCall(Box<MacCallStmt>),
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct MacCallStmt {
    pub mac: Box<MacCall>,
    pub style: MacStmtStyle,
    pub attrs: AttrVec,
    pub tokens: Option<LazyAttrTokenStream>,
}

#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
pub enum MacStmtStyle {
    /// The macro statement had a trailing semicolon (e.g., `foo! { ... };`
    /// `foo!(...);`, `foo![...];`).
    Semicolon,
    /// The macro statement had braces (e.g., `foo! { ... }`).
    Braces,
    /// The macro statement had parentheses or brackets and no semicolon (e.g.,
    /// `foo!(...)`). All of these will end up being converted into macro
    /// expressions.
    NoBraces,
}

/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Local {
    pub id: NodeId,
    pub super_: Option<Span>,
    pub pat: Box<Pat>,
    pub ty: Option<Box<Ty>>,
    pub kind: LocalKind,
    pub span: Span,
    pub colon_sp: Option<Span>,
    pub attrs: AttrVec,
    pub tokens: Option<LazyAttrTokenStream>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum LocalKind {
    /// Local declaration.
    /// Example: `let x;`
    Decl,
    /// Local declaration with an initializer.
    /// Example: `let x = y;`
    Init(Box<Expr>),
    /// Local declaration with an initializer and an `else` clause.
    /// Example: `let Some(x) = y else { return };`
    InitElse(Box<Expr>, Box<Block>),
}

impl LocalKind {
    pub fn init(&self) -> Option<&Expr> {
        match self {
            Self::Decl => None,
            Self::Init(i) | Self::InitElse(i, _) => Some(i),
        }
    }

    pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> {
        match self {
            Self::Decl => None,
            Self::Init(init) => Some((init, None)),
            Self::InitElse(init, els) => Some((init, Some(els))),
        }
    }
}

/// An arm of a 'match'.
///
/// E.g., `0..=10 => { println!("match!") }` as in
///
/// ```
/// match 123 {
///     0..=10 => { println!("match!") },
///     _ => { println!("no match!") },
/// }
/// ```
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Arm {
    pub attrs: AttrVec,
    /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`.
    pub pat: Box<Pat>,
    /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`.
    pub guard: Option<Box<Expr>>,
    /// Match arm body. Omitted if the pattern is a never pattern.
    pub body: Option<Box<Expr>>,
    pub span: Span,
    pub id: NodeId,
    pub is_placeholder: bool,
}

/// A single field in a struct expression, e.g. `x: value` and `y` in `Foo { x: value, y }`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct ExprField {
    pub attrs: AttrVec,
    pub id: NodeId,
    pub span: Span,
    pub ident: Ident,
    pub expr: Box<Expr>,
    pub is_shorthand: bool,
    pub is_placeholder: bool,
}

#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, Walkable)]
pub enum BlockCheckMode {
    Default,
    Unsafe(UnsafeSource),
}

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

/// 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.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct AnonConst {
    pub id: NodeId,
    pub value: Box<Expr>,
}

/// An expression.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Expr {
    pub id: NodeId,
    pub kind: ExprKind,
    pub span: Span,
    pub attrs: AttrVec,
    pub tokens: Option<LazyAttrTokenStream>,
}

impl Expr {
    /// Check if this expression is potentially a trivial const arg, i.e., one that can _potentially_
    /// be represented without an anon const in the HIR.
    ///
    /// This will unwrap at most one block level (curly braces). After that, if the expression
    /// is a path, it mostly dispatches to [`Path::is_potential_trivial_const_arg`].
    /// See there for more info about `allow_mgca_arg`.
    ///
    /// The only additional thing to note is that when `allow_mgca_arg` is false, this function
    /// will only allow paths with no qself, before dispatching to the `Path` function of
    /// the same name.
    ///
    /// Does not ensure that the path resolves to a const param/item, the caller should check this.
    /// This also does not consider macros, so it's only correct after macro-expansion.
    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
        let this = self.maybe_unwrap_block();
        if allow_mgca_arg {
            matches!(this.kind, ExprKind::Path(..))
        } else {
            if let ExprKind::Path(None, path) = &this.kind
                && path.is_potential_trivial_const_arg(allow_mgca_arg)
            {
                true
            } else {
                false
            }
        }
    }

    /// Returns an expression with (when possible) *one* outer brace removed
    pub fn maybe_unwrap_block(&self) -> &Expr {
        if let ExprKind::Block(block, None) = &self.kind
            && let [stmt] = block.stmts.as_slice()
            && let StmtKind::Expr(expr) = &stmt.kind
        {
            expr
        } else {
            self
        }
    }

    /// Determines whether this expression is a macro call optionally wrapped in braces . If
    /// `already_stripped_block` is set then we do not attempt to peel off a layer of braces.
    ///
    /// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled
    /// either before, or part of, this function.
    pub fn optionally_braced_mac_call(
        &self,
        already_stripped_block: bool,
    ) -> Option<(bool, NodeId)> {
        match &self.kind {
            ExprKind::Block(block, None)
                if let [stmt] = &*block.stmts
                    && !already_stripped_block =>
            {
                match &stmt.kind {
                    StmtKind::MacCall(_) => Some((true, stmt.id)),
                    StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
                        Some((true, expr.id))
                    }
                    _ => None,
                }
            }
            ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
            _ => None,
        }
    }

    pub fn to_bound(&self) -> Option<GenericBound> {
        match &self.kind {
            ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
                ThinVec::new(),
                path.clone(),
                TraitBoundModifiers::NONE,
                self.span,
                Parens::No,
            ))),
            _ => None,
        }
    }

    pub fn peel_parens(&self) -> &Expr {
        let mut expr = self;
        while let ExprKind::Paren(inner) = &expr.kind {
            expr = inner;
        }
        expr
    }

    pub fn peel_parens_and_refs(&self) -> &Expr {
        let mut expr = self;
        while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
        {
            expr = inner;
        }
        expr
    }

    /// Attempts to reparse as `Ty` (for diagnostic purposes).
    pub fn to_ty(&self) -> Option<Box<Ty>> {
        let kind = match &self.kind {
            // Trivial conversions.
            ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
            ExprKind::MacCall(mac) => TyKind::MacCall(mac.clone()),

            ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,

            ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
                expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
            }

            ExprKind::Repeat(expr, expr_len) => {
                expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
            }

            ExprKind::Array(exprs) if let [expr] = exprs.as_slice() => {
                expr.to_ty().map(TyKind::Slice)?
            }

            ExprKind::Tup(exprs) => {
                let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?;
                TyKind::Tup(tys)
            }

            // If binary operator is `Add` and both `lhs` and `rhs` are trait bounds,
            // then type of result is trait object.
            // Otherwise we don't assume the result type.
            ExprKind::Binary(binop, lhs, rhs) if binop.node == BinOpKind::Add => {
                if let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) {
                    TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
                } else {
                    return None;
                }
            }

            ExprKind::Underscore => TyKind::Infer,

            // This expression doesn't look like a type syntactically.
            _ => return None,
        };

        Some(Box::new(Ty { kind, id: self.id, span: self.span, tokens: None }))
    }

    pub fn precedence(&self) -> ExprPrecedence {
        fn prefix_attrs_precedence(attrs: &AttrVec) -> ExprPrecedence {
            for attr in attrs {
                if let AttrStyle::Outer = attr.style {
                    return ExprPrecedence::Prefix;
                }
            }
            ExprPrecedence::Unambiguous
        }

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

            ExprKind::Break(_ /*label*/, value)
            | ExprKind::Ret(value)
            | ExprKind::Yield(YieldKind::Prefix(value))
            | ExprKind::Yeet(value) => match value {
                Some(_) => ExprPrecedence::Jump,
                None => prefix_attrs_precedence(&self.attrs),
            },

            ExprKind::Become(_) => ExprPrecedence::Jump,

            // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
            // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
            // ensures that `pprust` will add parentheses in the right places to get the desired
            // parse.
            ExprKind::Range(..) => ExprPrecedence::Range,

            // 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::Await(..)
            | ExprKind::Use(..)
            | ExprKind::Block(..)
            | ExprKind::Call(..)
            | ExprKind::ConstBlock(_)
            | ExprKind::Continue(..)
            | ExprKind::Field(..)
            | ExprKind::ForLoop { .. }
            | ExprKind::FormatArgs(..)
            | ExprKind::Gen(..)
            | ExprKind::If(..)
            | ExprKind::IncludedBytes(..)
            | ExprKind::Index(..)
            | ExprKind::InlineAsm(..)
            | ExprKind::Lit(_)
            | ExprKind::Loop(..)
            | ExprKind::MacCall(..)
            | ExprKind::Match(..)
            | ExprKind::MethodCall(..)
            | ExprKind::OffsetOf(..)
            | ExprKind::Paren(..)
            | ExprKind::Path(..)
            | ExprKind::Repeat(..)
            | ExprKind::Struct(..)
            | ExprKind::Try(..)
            | ExprKind::TryBlock(..)
            | ExprKind::Tup(_)
            | ExprKind::Type(..)
            | ExprKind::Underscore
            | ExprKind::UnsafeBinderCast(..)
            | ExprKind::While(..)
            | ExprKind::Yield(YieldKind::Postfix(..))
            | ExprKind::Err(_)
            | ExprKind::Dummy => prefix_attrs_precedence(&self.attrs),
        }
    }

    /// To a first-order approximation, is this a pattern?
    pub fn is_approximately_pattern(&self) -> bool {
        matches!(
            &self.peel_parens().kind,
            ExprKind::Array(_)
                | ExprKind::Call(_, _)
                | ExprKind::Tup(_)
                | ExprKind::Lit(_)
                | ExprKind::Range(_, _, _)
                | ExprKind::Underscore
                | ExprKind::Path(_, _)
                | ExprKind::Struct(_)
        )
    }

    /// Creates a dummy `Expr`.
    ///
    /// Should only be used when it will be replaced afterwards or as a return value when an error was encountered.
    pub fn dummy() -> Expr {
        Expr {
            id: DUMMY_NODE_ID,
            kind: ExprKind::Dummy,
            span: DUMMY_SP,
            attrs: ThinVec::new(),
            tokens: None,
        }
    }
}

impl From<Box<Expr>> for Expr {
    fn from(value: Box<Expr>) -> Self {
        *value
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Closure {
    pub binder: ClosureBinder,
    pub capture_clause: CaptureBy,
    pub constness: Const,
    pub coroutine_kind: Option<CoroutineKind>,
    pub movability: Movability,
    pub fn_decl: Box<FnDecl>,
    pub body: Box<Expr>,
    /// The span of the declaration block: 'move |...| -> ...'
    pub fn_decl_span: Span,
    /// The span of the argument block `|...|`
    pub fn_arg_span: Span,
}

/// Limit types of a range (inclusive or exclusive).
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Walkable)]
pub enum RangeLimits {
    /// Inclusive at the beginning, exclusive at the end.
    HalfOpen,
    /// Inclusive at the beginning and end.
    Closed,
}

impl RangeLimits {
    pub fn as_str(&self) -> &'static str {
        match self {
            RangeLimits::HalfOpen => "..",
            RangeLimits::Closed => "..=",
        }
    }
}

/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`).
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct MethodCall {
    /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`.
    pub seg: PathSegment,
    /// The receiver, e.g. `x`.
    pub receiver: Box<Expr>,
    /// The arguments, e.g. `a, b, c`.
    pub args: ThinVec<Box<Expr>>,
    /// The span of the function, without the dot and receiver e.g. `foo::<Bar,
    /// Baz>(a, b, c)`.
    pub span: Span,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum StructRest {
    /// `..x`.
    Base(Box<Expr>),
    /// `..`.
    Rest(Span),
    /// No trailing `..` or expression.
    None,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct StructExpr {
    pub qself: Option<Box<QSelf>>,
    pub path: Path,
    pub fields: ThinVec<ExprField>,
    pub rest: StructRest,
}

// Adding a new variant? Please update `test_expr` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ExprKind {
    /// An array (e.g, `[a, b, c, d]`).
    Array(ThinVec<Box<Expr>>),
    /// Allow anonymous constants from an inline `const` block.
    ConstBlock(AnonConst),
    /// A function call.
    ///
    /// The first field resolves to the function itself,
    /// 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(Box<Expr>, ThinVec<Box<Expr>>),
    /// A method call (e.g., `x.foo::<Bar, Baz>(a, b, c)`).
    MethodCall(Box<MethodCall>),
    /// A tuple (e.g., `(a, b, c, d)`).
    Tup(ThinVec<Box<Expr>>),
    /// A binary operation (e.g., `a + b`, `a * b`).
    Binary(BinOp, Box<Expr>, Box<Expr>),
    /// A unary operation (e.g., `!x`, `*x`).
    Unary(UnOp, Box<Expr>),
    /// A literal (e.g., `1`, `"foo"`).
    Lit(token::Lit),
    /// A cast (e.g., `foo as f64`).
    Cast(Box<Expr>, Box<Ty>),
    /// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
    ///
    /// Usually not written directly in user code but
    /// indirectly via the macro `type_ascribe!(...)`.
    Type(Box<Expr>, Box<Ty>),
    /// A `let pat = expr` expression that is only semantically allowed in the condition
    /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
    ///
    /// `Span` represents the whole `let pat = expr` statement.
    Let(Box<Pat>, Box<Expr>, Span, Recovered),
    /// An `if` block, with an optional `else` block.
    ///
    /// `if expr { block } else { expr }`
    ///
    /// If present, the "else" expr is always `ExprKind::Block` (for `else`) or
    /// `ExprKind::If` (for `else if`).
    If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
    /// A while loop, with an optional label.
    ///
    /// `'label: while expr { block }`
    While(Box<Expr>, Box<Block>, Option<Label>),
    /// A `for` loop, with an optional label.
    ///
    /// `'label: for await? pat in iter { block }`
    ///
    /// This is desugared to a combination of `loop` and `match` expressions.
    ForLoop {
        pat: Box<Pat>,
        iter: Box<Expr>,
        body: Box<Block>,
        label: Option<Label>,
        kind: ForLoopKind,
    },
    /// Conditionless loop (can be exited with `break`, `continue`, or `return`).
    ///
    /// `'label: loop { block }`
    Loop(Box<Block>, Option<Label>, Span),
    /// A `match` block.
    Match(Box<Expr>, ThinVec<Arm>, MatchKind),
    /// A closure (e.g., `move |a, b, c| a + b + c`).
    Closure(Box<Closure>),
    /// A block (`'label: { ... }`).
    Block(Box<Block>, Option<Label>),
    /// An `async` block (`async move { ... }`),
    /// or a `gen` block (`gen move { ... }`).
    ///
    /// The span is the "decl", which is the header before the body `{ }`
    /// including the `asyng`/`gen` keywords and possibly `move`.
    Gen(CaptureBy, Box<Block>, GenBlockKind, Span),
    /// An await expression (`my_future.await`). Span is of await keyword.
    Await(Box<Expr>, Span),
    /// A use expression (`x.use`). Span is of use keyword.
    Use(Box<Expr>, Span),

    /// A try block (`try { ... }`).
    TryBlock(Box<Block>),

    /// An assignment (`a = foo()`).
    /// The `Span` argument is the span of the `=` token.
    Assign(Box<Expr>, Box<Expr>, Span),
    /// An assignment with an operator.
    ///
    /// E.g., `a += 1`.
    AssignOp(AssignOp, Box<Expr>, Box<Expr>),
    /// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
    Field(Box<Expr>, Ident),
    /// An indexing operation (e.g., `foo[2]`).
    /// The span represents the span of the `[2]`, including brackets.
    Index(Box<Expr>, Box<Expr>, Span),
    /// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assignment).
    Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
    /// An underscore, used in destructuring assignment to ignore a value.
    Underscore,

    /// Variable reference, possibly containing `::` and/or type
    /// parameters (e.g., `foo::bar::<baz>`).
    ///
    /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`).
    Path(Option<Box<QSelf>>, Path),

    /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`).
    AddrOf(BorrowKind, Mutability, Box<Expr>),
    /// A `break`, with an optional label to break, and an optional expression.
    Break(Option<Label>, Option<Box<Expr>>),
    /// A `continue`, with an optional label.
    Continue(Option<Label>),
    /// A `return`, with an optional value to be returned.
    Ret(Option<Box<Expr>>),

    /// Output of the `asm!()` macro.
    InlineAsm(Box<InlineAsm>),

    /// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
    ///
    /// Usually not written directly in user code but
    /// indirectly via the macro `core::mem::offset_of!(...)`.
    OffsetOf(Box<Ty>, Vec<Ident>),

    /// A macro invocation; pre-expansion.
    MacCall(Box<MacCall>),

    /// A struct literal expression.
    ///
    /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. rest}`.
    Struct(Box<StructExpr>),

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

    /// No-op: used solely so we can pretty-print faithfully.
    Paren(Box<Expr>),

    /// A try expression (`expr?`).
    Try(Box<Expr>),

    /// A `yield`, with an optional value to be yielded.
    Yield(YieldKind),

    /// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
    /// with an optional value to be returned.
    Yeet(Option<Box<Expr>>),

    /// A tail call return, with the value to be returned.
    ///
    /// While `.0` must be a function call, we check this later, after parsing.
    Become(Box<Expr>),

    /// Bytes included via `include_bytes!`
    ///
    /// Added for optimization purposes to avoid the need to escape
    /// large binary blobs - should always behave like [`ExprKind::Lit`]
    /// with a `ByteStr` literal.
    ///
    /// The value is stored as a `ByteSymbol`. It's unfortunate that we need to
    /// intern (hash) the bytes because they're likely to be large and unique.
    /// But it's necessary because this will eventually be lowered to
    /// `LitKind::ByteStr`, which needs a `ByteSymbol` to impl `Copy` and avoid
    /// arena allocation.
    IncludedBytes(ByteSymbol),

    /// A `format_args!()` expression.
    FormatArgs(Box<FormatArgs>),

    UnsafeBinderCast(UnsafeBinderCastKind, Box<Expr>, Option<Box<Ty>>),

    /// Placeholder for an expression that wasn't syntactically well formed in some way.
    Err(ErrorGuaranteed),

    /// Acts as a null expression. Lowering it will always emit a bug.
    Dummy,
}

/// Used to differentiate between `for` loops and `for await` loops.
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
pub enum ForLoopKind {
    For,
    ForAwait,
}

/// Used to differentiate between `async {}` blocks and `gen {}` blocks.
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, Walkable)]
pub enum GenBlockKind {
    Async,
    Gen,
    AsyncGen,
}

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

impl GenBlockKind {
    pub fn modifier(&self) -> &'static str {
        match self {
            GenBlockKind::Async => "async",
            GenBlockKind::Gen => "gen",
            GenBlockKind::AsyncGen => "async gen",
        }
    }
}

/// Whether we're unwrapping or wrapping an unsafe binder
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum UnsafeBinderCastKind {
    // e.g. `&i32` -> `unsafe<'a> &'a i32`
    Wrap,
    // e.g. `unsafe<'a> &'a i32` -> `&i32`
    Unwrap,
}

/// The explicit `Self` type in a "qualified path". The actual
/// path, including the trait and the associated item, is stored
/// separately. `position` represents the index of the associated
/// item qualified with this `Self` type.
///
/// ```ignore (only-for-syntax-highlight)
/// <Vec<T> as a::b::Trait>::AssociatedItem
///  ^~~~~     ~~~~~~~~~~~~~~^
///  ty        position = 3
///
/// <Vec<T>>::AssociatedItem
///  ^~~~~    ^
///  ty       position = 0
/// ```
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct QSelf {
    pub ty: Box<Ty>,

    /// The span of `a::b::Trait` in a path like `<Vec<T> as
    /// a::b::Trait>::AssociatedItem`; in the case where `position ==
    /// 0`, this is an empty span.
    pub path_span: Span,
    pub position: usize,
}

/// A capture clause used in closures and `async` blocks.
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub enum CaptureBy {
    /// `move |x| y + x`.
    Value {
        /// The span of the `move` keyword.
        move_kw: Span,
    },
    /// `move` or `use` keywords were not specified.
    Ref,
    /// `use |x| y + x`.
    ///
    /// Note that if you have a regular closure like `|| x.use`, this will *not* result
    /// in a `Use` capture. Instead, the `ExprUseVisitor` will look at the type
    /// of `x` and treat `x.use` as either a copy/clone/move as appropriate.
    Use {
        /// The span of the `use` keyword.
        use_kw: Span,
    },
}

/// Closure lifetime binder, `for<'a, 'b>` in `for<'a, 'b> |_: &'a (), _: &'b ()|`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum ClosureBinder {
    /// The binder is not present, all closure lifetimes are inferred.
    NotPresent,
    /// The binder is present.
    For {
        /// Span of the whole `for<>` clause
        ///
        /// ```text
        /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
        /// ^^^^^^^^^^^ -- this
        /// ```
        span: Span,

        /// Lifetimes in the `for<>` closure
        ///
        /// ```text
        /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... }
        ///     ^^^^^^ -- this
        /// ```
        generic_params: ThinVec<GenericParam>,
    },
}

/// Represents a macro invocation. The `path` indicates which macro
/// is being invoked, and the `args` are arguments passed to it.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct MacCall {
    pub path: Path,
    pub args: Box<DelimArgs>,
}

impl MacCall {
    pub fn span(&self) -> Span {
        self.path.span.to(self.args.dspan.entire())
    }
}

/// Arguments passed to an attribute macro.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
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,
        expr: Box<Expr>,
    },
}

impl AttrArgs {
    pub fn span(&self) -> Option<Span> {
        match self {
            AttrArgs::Empty => None,
            AttrArgs::Delimited(args) => Some(args.dspan.entire()),
            AttrArgs::Eq { eq_span, expr } => Some(eq_span.to(expr.span)),
        }
    }

    /// Tokens inside the delimiters or after `=`.
    /// Proc macros see these tokens, for example.
    pub fn inner_tokens(&self) -> TokenStream {
        match self {
            AttrArgs::Empty => TokenStream::default(),
            AttrArgs::Delimited(args) => args.tokens.clone(),
            AttrArgs::Eq { expr, .. } => TokenStream::from_ast(expr),
        }
    }
}

/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub struct DelimArgs {
    pub dspan: DelimSpan,
    pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
    pub tokens: TokenStream,
}

impl DelimArgs {
    /// Whether a macro with these arguments needs a semicolon
    /// when used as a standalone item or statement.
    pub fn need_semicolon(&self) -> bool {
        !matches!(self, DelimArgs { delim: Delimiter::Brace, .. })
    }
}

/// Represents a macro definition.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub struct MacroDef {
    pub body: Box<DelimArgs>,
    /// `true` if macro was defined with `macro_rules`.
    pub macro_rules: bool,
}

#[derive(Clone, Encodable, Decodable, Debug, Copy, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic, Walkable)]
pub enum StrStyle {
    /// A regular string, like `"foo"`.
    Cooked,
    /// A raw string, like `r##"foo"##`.
    ///
    /// The value is the number of `#` symbols used.
    Raw(u8),
}

/// The kind of match expression
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq, Walkable)]
pub enum MatchKind {
    /// match expr { ... }
    Prefix,
    /// expr.match { ... }
    Postfix,
}

/// The kind of yield expression
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum YieldKind {
    /// yield expr { ... }
    Prefix(Option<Box<Expr>>),
    /// expr.yield { ... }
    Postfix(Box<Expr>),
}

impl YieldKind {
    /// Returns the expression inside the yield expression, if any.
    ///
    /// For postfix yields, this is guaranteed to be `Some`.
    pub const fn expr(&self) -> Option<&Box<Expr>> {
        match self {
            YieldKind::Prefix(expr) => expr.as_ref(),
            YieldKind::Postfix(expr) => Some(expr),
        }
    }

    /// Returns a mutable reference to the expression being yielded, if any.
    pub const fn expr_mut(&mut self) -> Option<&mut Box<Expr>> {
        match self {
            YieldKind::Prefix(expr) => expr.as_mut(),
            YieldKind::Postfix(expr) => Some(expr),
        }
    }

    /// Returns true if both yields are prefix or both are postfix.
    pub const fn same_kind(&self, other: &Self) -> bool {
        match (self, other) {
            (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
            (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
            _ => false,
        }
    }
}

/// A literal in a meta item.
#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MetaItemLit {
    /// The original literal as written in the source code.
    pub symbol: Symbol,
    /// The original suffix as written in the source code.
    pub suffix: Option<Symbol>,
    /// The "semantic" representation of the literal lowered from the original tokens.
    /// Strings are unescaped, hexadecimal forms are eliminated, etc.
    pub kind: LitKind,
    pub span: Span,
}

/// Similar to `MetaItemLit`, but restricted to string literals.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
pub struct StrLit {
    /// The original literal as written in source code.
    pub symbol: Symbol,
    /// The original suffix as written in source code.
    pub suffix: Option<Symbol>,
    /// The semantic (unescaped) representation of the literal.
    pub symbol_unescaped: Symbol,
    pub style: StrStyle,
    pub span: Span,
}

impl StrLit {
    pub fn as_token_lit(&self) -> token::Lit {
        let token_kind = match self.style {
            StrStyle::Cooked => token::Str,
            StrStyle::Raw(n) => token::StrRaw(n),
        };
        token::Lit::new(token_kind, self.symbol, self.suffix)
    }
}

/// Type of the integer literal based on provided suffix.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum LitIntType {
    /// e.g. `42_i32`.
    Signed(IntTy),
    /// e.g. `42_u32`.
    Unsigned(UintTy),
    /// e.g. `42`.
    Unsuffixed,
}

/// Type of the float literal based on provided suffix.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum LitFloatType {
    /// A float literal with a suffix (`1f32` or `1E10f32`).
    Suffixed(FloatTy),
    /// A float literal without a suffix (`1.0 or 1.0E10`).
    Unsuffixed,
}

/// This type is used within both `ast::MetaItemLit` and `hir::Lit`.
///
/// Note that the entire literal (including the suffix) is considered when
/// deciding the `LitKind`. This means that float literals like `1f32` are
/// classified by this type as `Float`. This is different to `token::LitKind`
/// which does *not* consider the suffix.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
pub enum LitKind {
    /// A string literal (`"foo"`). The symbol is unescaped, and so may differ
    /// from the original token's symbol.
    Str(Symbol, StrStyle),
    /// A byte string (`b"foo"`). The symbol is unescaped, and so may differ
    /// from the original token's symbol.
    ByteStr(ByteSymbol, StrStyle),
    /// A C String (`c"foo"`). Guaranteed to only have `\0` at the end. The
    /// symbol is unescaped, and so may differ from the original token's
    /// symbol.
    CStr(ByteSymbol, StrStyle),
    /// A byte char (`b'f'`).
    Byte(u8),
    /// A character literal (`'a'`).
    Char(char),
    /// An integer literal (`1`).
    Int(Pu128, LitIntType),
    /// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
    /// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
    /// and `Hash`.
    Float(Symbol, LitFloatType),
    /// A boolean literal (`true`, `false`).
    Bool(bool),
    /// Placeholder for a literal that wasn't well-formed in some way.
    Err(ErrorGuaranteed),
}

impl LitKind {
    pub fn str(&self) -> Option<Symbol> {
        match *self {
            LitKind::Str(s, _) => Some(s),
            _ => None,
        }
    }

    /// Returns `true` if this literal is a string.
    pub fn is_str(&self) -> bool {
        matches!(self, LitKind::Str(..))
    }

    /// Returns `true` if this literal is byte literal string.
    pub fn is_bytestr(&self) -> bool {
        matches!(self, LitKind::ByteStr(..))
    }

    /// Returns `true` if this is a numeric literal.
    pub fn is_numeric(&self) -> bool {
        matches!(self, LitKind::Int(..) | LitKind::Float(..))
    }

    /// Returns `true` if this literal has no suffix.
    /// Note: this will return true for literals with prefixes such as raw strings and byte strings.
    pub fn is_unsuffixed(&self) -> bool {
        !self.is_suffixed()
    }

    /// Returns `true` if this literal has a suffix.
    pub fn is_suffixed(&self) -> bool {
        match *self {
            // suffixed variants
            LitKind::Int(_, LitIntType::Signed(..) | LitIntType::Unsigned(..))
            | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
            // unsuffixed variants
            LitKind::Str(..)
            | LitKind::ByteStr(..)
            | LitKind::CStr(..)
            | LitKind::Byte(..)
            | LitKind::Char(..)
            | LitKind::Int(_, LitIntType::Unsuffixed)
            | LitKind::Float(_, LitFloatType::Unsuffixed)
            | LitKind::Bool(..)
            | LitKind::Err(_) => false,
        }
    }
}

// N.B., If you change this, you'll probably want to change the corresponding
// type structure in `middle/ty.rs` as well.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct MutTy {
    pub ty: Box<Ty>,
    pub mutbl: Mutability,
}

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

impl FnSig {
    /// Return a span encompassing the header, or where to insert it if empty.
    pub fn header_span(&self) -> Span {
        match self.header.ext {
            Extern::Implicit(span) | Extern::Explicit(_, span) => {
                return self.span.with_hi(span.hi());
            }
            Extern::None => {}
        }

        match self.header.safety {
            Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
            Safety::Default => {}
        };

        if let Some(coroutine_kind) = self.header.coroutine_kind {
            return self.span.with_hi(coroutine_kind.span().hi());
        }

        if let Const::Yes(span) = self.header.constness {
            return self.span.with_hi(span.hi());
        }

        self.span.shrink_to_lo()
    }

    /// The span of the header's safety, or where to insert it if empty.
    pub fn safety_span(&self) -> Span {
        match self.header.safety {
            Safety::Unsafe(span) | Safety::Safe(span) => span,
            Safety::Default => {
                // Insert after the `coroutine_kind` if available.
                if let Some(extern_span) = self.header.ext.span() {
                    return extern_span.shrink_to_lo();
                }

                // Insert right at the front of the signature.
                self.header_span().shrink_to_hi()
            }
        }
    }

    /// The span of the header's extern, or where to insert it if empty.
    pub fn extern_span(&self) -> Span {
        self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
    }
}

/// 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(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct AssocItemConstraint {
    pub id: NodeId,
    pub ident: Ident,
    pub gen_args: Option<GenericArgs>,
    pub kind: AssocItemConstraintKind,
    pub span: Span,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum Term {
    Ty(Box<Ty>),
    Const(AnonConst),
}

impl From<Box<Ty>> for Term {
    fn from(v: Box<Ty>) -> Self {
        Term::Ty(v)
    }
}

impl From<AnonConst> for Term {
    fn from(v: AnonConst) -> Self {
        Term::Const(v)
    }
}

/// The kind of [associated item constraint][AssocItemConstraint].
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum AssocItemConstraintKind {
    /// 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 },
    /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
    Bound {
        #[visitable(extra = BoundKind::Bound)]
        bounds: GenericBounds,
    },
}

#[derive(Encodable, Decodable, Debug, Walkable)]
pub struct Ty {
    pub id: NodeId,
    pub kind: TyKind,
    pub span: Span,
    pub tokens: Option<LazyAttrTokenStream>,
}

impl Clone for Ty {
    fn clone(&self) -> Self {
        ensure_sufficient_stack(|| Self {
            id: self.id,
            kind: self.kind.clone(),
            span: self.span,
            tokens: self.tokens.clone(),
        })
    }
}

impl From<Box<Ty>> for Ty {
    fn from(value: Box<Ty>) -> Self {
        *value
    }
}

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

    pub fn is_maybe_parenthesised_infer(&self) -> bool {
        match &self.kind {
            TyKind::Infer => true,
            TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
            _ => false,
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct FnPtrTy {
    pub safety: Safety,
    pub ext: Extern,
    pub generic_params: ThinVec<GenericParam>,
    pub decl: Box<FnDecl>,
    /// Span of the `[unsafe] [extern] fn(...) -> ...` part, i.e. everything
    /// after the generic params (if there are any, e.g. `for<'a>`).
    pub decl_span: Span,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct UnsafeBinderTy {
    pub generic_params: ThinVec<GenericParam>,
    pub inner_ty: Box<Ty>,
}

/// The various kinds of type recognized by the compiler.
//
// Adding a new variant? Please update `test_ty` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum TyKind {
    /// A variable-length slice (`[T]`).
    Slice(Box<Ty>),
    /// A fixed length array (`[T; n]`).
    Array(Box<Ty>, AnonConst),
    /// A raw pointer (`*const T` or `*mut T`).
    Ptr(MutTy),
    /// A reference (`&'a T` or `&'a mut T`).
    Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
    /// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
    ///
    /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
    PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
    /// A function pointer type (e.g., `fn(usize) -> bool`).
    FnPtr(Box<FnPtrTy>),
    /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
    UnsafeBinder(Box<UnsafeBinderTy>),
    /// The never type (`!`).
    Never,
    /// A tuple (`(A, B, C, D,...)`).
    Tup(ThinVec<Box<Ty>>),
    /// A path (`module::module::...::Type`), optionally
    /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
    ///
    /// Type parameters are stored in the `Path` itself.
    Path(Option<Box<QSelf>>, Path),
    /// A trait object type `Bound1 + Bound2 + Bound3`
    /// where `Bound` is a trait or a lifetime.
    TraitObject(#[visitable(extra = BoundKind::TraitObject)] GenericBounds, TraitObjectSyntax),
    /// An `impl Bound1 + Bound2 + Bound3` type
    /// where `Bound` is a trait or a lifetime.
    ///
    /// The `NodeId` exists to prevent lowering from having to
    /// generate `NodeId`s on the fly, which would complicate
    /// the generation of opaque `type Foo = impl Trait` items significantly.
    ImplTrait(NodeId, #[visitable(extra = BoundKind::Impl)] GenericBounds),
    /// No-op; kept solely so that we can pretty-print faithfully.
    Paren(Box<Ty>),
    /// Unused for now.
    Typeof(AnonConst),
    /// This means the type should be inferred instead of it having been
    /// specified. This can appear anywhere in a type.
    Infer,
    /// Inferred type of a `self` or `&self` argument in a method.
    ImplicitSelf,
    /// A macro in the type position.
    MacCall(Box<MacCall>),
    /// Placeholder for a `va_list`.
    CVarArgs,
    /// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
    /// just as part of the type system.
    Pat(Box<Ty>, Box<TyPat>),
    /// Sometimes we need a dummy value when no error has occurred.
    Dummy,
    /// Placeholder for a kind that has failed to be defined.
    Err(ErrorGuaranteed),
}

impl TyKind {
    pub fn is_implicit_self(&self) -> bool {
        matches!(self, TyKind::ImplicitSelf)
    }

    pub fn is_unit(&self) -> bool {
        matches!(self, TyKind::Tup(tys) if tys.is_empty())
    }

    pub fn is_simple_path(&self) -> Option<Symbol> {
        if let TyKind::Path(None, Path { segments, .. }) = &self
            && let [segment] = &segments[..]
            && segment.args.is_none()
        {
            Some(segment.ident.name)
        } else {
            None
        }
    }

    /// Returns `true` if this type is considered a scalar primitive (e.g.,
    /// `i32`, `u8`, `bool`, etc).
    ///
    /// This check is based on **symbol equality** and does **not** remove any
    /// path prefixes or references. If a type alias or shadowing is present
    /// (e.g., `type i32 = CustomType;`), this method will still return `true`
    /// for `i32`, even though it may not refer to the primitive type.
    pub fn maybe_scalar(&self) -> bool {
        let Some(ty_sym) = self.is_simple_path() else {
            // unit type
            return self.is_unit();
        };
        matches!(
            ty_sym,
            sym::i8
                | sym::i16
                | sym::i32
                | sym::i64
                | sym::i128
                | sym::u8
                | sym::u16
                | sym::u32
                | sym::u64
                | sym::u128
                | sym::f16
                | sym::f32
                | sym::f64
                | sym::f128
                | sym::char
                | sym::bool
        )
    }
}

/// A pattern type pattern.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct TyPat {
    pub id: NodeId,
    pub kind: TyPatKind,
    pub span: Span,
    pub tokens: Option<LazyAttrTokenStream>,
}

/// All the different flavors of pattern that Rust recognizes.
//
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum TyPatKind {
    /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
    Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),

    /// A `!null` pattern for raw pointers.
    NotNull,

    Or(ThinVec<TyPat>),

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

/// Syntax used to declare a trait object.
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
#[repr(u8)]
pub enum TraitObjectSyntax {
    // SAFETY: When adding new variants make sure to update the `Tag` impl.
    Dyn = 0,
    None = 1,
}

/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
/// it can be represented with a `u2`. We use `repr(u8)` to guarantee the
/// discriminants of the variants are no greater than `3`.
unsafe impl Tag for TraitObjectSyntax {
    const BITS: u32 = 2;

    fn into_usize(self) -> usize {
        self as u8 as usize
    }

    unsafe fn from_usize(tag: usize) -> Self {
        match tag {
            0 => TraitObjectSyntax::Dyn,
            1 => TraitObjectSyntax::None,
            _ => unreachable!(),
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum PreciseCapturingArg {
    /// Lifetime parameter.
    Lifetime(#[visitable(extra = LifetimeCtxt::GenericArg)] Lifetime),
    /// Type or const parameter.
    Arg(Path, NodeId),
}

/// Inline assembly operand explicit register or register class.
///
/// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
pub enum InlineAsmRegOrRegClass {
    Reg(Symbol),
    RegClass(Symbol),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
pub struct InlineAsmOptions(u16);
bitflags::bitflags! {
    impl InlineAsmOptions: u16 {
        const PURE            = 1 << 0;
        const NOMEM           = 1 << 1;
        const READONLY        = 1 << 2;
        const PRESERVES_FLAGS = 1 << 3;
        const NORETURN        = 1 << 4;
        const NOSTACK         = 1 << 5;
        const ATT_SYNTAX      = 1 << 6;
        const RAW             = 1 << 7;
        const MAY_UNWIND      = 1 << 8;
    }
}

impl InlineAsmOptions {
    pub const COUNT: usize = Self::all().bits().count_ones() as usize;

    pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);

    pub fn human_readable_names(&self) -> Vec<&'static str> {
        let mut options = vec![];

        if self.contains(InlineAsmOptions::PURE) {
            options.push("pure");
        }
        if self.contains(InlineAsmOptions::NOMEM) {
            options.push("nomem");
        }
        if self.contains(InlineAsmOptions::READONLY) {
            options.push("readonly");
        }
        if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
            options.push("preserves_flags");
        }
        if self.contains(InlineAsmOptions::NORETURN) {
            options.push("noreturn");
        }
        if self.contains(InlineAsmOptions::NOSTACK) {
            options.push("nostack");
        }
        if self.contains(InlineAsmOptions::ATT_SYNTAX) {
            options.push("att_syntax");
        }
        if self.contains(InlineAsmOptions::RAW) {
            options.push("raw");
        }
        if self.contains(InlineAsmOptions::MAY_UNWIND) {
            options.push("may_unwind");
        }

        options
    }
}

impl std::fmt::Debug for InlineAsmOptions {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        bitflags::parser::to_writer(self, f)
    }
}

#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic, Walkable)]
pub enum InlineAsmTemplatePiece {
    String(Cow<'static, str>),
    Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
}

impl fmt::Display for InlineAsmTemplatePiece {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::String(s) => {
                for c in s.chars() {
                    match c {
                        '{' => f.write_str("{{")?,
                        '}' => f.write_str("}}")?,
                        _ => c.fmt(f)?,
                    }
                }
                Ok(())
            }
            Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => {
                write!(f, "{{{operand_idx}:{modifier}}}")
            }
            Self::Placeholder { operand_idx, modifier: None, .. } => {
                write!(f, "{{{operand_idx}}}")
            }
        }
    }
}

impl InlineAsmTemplatePiece {
    /// Rebuilds the asm template string from its pieces.
    pub fn to_string(s: &[Self]) -> String {
        use fmt::Write;
        let mut out = String::new();
        for p in s.iter() {
            let _ = write!(out, "{p}");
        }
        out
    }
}

/// Inline assembly symbol operands get their own AST node that is somewhat
/// similar to `AnonConst`.
///
/// The main difference is that we specifically don't assign it `DefId` in
/// `DefCollector`. Instead this is deferred until AST lowering where we
/// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
/// depending on what the path resolves to.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct InlineAsmSym {
    pub id: NodeId,
    pub qself: Option<Box<QSelf>>,
    pub path: Path,
}

/// Inline assembly operand.
///
/// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum InlineAsmOperand {
    In {
        reg: InlineAsmRegOrRegClass,
        expr: Box<Expr>,
    },
    Out {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        expr: Option<Box<Expr>>,
    },
    InOut {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        expr: Box<Expr>,
    },
    SplitInOut {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        in_expr: Box<Expr>,
        out_expr: Option<Box<Expr>>,
    },
    Const {
        anon_const: AnonConst,
    },
    Sym {
        sym: InlineAsmSym,
    },
    Label {
        block: Box<Block>,
    },
}

impl InlineAsmOperand {
    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::Sym { .. } | Self::Label { .. } => None,
        }
    }
}

#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
pub enum AsmMacro {
    /// The `asm!` macro
    Asm,
    /// The `global_asm!` macro
    GlobalAsm,
    /// The `naked_asm!` macro
    NakedAsm,
}

impl AsmMacro {
    pub const fn macro_name(self) -> &'static str {
        match self {
            AsmMacro::Asm => "asm",
            AsmMacro::GlobalAsm => "global_asm",
            AsmMacro::NakedAsm => "naked_asm",
        }
    }

    pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
        match self {
            AsmMacro::Asm => true,
            AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
            AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
        }
    }

    pub const fn diverges(self, options: InlineAsmOptions) -> bool {
        match self {
            AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
            AsmMacro::GlobalAsm => true,
            AsmMacro::NakedAsm => true,
        }
    }
}

/// Inline assembly.
///
/// E.g., `asm!("NOP");`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct InlineAsm {
    pub asm_macro: AsmMacro,
    pub template: Vec<InlineAsmTemplatePiece>,
    pub template_strs: Box<[(Symbol, Option<Symbol>, Span)]>,
    pub operands: Vec<(InlineAsmOperand, Span)>,
    pub clobber_abis: Vec<(Symbol, Span)>,
    #[visitable(ignore)]
    pub options: InlineAsmOptions,
    pub line_spans: Vec<Span>,
}

/// A parameter in a function header.
///
/// E.g., `bar: usize` as in `fn foo(bar: usize)`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Param {
    pub attrs: AttrVec,
    pub ty: Box<Ty>,
    pub pat: Box<Pat>,
    pub id: NodeId,
    pub span: Span,
    pub is_placeholder: bool,
}

/// Alternative representation for `Arg`s describing `self` parameter of methods.
///
/// E.g., `&mut self` as in `fn foo(&mut self)`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum SelfKind {
    /// `self`, `mut self`
    Value(Mutability),
    /// `&'lt self`, `&'lt mut self`
    Region(Option<Lifetime>, Mutability),
    /// `&'lt pin const self`, `&'lt pin mut self`
    Pinned(Option<Lifetime>, Mutability),
    /// `self: TYPE`, `mut self: TYPE`
    Explicit(Box<Ty>, Mutability),
}

impl SelfKind {
    pub fn to_ref_suggestion(&self) -> String {
        match self {
            SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
            SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
            SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
            SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
            SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
                unreachable!("if we had an explicit self, we wouldn't be here")
            }
        }
    }
}

pub type ExplicitSelf = Spanned<SelfKind>;

impl Param {
    /// Attempts to cast parameter to `ExplicitSelf`.
    pub fn to_self(&self) -> Option<ExplicitSelf> {
        if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind {
            if ident.name == kw::SelfLower {
                return match self.ty.kind {
                    TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
                    }
                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
                        if ty.kind.is_implicit_self() =>
                    {
                        Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
                    }
                    _ => Some(respan(
                        self.pat.span.to(self.ty.span),
                        SelfKind::Explicit(self.ty.clone(), mutbl),
                    )),
                };
            }
        }
        None
    }

    /// Returns `true` if parameter is `self`.
    pub fn is_self(&self) -> bool {
        if let PatKind::Ident(_, ident, _) = self.pat.kind {
            ident.name == kw::SelfLower
        } else {
            false
        }
    }

    /// Builds a `Param` object from `ExplicitSelf`.
    pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Param {
        let span = eself.span.to(eself_ident.span);
        let infer_ty = Box::new(Ty {
            id: DUMMY_NODE_ID,
            kind: TyKind::ImplicitSelf,
            span: eself_ident.span,
            tokens: None,
        });
        let (mutbl, ty) = match eself.node {
            SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
            SelfKind::Value(mutbl) => (mutbl, infer_ty),
            SelfKind::Region(lt, mutbl) => (
                Mutability::Not,
                Box::new(Ty {
                    id: DUMMY_NODE_ID,
                    kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
                    span,
                    tokens: None,
                }),
            ),
            SelfKind::Pinned(lt, mutbl) => (
                mutbl,
                Box::new(Ty {
                    id: DUMMY_NODE_ID,
                    kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
                    span,
                    tokens: None,
                }),
            ),
        };
        Param {
            attrs,
            pat: Box::new(Pat {
                id: DUMMY_NODE_ID,
                kind: PatKind::Ident(BindingMode(ByRef::No, mutbl), eself_ident, None),
                span,
                tokens: None,
            }),
            span,
            ty,
            id: DUMMY_NODE_ID,
            is_placeholder: false,
        }
    }
}

/// A signature (not the body) of a function declaration.
///
/// E.g., `fn foo(bar: baz)`.
///
/// Please note that it's different from `FnHeader` structure
/// which contains metadata about function safety, asyncness, constness and ABI.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct FnDecl {
    pub inputs: ThinVec<Param>,
    pub output: FnRetTy,
}

impl FnDecl {
    pub fn has_self(&self) -> bool {
        self.inputs.get(0).is_some_and(Param::is_self)
    }
    pub fn c_variadic(&self) -> bool {
        self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
    }
}

/// Is the trait definition an auto trait?
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub enum IsAuto {
    Yes,
    No,
}

/// Safety of items.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic, Walkable)]
pub enum Safety {
    /// `unsafe` an item is explicitly marked as `unsafe`.
    Unsafe(Span),
    /// `safe` an item is explicitly marked as `safe`.
    Safe(Span),
    /// Default means no value was provided, it will take a default value given the context in
    /// which is used.
    Default,
}

/// Describes what kind of coroutine markers, if any, a function has.
///
/// Coroutine markers are things that cause the function to generate a coroutine, such as `async`,
/// which makes the function return `impl Future`, or `gen`, which makes the function return `impl
/// Iterator`.
#[derive(Copy, Clone, Encodable, Decodable, Debug, Walkable)]
pub enum CoroutineKind {
    /// `async`, which returns an `impl Future`.
    Async { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
    /// `gen`, which returns an `impl Iterator`.
    Gen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
    /// `async gen`, which returns an `impl AsyncIterator`.
    AsyncGen { span: Span, closure_id: NodeId, return_impl_trait_id: NodeId },
}

impl CoroutineKind {
    pub fn span(self) -> Span {
        match self {
            CoroutineKind::Async { span, .. } => span,
            CoroutineKind::Gen { span, .. } => span,
            CoroutineKind::AsyncGen { span, .. } => span,
        }
    }

    pub fn as_str(self) -> &'static str {
        match self {
            CoroutineKind::Async { .. } => "async",
            CoroutineKind::Gen { .. } => "gen",
            CoroutineKind::AsyncGen { .. } => "async gen",
        }
    }

    pub fn closure_id(self) -> NodeId {
        match self {
            CoroutineKind::Async { closure_id, .. }
            | CoroutineKind::Gen { closure_id, .. }
            | CoroutineKind::AsyncGen { closure_id, .. } => closure_id,
        }
    }

    /// In this case this is an `async` or `gen` return, the `NodeId` for the generated `impl Trait`
    /// item.
    pub fn return_id(self) -> (NodeId, Span) {
        match self {
            CoroutineKind::Async { return_impl_trait_id, span, .. }
            | CoroutineKind::Gen { return_impl_trait_id, span, .. }
            | CoroutineKind::AsyncGen { return_impl_trait_id, span, .. } => {
                (return_impl_trait_id, span)
            }
        }
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic, Walkable)]
pub enum Const {
    Yes(Span),
    No,
}

/// Item defaultness.
/// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532).
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
pub enum Defaultness {
    Default(Span),
    Final,
}

#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum ImplPolarity {
    /// `impl Trait for Type`
    Positive,
    /// `impl !Trait for Type`
    Negative(Span),
}

impl fmt::Debug for ImplPolarity {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            ImplPolarity::Positive => "positive".fmt(f),
            ImplPolarity::Negative(_) => "negative".fmt(f),
        }
    }
}

/// The polarity of a trait bound.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
#[derive(HashStable_Generic, Walkable)]
pub enum BoundPolarity {
    /// `Type: Trait`
    Positive,
    /// `Type: !Trait`
    Negative(Span),
    /// `Type: ?Trait`
    Maybe(Span),
}

impl BoundPolarity {
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Positive => "",
            Self::Negative(_) => "!",
            Self::Maybe(_) => "?",
        }
    }
}

/// The constness of a trait bound.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, Hash)]
#[derive(HashStable_Generic, Walkable)]
pub enum BoundConstness {
    /// `Type: Trait`
    Never,
    /// `Type: const Trait`
    Always(Span),
    /// `Type: [const] Trait`
    Maybe(Span),
}

impl BoundConstness {
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Never => "",
            Self::Always(_) => "const",
            Self::Maybe(_) => "[const]",
        }
    }
}

/// The asyncness of a trait bound.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic, Walkable)]
pub enum BoundAsyncness {
    /// `Type: Trait`
    Normal,
    /// `Type: async Trait`
    Async(Span),
}

impl BoundAsyncness {
    pub fn as_str(self) -> &'static str {
        match self {
            Self::Normal => "",
            Self::Async(_) => "async",
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum FnRetTy {
    /// Returns type is not specified.
    ///
    /// Functions default to `()` and closures default to inference.
    /// Span points to where return type would be inserted.
    Default(Span),
    /// Everything else.
    Ty(Box<Ty>),
}

impl FnRetTy {
    pub fn span(&self) -> Span {
        match self {
            &FnRetTy::Default(span) => span,
            FnRetTy::Ty(ty) => ty.span,
        }
    }
}

#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, Walkable)]
pub enum Inline {
    Yes,
    No { had_parse_error: Result<(), ErrorGuaranteed> },
}

/// Module item kind.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum ModKind {
    /// Module with inlined definition `mod foo { ... }`,
    /// or with definition outlined to a separate file `mod foo;` and already loaded from it.
    /// The inner span is from the first token past `{` to the last token until `}`,
    /// or from the first to the last token in the loaded file.
    Loaded(ThinVec<Box<Item>>, Inline, ModSpans),
    /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it.
    Unloaded,
}

#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct ModSpans {
    /// `inner_span` covers the body of the module; for a file module, its the whole file.
    /// For an inline module, its the span inside the `{ ... }`, not including the curly braces.
    pub inner_span: Span,
    pub inject_use_span: Span,
}

/// Foreign module declaration.
///
/// E.g., `extern { .. }` or `extern "C" { .. }`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct ForeignMod {
    /// Span of the `extern` keyword.
    pub extern_span: Span,
    /// `unsafe` keyword accepted syntactically for macro DSLs, but not
    /// semantically by Rust.
    pub safety: Safety,
    pub abi: Option<StrLit>,
    pub items: ThinVec<Box<ForeignItem>>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct EnumDef {
    pub variants: ThinVec<Variant>,
}

/// Enum variant.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Variant {
    /// Attributes of the variant.
    pub attrs: AttrVec,
    /// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
    pub id: NodeId,
    /// Span
    pub span: Span,
    /// The visibility of the variant. Syntactically accepted but not semantically.
    pub vis: Visibility,
    /// Name of the variant.
    pub ident: Ident,

    /// Fields and constructor id of the variant.
    pub data: VariantData,
    /// Explicit discriminant, e.g., `Foo = 1`.
    pub disr_expr: Option<AnonConst>,
    /// Is a macro placeholder.
    pub is_placeholder: bool,
}

/// Part of `use` item to the right of its prefix.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum UseTreeKind {
    /// `use prefix` or `use prefix as rename`
    Simple(Option<Ident>),
    /// `use prefix::{...}`
    ///
    /// The span represents the braces of the nested group and all elements within:
    ///
    /// ```text
    /// use foo::{bar, baz};
    ///          ^^^^^^^^^^
    /// ```
    Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
    /// `use prefix::*`
    Glob,
}

/// A tree of paths sharing common prefixes.
/// Used in `use` items both at top-level and inside of braces in import groups.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct UseTree {
    pub prefix: Path,
    pub kind: UseTreeKind,
    pub span: Span,
}

impl UseTree {
    pub fn ident(&self) -> Ident {
        match self.kind {
            UseTreeKind::Simple(Some(rename)) => rename,
            UseTreeKind::Simple(None) => {
                self.prefix.segments.last().expect("empty prefix in a simple import").ident
            }
            _ => panic!("`UseTree::ident` can only be used on a simple import"),
        }
    }
}

/// Distinguishes between `Attribute`s that decorate items and Attributes that
/// are contained as statements within items. These two cases need to be
/// distinguished for pretty-printing.
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy, HashStable_Generic, Walkable)]
pub enum AttrStyle {
    Outer,
    Inner,
}

/// A list of attributes.
pub type AttrVec = ThinVec<Attribute>;

/// A syntax-level representation of an attribute.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Attribute {
    pub kind: AttrKind,
    pub id: AttrId,
    /// Denotes if the attribute decorates the following construct (outer)
    /// or the construct this attribute is contained within (inner).
    pub style: AttrStyle,
    pub span: Span,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum AttrKind {
    /// A normal attribute.
    Normal(Box<NormalAttr>),

    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
    /// variant (which is much less compact and thus more expensive).
    DocComment(CommentKind, Symbol),
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct NormalAttr {
    pub item: AttrItem,
    // Tokens for the full attribute, e.g. `#[foo]`, `#![bar]`.
    pub tokens: Option<LazyAttrTokenStream>,
}

impl NormalAttr {
    pub fn from_ident(ident: Ident) -> Self {
        Self {
            item: AttrItem {
                unsafety: Safety::Default,
                path: Path::from_ident(ident),
                args: AttrArgs::Empty,
                tokens: None,
            },
            tokens: None,
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct AttrItem {
    pub unsafety: Safety,
    pub path: Path,
    pub args: AttrArgs,
    // Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`.
    pub tokens: Option<LazyAttrTokenStream>,
}

impl AttrItem {
    pub fn is_valid_for_outer_style(&self) -> bool {
        self.path == sym::cfg_attr
            || self.path == sym::cfg
            || self.path == sym::forbid
            || self.path == sym::warn
            || self.path == sym::allow
            || self.path == sym::deny
    }
}

/// `TraitRef`s appear in impls.
///
/// Resolution maps each `TraitRef`'s `ref_id` to its defining trait; that's all
/// that the `ref_id` is for. The `impl_id` maps to the "self type" of this impl.
/// If this impl is an `ItemKind::Impl`, the `impl_id` is redundant (it could be the
/// same as the impl's `NodeId`).
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct TraitRef {
    pub path: Path,
    pub ref_id: NodeId,
}

/// Whether enclosing parentheses are present or not.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum Parens {
    Yes,
    No,
}

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

    // Optional constness, asyncness, or polarity.
    pub modifiers: TraitBoundModifiers,

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

    pub span: Span,

    /// When `Yes`, the first and last character of `span` are an opening
    /// and a closing paren respectively.
    pub parens: Parens,
}

impl PolyTraitRef {
    pub fn new(
        generic_params: ThinVec<GenericParam>,
        path: Path,
        modifiers: TraitBoundModifiers,
        span: Span,
        parens: Parens,
    ) -> Self {
        PolyTraitRef {
            bound_generic_params: generic_params,
            modifiers,
            trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
            span,
            parens,
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Visibility {
    pub kind: VisibilityKind,
    pub span: Span,
    pub tokens: Option<LazyAttrTokenStream>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum VisibilityKind {
    Public,
    Restricted { path: Box<Path>, id: NodeId, shorthand: bool },
    Inherited,
}

impl VisibilityKind {
    pub fn is_pub(&self) -> bool {
        matches!(self, VisibilityKind::Public)
    }
}

/// Field definition in a struct, variant or union.
///
/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct FieldDef {
    pub attrs: AttrVec,
    pub id: NodeId,
    pub span: Span,
    pub vis: Visibility,
    pub safety: Safety,
    pub ident: Option<Ident>,

    pub ty: Box<Ty>,
    pub default: Option<AnonConst>,
    pub is_placeholder: bool,
}

/// Was parsing recovery performed?
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, Walkable)]
pub enum Recovered {
    No,
    Yes(ErrorGuaranteed),
}

/// Fields and constructor ids of enum variants and structs.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum VariantData {
    /// Struct variant.
    ///
    /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
    Struct { fields: ThinVec<FieldDef>, recovered: Recovered },
    /// Tuple variant.
    ///
    /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
    Tuple(ThinVec<FieldDef>, NodeId),
    /// Unit variant.
    ///
    /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
    Unit(NodeId),
}

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

    /// Return the `NodeId` of this variant's constructor, if it has one.
    pub fn ctor_node_id(&self) -> Option<NodeId> {
        match *self {
            VariantData::Struct { .. } => None,
            VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
        }
    }
}

/// An item definition.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Item<K = ItemKind> {
    pub attrs: AttrVec,
    pub id: NodeId,
    pub span: Span,
    pub vis: Visibility,

    pub kind: K,

    /// Original tokens this item was parsed from. This isn't necessarily
    /// available for all items, although over time more and more items should
    /// have this be `Some`. Right now this is primarily used for procedural
    /// macros, notably custom attributes.
    ///
    /// Note that the tokens here do not include the outer attributes, but will
    /// include inner attributes.
    pub tokens: Option<LazyAttrTokenStream>,
}

impl Item {
    /// Return the span that encompasses the attributes.
    pub fn span_with_attributes(&self) -> Span {
        self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
    }

    pub fn opt_generics(&self) -> Option<&Generics> {
        match &self.kind {
            ItemKind::ExternCrate(..)
            | ItemKind::Use(_)
            | ItemKind::Mod(..)
            | ItemKind::ForeignMod(_)
            | ItemKind::GlobalAsm(_)
            | ItemKind::MacCall(_)
            | ItemKind::Delegation(_)
            | ItemKind::DelegationMac(_)
            | ItemKind::MacroDef(..) => None,
            ItemKind::Static(_) => None,
            ItemKind::Const(i) => Some(&i.generics),
            ItemKind::Fn(i) => Some(&i.generics),
            ItemKind::TyAlias(i) => Some(&i.generics),
            ItemKind::TraitAlias(_, generics, _)
            | ItemKind::Enum(_, generics, _)
            | ItemKind::Struct(_, generics, _)
            | ItemKind::Union(_, generics, _) => Some(&generics),
            ItemKind::Trait(i) => Some(&i.generics),
            ItemKind::Impl(i) => Some(&i.generics),
        }
    }
}

/// `extern` qualifier on a function item or function type.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
pub enum Extern {
    /// No explicit extern keyword was used.
    ///
    /// E.g. `fn foo() {}`.
    None,
    /// An explicit extern keyword was used, but with implicit ABI.
    ///
    /// E.g. `extern fn foo() {}`.
    ///
    /// This is just `extern "C"` (see `rustc_abi::ExternAbi::FALLBACK`).
    Implicit(Span),
    /// An explicit extern keyword was used with an explicit ABI.
    ///
    /// E.g. `extern "C" fn foo() {}`.
    Explicit(StrLit, Span),
}

impl Extern {
    pub fn from_abi(abi: Option<StrLit>, span: Span) -> Extern {
        match abi {
            Some(name) => Extern::Explicit(name, span),
            None => Extern::Implicit(span),
        }
    }

    pub fn span(self) -> Option<Span> {
        match self {
            Extern::None => None,
            Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
        }
    }
}

/// A function header.
///
/// All the information between the visibility and the name of the function is
/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
pub struct FnHeader {
    /// The `const` keyword, if any
    pub constness: Const,
    /// Whether this is `async`, `gen`, or nothing.
    pub coroutine_kind: Option<CoroutineKind>,
    /// Whether this is `unsafe`, or has a default safety.
    pub safety: Safety,
    /// The `extern` keyword and corresponding ABI string, if any.
    pub ext: Extern,
}

impl FnHeader {
    /// Does this function header have any qualifiers or is it empty?
    pub fn has_qualifiers(&self) -> bool {
        let Self { safety, coroutine_kind, constness, ext } = self;
        matches!(safety, Safety::Unsafe(_))
            || coroutine_kind.is_some()
            || matches!(constness, Const::Yes(_))
            || !matches!(ext, Extern::None)
    }
}

impl Default for FnHeader {
    fn default() -> FnHeader {
        FnHeader {
            safety: Safety::Default,
            coroutine_kind: None,
            constness: Const::No,
            ext: Extern::None,
        }
    }
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Trait {
    pub constness: Const,
    pub safety: Safety,
    pub is_auto: IsAuto,
    pub ident: Ident,
    pub generics: Generics,
    #[visitable(extra = BoundKind::SuperTraits)]
    pub bounds: GenericBounds,
    #[visitable(extra = AssocCtxt::Trait)]
    pub items: ThinVec<Box<AssocItem>>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct TyAlias {
    pub defaultness: Defaultness,
    pub ident: Ident,
    pub generics: Generics,
    /// There are two locations for where clause on type aliases. This represents the second
    /// where clause, before the semicolon. The first where clause is stored inside `generics`.
    ///
    /// Take this example:
    /// ```ignore (only-for-syntax-highlight)
    /// trait Foo {
    ///   type Assoc<'a, 'b> where Self: 'a, Self: 'b;
    /// }
    /// impl Foo for () {
    ///   type Assoc<'a, 'b> where Self: 'a = () where Self: 'b;
    ///   //                 ^^^^^^^^^^^^^^ before where clause
    ///   //                                     ^^^^^^^^^^^^^^ after where clause
    /// }
    /// ```
    pub after_where_clause: WhereClause,
    #[visitable(extra = BoundKind::Bound)]
    pub bounds: GenericBounds,
    pub ty: Option<Box<Ty>>,
}

#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Impl {
    pub generics: Generics,
    pub of_trait: Option<Box<TraitImplHeader>>,
    pub self_ty: Box<Ty>,
    pub items: ThinVec<Box<AssocItem>>,
}

#[derive(Clone, Encodable, Decodable, Debug)]
pub struct TraitImplHeader {
    pub defaultness: Defaultness,
    pub safety: Safety,
    pub constness: Const,
    pub polarity: ImplPolarity,
    pub trait_ref: TraitRef,
}

#[derive(Clone, Encodable, Decodable, Debug, Default, Walkable)]
pub struct FnContract {
    pub requires: Option<Box<Expr>>,
    pub ensures: Option<Box<Expr>>,
}

#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Fn {
    pub defaultness: Defaultness,
    pub ident: Ident,
    pub generics: Generics,
    pub sig: FnSig,
    pub contract: Option<Box<FnContract>>,
    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
    pub body: Option<Box<Block>>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Delegation {
    /// Path resolution id.
    pub id: NodeId,
    pub qself: Option<Box<QSelf>>,
    pub path: Path,
    pub ident: Ident,
    pub rename: Option<Ident>,
    pub body: Option<Box<Block>>,
    /// The item was expanded from a glob delegation item.
    pub from_glob: bool,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct DelegationMac {
    pub qself: Option<Box<QSelf>>,
    pub prefix: Path,
    // Some for list delegation, and None for glob delegation.
    pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
    pub body: Option<Box<Block>>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct StaticItem {
    pub ident: Ident,
    pub ty: Box<Ty>,
    pub safety: Safety,
    pub mutability: Mutability,
    pub expr: Option<Box<Expr>>,
    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct ConstItem {
    pub defaultness: Defaultness,
    pub ident: Ident,
    pub generics: Generics,
    pub ty: Box<Ty>,
    pub expr: Option<Box<Expr>>,
    pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
}

// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ItemKind {
    /// An `extern crate` item, with the 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),
    /// A use declaration item (`use`).
    ///
    /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
    Use(UseTree),
    /// A static item (`static`).
    ///
    /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
    Static(Box<StaticItem>),
    /// A constant item (`const`).
    ///
    /// E.g., `const FOO: i32 = 42;`.
    Const(Box<ConstItem>),
    /// A function declaration (`fn`).
    ///
    /// E.g., `fn foo(bar: usize) -> usize { .. }`.
    Fn(Box<Fn>),
    /// A module declaration (`mod`).
    ///
    /// E.g., `mod foo;` or `mod foo { .. }`.
    /// `unsafe` keyword on modules is accepted syntactically for macro DSLs, but not
    /// semantically by Rust.
    Mod(Safety, Ident, ModKind),
    /// An external module (`extern`).
    ///
    /// E.g., `extern {}` or `extern "C" {}`.
    ForeignMod(ForeignMod),
    /// Module-level inline assembly (from `global_asm!()`).
    GlobalAsm(Box<InlineAsm>),
    /// A type alias (`type`).
    ///
    /// E.g., `type Foo = Bar<u8>;`.
    TyAlias(Box<TyAlias>),
    /// An enum definition (`enum`).
    ///
    /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
    Enum(Ident, Generics, EnumDef),
    /// A struct definition (`struct`).
    ///
    /// E.g., `struct Foo<A> { x: A }`.
    Struct(Ident, Generics, VariantData),
    /// A union definition (`union`).
    ///
    /// E.g., `union Foo<A, B> { x: A, y: B }`.
    Union(Ident, Generics, VariantData),
    /// A trait declaration (`trait`).
    ///
    /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
    Trait(Box<Trait>),
    /// Trait alias.
    ///
    /// E.g., `trait Foo = Bar + Quux;`.
    TraitAlias(Ident, Generics, GenericBounds),
    /// An implementation.
    ///
    /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
    Impl(Impl),
    /// A macro invocation.
    ///
    /// E.g., `foo!(..)`.
    MacCall(Box<MacCall>),
    /// A macro definition.
    MacroDef(Ident, MacroDef),
    /// A single delegation item (`reuse`).
    ///
    /// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
    Delegation(Box<Delegation>),
    /// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`).
    /// Treated similarly to a macro call and expanded early.
    DelegationMac(Box<DelegationMac>),
}

impl ItemKind {
    pub fn ident(&self) -> Option<Ident> {
        match *self {
            ItemKind::ExternCrate(_, ident)
            | ItemKind::Static(box StaticItem { ident, .. })
            | ItemKind::Const(box ConstItem { ident, .. })
            | ItemKind::Fn(box Fn { ident, .. })
            | ItemKind::Mod(_, ident, _)
            | ItemKind::TyAlias(box TyAlias { ident, .. })
            | ItemKind::Enum(ident, ..)
            | ItemKind::Struct(ident, ..)
            | ItemKind::Union(ident, ..)
            | ItemKind::Trait(box Trait { ident, .. })
            | ItemKind::TraitAlias(ident, ..)
            | ItemKind::MacroDef(ident, _)
            | ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),

            ItemKind::Use(_)
            | ItemKind::ForeignMod(_)
            | ItemKind::GlobalAsm(_)
            | ItemKind::Impl(_)
            | ItemKind::MacCall(_)
            | ItemKind::DelegationMac(_) => None,
        }
    }

    /// "a" or "an"
    pub fn article(&self) -> &'static str {
        use ItemKind::*;
        match self {
            Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
            | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
            | Delegation(..) | DelegationMac(..) => "a",
            ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
        }
    }

    pub fn descr(&self) -> &'static str {
        match self {
            ItemKind::ExternCrate(..) => "extern crate",
            ItemKind::Use(..) => "`use` import",
            ItemKind::Static(..) => "static item",
            ItemKind::Const(..) => "constant item",
            ItemKind::Fn(..) => "function",
            ItemKind::Mod(..) => "module",
            ItemKind::ForeignMod(..) => "extern block",
            ItemKind::GlobalAsm(..) => "global asm item",
            ItemKind::TyAlias(..) => "type alias",
            ItemKind::Enum(..) => "enum",
            ItemKind::Struct(..) => "struct",
            ItemKind::Union(..) => "union",
            ItemKind::Trait(..) => "trait",
            ItemKind::TraitAlias(..) => "trait alias",
            ItemKind::MacCall(..) => "item macro invocation",
            ItemKind::MacroDef(..) => "macro definition",
            ItemKind::Impl { .. } => "implementation",
            ItemKind::Delegation(..) => "delegated function",
            ItemKind::DelegationMac(..) => "delegation",
        }
    }

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

/// Represents associated items.
/// These include items in `impl` and `trait` definitions.
pub type AssocItem = Item<AssocItemKind>;

/// Represents associated item kinds.
///
/// The term "provided" in the variants below refers to the item having a default
/// definition / body. Meanwhile, a "required" item lacks a definition / body.
/// In an implementation, all items must be provided.
/// The `Option`s below denote the bodies, where `Some(_)`
/// means "provided" and conversely `None` means "required".
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AssocItemKind {
    /// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
    /// If `def` is parsed, then the constant is provided, and otherwise required.
    Const(Box<ConstItem>),
    /// An associated function.
    Fn(Box<Fn>),
    /// An associated type.
    Type(Box<TyAlias>),
    /// A macro expanding to associated items.
    MacCall(Box<MacCall>),
    /// An associated delegation item.
    Delegation(Box<Delegation>),
    /// An associated list or glob delegation item.
    DelegationMac(Box<DelegationMac>),
}

impl AssocItemKind {
    pub fn ident(&self) -> Option<Ident> {
        match *self {
            AssocItemKind::Const(box ConstItem { ident, .. })
            | AssocItemKind::Fn(box Fn { ident, .. })
            | AssocItemKind::Type(box TyAlias { ident, .. })
            | AssocItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),

            AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(_) => None,
        }
    }

    pub fn defaultness(&self) -> Defaultness {
        match *self {
            Self::Const(box ConstItem { defaultness, .. })
            | Self::Fn(box Fn { defaultness, .. })
            | Self::Type(box TyAlias { defaultness, .. }) => defaultness,
            Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
                Defaultness::Final
            }
        }
    }
}

impl From<AssocItemKind> for ItemKind {
    fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
        match assoc_item_kind {
            AssocItemKind::Const(item) => ItemKind::Const(item),
            AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
            AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
            AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
            AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
            AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
        }
    }
}

impl TryFrom<ItemKind> for AssocItemKind {
    type Error = ItemKind;

    fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
        Ok(match item_kind {
            ItemKind::Const(item) => AssocItemKind::Const(item),
            ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
            ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
            ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
            ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
            ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
            _ => return Err(item_kind),
        })
    }
}

/// An item in `extern` block.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ForeignItemKind {
    /// A foreign static item (`static FOO: u8`).
    Static(Box<StaticItem>),
    /// A foreign function.
    Fn(Box<Fn>),
    /// A foreign type.
    TyAlias(Box<TyAlias>),
    /// A macro expanding to foreign items.
    MacCall(Box<MacCall>),
}

impl ForeignItemKind {
    pub fn ident(&self) -> Option<Ident> {
        match *self {
            ForeignItemKind::Static(box StaticItem { ident, .. })
            | ForeignItemKind::Fn(box Fn { ident, .. })
            | ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => Some(ident),

            ForeignItemKind::MacCall(_) => None,
        }
    }
}

impl From<ForeignItemKind> for ItemKind {
    fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
        match foreign_item_kind {
            ForeignItemKind::Static(box static_foreign_item) => {
                ItemKind::Static(Box::new(static_foreign_item))
            }
            ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
            ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
            ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
        }
    }
}

impl TryFrom<ItemKind> for ForeignItemKind {
    type Error = ItemKind;

    fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
        Ok(match item_kind {
            ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)),
            ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
            ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
            ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
            _ => return Err(item_kind),
        })
    }
}

pub type ForeignItem = Item<ForeignItemKind>;

// 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!(AssocItem, 80);
    static_assert_size!(AssocItemKind, 16);
    static_assert_size!(Attribute, 32);
    static_assert_size!(Block, 32);
    static_assert_size!(Expr, 72);
    static_assert_size!(ExprKind, 40);
    static_assert_size!(Fn, 184);
    static_assert_size!(ForeignItem, 80);
    static_assert_size!(ForeignItemKind, 16);
    static_assert_size!(GenericArg, 24);
    static_assert_size!(GenericBound, 88);
    static_assert_size!(Generics, 40);
    static_assert_size!(Impl, 64);
    static_assert_size!(Item, 144);
    static_assert_size!(ItemKind, 80);
    static_assert_size!(LitKind, 24);
    static_assert_size!(Local, 96);
    static_assert_size!(MetaItemLit, 40);
    static_assert_size!(Param, 40);
    static_assert_size!(Pat, 80);
    static_assert_size!(PatKind, 56);
    static_assert_size!(Path, 24);
    static_assert_size!(PathSegment, 24);
    static_assert_size!(Stmt, 32);
    static_assert_size!(StmtKind, 16);
    static_assert_size!(TraitImplHeader, 80);
    static_assert_size!(Ty, 64);
    static_assert_size!(TyKind, 40);
    // tidy-alphabetical-end
}
