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>>>;