use std::array::IntoIter;
use std::borrow::Cow;
use std::fmt::Debug;

use rustc_ast as ast;
use rustc_ast::NodeId;
use rustc_data_structures::stable_hasher::ToStableHashKey;
use rustc_data_structures::unord::UnordMap;
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::Symbol;
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::hygiene::MacroKind;

use crate::definitions::DefPathData;
use crate::hir;

/// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum CtorOf {
    /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
    Struct,
    /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
    Variant,
}

/// What kind of constructor something is.
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum CtorKind {
    /// Constructor function automatically created by a tuple struct/variant.
    Fn,
    /// Constructor constant automatically created by a unit struct/variant.
    Const,
}

/// A set of macro kinds, for macros that can have more than one kind
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
#[derive(HashStable_Generic)]
pub struct MacroKinds(u8);
bitflags::bitflags! {
    impl MacroKinds: u8 {
        const BANG = 1 << 0;
        const ATTR = 1 << 1;
        const DERIVE = 1 << 2;
    }
}

impl From<MacroKind> for MacroKinds {
    fn from(kind: MacroKind) -> Self {
        match kind {
            MacroKind::Bang => Self::BANG,
            MacroKind::Attr => Self::ATTR,
            MacroKind::Derive => Self::DERIVE,
        }
    }
}

impl MacroKinds {
    /// Convert the MacroKinds to a static string.
    ///
    /// This hardcodes all the possibilities, in order to return a static string.
    pub fn descr(self) -> &'static str {
        match self {
            // FIXME: change this to "function-like macro" and fix all tests
            Self::BANG => "macro",
            Self::ATTR => "attribute macro",
            Self::DERIVE => "derive macro",
            _ if self == (Self::ATTR | Self::BANG) => "attribute/function macro",
            _ if self == (Self::DERIVE | Self::BANG) => "derive/function macro",
            _ if self == (Self::ATTR | Self::DERIVE) => "attribute/derive macro",
            _ if self.is_all() => "attribute/derive/function macro",
            _ if self.is_empty() => "useless macro",
            _ => unreachable!(),
        }
    }

    /// Return an indefinite article (a/an) for use with `descr()`
    pub fn article(self) -> &'static str {
        if self.contains(Self::ATTR) { "an" } else { "a" }
    }
}

/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum NonMacroAttrKind {
    /// Single-segment attribute defined by the language (`#[inline]`)
    Builtin(Symbol),
    /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
    Tool,
    /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
    DeriveHelper,
    /// Single-segment custom attribute registered by a derive macro
    /// but used before that derive macro was expanded (deprecated).
    DeriveHelperCompat,
}

