rustc_hir/
def.rs

1use std::array::IntoIter;
2use std::fmt::Debug;
3
4use rustc_ast as ast;
5use rustc_ast::NodeId;
6use rustc_data_structures::stable_hasher::ToStableHashKey;
7use rustc_data_structures::unord::UnordMap;
8use rustc_macros::{Decodable, Encodable, HashStable_Generic};
9use rustc_span::Symbol;
10use rustc_span::def_id::{DefId, LocalDefId};
11use rustc_span::hygiene::MacroKind;
12
13use crate::definitions::DefPathData;
14use crate::hir;
15
16/// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
17#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
18pub enum CtorOf {
19    /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
20    Struct,
21    /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
22    Variant,
23}
24
25/// What kind of constructor something is.
26#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
27pub enum CtorKind {
28    /// Constructor function automatically created by a tuple struct/variant.
29    Fn,
30    /// Constructor constant automatically created by a unit struct/variant.
31    Const,
32}
33
34/// A set of macro kinds, for macros that can have more than one kind
35#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Hash, Debug)]
36#[derive(HashStable_Generic)]
37pub struct MacroKinds(u8);
38bitflags::bitflags! {
39    impl MacroKinds: u8 {
40        const BANG = 1 << 0;
41        const ATTR = 1 << 1;
42        const DERIVE = 1 << 2;
43    }
44}
45
46impl From<MacroKind> for MacroKinds {
47    fn from(kind: MacroKind) -> Self {
48        match kind {
49            MacroKind::Bang => Self::BANG,
50            MacroKind::Attr => Self::ATTR,
51            MacroKind::Derive => Self::DERIVE,
52        }
53    }
54}
55
56impl MacroKinds {
57    /// Convert the MacroKinds to a static string.
58    ///
59    /// This hardcodes all the possibilities, in order to return a static string.
60    pub fn descr(self) -> &'static str {
61        match self {
62            // FIXME: change this to "function-like macro" and fix all tests
63            Self::BANG => "macro",
64            Self::ATTR => "attribute macro",
65            Self::DERIVE => "derive macro",
66            _ if self == (Self::ATTR | Self::BANG) => "attribute/function macro",
67            _ if self == (Self::DERIVE | Self::BANG) => "derive/function macro",
68            _ if self == (Self::ATTR | Self::DERIVE) => "attribute/derive macro",
69            _ if self.is_all() => "attribute/derive/function macro",
70            _ if self.is_empty() => "useless macro",
71            _ => unreachable!(),
72        }
73    }
74
75    /// Return an indefinite article (a/an) for use with `descr()`
76    pub fn article(self) -> &'static str {
77        if self.contains(Self::ATTR) { "an" } else { "a" }
78    }
79}
80
81/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
82#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
83pub enum NonMacroAttrKind {
84    /// Single-segment attribute defined by the language (`#[inline]`)
85    Builtin(Symbol),
86    /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
87    Tool,
88    /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
89    DeriveHelper,
90    /// Single-segment custom attribute registered by a derive macro
91    /// but used before that derive macro was expanded (deprecated).
92    DeriveHelperCompat,
93}
94
95/// What kind of definition something is; e.g., `mod` vs `struct`.
96/// `enum DefPathData` may need to be updated if a new variant is added here.
97#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
98pub enum DefKind {
99    // Type namespace
100    Mod,
101    /// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.
102    Struct,
103    Union,
104    Enum,
105    /// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.
106    Variant,
107    Trait,
108    /// Type alias: `type Foo = Bar;`
109    TyAlias,
110    /// Type from an `extern` block.
111    ForeignTy,
112    /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
113    TraitAlias,
114    /// Associated type: `trait MyTrait { type Assoc; }`
115    AssocTy,
116    /// Type parameter: the `T` in `struct Vec<T> { ... }`
117    TyParam,
118
119    // Value namespace
120    Fn,
121    Const,
122    /// Constant generic parameter: `struct Foo<const N: usize> { ... }`
123    ConstParam,
124    Static {
125        /// Whether it's a `unsafe static`, `safe static` (inside extern only) or just a `static`.
126        safety: hir::Safety,
127        /// Whether it's a `static mut` or just a `static`.
128        mutability: ast::Mutability,
129        /// Whether it's an anonymous static generated for nested allocations.
130        nested: bool,
131    },
132    /// Refers to the struct or enum variant's constructor.
133    ///
134    /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and
135    /// [`DefKind::Variant`] is because structs and enum variants exist
136    /// in the *type* namespace, whereas struct and enum variant *constructors*
137    /// exist in the *value* namespace.
138    ///
139    /// You may wonder why enum variants exist in the type namespace as opposed
140    /// to the value namespace. Check out [RFC 2593] for intuition on why that is.
141    ///
142    /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593
143    Ctor(CtorOf, CtorKind),
144    /// Associated function: `impl MyStruct { fn associated() {} }`
145    /// or `trait Foo { fn associated() {} }`
146    AssocFn,
147    /// Associated constant: `trait MyTrait { const ASSOC: usize; }`
148    AssocConst,
149
150    // Macro namespace
151    Macro(MacroKinds),
152
153    // Not namespaced (or they are, but we don't treat them so)
154    ExternCrate,
155    Use,
156    /// An `extern` block.
157    ForeignMod,
158    /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`.
159    ///
160    /// Not all anon-consts are actually still relevant in the HIR. We lower
161    /// trivial const-arguments directly to `hir::ConstArgKind::Path`, at which
162    /// point the definition for the anon-const ends up unused and incomplete.
163    ///
164    /// We do not provide any a `Span` for the definition and pretty much all other
165    /// queries also ICE when using this `DefId`. Given that the `DefId` of such
166    /// constants should only be reachable by iterating all definitions of a
167    /// given crate, you should not have to worry about this.
168    AnonConst,
169    /// An inline constant, e.g. `const { 1 + 2 }`
170    InlineConst,
171    /// Opaque type, aka `impl Trait`.
172    OpaqueTy,
173    /// A field in a struct, enum or union. e.g.
174    /// - `bar` in `struct Foo { bar: u8 }`
175    /// - `Foo::Bar::0` in `enum Foo { Bar(u8) }`
176    Field,
177    /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
178    LifetimeParam,
179    /// A use of `global_asm!`.
180    GlobalAsm,
181    Impl {
182        of_trait: bool,
183    },
184    /// A closure, coroutine, or coroutine-closure.
185    ///
186    /// These are all represented with the same `ExprKind::Closure` in the AST and HIR,
187    /// which makes it difficult to distinguish these during def collection. Therefore,
188    /// we treat them all the same, and code which needs to distinguish them can match
189    /// or `hir::ClosureKind` or `type_of`.
190    Closure,
191    /// The definition of a synthetic coroutine body created by the lowering of a
192    /// coroutine-closure, such as an async closure.
193    SyntheticCoroutineBody,
194}
195
196impl DefKind {
197    /// Get an English description for the item's kind.
198    ///
199    /// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or
200    /// `TyCtxt::def_kind_descr` instead, because they give better
201    /// information for coroutines and associated functions.
202    pub fn descr(self, def_id: DefId) -> &'static str {
203        match self {
204            DefKind::Fn => "function",
205            DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate",
206            DefKind::Mod => "module",
207            DefKind::Static { .. } => "static",
208            DefKind::Enum => "enum",
209            DefKind::Variant => "variant",
210            DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",
211            DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",
212            DefKind::Struct => "struct",
213            DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
214            DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
215            DefKind::OpaqueTy => "opaque type",
216            DefKind::TyAlias => "type alias",
217            DefKind::TraitAlias => "trait alias",
218            DefKind::AssocTy => "associated type",
219            DefKind::Union => "union",
220            DefKind::Trait => "trait",
221            DefKind::ForeignTy => "foreign type",
222            DefKind::AssocFn => "associated function",
223            DefKind::Const => "constant",
224            DefKind::AssocConst => "associated constant",
225            DefKind::TyParam => "type parameter",
226            DefKind::ConstParam => "const parameter",
227            DefKind::Macro(kinds) => kinds.descr(),
228            DefKind::LifetimeParam => "lifetime parameter",
229            DefKind::Use => "import",
230            DefKind::ForeignMod => "foreign module",
231            DefKind::AnonConst => "constant expression",
232            DefKind::InlineConst => "inline constant",
233            DefKind::Field => "field",
234            DefKind::Impl { .. } => "implementation",
235            DefKind::Closure => "closure",
236            DefKind::ExternCrate => "extern crate",
237            DefKind::GlobalAsm => "global assembly block",
238            DefKind::SyntheticCoroutineBody => "synthetic mir body",
239        }
240    }
241
242    /// Gets an English article for the definition.
243    ///
244    /// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or
245    /// `TyCtxt::def_kind_descr_article` instead, because they give better
246    /// information for coroutines and associated functions.
247    pub fn article(&self) -> &'static str {
248        match *self {
249            DefKind::AssocTy
250            | DefKind::AssocConst
251            | DefKind::AssocFn
252            | DefKind::Enum
253            | DefKind::OpaqueTy
254            | DefKind::Impl { .. }
255            | DefKind::Use
256            | DefKind::InlineConst
257            | DefKind::ExternCrate => "an",
258            DefKind::Macro(kinds) => kinds.article(),
259            _ => "a",
260        }
261    }
262
263    pub fn ns(&self) -> Option<Namespace> {
264        match self {
265            DefKind::Mod
266            | DefKind::Struct
267            | DefKind::Union
268            | DefKind::Enum
269            | DefKind::Variant
270            | DefKind::Trait
271            | DefKind::TyAlias
272            | DefKind::ForeignTy
273            | DefKind::TraitAlias
274            | DefKind::AssocTy
275            | DefKind::TyParam => Some(Namespace::TypeNS),
276
277            DefKind::Fn
278            | DefKind::Const
279            | DefKind::ConstParam
280            | DefKind::Static { .. }
281            | DefKind::Ctor(..)
282            | DefKind::AssocFn
283            | DefKind::AssocConst => Some(Namespace::ValueNS),
284
285            DefKind::Macro(..) => Some(Namespace::MacroNS),
286
287            // Not namespaced.
288            DefKind::AnonConst
289            | DefKind::InlineConst
290            | DefKind::Field
291            | DefKind::LifetimeParam
292            | DefKind::ExternCrate
293            | DefKind::Closure
294            | DefKind::Use
295            | DefKind::ForeignMod
296            | DefKind::GlobalAsm
297            | DefKind::Impl { .. }
298            | DefKind::OpaqueTy
299            | DefKind::SyntheticCoroutineBody => None,
300        }
301    }
302
303    // Some `DefKind`s require a name, some don't. Panics if one is needed but
304    // not provided. (`AssocTy` is an exception, see below.)
305    pub fn def_path_data(self, name: Option<Symbol>) -> DefPathData {
306        match self {
307            DefKind::Mod
308            | DefKind::Struct
309            | DefKind::Union
310            | DefKind::Enum
311            | DefKind::Variant
312            | DefKind::Trait
313            | DefKind::TyAlias
314            | DefKind::ForeignTy
315            | DefKind::TraitAlias
316            | DefKind::TyParam
317            | DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()),
318
319            // An associated type name will be missing for an RPITIT (DefPathData::AnonAssocTy),
320            // but those provide their own DefPathData.
321            DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()),
322
323            DefKind::Fn
324            | DefKind::Const
325            | DefKind::ConstParam
326            | DefKind::Static { .. }
327            | DefKind::AssocFn
328            | DefKind::AssocConst
329            | DefKind::Field => DefPathData::ValueNs(name.unwrap()),
330            DefKind::Macro(..) => DefPathData::MacroNs(name.unwrap()),
331            DefKind::LifetimeParam => DefPathData::LifetimeNs(name.unwrap()),
332            DefKind::Ctor(..) => DefPathData::Ctor,
333            DefKind::Use => DefPathData::Use,
334            DefKind::ForeignMod => DefPathData::ForeignMod,
335            DefKind::AnonConst => DefPathData::AnonConst,
336            DefKind::InlineConst => DefPathData::AnonConst,
337            DefKind::OpaqueTy => DefPathData::OpaqueTy,
338            DefKind::GlobalAsm => DefPathData::GlobalAsm,
339            DefKind::Impl { .. } => DefPathData::Impl,
340            DefKind::Closure => DefPathData::Closure,
341            DefKind::SyntheticCoroutineBody => DefPathData::SyntheticCoroutineBody,
342        }
343    }
344
345    pub fn is_assoc(self) -> bool {
346        matches!(self, DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy)
347    }
348
349    /// This is a "module" in name resolution sense.
350    #[inline]
351    pub fn is_module_like(self) -> bool {
352        matches!(self, DefKind::Mod | DefKind::Enum | DefKind::Trait)
353    }
354
355    #[inline]
356    pub fn is_adt(self) -> bool {
357        matches!(self, DefKind::Struct | DefKind::Union | DefKind::Enum)
358    }
359
360    #[inline]
361    pub fn is_fn_like(self) -> bool {
362        matches!(
363            self,
364            DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::SyntheticCoroutineBody
365        )
366    }
367
368    /// Whether the corresponding item has generic parameters, ie. the `generics_of` query works.
369    pub fn has_generics(self) -> bool {
370        match self {
371            DefKind::AnonConst
372            | DefKind::AssocConst
373            | DefKind::AssocFn
374            | DefKind::AssocTy
375            | DefKind::Closure
376            | DefKind::Const
377            | DefKind::Ctor(..)
378            | DefKind::Enum
379            | DefKind::Field
380            | DefKind::Fn
381            | DefKind::ForeignTy
382            | DefKind::Impl { .. }
383            | DefKind::InlineConst
384            | DefKind::OpaqueTy
385            | DefKind::Static { .. }
386            | DefKind::Struct
387            | DefKind::SyntheticCoroutineBody
388            | DefKind::Trait
389            | DefKind::TraitAlias
390            | DefKind::TyAlias
391            | DefKind::Union
392            | DefKind::Variant => true,
393            DefKind::ConstParam
394            | DefKind::ExternCrate
395            | DefKind::ForeignMod
396            | DefKind::GlobalAsm
397            | DefKind::LifetimeParam
398            | DefKind::Macro(_)
399            | DefKind::Mod
400            | DefKind::TyParam
401            | DefKind::Use => false,
402        }
403    }
404
405    /// Whether `query get_codegen_attrs` should be used with this definition.
406    pub fn has_codegen_attrs(self) -> bool {
407        match self {
408            DefKind::Fn
409            | DefKind::AssocFn
410            | DefKind::Ctor(..)
411            | DefKind::Closure
412            | DefKind::Static { .. }
413            | DefKind::SyntheticCoroutineBody => true,
414            DefKind::Mod
415            | DefKind::Struct
416            | DefKind::Union
417            | DefKind::Enum
418            | DefKind::Variant
419            | DefKind::Trait
420            | DefKind::TyAlias
421            | DefKind::ForeignTy
422            | DefKind::TraitAlias
423            | DefKind::AssocTy
424            | DefKind::Const
425            | DefKind::AssocConst
426            | DefKind::Macro(..)
427            | DefKind::Use
428            | DefKind::ForeignMod
429            | DefKind::OpaqueTy
430            | DefKind::Impl { .. }
431            | DefKind::Field
432            | DefKind::TyParam
433            | DefKind::ConstParam
434            | DefKind::LifetimeParam
435            | DefKind::AnonConst
436            | DefKind::InlineConst
437            | DefKind::GlobalAsm
438            | DefKind::ExternCrate => false,
439        }
440    }
441}
442
443/// The resolution of a path or export.
444///
445/// For every path or identifier in Rust, the compiler must determine
446/// what the path refers to. This process is called name resolution,
447/// and `Res` is the primary result of name resolution.
448///
449/// For example, everything prefixed with `/* Res */` in this example has
450/// an associated `Res`:
451///
452/// ```ignore (illustrative)
453/// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
454///     /* Res */ String::from(/* Res */ s)
455/// }
456///
457/// /* Res */ str_to_string("hello");
458/// ```
459///
460/// The associated `Res`s will be:
461///
462/// - `str` will resolve to [`Res::PrimTy`];
463/// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
464///   for `String` as defined in the standard library;
465/// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
466///   pointing to `String::from`;
467/// - `s` will resolve to [`Res::Local`];
468/// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
469///   pointing to the definition of `str_to_string` in the current crate.
470//
471#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug, HashStable_Generic)]
472pub enum Res<Id = hir::HirId> {
473    /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
474    ///
475    /// **Not bound to a specific namespace.**
476    Def(DefKind, DefId),
477
478    // Type namespace
479    /// A primitive type such as `i32` or `str`.
480    ///
481    /// **Belongs to the type namespace.**
482    PrimTy(hir::PrimTy),
483
484    /// The `Self` type, as used within a trait.
485    ///
486    /// **Belongs to the type namespace.**
487    ///
488    /// See the examples on [`Res::SelfTyAlias`] for details.
489    SelfTyParam {
490        /// The trait this `Self` is a generic parameter for.
491        trait_: DefId,
492    },
493
494    /// The `Self` type, as used somewhere other than within a trait.
495    ///
496    /// **Belongs to the type namespace.**
497    ///
498    /// Examples:
499    /// ```
500    /// struct Bar(Box<Self>); // SelfTyAlias
501    ///
502    /// trait Foo {
503    ///     fn foo() -> Box<Self>; // SelfTyParam
504    /// }
505    ///
506    /// impl Bar {
507    ///     fn blah() {
508    ///         let _: Self; // SelfTyAlias
509    ///     }
510    /// }
511    ///
512    /// impl Foo for Bar {
513    ///     fn foo() -> Box<Self /* SelfTyAlias */> {
514    ///         let _: Self;        // SelfTyAlias
515    ///
516    ///         todo!()
517    ///     }
518    /// }
519    /// ```
520    /// *See also [`Res::SelfCtor`].*
521    ///
522    SelfTyAlias {
523        /// The item introducing the `Self` type alias. Can be used in the `type_of` query
524        /// to get the underlying type.
525        alias_to: DefId,
526
527        /// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an
528        /// anonymous constant).
529        ///
530        /// HACK(min_const_generics): self types also have an optional requirement to **not**
531        /// mention any generic parameters to allow the following with `min_const_generics`:
532        /// ```
533        /// # struct Foo;
534        /// impl Foo { fn test() -> [u8; size_of::<Self>()] { todo!() } }
535        ///
536        /// struct Bar([u8; baz::<Self>()]);
537        /// const fn baz<T>() -> usize { 10 }
538        /// ```
539        /// We do however allow `Self` in repeat expression even if it is generic to not break code
540        /// which already works on stable while causing the `const_evaluatable_unchecked` future
541        /// compat lint:
542        /// ```
543        /// fn foo<T>() {
544        ///     let _bar = [1_u8; size_of::<*mut T>()];
545        /// }
546        /// ```
547        // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
548        forbid_generic: bool,
549
550        /// Is this within an `impl Foo for bar`?
551        is_trait_impl: bool,
552    },
553
554    // Value namespace
555    /// The `Self` constructor, along with the [`DefId`]
556    /// of the impl it is associated with.
557    ///
558    /// **Belongs to the value namespace.**
559    ///
560    /// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].*
561    SelfCtor(DefId),
562
563    /// A local variable or function parameter.
564    ///
565    /// **Belongs to the value namespace.**
566    Local(Id),
567
568    /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
569    ///
570    /// **Belongs to the type namespace.**
571    ToolMod,
572
573    // Macro namespace
574    /// An attribute that is *not* implemented via macro.
575    /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
576    /// as opposed to `#[test]`, which is a builtin macro.
577    ///
578    /// **Belongs to the macro namespace.**
579    NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
580
581    // All namespaces
582    /// Name resolution failed. We use a dummy `Res` variant so later phases
583    /// of the compiler won't crash and can instead report more errors.
584    ///
585    /// **Not bound to a specific namespace.**
586    Err,
587}
588
589/// The result of resolving a path before lowering to HIR,
590/// with "module" segments resolved and associated item
591/// segments deferred to type checking.
592/// `base_res` is the resolution of the resolved part of the
593/// path, `unresolved_segments` is the number of unresolved
594/// segments.
595///
596/// ```text
597/// module::Type::AssocX::AssocY::MethodOrAssocType
598/// ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
599/// base_res      unresolved_segments = 3
600///
601/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
602///       ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
603///       base_res        unresolved_segments = 2
604/// ```
605#[derive(Copy, Clone, Debug)]
606pub struct PartialRes {
607    base_res: Res<NodeId>,
608    unresolved_segments: usize,
609}
610
611impl PartialRes {
612    #[inline]
613    pub fn new(base_res: Res<NodeId>) -> Self {
614        PartialRes { base_res, unresolved_segments: 0 }
615    }
616
617    #[inline]
618    pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
619        if base_res == Res::Err {
620            unresolved_segments = 0
621        }
622        PartialRes { base_res, unresolved_segments }
623    }
624
625    #[inline]
626    pub fn base_res(&self) -> Res<NodeId> {
627        self.base_res
628    }
629
630    #[inline]
631    pub fn unresolved_segments(&self) -> usize {
632        self.unresolved_segments
633    }
634
635    #[inline]
636    pub fn full_res(&self) -> Option<Res<NodeId>> {
637        (self.unresolved_segments == 0).then_some(self.base_res)
638    }
639
640    #[inline]
641    pub fn expect_full_res(&self) -> Res<NodeId> {
642        self.full_res().expect("unexpected unresolved segments")
643    }
644}
645
646/// Different kinds of symbols can coexist even if they share the same textual name.
647/// Therefore, they each have a separate universe (known as a "namespace").
648#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
649#[derive(HashStable_Generic)]
650pub enum Namespace {
651    /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
652    /// (and, by extension, crates).
653    ///
654    /// Note that the type namespace includes other items; this is not an
655    /// exhaustive list.
656    TypeNS,
657    /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
658    ValueNS,
659    /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
660    /// procedural macros, attribute macros, `derive` macros, and non-macro attributes
661    /// like `#[inline]` and `#[rustfmt::skip]`.
662    MacroNS,
663}
664
665impl Namespace {
666    /// The English description of the namespace.
667    pub fn descr(self) -> &'static str {
668        match self {
669            Self::TypeNS => "type",
670            Self::ValueNS => "value",
671            Self::MacroNS => "macro",
672        }
673    }
674}
675
676impl<CTX: crate::HashStableContext> ToStableHashKey<CTX> for Namespace {
677    type KeyType = Namespace;
678
679    #[inline]
680    fn to_stable_hash_key(&self, _: &CTX) -> Namespace {
681        *self
682    }
683}
684
685/// Just a helper ‒ separate structure for each namespace.
686#[derive(Copy, Clone, Default, Debug, HashStable_Generic)]
687pub struct PerNS<T> {
688    pub value_ns: T,
689    pub type_ns: T,
690    pub macro_ns: T,
691}
692
693impl<T> PerNS<T> {
694    pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> PerNS<U> {
695        PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
696    }
697
698    /// Note: Do you really want to use this? Often you know which namespace a
699    /// name will belong in, and you can consider just that namespace directly,
700    /// rather than iterating through all of them.
701    pub fn into_iter(self) -> IntoIter<T, 3> {
702        [self.value_ns, self.type_ns, self.macro_ns].into_iter()
703    }
704
705    /// Note: Do you really want to use this? Often you know which namespace a
706    /// name will belong in, and you can consider just that namespace directly,
707    /// rather than iterating through all of them.
708    pub fn iter(&self) -> IntoIter<&T, 3> {
709        [&self.value_ns, &self.type_ns, &self.macro_ns].into_iter()
710    }
711}
712
713impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
714    type Output = T;
715
716    fn index(&self, ns: Namespace) -> &T {
717        match ns {
718            Namespace::ValueNS => &self.value_ns,
719            Namespace::TypeNS => &self.type_ns,
720            Namespace::MacroNS => &self.macro_ns,
721        }
722    }
723}
724
725impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
726    fn index_mut(&mut self, ns: Namespace) -> &mut T {
727        match ns {
728            Namespace::ValueNS => &mut self.value_ns,
729            Namespace::TypeNS => &mut self.type_ns,
730            Namespace::MacroNS => &mut self.macro_ns,
731        }
732    }
733}
734
735impl<T> PerNS<Option<T>> {
736    /// Returns `true` if all the items in this collection are `None`.
737    pub fn is_empty(&self) -> bool {
738        self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none()
739    }
740
741    /// Returns an iterator over the items which are `Some`.
742    ///
743    /// Note: Do you really want to use this? Often you know which namespace a
744    /// name will belong in, and you can consider just that namespace directly,
745    /// rather than iterating through all of them.
746    pub fn present_items(self) -> impl Iterator<Item = T> {
747        [self.type_ns, self.value_ns, self.macro_ns].into_iter().flatten()
748    }
749}
750
751impl CtorKind {
752    pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> {
753        match *vdata {
754            ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)),
755            ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)),
756            ast::VariantData::Struct { .. } => None,
757        }
758    }
759}
760
761impl NonMacroAttrKind {
762    pub fn descr(self) -> &'static str {
763        match self {
764            NonMacroAttrKind::Builtin(..) => "built-in attribute",
765            NonMacroAttrKind::Tool => "tool attribute",
766            NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
767                "derive helper attribute"
768            }
769        }
770    }
771
772    // Currently trivial, but exists in case a new kind is added in the future whose name starts
773    // with a vowel.
774    pub fn article(self) -> &'static str {
775        "a"
776    }
777
778    /// Users of some attributes cannot mark them as used, so they are considered always used.
779    pub fn is_used(self) -> bool {
780        match self {
781            NonMacroAttrKind::Tool
782            | NonMacroAttrKind::DeriveHelper
783            | NonMacroAttrKind::DeriveHelperCompat => true,
784            NonMacroAttrKind::Builtin(..) => false,
785        }
786    }
787}
788
789impl<Id> Res<Id> {
790    /// Return the `DefId` of this `Def` if it has an ID, else panic.
791    pub fn def_id(&self) -> DefId
792    where
793        Id: Debug,
794    {
795        self.opt_def_id().unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {self:?}"))
796    }
797
798    /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
799    pub fn opt_def_id(&self) -> Option<DefId> {
800        match *self {
801            Res::Def(_, id) => Some(id),
802
803            Res::Local(..)
804            | Res::PrimTy(..)
805            | Res::SelfTyParam { .. }
806            | Res::SelfTyAlias { .. }
807            | Res::SelfCtor(..)
808            | Res::ToolMod
809            | Res::NonMacroAttr(..)
810            | Res::Err => None,
811        }
812    }
813
814    /// Return the `DefId` of this `Res` if it represents a module.
815    pub fn mod_def_id(&self) -> Option<DefId> {
816        match *self {
817            Res::Def(DefKind::Mod, id) => Some(id),
818            _ => None,
819        }
820    }
821
822    /// If this is a "module" in name resolution sense, return its `DefId`.
823    #[inline]
824    pub fn module_like_def_id(&self) -> Option<DefId> {
825        match self {
826            Res::Def(def_kind, def_id) if def_kind.is_module_like() => Some(*def_id),
827            _ => None,
828        }
829    }
830
831    /// A human readable name for the res kind ("function", "module", etc.).
832    pub fn descr(&self) -> &'static str {
833        match *self {
834            Res::Def(kind, def_id) => kind.descr(def_id),
835            Res::SelfCtor(..) => "self constructor",
836            Res::PrimTy(..) => "builtin type",
837            Res::Local(..) => "local variable",
838            Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
839            Res::ToolMod => "tool module",
840            Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
841            Res::Err => "unresolved item",
842        }
843    }
844
845    /// Gets an English article for the `Res`.
846    pub fn article(&self) -> &'static str {
847        match *self {
848            Res::Def(kind, _) => kind.article(),
849            Res::NonMacroAttr(kind) => kind.article(),
850            Res::Err => "an",
851            _ => "a",
852        }
853    }
854
855    pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
856        match self {
857            Res::Def(kind, id) => Res::Def(kind, id),
858            Res::SelfCtor(id) => Res::SelfCtor(id),
859            Res::PrimTy(id) => Res::PrimTy(id),
860            Res::Local(id) => Res::Local(map(id)),
861            Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
862            Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
863                Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
864            }
865            Res::ToolMod => Res::ToolMod,
866            Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
867            Res::Err => Res::Err,
868        }
869    }
870
871    pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {
872        Ok(match self {
873            Res::Def(kind, id) => Res::Def(kind, id),
874            Res::SelfCtor(id) => Res::SelfCtor(id),
875            Res::PrimTy(id) => Res::PrimTy(id),
876            Res::Local(id) => Res::Local(map(id)?),
877            Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
878            Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
879                Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
880            }
881            Res::ToolMod => Res::ToolMod,
882            Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
883            Res::Err => Res::Err,
884        })
885    }
886
887    #[track_caller]
888    pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
889        self.map_id(
890            #[track_caller]
891            |_| panic!("unexpected `Res::Local`"),
892        )
893    }
894
895    pub fn macro_kinds(self) -> Option<MacroKinds> {
896        match self {
897            Res::Def(DefKind::Macro(kinds), _) => Some(kinds),
898            Res::NonMacroAttr(..) => Some(MacroKinds::ATTR),
899            _ => None,
900        }
901    }
902
903    /// Returns `None` if this is `Res::Err`
904    pub fn ns(&self) -> Option<Namespace> {
905        match self {
906            Res::Def(kind, ..) => kind.ns(),
907            Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
908                Some(Namespace::TypeNS)
909            }
910            Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
911            Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
912            Res::Err => None,
913        }
914    }
915
916    /// Always returns `true` if `self` is `Res::Err`
917    pub fn matches_ns(&self, ns: Namespace) -> bool {
918        self.ns().is_none_or(|actual_ns| actual_ns == ns)
919    }
920
921    /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
922    pub fn expected_in_tuple_struct_pat(&self) -> bool {
923        matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..))
924    }
925
926    /// Returns whether such a resolved path can occur in a unit struct/variant pattern
927    pub fn expected_in_unit_struct_pat(&self) -> bool {
928        matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..))
929    }
930}
931
932/// Resolution for a lifetime appearing in a type.
933#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
934pub enum LifetimeRes {
935    /// Successfully linked the lifetime to a generic parameter.
936    Param {
937        /// Id of the generic parameter that introduced it.
938        param: LocalDefId,
939        /// Id of the introducing place. That can be:
940        /// - an item's id, for the item's generic parameters;
941        /// - a TraitRef's ref_id, identifying the `for<...>` binder;
942        /// - a FnPtr type's id.
943        ///
944        /// This information is used for impl-trait lifetime captures, to know when to or not to
945        /// capture any given lifetime.
946        binder: NodeId,
947    },
948    /// Created a generic parameter for an anonymous lifetime.
949    Fresh {
950        /// Id of the generic parameter that introduced it.
951        ///
952        /// Creating the associated `LocalDefId` is the responsibility of lowering.
953        param: NodeId,
954        /// Id of the introducing place. See `Param`.
955        binder: NodeId,
956        /// Kind of elided lifetime
957        kind: hir::MissingLifetimeKind,
958    },
959    /// This variant is used for anonymous lifetimes that we did not resolve during
960    /// late resolution. Those lifetimes will be inferred by typechecking.
961    Infer,
962    /// `'static` lifetime.
963    Static,
964    /// Resolution failure.
965    Error,
966    /// HACK: This is used to recover the NodeId of an elided lifetime.
967    ElidedAnchor { start: NodeId, end: NodeId },
968}
969
970pub type DocLinkResMap = UnordMap<(Symbol, Namespace), Option<Res<NodeId>>>;