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
;
10 use std
::array
::IntoIter
;
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)]
17 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
19 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
23 /// What kind of constructor something is.
24 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
25 #[derive(HashStable_Generic)]
27 /// Constructor function automatically created by a tuple struct/variant.
29 /// Constructor constant automatically created by a unit struct/variant.
31 /// Unusable name in value namespace created by a struct variant.
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]`)
41 /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
43 /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
45 /// Single-segment custom attribute registered by a derive macro
46 /// but used before that derive macro was expanded (deprecated).
48 /// Single-segment custom attribute registered with `#[register_attr]`.
52 /// What kind of definition something is; e.g., `mod` vs `struct`.
53 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
54 #[derive(HashStable_Generic)]
58 /// Refers to the struct itself, [`DefKind::Ctor`] refers to its constructor if it exists.
62 /// Refers to the variant itself, [`DefKind::Ctor`] refers to its constructor if it exists.
65 /// Type alias: `type Foo = Bar;`
67 /// Type from an `extern` block.
69 /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
71 /// Associated type: `trait MyTrait { type Assoc; }`
73 /// Type parameter: the `T` in `struct Vec<T> { ... }`
79 /// Constant generic parameter: `struct Foo<const N: usize> { ... }`
81 Static(ast
::Mutability
),
82 /// Refers to the struct or enum variant's constructor.
84 /// The reason `Ctor` exists in addition to [`DefKind::Struct`] and
85 /// [`DefKind::Variant`] is because structs and enum variants exist
86 /// in the *type* namespace, whereas struct and enum variant *constructors*
87 /// exist in the *value* namespace.
89 /// You may wonder why enum variants exist in the type namespace as opposed
90 /// to the value namespace. Check out [RFC 2593] for intuition on why that is.
92 /// [RFC 2593]: https://github.com/rust-lang/rfcs/pull/2593
93 Ctor(CtorOf
, CtorKind
),
94 /// Associated function: `impl MyStruct { fn associated() {} }`
95 /// or `trait Foo { fn associated() {} }`
97 /// Associated constant: `trait MyTrait { const ASSOC: usize; }`
103 // Not namespaced (or they are, but we don't treat them so)
106 /// An `extern` block.
108 /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`
110 /// An inline constant, e.g. `const { 1 + 2 }`
112 /// Opaque type, aka `impl Trait`.
115 /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
117 /// A use of `global_asm!`.
125 pub fn descr(self, def_id
: DefId
) -> &'
static str {
127 DefKind
::Fn
=> "function",
128 DefKind
::Mod
if def_id
.is_crate_root() && !def_id
.is_local() => "crate",
129 DefKind
::Mod
=> "module",
130 DefKind
::Static(..) => "static",
131 DefKind
::Enum
=> "enum",
132 DefKind
::Variant
=> "variant",
133 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Fn
) => "tuple variant",
134 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Const
) => "unit variant",
135 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Fictive
) => "struct variant",
136 DefKind
::Struct
=> "struct",
137 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Fn
) => "tuple struct",
138 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Const
) => "unit struct",
139 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Fictive
) => {
140 panic
!("impossible struct constructor")
142 DefKind
::OpaqueTy
=> "opaque type",
143 DefKind
::TyAlias
=> "type alias",
144 DefKind
::TraitAlias
=> "trait alias",
145 DefKind
::AssocTy
=> "associated type",
146 DefKind
::Union
=> "union",
147 DefKind
::Trait
=> "trait",
148 DefKind
::ForeignTy
=> "foreign type",
149 DefKind
::AssocFn
=> "associated function",
150 DefKind
::Const
=> "constant",
151 DefKind
::AssocConst
=> "associated constant",
152 DefKind
::TyParam
=> "type parameter",
153 DefKind
::ConstParam
=> "const parameter",
154 DefKind
::Macro(macro_kind
) => macro_kind
.descr(),
155 DefKind
::LifetimeParam
=> "lifetime parameter",
156 DefKind
::Use
=> "import",
157 DefKind
::ForeignMod
=> "foreign module",
158 DefKind
::AnonConst
=> "constant expression",
159 DefKind
::InlineConst
=> "inline constant",
160 DefKind
::Field
=> "field",
161 DefKind
::Impl
=> "implementation",
162 DefKind
::Closure
=> "closure",
163 DefKind
::Generator
=> "generator",
164 DefKind
::ExternCrate
=> "extern crate",
165 DefKind
::GlobalAsm
=> "global assembly block",
169 /// Gets an English article for the definition.
170 pub fn article(&self) -> &'
static str {
173 | DefKind
::AssocConst
179 | DefKind
::InlineConst
180 | DefKind
::ExternCrate
=> "an",
181 DefKind
::Macro(macro_kind
) => macro_kind
.article(),
186 pub fn ns(&self) -> Option
<Namespace
> {
197 | DefKind
::TraitAlias
199 | DefKind
::TyParam
=> Some(Namespace
::TypeNS
),
203 | DefKind
::ConstParam
204 | DefKind
::Static(..)
207 | DefKind
::AssocConst
=> Some(Namespace
::ValueNS
),
209 DefKind
::Macro(..) => Some(Namespace
::MacroNS
),
213 | DefKind
::InlineConst
215 | DefKind
::LifetimeParam
216 | DefKind
::ExternCrate
220 | DefKind
::ForeignMod
222 | DefKind
::Impl
=> None
,
227 pub fn is_fn_like(self) -> bool
{
229 DefKind
::Fn
| DefKind
::AssocFn
| DefKind
::Closure
| DefKind
::Generator
=> true,
234 /// Whether `query get_codegen_attrs` should be used with this definition.
235 pub fn has_codegen_attrs(self) -> bool
{
242 | DefKind
::Static(_
) => true,
251 | DefKind
::TraitAlias
254 | DefKind
::AssocConst
257 | DefKind
::ForeignMod
262 | DefKind
::ConstParam
263 | DefKind
::LifetimeParam
265 | DefKind
::InlineConst
267 | DefKind
::ExternCrate
=> false,
272 /// The resolution of a path or export.
274 /// For every path or identifier in Rust, the compiler must determine
275 /// what the path refers to. This process is called name resolution,
276 /// and `Res` is the primary result of name resolution.
278 /// For example, everything prefixed with `/* Res */` in this example has
279 /// an associated `Res`:
282 /// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
283 /// /* Res */ String::from(/* Res */ s)
286 /// /* Res */ str_to_string("hello");
289 /// The associated `Res`s will be:
291 /// - `str` will resolve to [`Res::PrimTy`];
292 /// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
293 /// for `String` as defined in the standard library;
294 /// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
295 /// pointing to `String::from`;
296 /// - `s` will resolve to [`Res::Local`];
297 /// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
298 /// pointing to the definition of `str_to_string` in the current crate.
300 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
301 #[derive(HashStable_Generic)]
302 pub enum Res
<Id
= hir
::HirId
> {
303 /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
305 /// **Not bound to a specific namespace.**
309 /// A primitive type such as `i32` or `str`.
311 /// **Belongs to the type namespace.**
313 /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
314 /// optionally with the [`DefId`] of the item introducing the `Self` type alias.
316 /// **Belongs to the type namespace.**
320 /// struct Bar(Box<Self>);
321 /// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
324 /// fn foo() -> Box<Self>;
325 /// // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
331 /// // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
335 /// impl Foo for Bar {
336 /// fn foo() -> Box<Self> {
337 /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
339 /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
346 /// *See also [`Res::SelfCtor`].*
350 /// HACK(min_const_generics): self types also have an optional requirement to **not** mention
351 /// any generic parameters to allow the following with `min_const_generics`:
354 /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
356 /// struct Bar([u8; baz::<Self>()]);
357 /// const fn baz<T>() -> usize { 10 }
359 /// We do however allow `Self` in repeat expression even if it is generic to not break code
360 /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint:
363 /// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
366 // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
368 /// The trait this `Self` is a generic arg for.
369 trait_
: Option
<DefId
>,
370 /// The item introducing the `Self` type alias. Can be used in the `type_of` query
371 /// to get the underlying type. Additionally whether the `Self` type is disallowed
372 /// from mentioning generics (i.e. when used in an anonymous constant).
373 alias_to
: Option
<(DefId
, bool
)>,
375 /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
377 /// **Belongs to the type namespace.**
381 /// The `Self` constructor, along with the [`DefId`]
382 /// of the impl it is associated with.
384 /// **Belongs to the value namespace.**
386 /// *See also [`Res::SelfTy`].*
388 /// A local variable or function parameter.
390 /// **Belongs to the value namespace.**
394 /// An attribute that is *not* implemented via macro.
395 /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
396 /// as opposed to `#[test]`, which is a builtin macro.
398 /// **Belongs to the macro namespace.**
399 NonMacroAttr(NonMacroAttrKind
), // e.g., `#[inline]` or `#[rustfmt::skip]`
402 /// Name resolution failed. We use a dummy `Res` variant so later phases
403 /// of the compiler won't crash and can instead report more errors.
405 /// **Not bound to a specific namespace.**
409 /// The result of resolving a path before lowering to HIR,
410 /// with "module" segments resolved and associated item
411 /// segments deferred to type checking.
412 /// `base_res` is the resolution of the resolved part of the
413 /// path, `unresolved_segments` is the number of unresolved
417 /// module::Type::AssocX::AssocY::MethodOrAssocType
418 /// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
419 /// base_res unresolved_segments = 3
421 /// <T as Trait>::AssocX::AssocY::MethodOrAssocType
422 /// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
423 /// base_res unresolved_segments = 2
425 #[derive(Copy, Clone, Debug)]
426 pub struct PartialRes
{
427 base_res
: Res
<NodeId
>,
428 unresolved_segments
: usize,
433 pub fn new(base_res
: Res
<NodeId
>) -> Self {
434 PartialRes { base_res, unresolved_segments: 0 }
438 pub fn with_unresolved_segments(base_res
: Res
<NodeId
>, mut unresolved_segments
: usize) -> Self {
439 if base_res
== Res
::Err
{
440 unresolved_segments
= 0
442 PartialRes { base_res, unresolved_segments }
446 pub fn base_res(&self) -> Res
<NodeId
> {
451 pub fn unresolved_segments(&self) -> usize {
452 self.unresolved_segments
456 /// Different kinds of symbols can coexist even if they share the same textual name.
457 /// Therefore, they each have a separate universe (known as a "namespace").
458 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
460 /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
461 /// (and, by extension, crates).
463 /// Note that the type namespace includes other items; this is not an
466 /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
468 /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
469 /// procedural macros, attribute macros, `derive` macros, and non-macro attributes
470 /// like `#[inline]` and `#[rustfmt::skip]`.
475 /// The English description of the namespace.
476 pub fn descr(self) -> &'
static str {
478 Self::TypeNS
=> "type",
479 Self::ValueNS
=> "value",
480 Self::MacroNS
=> "macro",
485 /// Just a helper ‒ separate structure for each namespace.
486 #[derive(Copy, Clone, Default, Debug)]
487 pub struct PerNS
<T
> {
494 pub fn map
<U
, F
: FnMut(T
) -> U
>(self, mut f
: F
) -> PerNS
<U
> {
495 PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
498 pub fn into_iter(self) -> IntoIter
<T
, 3> {
499 [self.value_ns
, self.type_ns
, self.macro_ns
].into_iter()
502 pub fn iter(&self) -> IntoIter
<&T
, 3> {
503 [&self.value_ns
, &self.type_ns
, &self.macro_ns
].into_iter()
507 impl<T
> ::std
::ops
::Index
<Namespace
> for PerNS
<T
> {
510 fn index(&self, ns
: Namespace
) -> &T
{
512 Namespace
::ValueNS
=> &self.value_ns
,
513 Namespace
::TypeNS
=> &self.type_ns
,
514 Namespace
::MacroNS
=> &self.macro_ns
,
519 impl<T
> ::std
::ops
::IndexMut
<Namespace
> for PerNS
<T
> {
520 fn index_mut(&mut self, ns
: Namespace
) -> &mut T
{
522 Namespace
::ValueNS
=> &mut self.value_ns
,
523 Namespace
::TypeNS
=> &mut self.type_ns
,
524 Namespace
::MacroNS
=> &mut self.macro_ns
,
529 impl<T
> PerNS
<Option
<T
>> {
530 /// Returns `true` if all the items in this collection are `None`.
531 pub fn is_empty(&self) -> bool
{
532 self.type_ns
.is_none() && self.value_ns
.is_none() && self.macro_ns
.is_none()
535 /// Returns an iterator over the items which are `Some`.
536 pub fn present_items(self) -> impl Iterator
<Item
= T
> {
537 [self.type_ns
, self.value_ns
, self.macro_ns
].into_iter().flatten()
542 pub fn from_ast(vdata
: &ast
::VariantData
) -> CtorKind
{
544 ast
::VariantData
::Tuple(..) => CtorKind
::Fn
,
545 ast
::VariantData
::Unit(..) => CtorKind
::Const
,
546 ast
::VariantData
::Struct(..) => CtorKind
::Fictive
,
550 pub fn from_hir(vdata
: &hir
::VariantData
<'_
>) -> CtorKind
{
552 hir
::VariantData
::Tuple(..) => CtorKind
::Fn
,
553 hir
::VariantData
::Unit(..) => CtorKind
::Const
,
554 hir
::VariantData
::Struct(..) => CtorKind
::Fictive
,
559 impl NonMacroAttrKind
{
560 pub fn descr(self) -> &'
static str {
562 NonMacroAttrKind
::Builtin(..) => "built-in attribute",
563 NonMacroAttrKind
::Tool
=> "tool attribute",
564 NonMacroAttrKind
::DeriveHelper
| NonMacroAttrKind
::DeriveHelperCompat
=> {
565 "derive helper attribute"
567 NonMacroAttrKind
::Registered
=> "explicitly registered attribute",
571 pub fn article(self) -> &'
static str {
573 NonMacroAttrKind
::Registered
=> "an",
578 /// Users of some attributes cannot mark them as used, so they are considered always used.
579 pub fn is_used(self) -> bool
{
581 NonMacroAttrKind
::Tool
582 | NonMacroAttrKind
::DeriveHelper
583 | NonMacroAttrKind
::DeriveHelperCompat
=> true,
584 NonMacroAttrKind
::Builtin(..) | NonMacroAttrKind
::Registered
=> false,
590 /// Return the `DefId` of this `Def` if it has an ID, else panic.
591 pub fn def_id(&self) -> DefId
596 .unwrap_or_else(|| panic
!("attempted .def_id() on invalid res: {:?}", self))
599 /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
600 pub fn opt_def_id(&self) -> Option
<DefId
> {
602 Res
::Def(_
, id
) => Some(id
),
609 | Res
::NonMacroAttr(..)
614 /// Return the `DefId` of this `Res` if it represents a module.
615 pub fn mod_def_id(&self) -> Option
<DefId
> {
617 Res
::Def(DefKind
::Mod
, id
) => Some(id
),
622 /// A human readable name for the res kind ("function", "module", etc.).
623 pub fn descr(&self) -> &'
static str {
625 Res
::Def(kind
, def_id
) => kind
.descr(def_id
),
626 Res
::SelfCtor(..) => "self constructor",
627 Res
::PrimTy(..) => "builtin type",
628 Res
::Local(..) => "local variable",
629 Res
::SelfTy { .. }
=> "self type",
630 Res
::ToolMod
=> "tool module",
631 Res
::NonMacroAttr(attr_kind
) => attr_kind
.descr(),
632 Res
::Err
=> "unresolved item",
636 /// Gets an English article for the `Res`.
637 pub fn article(&self) -> &'
static str {
639 Res
::Def(kind
, _
) => kind
.article(),
640 Res
::NonMacroAttr(kind
) => kind
.article(),
646 pub fn map_id
<R
>(self, mut map
: impl FnMut(Id
) -> R
) -> Res
<R
> {
648 Res
::Def(kind
, id
) => Res
::Def(kind
, id
),
649 Res
::SelfCtor(id
) => Res
::SelfCtor(id
),
650 Res
::PrimTy(id
) => Res
::PrimTy(id
),
651 Res
::Local(id
) => Res
::Local(map(id
)),
652 Res
::SelfTy { trait_, alias_to }
=> Res
::SelfTy { trait_, alias_to }
,
653 Res
::ToolMod
=> Res
::ToolMod
,
654 Res
::NonMacroAttr(attr_kind
) => Res
::NonMacroAttr(attr_kind
),
655 Res
::Err
=> Res
::Err
,
659 pub fn apply_id
<R
, E
>(self, mut map
: impl FnMut(Id
) -> Result
<R
, E
>) -> Result
<Res
<R
>, E
> {
661 Res
::Def(kind
, id
) => Res
::Def(kind
, id
),
662 Res
::SelfCtor(id
) => Res
::SelfCtor(id
),
663 Res
::PrimTy(id
) => Res
::PrimTy(id
),
664 Res
::Local(id
) => Res
::Local(map(id
)?
),
665 Res
::SelfTy { trait_, alias_to }
=> Res
::SelfTy { trait_, alias_to }
,
666 Res
::ToolMod
=> Res
::ToolMod
,
667 Res
::NonMacroAttr(attr_kind
) => Res
::NonMacroAttr(attr_kind
),
668 Res
::Err
=> Res
::Err
,
673 pub fn expect_non_local
<OtherId
>(self) -> Res
<OtherId
> {
676 |_
| panic
!("unexpected `Res::Local`"),
680 pub fn macro_kind(self) -> Option
<MacroKind
> {
682 Res
::Def(DefKind
::Macro(kind
), _
) => Some(kind
),
683 Res
::NonMacroAttr(..) => Some(MacroKind
::Attr
),
688 /// Returns `None` if this is `Res::Err`
689 pub fn ns(&self) -> Option
<Namespace
> {
691 Res
::Def(kind
, ..) => kind
.ns(),
692 Res
::PrimTy(..) | Res
::SelfTy { .. }
| Res
::ToolMod
=> Some(Namespace
::TypeNS
),
693 Res
::SelfCtor(..) | Res
::Local(..) => Some(Namespace
::ValueNS
),
694 Res
::NonMacroAttr(..) => Some(Namespace
::MacroNS
),
699 /// Always returns `true` if `self` is `Res::Err`
700 pub fn matches_ns(&self, ns
: Namespace
) -> bool
{
701 self.ns().map_or(true, |actual_ns
| actual_ns
== ns
)
704 /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
705 pub fn expected_in_tuple_struct_pat(&self) -> bool
{
706 matches
!(self, Res
::Def(DefKind
::Ctor(_
, CtorKind
::Fn
), _
) | Res
::SelfCtor(..))
709 /// Returns whether such a resolved path can occur in a unit struct/variant pattern
710 pub fn expected_in_unit_struct_pat(&self) -> bool
{
711 matches
!(self, Res
::Def(DefKind
::Ctor(_
, CtorKind
::Const
), _
) | Res
::SelfCtor(..))
715 /// Resolution for a lifetime appearing in a type.
716 #[derive(Copy, Clone, Debug)]
717 pub enum LifetimeRes
{
718 /// Successfully linked the lifetime to a generic parameter.
720 /// Id of the generic parameter that introduced it.
722 /// Id of the introducing place. That can be:
723 /// - an item's id, for the item's generic parameters;
724 /// - a TraitRef's ref_id, identifying the `for<...>` binder;
725 /// - a BareFn type's id.
727 /// This information is used for impl-trait lifetime captures, to know when to or not to
728 /// capture any given lifetime.
731 /// Created a generic parameter for an anonymous lifetime.
733 /// Id of the generic parameter that introduced it.
735 /// Creating the associated `LocalDefId` is the responsibility of lowering.
737 /// Id of the introducing place. See `Param`.
740 /// This variant is used for anonymous lifetimes that we did not resolve during
741 /// late resolution. Shifting the work to the HIR lifetime resolver.
743 /// Id of the introducing place. See `Param`.
745 /// Whether this lifetime was spelled or elided.
748 /// Explicit `'static` lifetime.
750 /// Resolution failure.
752 /// HACK: This is used to recover the NodeId of an elided lifetime.
753 ElidedAnchor { start: NodeId, end: NodeId }
,