/// What kind of definition something is; e.g., `mod` vs `struct`.
/// `enum DefPathData` may need to be updated if a new variant is added here.
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum DefKind {
    // Type namespace
    Mod,
    /// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.
    Struct,
    Union,
    Enum,
    /// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.
    Variant,
    Trait,
    /// Type alias: `type Foo = Bar;`
    TyAlias,
    /// Type from an `extern` block.
    ForeignTy,
    /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
    TraitAlias,
    /// Associated type: `trait MyTrait { type Assoc; }`
    AssocTy,
    /// Type parameter: the `T` in `struct Vec<T> { ... }`
    TyParam,

    // Value namespace
    Fn,
    Const,
    /// Constant generic parameter: `struct Foo<const N: usize> { ... }`
    ConstParam,
    Static {
        /// Whether it's a `unsafe static`, `safe static` (inside extern only) or just a `static`.
        safety: hir::Safety,
        /// Whether it's a `static mut` or just a `static`.
        mutability: ast::Mutability,
        /// Whether it's an anonymous static generated for nested allocations.
        nested: bool,
    },
    /// Refers to the struct or enum variant's constructor.
    ///
    /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and
    /// [`DefKind::Variant`] is because structs and enum variants exist
    /// in the *type* namespace, whereas struct and enum variant *constructors*
    /// exist in the *value* namespace.
    ///
    /// You may wonder why enum variants exist in the type namespace as opposed
    /// to the value namespace. Check out [RFC 2593] for intuition on why that is.
    ///
    /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593
    Ctor(CtorOf, CtorKind),
    /// Associated function: `impl MyStruct { fn associated() {} }`
    /// or `trait Foo { fn associated() {} }`
    AssocFn,
    /// Associated constant: `trait MyTrait { const ASSOC: usize; }`
    AssocConst,

    // Macro namespace
    Macro(MacroKinds),

    // Not namespaced (or they are, but we don't treat them so)
    ExternCrate,
    Use,
    /// An `extern` block.
    ForeignMod,
    /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`.
    ///
    /// Not all anon-consts are actually still relevant in the HIR. We lower
    /// trivial const-arguments directly to `hir::ConstArgKind::Path`, at which
    /// point the definition for the anon-const ends up unused and incomplete.
    ///
    /// We do not provide any a `Span` for the definition and pretty much all other
    /// queries also ICE when using this `DefId`. Given that the `DefId` of such
    /// constants should only be reachable by iterating all definitions of a
    /// given crate, you should not have to worry about this.
    AnonConst,
    /// An inline constant, e.g. `const { 1 + 2 }`
    InlineConst,
    /// Opaque type, aka `impl Trait`.
    OpaqueTy,
    /// A field in a struct, enum or union. e.g.
    /// - `bar` in `struct Foo { bar: u8 }`
    /// - `Foo::Bar::0` in `enum Foo { Bar(u8) }`
    Field,
    /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
    LifetimeParam,
    /// A use of `global_asm!`.
    GlobalAsm,
    Impl {
        of_trait: bool,
    },
    /// A closure, coroutine, or coroutine-closure.
    ///
    /// These are all represented with the same `ExprKind::Closure` in the AST and HIR,
    /// which makes it difficult to distinguish these during def collection. Therefore,
    /// we treat them all the same, and code which needs to distinguish them can match
    /// or `hir::ClosureKind` or `type_of`.
    Closure,
    /// The definition of a synthetic coroutine body created by the lowering of a
    /// coroutine-closure, such as an async closure.
    SyntheticCoroutineBody,
}

impl DefKind {
    /// Get an English description for the item's kind.
    ///
    /// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or
    /// `TyCtxt::def_kind_descr` instead, because they give better
    /// information for coroutines and associated functions.
    pub fn descr(self, def_id: DefId) -> &'static str {
        match self {
            DefKind::Fn => "function",
            DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate",
            DefKind::Mod => "module",
            DefKind::Static { .. } => "static",
            DefKind::Enum => "enum",
            DefKind::Variant => "variant",
            DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",
            DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",
            DefKind::Struct => "struct",
            DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
            DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
            DefKind::OpaqueTy => "opaque type",
            DefKind::TyAlias => "type alias",
            DefKind::TraitAlias => "trait alias",
            DefKind::AssocTy => "associated type",
            DefKind::Union => "union",
            DefKind::Trait => "trait",
            DefKind::ForeignTy => "foreign type",
            DefKind::AssocFn => "associated function",
            DefKind::Const => "constant",
            DefKind::AssocConst => "associated constant",
            DefKind::TyParam => "type parameter",
            DefKind::ConstParam => "const parameter",
            DefKind::Macro(kinds) => kinds.descr(),
            DefKind::LifetimeParam => "lifetime parameter",
            DefKind::Use => "import",
            DefKind::ForeignMod => "foreign module",
            DefKind::AnonConst => "constant expression",
            DefKind::InlineConst => "inline constant",
            DefKind::Field => "field",
            DefKind::Impl { .. } => "implementation",
            DefKind::Closure => "closure",
            DefKind::ExternCrate => "extern crate",
            DefKind::GlobalAsm => "global assembly block",
            DefKind::SyntheticCoroutineBody => "synthetic mir body",
        }
    }

    /// Gets an English article for the definition.
    ///
    /// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or
    /// `TyCtxt::def_kind_descr_article` instead, because they give better
    /// information for coroutines and associated functions.
    pub fn article(&self) -> &'static str {
        match *self {
            DefKind::AssocTy
            | DefKind::AssocConst
            | DefKind::AssocFn
            | DefKind::Enum
            | DefKind::OpaqueTy
            | DefKind::Impl { .. }
            | DefKind::Use
            | DefKind::InlineConst
            | DefKind::ExternCrate => "an",
            DefKind::Macro(kinds) => kinds.article(),
            _ => "a",
        }
    }

    pub fn ns(&self) -> Option<Namespace> {
        match self {
            DefKind::Mod
            | DefKind::Struct
            | DefKind::Union
            | DefKind::Enum
            | DefKind::Variant
            | DefKind::Trait
            | DefKind::TyAlias
            | DefKind::ForeignTy
            | DefKind::TraitAlias
            | DefKind::AssocTy
            | DefKind::TyParam => Some(Namespace::TypeNS),

            DefKind::Fn
            | DefKind::Const
            | DefKind::ConstParam
            | DefKind::Static { .. }
            | DefKind::Ctor(..)
            | DefKind::AssocFn
            | DefKind::AssocConst => Some(Namespace::ValueNS),

            DefKind::Macro(..) => Some(Namespace::MacroNS),

            // Not namespaced.
            DefKind::AnonConst
            | DefKind::InlineConst
            | DefKind::Field
            | DefKind::LifetimeParam
            | DefKind::ExternCrate
            | DefKind::Closure
            | DefKind::Use
            | DefKind::ForeignMod
            | DefKind::GlobalAsm
            | DefKind::Impl { .. }
            | DefKind::OpaqueTy
            | DefKind::SyntheticCoroutineBody => None,
        }
    }

    // Some `DefKind`s require a name, some don't. Panics if one is needed but
    // not provided. (`AssocTy` is an exception, see below.)
    pub fn def_path_data(self, name: Option<Symbol>) -> DefPathData {
        match self {
            DefKind::Mod
            | DefKind::Struct
            | DefKind::Union
            | DefKind::Enum
            | DefKind::Variant
            | DefKind::Trait
            | DefKind::TyAlias
            | DefKind::ForeignTy
            | DefKind::TraitAlias
            | DefKind::TyParam
            | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()),

            // An associated type name will be missing for an RPITIT (DefPathData::AnonAssocTy),
            // but those provide their own DefPathData.
            DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()),

            DefKind::Fn
            | DefKind::Const
            | DefKind::ConstParam
            | DefKind::Static { .. }
            | DefKind::AssocFn
            | DefKind::AssocConst
            | DefKind::Field => DefPathData::ValueNs(name.unwrap()),
            DefKind::Macro(..) => DefPathData::MacroNs(name.unwrap()),
            DefKind::LifetimeParam => DefPathData::LifetimeNs(name.unwrap()),
            DefKind::Ctor(..) => DefPathData::Ctor,
            DefKind::Use => DefPathData::Use,
            DefKind::ForeignMod => DefPathData::ForeignMod,
            DefKind::AnonConst => DefPathData::AnonConst,
            DefKind::InlineConst => DefPathData::AnonConst,
            DefKind::OpaqueTy => DefPathData::OpaqueTy,
            DefKind::GlobalAsm => DefPathData::GlobalAsm,
            DefKind::Impl { .. } => DefPathData::Impl,
            DefKind::Closure => DefPathData::Closure,
            DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody,
        }
    }

    pub fn is_assoc(self) -> bool {
        matches!(self, DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy)
    }

    /// This is a "module" in name resolution sense.
    #[inline]
    pub fn is_module_like(self) -> bool {
        matches!(self, DefKind::Mod | DefKind::Enum | DefKind::Trait)
    }

    #[inline]
    pub fn is_adt(self) -> bool {
        matches!(self, DefKind::Struct | DefKind::Union | DefKind::Enum)
    }

    #[inline]
    pub fn is_fn_like(self) -> bool {
        matches!(
            self,
            DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::SyntheticCoroutineBody
        )
    }

    /// Whether the corresponding item has generic parameters, ie. the `generics_of` query works.
    pub fn has_generics(self) -> bool {
        match self {
            DefKind::AnonConst
            | DefKind::AssocConst
            | DefKind::AssocFn
            | DefKind::AssocTy
            | DefKind::Closure
            | DefKind::Const
            | DefKind::Ctor(..)
            | DefKind::Enum
            | DefKind::Field
            | DefKind::Fn
            | DefKind::ForeignTy
            | DefKind::Impl { .. }
            | DefKind::InlineConst
            | DefKind::OpaqueTy
            | DefKind::Static { .. }
            | DefKind::Struct
            | DefKind::SyntheticCoroutineBody
            | DefKind::Trait
            | DefKind::TraitAlias
            | DefKind::TyAlias
            | DefKind::Union
            | DefKind::Variant => true,
            DefKind::ConstParam
            | DefKind::ExternCrate
            | DefKind::ForeignMod
            | DefKind::GlobalAsm
            | DefKind::LifetimeParam
            | DefKind::Macro(_)
            | DefKind::Mod
            | DefKind::TyParam
            | DefKind::Use => false,
        }
    }

    /// Whether `query get_codegen_attrs` should be used with this definition.
    pub fn has_codegen_attrs(self) -> bool {
        match self {
            DefKind::Fn
            | DefKind::AssocFn
            | DefKind::Ctor(..)
            | DefKind::Closure
            | DefKind::Static { .. }
            | DefKind::SyntheticCoroutineBody => true,
            DefKind::Mod
            | DefKind::Struct
            | DefKind::Union
            | DefKind::Enum
            | DefKind::Variant
            | DefKind::Trait
            | DefKind::TyAlias
            | DefKind::ForeignTy
            | DefKind::TraitAlias
            | DefKind::AssocTy
            | DefKind::Const
            | DefKind::AssocConst
            | DefKind::Macro(..)
            | DefKind::Use
            | DefKind::ForeignMod
            | DefKind::OpaqueTy
            | DefKind::Impl { .. }
            | DefKind::Field
            | DefKind::TyParam
            | DefKind::ConstParam
            | DefKind::LifetimeParam
            | DefKind::AnonConst
            | DefKind::InlineConst
            | DefKind::GlobalAsm
            | DefKind::ExternCrate => false,
        }
    }
}

/// The resolution of a path or export.
///
/// For every path or identifier in Rust, the compiler must determine
/// what the path refers to. This process is called name resolution,
/// and `Res` is the primary result of name resolution.
///
/// For example, everything prefixed with `/* Res */` in this example has
/// an associated `Res`:
///
/// ```ignore (illustrative)
/// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
///     /* Res */ String::from(/* Res */ s)
/// }
///
/// /* Res */ str_to_string("hello");
/// ```
///
/// The associated `Res`s will be:
///
/// - `str` will resolve to [`Res::PrimTy`];
/// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
///   for `String` as defined in the standard library;
/// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
///   pointing to `String::from`;
/// - `s` will resolve to [`Res::Local`];
/// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
///   pointing to the definition of `str_to_string` in the current crate.
//
#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
pub enum Res<Id = hir::HirId> {
    /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
    ///
    /// **Not bound to a specific namespace.**
    Def(DefKind, DefId),

    // Type namespace
    /// A primitive type such as `i32` or `str`.
    ///
    /// **Belongs to the type namespace.**
    PrimTy(hir::PrimTy),

    /// The `Self` type, as used within a trait.
    ///
    /// **Belongs to the type namespace.**
    ///
    /// See the examples on [`Res::SelfTyAlias`] for details.
    SelfTyParam {
        /// The trait this `Self` is a generic parameter for.
        trait_: DefId,
    },

    /// The `Self` type, as used somewhere other than within a trait.
    ///
    /// **Belongs to the type namespace.**
    ///
    /// Examples:
    /// ```
    /// struct Bar(Box<Self>); // SelfTyAlias
    ///
    /// trait Foo {
    ///     fn foo() -> Box<Self>; // SelfTyParam
    /// }
    ///
    /// impl Bar {
    ///     fn blah() {
    ///         let _: Self; // SelfTyAlias
    ///     }
    /// }
    ///
    /// impl Foo for Bar {
    ///     fn foo() -> Box<Self /* SelfTyAlias */> {
    ///         let _: Self;        // SelfTyAlias
    ///
    ///         todo!()
    ///     }
    /// }
    /// ```
    /// *See also [`Res::SelfCtor`].*
    ///
    SelfTyAlias {
        /// The item introducing the `Self` type alias. Can be used in the `type_of` query
        /// to get the underlying type.
        alias_to: DefId,

        /// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an
        /// anonymous constant).
        ///
        /// HACK(min_const_generics): self types also have an optional requirement to **not**
        /// mention any generic parameters to allow the following with `min_const_generics`:
        /// ```
        /// # struct Foo;
        /// impl Foo { fn test() -> [u8; size_of::<Self>()] { todo!() } }
        ///
        /// struct Bar([u8; baz::<Self>()]);
        /// const fn baz<T>() -> usize { 10 }
        /// ```
        /// We do however allow `Self` in repeat expression even if it is generic to not break code
        /// which already works on stable while causing the `const_evaluatable_unchecked` future
        /// compat lint:
        /// ```
        /// fn foo<T>() {
        ///     let _bar = [1_u8; size_of::<*mut T>()];
        /// }
        /// ```
        // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
        forbid_generic: bool,

        /// Is this within an `impl Foo for bar`?
        is_trait_impl: bool,
    },

    // Value namespace
    /// The `Self` constructor, along with the [`DefId`]
    /// of the impl it is associated with.
    ///
    /// **Belongs to the value namespace.**
    ///
    /// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].*
    SelfCtor(DefId),

    /// A local variable or function parameter.
    ///
    /// **Belongs to the value namespace.**
    Local(Id),

    /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
    ///
    /// **Belongs to the type namespace.**
    ToolMod,

    // Macro namespace
    /// An attribute that is *not* implemented via macro.
    /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
    /// as opposed to `#[test]`, which is a builtin macro.
    ///
    /// **Belongs to the macro namespace.**
    NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`

    // All namespaces
    /// Name resolution failed. We use a dummy `Res` variant so later phases
    /// of the compiler won't crash and can instead report more errors.
    ///
    /// **Not bound to a specific namespace.**
    Err,
}

impl<Id> IntoDiagArg for Res<Id> {
    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
        DiagArgValue::Str(Cow::Borrowed(self.descr()))
    }
}

/// The result of resolving a path before lowering to HIR,
/// with "module" segments resolved and associated item
/// segments deferred to type checking.
/// `base_res` is the resolution of the resolved part of the
/// path, `unresolved_segments` is the number of unresolved
/// segments.
///
/// ```text
/// module::Type::AssocX::AssocY::MethodOrAssocType
/// ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// base_res      unresolved_segments = 3
///
/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
///       ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
///       base_res        unresolved_segments = 2
/// ```
#[derive(Copy, Clone, Debug)]
pub struct PartialRes {
    base_res: Res<NodeId>,
    unresolved_segments: usize,
}

impl PartialRes {
    #[inline]
    pub fn new(base_res: Res<NodeId>) -> Self {
        PartialRes { base_res, unresolved_segments: 0 }
    }

    #[inline]
    pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
        if base_res == Res::Err {
            unresolved_segments = 0
        }
        PartialRes { base_res, unresolved_segments }
    }

    #[inline]
    pub fn base_res(&self) -> Res<NodeId> {
        self.base_res
    }

    #[inline]
    pub fn unresolved_segments(&self) -> usize {
        self.unresolved_segments
    }

    #[inline]
    pub fn full_res(&self) -> Option<Res<NodeId>> {
        (self.unresolved_segments == 0).then_some(self.base_res)
    }

    #[inline]
    pub fn expect_full_res(&self) -> Res<NodeId> {
        self.full_res().expect("unexpected unresolved segments")
    }
}

/// Different kinds of symbols can coexist even if they share the same textual name.
/// Therefore, they each have a separate universe (known as a "namespace").
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
#[derive(HashStable_Generic)]
pub enum Namespace {
    /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
    /// (and, by extension, crates).
    ///
    /// Note that the type namespace includes other items; this is not an
    /// exhaustive list.
    TypeNS,
    /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
    ValueNS,
    /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
    /// procedural macros, attribute macros, `derive` macros, and non-macro attributes
    /// like `#[inline]` and `#[rustfmt::skip]`.
    MacroNS,
}

impl Namespace {
    /// The English description of the namespace.
    pub fn descr(self) -> &'static str {
        match self {
            Self::TypeNS => "type",
            Self::ValueNS => "value",
            Self::MacroNS => "macro",
        }
    }
}

