]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_hir/src/def.rs
Point at type parameter in plain path expr
[rust.git] / compiler / rustc_hir / src / def.rs
1 use crate::hir;
2
3 use rustc_ast as ast;
4 use rustc_ast::NodeId;
5 use rustc_macros::HashStable_Generic;
6 use rustc_span::def_id::{DefId, LocalDefId};
7 use rustc_span::hygiene::MacroKind;
8 use rustc_span::Symbol;
9
10 use std::array::IntoIter;
11 use std::fmt::Debug;
12
13 /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
14 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
15 #[derive(HashStable_Generic)]
16 pub enum CtorOf {
17     /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
18     Struct,
19     /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
20     Variant,
21 }
22
23 /// What kind of constructor something is.
24 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
25 #[derive(HashStable_Generic)]
26 pub enum CtorKind {
27     /// Constructor function automatically created by a tuple struct/variant.
28     Fn,
29     /// Constructor constant automatically created by a unit struct/variant.
30     Const,
31     /// Unusable name in value namespace created by a struct variant.
32     Fictive,
33 }
34
35 /// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
36 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
37 #[derive(HashStable_Generic)]
38 pub enum NonMacroAttrKind {
39     /// Single-segment attribute defined by the language (`#[inline]`)
40     Builtin(Symbol),
41     /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
42     Tool,
43     /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
44     DeriveHelper,
45     /// Single-segment custom attribute registered by a derive macro
46     /// but used before that derive macro was expanded (deprecated).
47     DeriveHelperCompat,
48 }
49
50 /// What kind of definition something is; e.g., `mod` vs `struct`.
51 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
52 #[derive(HashStable_Generic)]
53 pub enum DefKind {
54     // Type namespace
55     Mod,
56     /// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.
57     Struct,
58     Union,
59     Enum,
60     /// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.
61     Variant,
62     Trait,
63     /// Type alias: `type Foo = Bar;`
64     TyAlias,
65     /// Type from an `extern` block.
66     ForeignTy,
67     /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
68     TraitAlias,
69     /// Associated type: `trait MyTrait { type Assoc; }`
70     AssocTy,
71     /// Type parameter: the `T` in `struct Vec<T> { ... }`
72     TyParam,
73
74     // Value namespace
75     Fn,
76     Const,
77     /// Constant generic parameter: `struct Foo<const N: usize> { ... }`
78     ConstParam,
79     Static(ast::Mutability),
80     /// Refers to the struct or enum variant's constructor.
81     ///
82     /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and
83     /// [`DefKind::Variant`] is because structs and enum variants exist
84     /// in the *type* namespace, whereas struct and enum variant *constructors*
85     /// exist in the *value* namespace.
86     ///
87     /// You may wonder why enum variants exist in the type namespace as opposed
88     /// to the value namespace. Check out [RFC 2593] for intuition on why that is.
89     ///
90     /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593
91     Ctor(CtorOf, CtorKind),
92     /// Associated function: `impl MyStruct { fn associated() {} }`
93     /// or `trait Foo { fn associated() {} }`
94     AssocFn,
95     /// Associated constant: `trait MyTrait { const ASSOC: usize; }`
96     AssocConst,
97
98     // Macro namespace
99     Macro(MacroKind),
100
101     // Not namespaced (or they are, but we don't treat them so)
102     ExternCrate,
103     Use,
104     /// An `extern` block.
105     ForeignMod,
106     /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`
107     AnonConst,
108     /// An inline constant, e.g. `const { 1 + 2 }`
109     InlineConst,
110     /// Opaque type, aka `impl Trait`.
111     OpaqueTy,
112     Field,
113     /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
114     LifetimeParam,
115     /// A use of `global_asm!`.
116     GlobalAsm,
117     Impl,
118     Closure,
119     Generator,
120 }
121
122 impl DefKind {
123     pub fn descr(self, def_id: DefId) -> &'static str {
124         match self {
125             DefKind::Fn => "function",
126             DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate",
127             DefKind::Mod => "module",
128             DefKind::Static(..) => "static",
129             DefKind::Enum => "enum",
130             DefKind::Variant => "variant",
131             DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",
132             DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",
133             DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant",
134             DefKind::Struct => "struct",
135             DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
136             DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
137             DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => {
138                 panic!("impossible struct constructor")
139             }
140             DefKind::OpaqueTy => "opaque type",
141             DefKind::TyAlias => "type alias",
142             DefKind::TraitAlias => "trait alias",
143             DefKind::AssocTy => "associated type",
144             DefKind::Union => "union",
145             DefKind::Trait => "trait",
146             DefKind::ForeignTy => "foreign type",
147             DefKind::AssocFn => "associated function",
148             DefKind::Const => "constant",
149             DefKind::AssocConst => "associated constant",
150             DefKind::TyParam => "type parameter",
151             DefKind::ConstParam => "const parameter",
152             DefKind::Macro(macro_kind) => macro_kind.descr(),
153             DefKind::LifetimeParam => "lifetime parameter",
154             DefKind::Use => "import",
155             DefKind::ForeignMod => "foreign module",
156             DefKind::AnonConst => "constant expression",
157             DefKind::InlineConst => "inline constant",
158             DefKind::Field => "field",
159             DefKind::Impl => "implementation",
160             DefKind::Closure => "closure",
161             DefKind::Generator => "generator",
162             DefKind::ExternCrate => "extern crate",
163             DefKind::GlobalAsm => "global assembly block",
164         }
165     }
166
167     /// Gets an English article for the definition.
168     pub fn article(&self) -> &'static str {
169         match *self {
170             DefKind::AssocTy
171             | DefKind::AssocConst
172             | DefKind::AssocFn
173             | DefKind::Enum
174             | DefKind::OpaqueTy
175             | DefKind::Impl
176             | DefKind::Use
177             | DefKind::InlineConst
178             | DefKind::ExternCrate => "an",
179             DefKind::Macro(macro_kind) => macro_kind.article(),
180             _ => "a",
181         }
182     }
183
184     pub fn ns(&self) -> Option<Namespace> {
185         match self {
186             DefKind::Mod
187             | DefKind::Struct
188             | DefKind::Union
189             | DefKind::Enum
190             | DefKind::Variant
191             | DefKind::Trait
192             | DefKind::OpaqueTy
193             | DefKind::TyAlias
194             | DefKind::ForeignTy
195             | DefKind::TraitAlias
196             | DefKind::AssocTy
197             | DefKind::TyParam => Some(Namespace::TypeNS),
198
199             DefKind::Fn
200             | DefKind::Const
201             | DefKind::ConstParam
202             | DefKind::Static(..)
203             | DefKind::Ctor(..)
204             | DefKind::AssocFn
205             | DefKind::AssocConst => Some(Namespace::ValueNS),
206
207             DefKind::Macro(..) => Some(Namespace::MacroNS),
208
209             // Not namespaced.
210             DefKind::AnonConst
211             | DefKind::InlineConst
212             | DefKind::Field
213             | DefKind::LifetimeParam
214             | DefKind::ExternCrate
215             | DefKind::Closure
216             | DefKind::Generator
217             | DefKind::Use
218             | DefKind::ForeignMod
219             | DefKind::GlobalAsm
220             | DefKind::Impl => None,
221         }
222     }
223
224     #[inline]
225     pub fn is_fn_like(self) -> bool {
226         match self {
227             DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator => true,
228             _ => false,
229         }
230     }
231
232     /// Whether `query get_codegen_attrs` should be used with this definition.
233     pub fn has_codegen_attrs(self) -> bool {
234         match self {
235             DefKind::Fn
236             | DefKind::AssocFn
237             | DefKind::Ctor(..)
238             | DefKind::Closure
239             | DefKind::Generator
240             | DefKind::Static(_) => true,
241             DefKind::Mod
242             | DefKind::Struct
243             | DefKind::Union
244             | DefKind::Enum
245             | DefKind::Variant
246             | DefKind::Trait
247             | DefKind::TyAlias
248             | DefKind::ForeignTy
249             | DefKind::TraitAlias
250             | DefKind::AssocTy
251             | DefKind::Const
252             | DefKind::AssocConst
253             | DefKind::Macro(..)
254             | DefKind::Use
255             | DefKind::ForeignMod
256             | DefKind::OpaqueTy
257             | DefKind::Impl
258             | DefKind::Field
259             | DefKind::TyParam
260             | DefKind::ConstParam
261             | DefKind::LifetimeParam
262             | DefKind::AnonConst
263             | DefKind::InlineConst
264             | DefKind::GlobalAsm
265             | DefKind::ExternCrate => false,
266         }
267     }
268 }
269
270 /// The resolution of a path or export.
271 ///
272 /// For every path or identifier in Rust, the compiler must determine
273 /// what the path refers to. This process is called name resolution,
274 /// and `Res` is the primary result of name resolution.
275 ///
276 /// For example, everything prefixed with `/* Res */` in this example has
277 /// an associated `Res`:
278 ///
279 /// ```
280 /// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
281 ///     /* Res */ String::from(/* Res */ s)
282 /// }
283 ///
284 /// /* Res */ str_to_string("hello");
285 /// ```
286 ///
287 /// The associated `Res`s will be:
288 ///
289 /// - `str` will resolve to [`Res::PrimTy`];
290 /// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
291 ///   for `String` as defined in the standard library;
292 /// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
293 ///   pointing to `String::from`;
294 /// - `s` will resolve to [`Res::Local`];
295 /// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
296 ///   pointing to the definition of `str_to_string` in the current crate.
297 //
298 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
299 #[derive(HashStable_Generic)]
300 pub enum Res<Id = hir::HirId> {
301     /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
302     ///
303     /// **Not bound to a specific namespace.**
304     Def(DefKind, DefId),
305
306     // Type namespace
307     /// A primitive type such as `i32` or `str`.
308     ///
309     /// **Belongs to the type namespace.**
310     PrimTy(hir::PrimTy),
311     /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
312     /// optionally with the [`DefId`] of the item introducing the `Self` type alias.
313     ///
314     /// **Belongs to the type namespace.**
315     ///
316     /// Examples:
317     /// ```
318     /// struct Bar(Box<Self>);
319     /// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
320     ///
321     /// trait Foo {
322     ///     fn foo() -> Box<Self>;
323     ///     // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
324     /// }
325     ///
326     /// impl Bar {
327     ///     fn blah() {
328     ///         let _: Self;
329     ///         // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
330     ///     }
331     /// }
332     ///
333     /// impl Foo for Bar {
334     ///     fn foo() -> Box<Self> {
335     ///     // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
336     ///         let _: Self;
337     ///         // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
338     ///
339     ///         todo!()
340     ///     }
341     /// }
342     /// ```
343     ///
344     /// *See also [`Res::SelfCtor`].*
345     ///
346     /// -----
347     ///
348     /// HACK(min_const_generics): self types also have an optional requirement to **not** mention
349     /// any generic parameters to allow the following with `min_const_generics`:
350     /// ```
351     /// # struct Foo;
352     /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
353     ///
354     /// struct Bar([u8; baz::<Self>()]);
355     /// const fn baz<T>() -> usize { 10 }
356     /// ```
357     /// We do however allow `Self` in repeat expression even if it is generic to not break code
358     /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint:
359     /// ```
360     /// fn foo<T>() {
361     ///     let _bar = [1_u8; std::mem::size_of::<*mut T>()];
362     /// }
363     /// ```
364     // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
365     SelfTy {
366         /// The trait this `Self` is a generic arg for.
367         trait_: Option<DefId>,
368         /// The item introducing the `Self` type alias. Can be used in the `type_of` query
369         /// to get the underlying type. Additionally whether the `Self` type is disallowed
370         /// from mentioning generics (i.e. when used in an anonymous constant).
371         alias_to: Option<(DefId, bool)>,
372     },
373     /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
374     ///
375     /// **Belongs to the type namespace.**
376     ToolMod,
377
378     // Value namespace
379     /// The `Self` constructor, along with the [`DefId`]
380     /// of the impl it is associated with.
381     ///
382     /// **Belongs to the value namespace.**
383     ///
384     /// *See also [`Res::SelfTy`].*
385     SelfCtor(DefId),
386     /// A local variable or function parameter.
387     ///
388     /// **Belongs to the value namespace.**
389     Local(Id),
390
391     // Macro namespace
392     /// An attribute that is *not* implemented via macro.
393     /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
394     /// as opposed to `#[test]`, which is a builtin macro.
395     ///
396     /// **Belongs to the macro namespace.**
397     NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
398
399     // All namespaces
400     /// Name resolution failed. We use a dummy `Res` variant so later phases
401     /// of the compiler won't crash and can instead report more errors.
402     ///
403     /// **Not bound to a specific namespace.**
404     Err,
405 }
406
407 /// The result of resolving a path before lowering to HIR,
408 /// with "module" segments resolved and associated item
409 /// segments deferred to type checking.
410 /// `base_res` is the resolution of the resolved part of the
411 /// path, `unresolved_segments` is the number of unresolved
412 /// segments.
413 ///
414 /// ```text
415 /// module::Type::AssocX::AssocY::MethodOrAssocType
416 /// ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
417 /// base_res      unresolved_segments = 3
418 ///
419 /// <T as Trait>::AssocX::AssocY::MethodOrAssocType
420 ///       ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
421 ///       base_res        unresolved_segments = 2
422 /// ```
423 #[derive(Copy, Clone, Debug)]
424 pub struct PartialRes {
425     base_res: Res<NodeId>,
426     unresolved_segments: usize,
427 }
428
429 impl PartialRes {
430     #[inline]
431     pub fn new(base_res: Res<NodeId>) -> Self {
432         PartialRes { base_res, unresolved_segments: 0 }
433     }
434
435     #[inline]
436     pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
437         if base_res == Res::Err {
438             unresolved_segments = 0
439         }
440         PartialRes { base_res, unresolved_segments }
441     }
442
443     #[inline]
444     pub fn base_res(&self) -> Res<NodeId> {
445         self.base_res
446     }
447
448     #[inline]
449     pub fn unresolved_segments(&self) -> usize {
450         self.unresolved_segments
451     }
452 }
453
454 /// Different kinds of symbols can coexist even if they share the same textual name.
455 /// Therefore, they each have a separate universe (known as a "namespace").
456 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
457 pub enum Namespace {
458     /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
459     /// (and, by extension, crates).
460     ///
461     /// Note that the type namespace includes other items; this is not an
462     /// exhaustive list.
463     TypeNS,
464     /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
465     ValueNS,
466     /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
467     /// procedural macros, attribute macros, `derive` macros, and non-macro attributes
468     /// like `#[inline]` and `#[rustfmt::skip]`.
469     MacroNS,
470 }
471
472 impl Namespace {
473     /// The English description of the namespace.
474     pub fn descr(self) -> &'static str {
475         match self {
476             Self::TypeNS => "type",
477             Self::ValueNS => "value",
478             Self::MacroNS => "macro",
479         }
480     }
481 }
482
483 /// Just a helper â€’ separate structure for each namespace.
484 #[derive(Copy, Clone, Default, Debug)]
485 pub struct PerNS<T> {
486     pub value_ns: T,
487     pub type_ns: T,
488     pub macro_ns: T,
489 }
490
491 impl<T> PerNS<T> {
492     pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> PerNS<U> {
493         PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
494     }
495
496     pub fn into_iter(self) -> IntoIter<T, 3> {
497         [self.value_ns, self.type_ns, self.macro_ns].into_iter()
498     }
499
500     pub fn iter(&self) -> IntoIter<&T, 3> {
501         [&self.value_ns, &self.type_ns, &self.macro_ns].into_iter()
502     }
503 }
504
505 impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
506     type Output = T;
507
508     fn index(&self, ns: Namespace) -> &T {
509         match ns {
510             Namespace::ValueNS => &self.value_ns,
511             Namespace::TypeNS => &self.type_ns,
512             Namespace::MacroNS => &self.macro_ns,
513         }
514     }
515 }
516
517 impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
518     fn index_mut(&mut self, ns: Namespace) -> &mut T {
519         match ns {
520             Namespace::ValueNS => &mut self.value_ns,
521             Namespace::TypeNS => &mut self.type_ns,
522             Namespace::MacroNS => &mut self.macro_ns,
523         }
524     }
525 }
526
527 impl<T> PerNS<Option<T>> {
528     /// Returns `true` if all the items in this collection are `None`.
529     pub fn is_empty(&self) -> bool {
530         self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none()
531     }
532
533     /// Returns an iterator over the items which are `Some`.
534     pub fn present_items(self) -> impl Iterator<Item = T> {
535         [self.type_ns, self.value_ns, self.macro_ns].into_iter().flatten()
536     }
537 }
538
539 impl CtorKind {
540     pub fn from_ast(vdata: &ast::VariantData) -> CtorKind {
541         match *vdata {
542             ast::VariantData::Tuple(..) => CtorKind::Fn,
543             ast::VariantData::Unit(..) => CtorKind::Const,
544             ast::VariantData::Struct(..) => CtorKind::Fictive,
545         }
546     }
547
548     pub fn from_hir(vdata: &hir::VariantData<'_>) -> CtorKind {
549         match *vdata {
550             hir::VariantData::Tuple(..) => CtorKind::Fn,
551             hir::VariantData::Unit(..) => CtorKind::Const,
552             hir::VariantData::Struct(..) => CtorKind::Fictive,
553         }
554     }
555 }
556
557 impl NonMacroAttrKind {
558     pub fn descr(self) -> &'static str {
559         match self {
560             NonMacroAttrKind::Builtin(..) => "built-in attribute",
561             NonMacroAttrKind::Tool => "tool attribute",
562             NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
563                 "derive helper attribute"
564             }
565         }
566     }
567
568     pub fn article(self) -> &'static str {
569         "a"
570     }
571
572     /// Users of some attributes cannot mark them as used, so they are considered always used.
573     pub fn is_used(self) -> bool {
574         match self {
575             NonMacroAttrKind::Tool
576             | NonMacroAttrKind::DeriveHelper
577             | NonMacroAttrKind::DeriveHelperCompat => true,
578             NonMacroAttrKind::Builtin(..) => false,
579         }
580     }
581 }
582
583 impl<Id> Res<Id> {
584     /// Return the `DefId` of this `Def` if it has an ID, else panic.
585     pub fn def_id(&self) -> DefId
586     where
587         Id: Debug,
588     {
589         self.opt_def_id()
590             .unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {:?}", self))
591     }
592
593     /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
594     pub fn opt_def_id(&self) -> Option<DefId> {
595         match *self {
596             Res::Def(_, id) => Some(id),
597
598             Res::Local(..)
599             | Res::PrimTy(..)
600             | Res::SelfTy { .. }
601             | Res::SelfCtor(..)
602             | Res::ToolMod
603             | Res::NonMacroAttr(..)
604             | Res::Err => None,
605         }
606     }
607
608     /// Return the `DefId` of this `Res` if it represents a module.
609     pub fn mod_def_id(&self) -> Option<DefId> {
610         match *self {
611             Res::Def(DefKind::Mod, id) => Some(id),
612             _ => None,
613         }
614     }
615
616     /// A human readable name for the res kind ("function", "module", etc.).
617     pub fn descr(&self) -> &'static str {
618         match *self {
619             Res::Def(kind, def_id) => kind.descr(def_id),
620             Res::SelfCtor(..) => "self constructor",
621             Res::PrimTy(..) => "builtin type",
622             Res::Local(..) => "local variable",
623             Res::SelfTy { .. } => "self type",
624             Res::ToolMod => "tool module",
625             Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
626             Res::Err => "unresolved item",
627         }
628     }
629
630     /// Gets an English article for the `Res`.
631     pub fn article(&self) -> &'static str {
632         match *self {
633             Res::Def(kind, _) => kind.article(),
634             Res::NonMacroAttr(kind) => kind.article(),
635             Res::Err => "an",
636             _ => "a",
637         }
638     }
639
640     pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
641         match self {
642             Res::Def(kind, id) => Res::Def(kind, id),
643             Res::SelfCtor(id) => Res::SelfCtor(id),
644             Res::PrimTy(id) => Res::PrimTy(id),
645             Res::Local(id) => Res::Local(map(id)),
646             Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
647             Res::ToolMod => Res::ToolMod,
648             Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
649             Res::Err => Res::Err,
650         }
651     }
652
653     pub fn apply_id<R, E>(self, mut map: impl FnMut(Id) -> Result<R, E>) -> Result<Res<R>, E> {
654         Ok(match self {
655             Res::Def(kind, id) => Res::Def(kind, id),
656             Res::SelfCtor(id) => Res::SelfCtor(id),
657             Res::PrimTy(id) => Res::PrimTy(id),
658             Res::Local(id) => Res::Local(map(id)?),
659             Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
660             Res::ToolMod => Res::ToolMod,
661             Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
662             Res::Err => Res::Err,
663         })
664     }
665
666     #[track_caller]
667     pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
668         self.map_id(
669             #[track_caller]
670             |_| panic!("unexpected `Res::Local`"),
671         )
672     }
673
674     pub fn macro_kind(self) -> Option<MacroKind> {
675         match self {
676             Res::Def(DefKind::Macro(kind), _) => Some(kind),
677             Res::NonMacroAttr(..) => Some(MacroKind::Attr),
678             _ => None,
679         }
680     }
681
682     /// Returns `None` if this is `Res::Err`
683     pub fn ns(&self) -> Option<Namespace> {
684         match self {
685             Res::Def(kind, ..) => kind.ns(),
686             Res::PrimTy(..) | Res::SelfTy { .. } | Res::ToolMod => Some(Namespace::TypeNS),
687             Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
688             Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
689             Res::Err => None,
690         }
691     }
692
693     /// Always returns `true` if `self` is `Res::Err`
694     pub fn matches_ns(&self, ns: Namespace) -> bool {
695         self.ns().map_or(true, |actual_ns| actual_ns == ns)
696     }
697
698     /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
699     pub fn expected_in_tuple_struct_pat(&self) -> bool {
700         matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..))
701     }
702
703     /// Returns whether such a resolved path can occur in a unit struct/variant pattern
704     pub fn expected_in_unit_struct_pat(&self) -> bool {
705         matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..))
706     }
707 }
708
709 /// Resolution for a lifetime appearing in a type.
710 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
711 pub enum LifetimeRes {
712     /// Successfully linked the lifetime to a generic parameter.
713     Param {
714         /// Id of the generic parameter that introduced it.
715         param: LocalDefId,
716         /// Id of the introducing place. That can be:
717         /// - an item's id, for the item's generic parameters;
718         /// - a TraitRef's ref_id, identifying the `for<...>` binder;
719         /// - a BareFn type's id.
720         ///
721         /// This information is used for impl-trait lifetime captures, to know when to or not to
722         /// capture any given lifetime.
723         binder: NodeId,
724     },
725     /// Created a generic parameter for an anonymous lifetime.
726     Fresh {
727         /// Id of the generic parameter that introduced it.
728         ///
729         /// Creating the associated `LocalDefId` is the responsibility of lowering.
730         param: NodeId,
731         /// Id of the introducing place. See `Param`.
732         binder: NodeId,
733     },
734     /// This variant is used for anonymous lifetimes that we did not resolve during
735     /// late resolution.  Those lifetimes will be inferred by typechecking.
736     Infer,
737     /// Explicit `'static` lifetime.
738     Static,
739     /// Resolution failure.
740     Error,
741     /// HACK: This is used to recover the NodeId of an elided lifetime.
742     ElidedAnchor { start: NodeId, end: NodeId },
743 }