1use std::array::IntoIter;2use std::borrow::Cow;3use std::fmt::Debug;45use rustc_ast as ast;6use rustc_ast::NodeId;7use rustc_data_structures::stable_hasher::ToStableHashKey;8use rustc_data_structures::unord::UnordMap;9use rustc_error_messages::{DiagArgValue, IntoDiagArg};10use rustc_macros::{Decodable, Encodable, StableHash};11use rustc_span::Symbol;12use rustc_span::def_id::{DefId, LocalDefId};13use rustc_span::hygiene::MacroKind;1415use crate::definitions::DefPathData;16use crate::hir;1718/// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.19#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, StableHash)]20pub enum CtorOf {21 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.22 Struct,23 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.24 Variant,25}2627/// What kind of constructor something is.28#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, StableHash)]29pub enum CtorKind {30 /// Constructor function automatically created by a tuple struct/variant.31 Fn,32 /// Constructor constant automatically created by a unit struct/variant.33 Const,34}3536/// A set of macro kinds, for macros that can have more than one kind37#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]38#[derive(StableHash)]39pub struct MacroKinds(u8);40bitflags::bitflags! {41 impl MacroKinds: u8 {42 const BANG = 1 << 0;43 const ATTR = 1 << 1;44 const DERIVE = 1 << 2;45 }46}4748impl From<MacroKind> for MacroKinds {49 fn from(kind: MacroKind) -> Self {50 match kind {51 MacroKind::Bang => Self::BANG,52 MacroKind::Attr => Self::ATTR,53 MacroKind::Derive => Self::DERIVE,54 }55 }56}5758impl MacroKinds {59 /// Convert the MacroKinds to a static string.60 ///61 /// This hardcodes all the possibilities, in order to return a static string.62 pub fn descr(self) -> &'static str {63 match self {64 // FIXME: change this to "function-like macro" and fix all tests65 Self::BANG => "macro",66 Self::ATTR => "attribute macro",67 Self::DERIVE => "derive macro",68 _ if self == (Self::ATTR | Self::BANG) => "attribute/function macro",69 _ if self == (Self::DERIVE | Self::BANG) => "derive/function macro",70 _ if self == (Self::ATTR | Self::DERIVE) => "attribute/derive macro",71 _ if self.is_all() => "attribute/derive/function macro",72 _ if self.is_empty() => "useless macro",73 _ => unreachable!(),74 }75 }7677 /// Return an indefinite article (a/an) for use with `descr()`78 pub fn article(self) -> &'static str {79 if self.contains(Self::ATTR) { "an" } else { "a" }80 }81}8283/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.84#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, StableHash)]85pub enum NonMacroAttrKind {86 /// Single-segment attribute defined by the language (`#[inline]`)87 Builtin(Symbol),88 /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).89 Tool,90 /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).91 DeriveHelper,92 /// Single-segment custom attribute registered by a derive macro93 /// but used before that derive macro was expanded (deprecated).94 DeriveHelperCompat,95}9697/// What kind of definition something is; e.g., `mod` vs `struct`.98/// `enum DefPathData` may need to be updated if a new variant is added here.99#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, StableHash)]100pub enum DefKind {101 // Type namespace102 Mod,103 /// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.104 Struct,105 Union,106 Enum,107 /// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.108 Variant,109 Trait,110 /// Type alias: `type Foo = Bar;`111 TyAlias,112 /// Type from an `extern` block.113 ForeignTy,114 /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`115 TraitAlias,116 /// Associated type: `trait MyTrait { type Assoc; }`117 AssocTy,118 /// Type parameter: the `T` in `struct Vec<T> { ... }`119 TyParam,120121 // Value namespace122 Fn,123 Const {124 is_type_const: bool,125 },126 /// Constant generic parameter: `struct Foo<const N: usize> { ... }`127 ConstParam,128 Static {129 /// Whether it's a `unsafe static`, `safe static` (inside extern only) or just a `static`.130 safety: hir::Safety,131 /// Whether it's a `static mut` or just a `static`.132 mutability: ast::Mutability,133 /// Whether it's an anonymous static generated for nested allocations.134 nested: bool,135 },136 /// Refers to the struct or enum variant's constructor.137 ///138 /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and139 /// [`DefKind::Variant`] is because structs and enum variants exist140 /// in the *type* namespace, whereas struct and enum variant *constructors*141 /// exist in the *value* namespace.142 ///143 /// You may wonder why enum variants exist in the type namespace as opposed144 /// to the value namespace. Check out [RFC 2593] for intuition on why that is.145 ///146 /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593147 Ctor(CtorOf, CtorKind),148 /// Associated function: `impl MyStruct { fn associated() {} }`149 /// or `trait Foo { fn associated() {} }`150 AssocFn,151 /// Associated constant: `trait MyTrait { const ASSOC: usize; }`152 AssocConst {153 is_type_const: bool,154 },155156 // Macro namespace157 Macro(MacroKinds),158159 // Not namespaced (or they are, but we don't treat them so)160 ExternCrate,161 Use,162 /// An `extern` block.163 ForeignMod,164 /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`.165 ///166 /// Not all anon-consts are actually still relevant in the HIR. We lower167 /// trivial const-arguments directly to `hir::ConstArgKind::Path`, at which168 /// point the definition for the anon-const ends up unused and incomplete.169 ///170 /// We do not provide any a `Span` for the definition and pretty much all other171 /// queries also ICE when using this `DefId`. Given that the `DefId` of such172 /// constants should only be reachable by iterating all definitions of a173 /// given crate, you should not have to worry about this.174 AnonConst,175 /// An inline constant, e.g. `const { 1 + 2 }`176 InlineConst,177 /// Opaque type, aka `impl Trait`.178 OpaqueTy,179 /// A field in a struct, enum or union. e.g.180 /// - `bar` in `struct Foo { bar: u8 }`181 /// - `Foo::Bar::0` in `enum Foo { Bar(u8) }`182 Field,183 /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`184 LifetimeParam,185 /// A use of `global_asm!`.186 GlobalAsm,187 Impl {188 of_trait: bool,189 },190 /// A closure, coroutine, or coroutine-closure.191 ///192 /// These are all represented with the same `ExprKind::Closure` in the AST and HIR,193 /// which makes it difficult to distinguish these during def collection. Therefore,194 /// we treat them all the same, and code which needs to distinguish them can match195 /// on `hir::ClosureKind` or `type_of`.196 Closure,197 /// The definition of a synthetic coroutine body created by the lowering of a198 /// coroutine-closure, such as an async closure.199 SyntheticCoroutineBody,200}201202impl DefKind {203 /// Get an English description for the item's kind.204 ///205 /// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or206 /// `TyCtxt::def_kind_descr` instead, because they give better207 /// information for coroutines and associated functions.208 pub fn descr(self, def_id: DefId) -> &'static str {209 match self {210 DefKind::Fn => "function",211 DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate",212 DefKind::Mod => "module",213 DefKind::Static { .. } => "static",214 DefKind::Enum => "enum",215 DefKind::Variant => "variant",216 DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",217 DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",218 DefKind::Struct => "struct",219 DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",220 DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",221 DefKind::OpaqueTy => "opaque type",222 DefKind::TyAlias => "type alias",223 DefKind::TraitAlias => "trait alias",224 DefKind::AssocTy => "associated type",225 DefKind::Union => "union",226 DefKind::Trait => "trait",227 DefKind::ForeignTy => "foreign type",228 DefKind::AssocFn => "associated function",229 DefKind::Const { .. } => "constant",230 DefKind::AssocConst { .. } => "associated constant",231 DefKind::TyParam => "type parameter",232 DefKind::ConstParam => "const parameter",233 DefKind::Macro(kinds) => kinds.descr(),234 DefKind::LifetimeParam => "lifetime parameter",235 DefKind::Use => "import",236 DefKind::ForeignMod => "foreign module",237 DefKind::AnonConst => "constant expression",238 DefKind::InlineConst => "inline constant",239 DefKind::Field => "field",240 DefKind::Impl { .. } => "implementation",241 DefKind::Closure => "closure",242 DefKind::ExternCrate => "extern crate",243 DefKind::GlobalAsm => "global assembly block",244 DefKind::SyntheticCoroutineBody => "synthetic mir body",245 }246 }247248 /// Gets an English article for the definition.249 ///250 /// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or251 /// `TyCtxt::def_kind_descr_article` instead, because they give better252 /// information for coroutines and associated functions.253 pub fn article(&self) -> &'static str {254 match *self {255 DefKind::AssocTy256 | DefKind::AssocConst { .. }257 | DefKind::AssocFn258 | DefKind::Enum259 | DefKind::OpaqueTy260 | DefKind::Impl { .. }261 | DefKind::Use262 | DefKind::InlineConst263 | DefKind::ExternCrate => "an",264 DefKind::Macro(kinds) => kinds.article(),265 _ => "a",266 }267 }268269 pub fn ns(&self) -> Option<Namespace> {270 match self {271 DefKind::Mod272 | DefKind::Struct273 | DefKind::Union274 | DefKind::Enum275 | DefKind::Variant276 | DefKind::Trait277 | DefKind::TyAlias278 | DefKind::ForeignTy279 | DefKind::TraitAlias280 | DefKind::AssocTy281 | DefKind::TyParam => Some(Namespace::TypeNS),282283 DefKind::Fn284 | DefKind::Const { .. }285 | DefKind::ConstParam286 | DefKind::Static { .. }287 | DefKind::Ctor(..)288 | DefKind::AssocFn289 | DefKind::AssocConst { .. } => Some(Namespace::ValueNS),290291 DefKind::Macro(..) => Some(Namespace::MacroNS),292293 // Not namespaced.294 DefKind::AnonConst295 | DefKind::InlineConst296 | DefKind::Field297 | DefKind::LifetimeParam298 | DefKind::ExternCrate299 | DefKind::Closure300 | DefKind::Use301 | DefKind::ForeignMod302 | DefKind::GlobalAsm303 | DefKind::Impl { .. }304 | DefKind::OpaqueTy305 | DefKind::SyntheticCoroutineBody => None,306 }307 }308309 // Some `DefKind`s require a name, some don't. Panics if one is needed but310 // not provided. (`AssocTy` is an exception, see below.)311 pub fn def_path_data(self, name: Option<Symbol>) -> DefPathData {312 match self {313 DefKind::Mod314 | DefKind::Struct315 | DefKind::Union316 | DefKind::Enum317 | DefKind::Variant318 | DefKind::Trait319 | DefKind::TyAlias320 | DefKind::ForeignTy321 | DefKind::TraitAlias322 | DefKind::TyParam323 | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()),324325 // An associated type name will be missing for an RPITIT (DefPathData::AnonAssocTy),326 // but those provide their own DefPathData.327 DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()),328329 DefKind::Fn330 | DefKind::Const { .. }331 | DefKind::ConstParam332 | DefKind::Static { .. }333 | DefKind::AssocFn334 | DefKind::AssocConst { .. }335 | DefKind::Field => DefPathData::ValueNs(name.unwrap()),336 DefKind::Macro(..) => DefPathData::MacroNs(name.unwrap()),337 DefKind::LifetimeParam => DefPathData::LifetimeNs(name.unwrap()),338 DefKind::Ctor(..) => DefPathData::Ctor,339 DefKind::Use => DefPathData::Use,340 DefKind::ForeignMod => DefPathData::ForeignMod,341 DefKind::AnonConst => DefPathData::AnonConst,342 DefKind::InlineConst => DefPathData::AnonConst,343 DefKind::OpaqueTy => DefPathData::OpaqueTy,344 DefKind::GlobalAsm => DefPathData::GlobalAsm,345 DefKind::Impl { .. } => DefPathData::Impl,346 DefKind::Closure => DefPathData::Closure,347 DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody,348 }349 }350351 pub fn is_assoc(self) -> bool {352 matches!(self, DefKind::AssocConst { .. } | DefKind::AssocFn | DefKind::AssocTy)353 }354355 /// This is a "module" in name resolution sense.356 #[inline]357 pub fn is_module_like(self) -> bool {358 matches!(self, DefKind::Mod | DefKind::Enum | DefKind::Trait)359 }360361 #[inline]362 pub fn is_adt(self) -> bool {363 matches!(self, DefKind::Struct | DefKind::Union | DefKind::Enum)364 }365366 #[inline]367 pub fn is_fn_like(self) -> bool {368 matches!(369 self,370 DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::SyntheticCoroutineBody371 )372 }373374 /// Whether the corresponding item has generic parameters, i.e. the `generics_of` query works.375 pub fn has_generics(self) -> bool {376 match self {377 DefKind::AnonConst378 | DefKind::AssocConst { .. }379 | DefKind::AssocFn380 | DefKind::AssocTy381 | DefKind::Closure382 | DefKind::Const { .. }383 | DefKind::Ctor(..)384 | DefKind::Enum385 | DefKind::Field386 | DefKind::Fn387 | DefKind::ForeignTy388 | DefKind::Impl { .. }389 | DefKind::InlineConst390 | DefKind::OpaqueTy391 | DefKind::Static { .. }392 | DefKind::Struct393 | DefKind::SyntheticCoroutineBody394 | DefKind::Trait395 | DefKind::TraitAlias396 | DefKind::TyAlias397 | DefKind::Union398 | DefKind::Variant => true,399 DefKind::ConstParam400 | DefKind::ExternCrate401 | DefKind::ForeignMod402 | DefKind::GlobalAsm403 | DefKind::LifetimeParam404 | DefKind::Macro(_)405 | DefKind::Mod406 | DefKind::TyParam407 | DefKind::Use => false,408 }409 }410411 /// Whether `query get_codegen_attrs` should be used with this definition.412 pub fn has_codegen_attrs(self) -> bool {413 match self {414 DefKind::Fn415 | DefKind::AssocFn416 | DefKind::Ctor(..)417 | DefKind::Closure418 | DefKind::Static { .. }419 | DefKind::SyntheticCoroutineBody => true,420 DefKind::Mod421 | DefKind::Struct422 | DefKind::Union423 | DefKind::Enum424 | DefKind::Variant425 | DefKind::Trait426 | DefKind::TyAlias427 | DefKind::ForeignTy428 | DefKind::TraitAlias429 | DefKind::AssocTy430 | DefKind::Const { .. }431 | DefKind::AssocConst { .. }432 | DefKind::Macro(..)433 | DefKind::Use434 | DefKind::ForeignMod435 | DefKind::OpaqueTy436 | DefKind::Impl { .. }437 | DefKind::Field438 | DefKind::TyParam439 | DefKind::ConstParam440 | DefKind::LifetimeParam441 | DefKind::AnonConst442 | DefKind::InlineConst443 | DefKind::GlobalAsm444 | DefKind::ExternCrate => false,445 }446 }447448 /// Returns `true` if `self` is a kind of definition that does not have its own449 /// type-checking context, i.e. closure, coroutine or inline const.450 #[inline]451 pub fn is_typeck_child(self) -> bool {452 match self {453 DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody => true,454 DefKind::Mod455 | DefKind::Struct456 | DefKind::Union457 | DefKind::Enum458 | DefKind::Variant459 | DefKind::Trait460 | DefKind::TyAlias461 | DefKind::ForeignTy462 | DefKind::TraitAlias463 | DefKind::AssocTy464 | DefKind::TyParam465 | DefKind::Fn466 | DefKind::Const { .. }467 | DefKind::ConstParam468 | DefKind::Static { .. }469 | DefKind::Ctor(_, _)470 | DefKind::AssocFn471 | DefKind::AssocConst { .. }472 | DefKind::Macro(_)473 | DefKind::ExternCrate474 | DefKind::Use475 | DefKind::ForeignMod476 | DefKind::AnonConst477 | DefKind::OpaqueTy478 | DefKind::Field479 | DefKind::LifetimeParam480 | DefKind::GlobalAsm481 | DefKind::Impl { .. } => false,482 }483 }484}485486/// The resolution of a path or export.487///488/// For every path or identifier in Rust, the compiler must determine489/// what the path refers to. This process is called name resolution,490/// and `Res` is the primary result of name resolution.491///492/// For example, everything prefixed with `/* Res */` in this example has493/// an associated `Res`:494///495/// ```ignore (illustrative)496/// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {497/// /* Res */ String::from(/* Res */ s)498/// }499///500/// /* Res */ str_to_string("hello");501/// ```502///503/// The associated `Res`s will be:504///505/// - `str` will resolve to [`Res::PrimTy`];506/// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]507/// for `String` as defined in the standard library;508/// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]509/// pointing to `String::from`;510/// - `s` will resolve to [`Res::Local`];511/// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]512/// pointing to the definition of `str_to_string` in the current crate.513//514#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, StableHash)]515pub enum Res<Id = hir::HirId> {516 /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.517 ///518 /// **Not bound to a specific namespace.**519 Def(DefKind, DefId),520521 // Type namespace522 /// A primitive type such as `i32` or `str`.523 ///524 /// **Belongs to the type namespace.**525 PrimTy(hir::PrimTy),526527 /// The `Self` type, as used within a trait.528 ///529 /// **Belongs to the type namespace.**530 ///531 /// See the examples on [`Res::SelfTyAlias`] for details.532 SelfTyParam {533 /// The trait this `Self` is a generic parameter for.534 trait_: DefId,535 },536537 /// The `Self` type, as used somewhere other than within a trait.538 ///539 /// **Belongs to the type namespace.**540 ///541 /// Examples:542 /// ```543 /// struct Bar(Box<Self>); // SelfTyAlias544 ///545 /// trait Foo {546 /// fn foo() -> Box<Self>; // SelfTyParam547 /// }548 ///549 /// impl Bar {550 /// fn blah() {551 /// let _: Self; // SelfTyAlias552 /// }553 /// }554 ///555 /// impl Foo for Bar {556 /// fn foo() -> Box<Self /* SelfTyAlias */> {557 /// let _: Self; // SelfTyAlias558 ///559 /// todo!()560 /// }561 /// }562 /// ```563 /// *See also [`Res::SelfCtor`].*564 ///565 SelfTyAlias {566 /// The item introducing the `Self` type alias. Can be used in the `type_of` query567 /// to get the underlying type.568 alias_to: DefId,569570 /// Is this within an `impl Foo for bar`?571 is_trait_impl: bool,572 },573574 // Value namespace575 /// The `Self` constructor, along with the [`DefId`]576 /// of the impl it is associated with.577 ///578 /// **Belongs to the value namespace.**579 ///580 /// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].*581 SelfCtor(DefId),582583 /// A local variable or function parameter.584 ///585 /// **Belongs to the value namespace.**586 Local(Id),587588 /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.589 ///590 /// **Belongs to the type namespace.**591 ToolMod,592593 /// The resolution for an open module in a namespaced crate. E.g. `my_api`594 /// in the namespaced crate `my_api::utils` when `my_api` isn't part of the595 /// extern prelude.596 ///597 /// **Belongs to the type namespace.**598 OpenMod(Symbol),599600 // Macro namespace601 /// An attribute that is *not* implemented via macro.602 /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,603 /// as opposed to `#[test]`, which is a builtin macro.604 ///605 /// **Belongs to the macro namespace.**606 NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`607608 // All namespaces609 /// Name resolution failed. We use a dummy `Res` variant so later phases610 /// of the compiler won't crash and can instead report more errors.611 ///612 /// **Not bound to a specific namespace.**613 Err,614}615616impl<Id> IntoDiagArg for Res<Id> {617 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {618 DiagArgValue::Str(Cow::Borrowed(self.descr()))619 }620}621622/// The result of resolving a path before lowering to HIR,623/// with "module" segments resolved and associated item624/// segments deferred to type checking.625/// `base_res` is the resolution of the resolved part of the626/// path, `unresolved_segments` is the number of unresolved627/// segments.628///629/// ```text630/// module::Type::AssocX::AssocY::MethodOrAssocType631/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~632/// base_res unresolved_segments = 3633///634/// <T as Trait>::AssocX::AssocY::MethodOrAssocType635/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~636/// base_res unresolved_segments = 2637/// ```638#[derive(Copy, Clone, Debug)]639pub struct PartialRes {640 base_res: Res<NodeId>,641 unresolved_segments: usize,642}643644impl PartialRes {645 #[inline]646 pub fn new(base_res: Res<NodeId>) -> Self {647 PartialRes { base_res, unresolved_segments: 0 }648 }649650 #[inline]651 pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {652 if base_res == Res::Err {653 unresolved_segments = 0654 }655 PartialRes { base_res, unresolved_segments }656 }657658 #[inline]659 pub fn base_res(&self) -> Res<NodeId> {660 self.base_res661 }662663 #[inline]664 pub fn unresolved_segments(&self) -> usize {665 self.unresolved_segments666 }667668 #[inline]669 pub fn full_res(&self) -> Option<Res<NodeId>> {670 (self.unresolved_segments == 0).then_some(self.base_res)671 }672673 #[inline]674 pub fn expect_full_res(&self) -> Res<NodeId> {675 self.full_res().expect("unexpected unresolved segments")676 }677}678679/// Different kinds of symbols can coexist even if they share the same textual name.680/// Therefore, they each have a separate universe (known as a "namespace").681#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]682#[derive(StableHash)]683pub enum Namespace {684 /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s685 /// (and, by extension, crates).686 ///687 /// Note that the type namespace includes other items; this is not an688 /// exhaustive list.689 TypeNS,690 /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).691 ValueNS,692 /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,693 /// procedural macros, attribute macros, `derive` macros, and non-macro attributes694 /// like `#[inline]` and `#[rustfmt::skip]`.695 MacroNS,696}697698impl Namespace {699 /// The English description of the namespace.700 pub fn descr(self) -> &'static str {701 match self {702 Self::TypeNS => "type",703 Self::ValueNS => "value",704 Self::MacroNS => "macro",705 }706 }707}708709impl IntoDiagArg for Namespace {710 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {711 DiagArgValue::Str(Cow::Borrowed(self.descr()))712 }713}714715impl ToStableHashKey for Namespace {716 type KeyType = Namespace;717718 #[inline]719 fn to_stable_hash_key<Hcx>(&self, _: &mut Hcx) -> Namespace {720 *self721 }722}723724/// Just a helper ‒ separate structure for each namespace.725#[derive(Copy, Clone, Default, Debug, StableHash)]726pub struct PerNS<T> {727 pub value_ns: T,728 pub type_ns: T,729 pub macro_ns: T,730}731732impl<T> PerNS<T> {733 pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> PerNS<U> {734 PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }735 }736737 /// Note: Do you really want to use this? Often you know which namespace a738 /// name will belong in, and you can consider just that namespace directly,739 /// rather than iterating through all of them.740 pub fn into_iter(self) -> IntoIter<T, 3> {741 [self.value_ns, self.type_ns, self.macro_ns].into_iter()742 }743744 /// Note: Do you really want to use this? Often you know which namespace a745 /// name will belong in, and you can consider just that namespace directly,746 /// rather than iterating through all of them.747 pub fn iter(&self) -> IntoIter<&T, 3> {748 [&self.value_ns, &self.type_ns, &self.macro_ns].into_iter()749 }750}751752impl<T> ::std::ops::Index<Namespace> for PerNS<T> {753 type Output = T;754755 fn index(&self, ns: Namespace) -> &T {756 match ns {757 Namespace::ValueNS => &self.value_ns,758 Namespace::TypeNS => &self.type_ns,759 Namespace::MacroNS => &self.macro_ns,760 }761 }762}763764impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {765 fn index_mut(&mut self, ns: Namespace) -> &mut T {766 match ns {767 Namespace::ValueNS => &mut self.value_ns,768 Namespace::TypeNS => &mut self.type_ns,769 Namespace::MacroNS => &mut self.macro_ns,770 }771 }772}773774impl<T> PerNS<Option<T>> {775 /// Returns `true` if all the items in this collection are `None`.776 pub fn is_empty(&self) -> bool {777 self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none()778 }779780 /// Returns an iterator over the items which are `Some`.781 ///782 /// Note: Do you really want to use this? Often you know which namespace a783 /// name will belong in, and you can consider just that namespace directly,784 /// rather than iterating through all of them.785 pub fn present_items(self) -> impl Iterator<Item = T> {786 [self.type_ns, self.value_ns, self.macro_ns].into_iter().flatten()787 }788}789790impl CtorKind {791 pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> {792 match *vdata {793 ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)),794 ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)),795 ast::VariantData::Struct { .. } => None,796 }797 }798}799800impl NonMacroAttrKind {801 pub fn descr(self) -> &'static str {802 match self {803 NonMacroAttrKind::Builtin(..) => "built-in attribute",804 NonMacroAttrKind::Tool => "tool attribute",805 NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {806 "derive helper attribute"807 }808 }809 }810811 // Currently trivial, but exists in case a new kind is added in the future whose name starts812 // with a vowel.813 pub fn article(self) -> &'static str {814 "a"815 }816817 /// Users of some attributes cannot mark them as used, so they are considered always used.818 pub fn is_used(self) -> bool {819 match self {820 NonMacroAttrKind::Tool821 | NonMacroAttrKind::DeriveHelper822 | NonMacroAttrKind::DeriveHelperCompat => true,823 NonMacroAttrKind::Builtin(..) => false,824 }825 }826}827828impl<Id> Res<Id> {829 /// Return the `DefId` of this `Def` if it has an ID, else panic.830 pub fn def_id(&self) -> DefId831 where832 Id: Debug,833 {834 self.opt_def_id().unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {self:?}"))835 }836837 /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.838 pub fn opt_def_id(&self) -> Option<DefId> {839 match *self {840 Res::Def(_, id) => Some(id),841842 Res::Local(..)843 | Res::PrimTy(..)844 | Res::SelfTyParam { .. }845 | Res::SelfTyAlias { .. }846 | Res::SelfCtor(..)847 | Res::ToolMod848 | Res::OpenMod(..)849 | Res::NonMacroAttr(..)850 | Res::Err => None,851 }852 }853854 /// Return the `DefId` of this `Res` if it represents a module.855 pub fn mod_def_id(&self) -> Option<DefId> {856 match *self {857 Res::Def(DefKind::Mod, id) => Some(id),858 _ => None,859 }860 }861862 /// If this is a "module" in name resolution sense, return its `DefId`.863 #[inline]864 pub fn module_like_def_id(&self) -> Option<DefId> {865 match self {866 Res::Def(def_kind, def_id) if def_kind.is_module_like() => Some(*def_id),867 _ => None,868 }869 }870871 /// A human readable name for the res kind ("function", "module", etc.).872 pub fn descr(&self) -> &'static str {873 match *self {874 Res::Def(kind, def_id) => kind.descr(def_id),875 Res::SelfCtor(..) => "self constructor",876 Res::PrimTy(..) => "builtin type",877 Res::Local(..) => "local variable",878 Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",879 Res::ToolMod => "tool module",880 Res::OpenMod(..) => "namespaced crate",881 Res::NonMacroAttr(attr_kind) => attr_kind.descr(),882 Res::Err => "unresolved item",883 }884 }885886 /// Gets an English article for the `Res`.887 pub fn article(&self) -> &'static str {888 match *self {889 Res::Def(kind, _) => kind.article(),890 Res::NonMacroAttr(kind) => kind.article(),891 Res::Err => "an",892 _ => "a",893 }894 }895896 pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {897 match self {898 Res::Def(kind, id) => Res::Def(kind, id),899 Res::SelfCtor(id) => Res::SelfCtor(id),900 Res::PrimTy(id) => Res::PrimTy(id),901 Res::Local(id) => Res::Local(map(id)),902 Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },903 Res::SelfTyAlias { alias_to, is_trait_impl } => {904 Res::SelfTyAlias { alias_to, is_trait_impl }905 }906 Res::ToolMod => Res::ToolMod,907 Res::OpenMod(sym) => Res::OpenMod(sym),908 Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),909 Res::Err => Res::Err,910 }911 }912913 pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {914 Ok(match self {915 Res::Def(kind, id) => Res::Def(kind, id),916 Res::SelfCtor(id) => Res::SelfCtor(id),917 Res::PrimTy(id) => Res::PrimTy(id),918 Res::Local(id) => Res::Local(map(id)?),919 Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },920 Res::SelfTyAlias { alias_to, is_trait_impl } => {921 Res::SelfTyAlias { alias_to, is_trait_impl }922 }923 Res::ToolMod => Res::ToolMod,924 Res::OpenMod(sym) => Res::OpenMod(sym),925 Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),926 Res::Err => Res::Err,927 })928 }929930 #[track_caller]931 pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {932 self.map_id(933 #[track_caller]934 |_| panic!("unexpected `Res::Local`"),935 )936 }937938 pub fn macro_kinds(self) -> Option<MacroKinds> {939 match self {940 Res::Def(DefKind::Macro(kinds), _) => Some(kinds),941 Res::NonMacroAttr(..) => Some(MacroKinds::ATTR),942 _ => None,943 }944 }945946 /// Returns `None` if this is `Res::Err`947 pub fn ns(&self) -> Option<Namespace> {948 match self {949 Res::Def(kind, ..) => kind.ns(),950 Res::PrimTy(..)951 | Res::SelfTyParam { .. }952 | Res::SelfTyAlias { .. }953 | Res::ToolMod954 | Res::OpenMod(..) => Some(Namespace::TypeNS),955 Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),956 Res::NonMacroAttr(..) => Some(Namespace::MacroNS),957 Res::Err => None,958 }959 }960961 /// Always returns `true` if `self` is `Res::Err`962 pub fn matches_ns(&self, ns: Namespace) -> bool {963 self.ns().is_none_or(|actual_ns| actual_ns == ns)964 }965966 /// Returns whether such a resolved path can occur in a tuple struct/variant pattern967 pub fn expected_in_tuple_struct_pat(&self) -> bool {968 matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..))969 }970971 /// Returns whether such a resolved path can occur in a unit struct/variant pattern972 pub fn expected_in_unit_struct_pat(&self) -> bool {973 matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..))974 }975}976977/// Resolution for a lifetime appearing in a type.978#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]979pub enum LifetimeRes {980 /// Successfully linked the lifetime to a generic parameter.981 Param {982 /// Id of the generic parameter that introduced it.983 param: LocalDefId,984 /// Id of the introducing place. That can be:985 /// - an item's id, for the item's generic parameters;986 /// - a TraitRef's ref_id, identifying the `for<...>` binder;987 /// - a FnPtr type's id.988 ///989 /// This information is used for impl-trait lifetime captures, to know when to or not to990 /// capture any given lifetime.991 binder: NodeId,992 },993 /// Created a generic parameter for an anonymous lifetime.994 Fresh {995 /// Id of the generic parameter that introduced it.996 ///997 /// Creating the associated `LocalDefId` is the responsibility of lowering.998 param: NodeId,999 /// Id of the introducing place. See `Param`.1000 binder: NodeId,1001 /// Kind of elided lifetime1002 kind: hir::MissingLifetimeKind,1003 },1004 /// This variant is used for anonymous lifetimes that we did not resolve during1005 /// late resolution. Those lifetimes will be inferred by typechecking.1006 Infer,1007 /// `'static` lifetime.1008 Static,1009 /// Resolution failure.1010 Error(rustc_span::ErrorGuaranteed),1011 /// HACK: This is used to recover the NodeId of an elided lifetime.1012 ElidedAnchor { start: NodeId, end: NodeId },1013}10141015pub type DocLinkResMap = UnordMap<(Symbol, Namespace), Option<Res<NodeId>>>;