impl IntoDiagArg for Namespace {
    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
        DiagArgValue::Str(Cow::Borrowed(self.descr()))
    }
}

impl<CTX: crate::HashStableContext> ToStableHashKey<CTX> for Namespace {
    type KeyType = Namespace;

    #[inline]
    fn to_stable_hash_key(&self, _: &CTX) -> Namespace {
        *self
    }
}

/// Just a helper ‒ separate structure for each namespace.
#[derive(Copy, Clone, Default, Debug, HashStable_Generic)]
pub struct PerNS<T> {
    pub value_ns: T,
    pub type_ns: T,
    pub macro_ns: T,
}

impl<T> PerNS<T> {
    pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> PerNS<U> {
        PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
    }

    /// Note: Do you really want to use this? Often you know which namespace a
    /// name will belong in, and you can consider just that namespace directly,
    /// rather than iterating through all of them.
    pub fn into_iter(self) -> IntoIter<T, 3> {
        [self.value_ns, self.type_ns, self.macro_ns].into_iter()
    }

    /// Note: Do you really want to use this? Often you know which namespace a
    /// name will belong in, and you can consider just that namespace directly,
    /// rather than iterating through all of them.
    pub fn iter(&self) -> IntoIter<&T, 3> {
        [&self.value_ns, &self.type_ns, &self.macro_ns].into_iter()
    }
}

impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
    type Output = T;

    fn index(&self, ns: Namespace) -> &T {
        match ns {
            Namespace::ValueNS => &self.value_ns,
            Namespace::TypeNS => &self.type_ns,
            Namespace::MacroNS => &self.macro_ns,
        }
    }
}

impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
    fn index_mut(&mut self, ns: Namespace) -> &mut T {
        match ns {
            Namespace::ValueNS => &mut self.value_ns,
            Namespace::TypeNS => &mut self.type_ns,
            Namespace::MacroNS => &mut self.macro_ns,
        }
    }
}

impl<T> PerNS<Option<T>> {
    /// Returns `true` if all the items in this collection are `None`.
    pub fn is_empty(&self) -> bool {
        self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none()
    }

    /// Returns an iterator over the items which are `Some`.
    ///
    /// Note: Do you really want to use this? Often you know which namespace a
    /// name will belong in, and you can consider just that namespace directly,
    /// rather than iterating through all of them.
    pub fn present_items(self) -> impl Iterator<Item = T> {
        [self.type_ns, self.value_ns, self.macro_ns].into_iter().flatten()
    }
}

impl CtorKind {
    pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> {
        match *vdata {
            ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)),
            ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)),
            ast::VariantData::Struct { .. } => None,
        }
    }
}

impl NonMacroAttrKind {
    pub fn descr(self) -> &'static str {
        match self {
            NonMacroAttrKind::Builtin(..) => "built-in attribute",
            NonMacroAttrKind::Tool => "tool attribute",
            NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
                "derive helper attribute"
            }
        }
    }

    // Currently trivial, but exists in case a new kind is added in the future whose name starts
    // with a vowel.
    pub fn article(self) -> &'static str {
        "a"
    }

    /// Users of some attributes cannot mark them as used, so they are considered always used.
    pub fn is_used(self) -> bool {
        match self {
            NonMacroAttrKind::Tool
            | NonMacroAttrKind::DeriveHelper
            | NonMacroAttrKind::DeriveHelperCompat => true,
            NonMacroAttrKind::Builtin(..) => false,
        }
    }
}

impl<Id> Res<Id> {
    /// Return the `DefId` of this `Def` if it has an ID, else panic.
    pub fn def_id(&self) -> DefId
    where
        Id: Debug,
    {
        self.opt_def_id().unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {self:?}"))
    }

    /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
    pub fn opt_def_id(&self) -> Option<DefId> {
        match *self {
            Res::Def(_, id) => Some(id),

            Res::Local(..)
            | Res::PrimTy(..)
            | Res::SelfTyParam { .. }
            | Res::SelfTyAlias { .. }
            | Res::SelfCtor(..)
            | Res::ToolMod
            | Res::NonMacroAttr(..)
            | Res::Err => None,
        }
    }

    /// Return the `DefId` of this `Res` if it represents a module.
    pub fn mod_def_id(&self) -> Option<DefId> {
        match *self {
            Res::Def(DefKind::Mod, id) => Some(id),
            _ => None,
        }
    }

    /// If this is a "module" in name resolution sense, return its `DefId`.
    #[inline]
    pub fn module_like_def_id(&self) -> Option<DefId> {
        match self {
            Res::Def(def_kind, def_id) if def_kind.is_module_like() => Some(*def_id),
            _ => None,
        }
    }

    /// A human readable name for the res kind ("function", "module", etc.).
    pub fn descr(&self) -> &'static str {
        match *self {
            Res::Def(kind, def_id) => kind.descr(def_id),
            Res::SelfCtor(..) => "self constructor",
            Res::PrimTy(..) => "builtin type",
            Res::Local(..) => "local variable",
            Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
            Res::ToolMod => "tool module",
            Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
            Res::Err => "unresolved item",
        }
    }

    /// Gets an English article for the `Res`.
    pub fn article(&self) -> &'static str {
        match *self {
            Res::Def(kind, _) => kind.article(),
            Res::NonMacroAttr(kind) => kind.article(),
            Res::Err => "an",
            _ => "a",
        }
    }

    pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
        match self {
            Res::Def(kind, id) => Res::Def(kind, id),
            Res::SelfCtor(id) => Res::SelfCtor(id),
            Res::PrimTy(id) => Res::PrimTy(id),
            Res::Local(id) => Res::Local(map(id)),
            Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
            Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
                Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
            }
            Res::ToolMod => Res::ToolMod,
            Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
            Res::Err => Res::Err,
        }
    }

    pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {
        Ok(match self {
            Res::Def(kind, id) => Res::Def(kind, id),
            Res::SelfCtor(id) => Res::SelfCtor(id),
            Res::PrimTy(id) => Res::PrimTy(id),
            Res::Local(id) => Res::Local(map(id)?),
            Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
            Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
                Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
            }
            Res::ToolMod => Res::ToolMod,
            Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
            Res::Err => Res::Err,
        })
    }

    #[track_caller]
    pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
        self.map_id(
            #[track_caller]
            |_| panic!("unexpected `Res::Local`"),
        )
    }

    pub fn macro_kinds(self) -> Option<MacroKinds> {
        match self {
            Res::Def(DefKind::Macro(kinds), _) => Some(kinds),
            Res::NonMacroAttr(..) => Some(MacroKinds::ATTR),
            _ => None,
        }
    }

    /// Returns `None` if this is `Res::Err`
    pub fn ns(&self) -> Option<Namespace> {
        match self {
            Res::Def(kind, ..) => kind.ns(),
            Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
                Some(Namespace::TypeNS)
            }
            Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
            Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
            Res::Err => None,
        }
    }

    /// Always returns `true` if `self` is `Res::Err`
    pub fn matches_ns(&self, ns: Namespace) -> bool {
        self.ns().is_none_or(|actual_ns| actual_ns == ns)
    }

    /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
    pub fn expected_in_tuple_struct_pat(&self) -> bool {
        matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..))
    }

    /// Returns whether such a resolved path can occur in a unit struct/variant pattern
    pub fn expected_in_unit_struct_pat(&self) -> bool {
        matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..))
    }
}

/// Resolution for a lifetime appearing in a type.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum LifetimeRes {
    /// Successfully linked the lifetime to a generic parameter.
    Param {
        /// Id of the generic parameter that introduced it.
        param: LocalDefId,
        /// Id of the introducing place. That can be:
        /// - an item's id, for the item's generic parameters;
        /// - a TraitRef's ref_id, identifying the `for<...>` binder;
        /// - a FnPtr type's id.
        ///
        /// This information is used for impl-trait lifetime captures, to know when to or not to
        /// capture any given lifetime.
        binder: NodeId,
    },
    /// Created a generic parameter for an anonymous lifetime.
    Fresh {
        /// Id of the generic parameter that introduced it.
        ///
        /// Creating the associated `LocalDefId` is the responsibility of lowering.
        param: NodeId,
        /// Id of the introducing place. See `Param`.
        binder: NodeId,
        /// Kind of elided lifetime
        kind: hir::MissingLifetimeKind,
    },
    /// This variant is used for anonymous lifetimes that we did not resolve during
    /// late resolution. Those lifetimes will be inferred by typechecking.
    Infer,
    /// `'static` lifetime.
    Static,
    /// Resolution failure.
    Error,
    /// HACK: This is used to recover the NodeId of an elided lifetime.
    ElidedAnchor { start: NodeId, end: NodeId },
}

pub type DocLinkResMap = UnordMap<(Symbol, Namespace), Option<Res<NodeId>>>;
