1 use crate::def_id
::DefId
;
6 use rustc_macros
::HashStable_Generic
;
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() {} }`
96 /// Associated constant: `trait MyTrait { const ASSOC: usize; }`
102 // Not namespaced (or they are, but we don't treat them so)
105 /// An `extern` block.
107 /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`
109 /// An inline constant, e.g. `const { 1 + 2 }`
111 /// Opaque type, aka `impl Trait`.
114 /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
116 /// A use of `global_asm!`.
124 pub fn descr(self, def_id
: DefId
) -> &'
static str {
126 DefKind
::Fn
=> "function",
127 DefKind
::Mod
if def_id
.is_crate_root() && !def_id
.is_local() => "crate",
128 DefKind
::Mod
=> "module",
129 DefKind
::Static(..) => "static",
130 DefKind
::Enum
=> "enum",
131 DefKind
::Variant
=> "variant",
132 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Fn
) => "tuple variant",
133 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Const
) => "unit variant",
134 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Fictive
) => "struct variant",
135 DefKind
::Struct
=> "struct",
136 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Fn
) => "tuple struct",
137 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Const
) => "unit struct",
138 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Fictive
) => {
139 panic
!("impossible struct constructor")
141 DefKind
::OpaqueTy
=> "opaque type",
142 DefKind
::TyAlias
=> "type alias",
143 DefKind
::TraitAlias
=> "trait alias",
144 DefKind
::AssocTy
=> "associated type",
145 DefKind
::Union
=> "union",
146 DefKind
::Trait
=> "trait",
147 DefKind
::ForeignTy
=> "foreign type",
148 DefKind
::AssocFn
=> "associated function",
149 DefKind
::Const
=> "constant",
150 DefKind
::AssocConst
=> "associated constant",
151 DefKind
::TyParam
=> "type parameter",
152 DefKind
::ConstParam
=> "const parameter",
153 DefKind
::Macro(macro_kind
) => macro_kind
.descr(),
154 DefKind
::LifetimeParam
=> "lifetime parameter",
155 DefKind
::Use
=> "import",
156 DefKind
::ForeignMod
=> "foreign module",
157 DefKind
::AnonConst
=> "constant expression",
158 DefKind
::InlineConst
=> "inline constant",
159 DefKind
::Field
=> "field",
160 DefKind
::Impl
=> "implementation",
161 DefKind
::Closure
=> "closure",
162 DefKind
::Generator
=> "generator",
163 DefKind
::ExternCrate
=> "extern crate",
164 DefKind
::GlobalAsm
=> "global assembly block",
168 /// Gets an English article for the definition.
169 pub fn article(&self) -> &'
static str {
172 | DefKind
::AssocConst
178 | DefKind
::InlineConst
179 | DefKind
::ExternCrate
=> "an",
180 DefKind
::Macro(macro_kind
) => macro_kind
.article(),
185 pub fn ns(&self) -> Option
<Namespace
> {
196 | DefKind
::TraitAlias
198 | DefKind
::TyParam
=> Some(Namespace
::TypeNS
),
202 | DefKind
::ConstParam
203 | DefKind
::Static(..)
206 | DefKind
::AssocConst
=> Some(Namespace
::ValueNS
),
208 DefKind
::Macro(..) => Some(Namespace
::MacroNS
),
212 | DefKind
::InlineConst
214 | DefKind
::LifetimeParam
215 | DefKind
::ExternCrate
219 | DefKind
::ForeignMod
221 | DefKind
::Impl
=> None
,
226 pub fn is_fn_like(self) -> bool
{
228 DefKind
::Fn
| DefKind
::AssocFn
| DefKind
::Closure
| DefKind
::Generator
=> true,
233 /// Whether `query get_codegen_attrs` should be used with this definition.
234 pub fn has_codegen_attrs(self) -> bool
{
241 | DefKind
::Static(_
) => true,
250 | DefKind
::TraitAlias
253 | DefKind
::AssocConst
256 | DefKind
::ForeignMod
261 | DefKind
::ConstParam
262 | DefKind
::LifetimeParam
264 | DefKind
::InlineConst
266 | DefKind
::ExternCrate
=> false,
271 /// The resolution of a path or export.
273 /// For every path or identifier in Rust, the compiler must determine
274 /// what the path refers to. This process is called name resolution,
275 /// and `Res` is the primary result of name resolution.
277 /// For example, everything prefixed with `/* Res */` in this example has
278 /// an associated `Res`:
281 /// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
282 /// /* Res */ String::from(/* Res */ s)
285 /// /* Res */ str_to_string("hello");
288 /// The associated `Res`s will be:
290 /// - `str` will resolve to [`Res::PrimTy`];
291 /// - `String` will resolve to [`Res::Def`], and the `Res` will include the [`DefId`]
292 /// for `String` as defined in the standard library;
293 /// - `String::from` will also resolve to [`Res::Def`], with the [`DefId`]
294 /// pointing to `String::from`;
295 /// - `s` will resolve to [`Res::Local`];
296 /// - the call to `str_to_string` will resolve to [`Res::Def`], with the [`DefId`]
297 /// pointing to the definition of `str_to_string` in the current crate.
299 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
300 #[derive(HashStable_Generic)]
301 pub enum Res
<Id
= hir
::HirId
> {
302 /// Definition having a unique ID (`DefId`), corresponds to something defined in user code.
304 /// **Not bound to a specific namespace.**
308 /// A primitive type such as `i32` or `str`.
310 /// **Belongs to the type namespace.**
312 /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
313 /// optionally with the [`DefId`] of the item introducing the `Self` type alias.
315 /// **Belongs to the type namespace.**
319 /// struct Bar(Box<Self>);
320 /// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
323 /// fn foo() -> Box<Self>;
324 /// // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
330 /// // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
334 /// impl Foo for Bar {
335 /// fn foo() -> Box<Self> {
336 /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
338 /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
345 /// *See also [`Res::SelfCtor`].*
349 /// HACK(min_const_generics): self types also have an optional requirement to **not** mention
350 /// any generic parameters to allow the following with `min_const_generics`:
353 /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
355 /// struct Bar([u8; baz::<Self>()]);
356 /// const fn baz<T>() -> usize { 10 }
358 /// We do however allow `Self` in repeat expression even if it is generic to not break code
359 /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint:
362 /// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
365 // FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
367 /// The trait this `Self` is a generic arg for.
368 trait_
: Option
<DefId
>,
369 /// The item introducing the `Self` type alias. Can be used in the `type_of` query
370 /// to get the underlying type. Additionally whether the `Self` type is disallowed
371 /// from mentioning generics (i.e. when used in an anonymous constant).
372 alias_to
: Option
<(DefId
, bool
)>,
374 /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
376 /// **Belongs to the type namespace.**
380 /// The `Self` constructor, along with the [`DefId`]
381 /// of the impl it is associated with.
383 /// **Belongs to the value namespace.**
385 /// *See also [`Res::SelfTy`].*
387 /// A local variable or function parameter.
389 /// **Belongs to the value namespace.**
393 /// An attribute that is *not* implemented via macro.
394 /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
395 /// as opposed to `#[test]`, which is a builtin macro.
397 /// **Belongs to the macro namespace.**
398 NonMacroAttr(NonMacroAttrKind
), // e.g., `#[inline]` or `#[rustfmt::skip]`
401 /// Name resolution failed. We use a dummy `Res` variant so later phases
402 /// of the compiler won't crash and can instead report more errors.
404 /// **Not bound to a specific namespace.**
408 /// The result of resolving a path before lowering to HIR,
409 /// with "module" segments resolved and associated item
410 /// segments deferred to type checking.
411 /// `base_res` is the resolution of the resolved part of the
412 /// path, `unresolved_segments` is the number of unresolved
416 /// module::Type::AssocX::AssocY::MethodOrAssocType
417 /// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
418 /// base_res unresolved_segments = 3
420 /// <T as Trait>::AssocX::AssocY::MethodOrAssocType
421 /// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
422 /// base_res unresolved_segments = 2
424 #[derive(Copy, Clone, Debug)]
425 pub struct PartialRes
{
426 base_res
: Res
<NodeId
>,
427 unresolved_segments
: usize,
432 pub fn new(base_res
: Res
<NodeId
>) -> Self {
433 PartialRes { base_res, unresolved_segments: 0 }
437 pub fn with_unresolved_segments(base_res
: Res
<NodeId
>, mut unresolved_segments
: usize) -> Self {
438 if base_res
== Res
::Err
{
439 unresolved_segments
= 0
441 PartialRes { base_res, unresolved_segments }
445 pub fn base_res(&self) -> Res
<NodeId
> {
450 pub fn unresolved_segments(&self) -> usize {
451 self.unresolved_segments
455 /// Different kinds of symbols can coexist even if they share the same textual name.
456 /// Therefore, they each have a separate universe (known as a "namespace").
457 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
459 /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and `mod`s
460 /// (and, by extension, crates).
462 /// Note that the type namespace includes other items; this is not an
465 /// The value namespace includes `fn`s, `const`s, `static`s, and local variables (including function arguments).
467 /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
468 /// procedural macros, attribute macros, `derive` macros, and non-macro attributes
469 /// like `#[inline]` and `#[rustfmt::skip]`.
474 /// The English description of the namespace.
475 pub fn descr(self) -> &'
static str {
477 Self::TypeNS
=> "type",
478 Self::ValueNS
=> "value",
479 Self::MacroNS
=> "macro",
484 /// Just a helper ‒ separate structure for each namespace.
485 #[derive(Copy, Clone, Default, Debug)]
486 pub struct PerNS
<T
> {
493 pub fn map
<U
, F
: FnMut(T
) -> U
>(self, mut f
: F
) -> PerNS
<U
> {
494 PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
497 pub fn into_iter(self) -> IntoIter
<T
, 3> {
498 [self.value_ns
, self.type_ns
, self.macro_ns
].into_iter()
501 pub fn iter(&self) -> IntoIter
<&T
, 3> {
502 [&self.value_ns
, &self.type_ns
, &self.macro_ns
].into_iter()
506 impl<T
> ::std
::ops
::Index
<Namespace
> for PerNS
<T
> {
509 fn index(&self, ns
: Namespace
) -> &T
{
511 Namespace
::ValueNS
=> &self.value_ns
,
512 Namespace
::TypeNS
=> &self.type_ns
,
513 Namespace
::MacroNS
=> &self.macro_ns
,
518 impl<T
> ::std
::ops
::IndexMut
<Namespace
> for PerNS
<T
> {
519 fn index_mut(&mut self, ns
: Namespace
) -> &mut T
{
521 Namespace
::ValueNS
=> &mut self.value_ns
,
522 Namespace
::TypeNS
=> &mut self.type_ns
,
523 Namespace
::MacroNS
=> &mut self.macro_ns
,
528 impl<T
> PerNS
<Option
<T
>> {
529 /// Returns `true` if all the items in this collection are `None`.
530 pub fn is_empty(&self) -> bool
{
531 self.type_ns
.is_none() && self.value_ns
.is_none() && self.macro_ns
.is_none()
534 /// Returns an iterator over the items which are `Some`.
535 pub fn present_items(self) -> impl Iterator
<Item
= T
> {
536 [self.type_ns
, self.value_ns
, self.macro_ns
].into_iter().flatten()
541 pub fn from_ast(vdata
: &ast
::VariantData
) -> CtorKind
{
543 ast
::VariantData
::Tuple(..) => CtorKind
::Fn
,
544 ast
::VariantData
::Unit(..) => CtorKind
::Const
,
545 ast
::VariantData
::Struct(..) => CtorKind
::Fictive
,
549 pub fn from_hir(vdata
: &hir
::VariantData
<'_
>) -> CtorKind
{
551 hir
::VariantData
::Tuple(..) => CtorKind
::Fn
,
552 hir
::VariantData
::Unit(..) => CtorKind
::Const
,
553 hir
::VariantData
::Struct(..) => CtorKind
::Fictive
,
558 impl NonMacroAttrKind
{
559 pub fn descr(self) -> &'
static str {
561 NonMacroAttrKind
::Builtin(..) => "built-in attribute",
562 NonMacroAttrKind
::Tool
=> "tool attribute",
563 NonMacroAttrKind
::DeriveHelper
| NonMacroAttrKind
::DeriveHelperCompat
=> {
564 "derive helper attribute"
566 NonMacroAttrKind
::Registered
=> "explicitly registered attribute",
570 pub fn article(self) -> &'
static str {
572 NonMacroAttrKind
::Registered
=> "an",
577 /// Users of some attributes cannot mark them as used, so they are considered always used.
578 pub fn is_used(self) -> bool
{
580 NonMacroAttrKind
::Tool
581 | NonMacroAttrKind
::DeriveHelper
582 | NonMacroAttrKind
::DeriveHelperCompat
=> true,
583 NonMacroAttrKind
::Builtin(..) | NonMacroAttrKind
::Registered
=> false,
589 /// Return the `DefId` of this `Def` if it has an ID, else panic.
590 pub fn def_id(&self) -> DefId
595 .unwrap_or_else(|| panic
!("attempted .def_id() on invalid res: {:?}", self))
598 /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
599 pub fn opt_def_id(&self) -> Option
<DefId
> {
601 Res
::Def(_
, id
) => Some(id
),
608 | Res
::NonMacroAttr(..)
613 /// Return the `DefId` of this `Res` if it represents a module.
614 pub fn mod_def_id(&self) -> Option
<DefId
> {
616 Res
::Def(DefKind
::Mod
, id
) => Some(id
),
621 /// A human readable name for the res kind ("function", "module", etc.).
622 pub fn descr(&self) -> &'
static str {
624 Res
::Def(kind
, def_id
) => kind
.descr(def_id
),
625 Res
::SelfCtor(..) => "self constructor",
626 Res
::PrimTy(..) => "builtin type",
627 Res
::Local(..) => "local variable",
628 Res
::SelfTy { .. }
=> "self type",
629 Res
::ToolMod
=> "tool module",
630 Res
::NonMacroAttr(attr_kind
) => attr_kind
.descr(),
631 Res
::Err
=> "unresolved item",
635 /// Gets an English article for the `Res`.
636 pub fn article(&self) -> &'
static str {
638 Res
::Def(kind
, _
) => kind
.article(),
639 Res
::NonMacroAttr(kind
) => kind
.article(),
645 pub fn map_id
<R
>(self, mut map
: impl FnMut(Id
) -> R
) -> Res
<R
> {
647 Res
::Def(kind
, id
) => Res
::Def(kind
, id
),
648 Res
::SelfCtor(id
) => Res
::SelfCtor(id
),
649 Res
::PrimTy(id
) => Res
::PrimTy(id
),
650 Res
::Local(id
) => Res
::Local(map(id
)),
651 Res
::SelfTy { trait_, alias_to }
=> Res
::SelfTy { trait_, alias_to }
,
652 Res
::ToolMod
=> Res
::ToolMod
,
653 Res
::NonMacroAttr(attr_kind
) => Res
::NonMacroAttr(attr_kind
),
654 Res
::Err
=> Res
::Err
,
658 pub fn apply_id
<R
, E
>(self, mut map
: impl FnMut(Id
) -> Result
<R
, E
>) -> Result
<Res
<R
>, E
> {
660 Res
::Def(kind
, id
) => Res
::Def(kind
, id
),
661 Res
::SelfCtor(id
) => Res
::SelfCtor(id
),
662 Res
::PrimTy(id
) => Res
::PrimTy(id
),
663 Res
::Local(id
) => Res
::Local(map(id
)?
),
664 Res
::SelfTy { trait_, alias_to }
=> Res
::SelfTy { trait_, alias_to }
,
665 Res
::ToolMod
=> Res
::ToolMod
,
666 Res
::NonMacroAttr(attr_kind
) => Res
::NonMacroAttr(attr_kind
),
667 Res
::Err
=> Res
::Err
,
672 pub fn expect_non_local
<OtherId
>(self) -> Res
<OtherId
> {
673 self.map_id(|_
| panic
!("unexpected `Res::Local`"))
676 pub fn macro_kind(self) -> Option
<MacroKind
> {
678 Res
::Def(DefKind
::Macro(kind
), _
) => Some(kind
),
679 Res
::NonMacroAttr(..) => Some(MacroKind
::Attr
),
684 /// Returns `None` if this is `Res::Err`
685 pub fn ns(&self) -> Option
<Namespace
> {
687 Res
::Def(kind
, ..) => kind
.ns(),
688 Res
::PrimTy(..) | Res
::SelfTy { .. }
| Res
::ToolMod
=> Some(Namespace
::TypeNS
),
689 Res
::SelfCtor(..) | Res
::Local(..) => Some(Namespace
::ValueNS
),
690 Res
::NonMacroAttr(..) => Some(Namespace
::MacroNS
),
695 /// Always returns `true` if `self` is `Res::Err`
696 pub fn matches_ns(&self, ns
: Namespace
) -> bool
{
697 self.ns().map_or(true, |actual_ns
| actual_ns
== ns
)
700 /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
701 pub fn expected_in_tuple_struct_pat(&self) -> bool
{
702 matches
!(self, Res
::Def(DefKind
::Ctor(_
, CtorKind
::Fn
), _
) | Res
::SelfCtor(..))
705 /// Returns whether such a resolved path can occur in a unit struct/variant pattern
706 pub fn expected_in_unit_struct_pat(&self) -> bool
{
707 matches
!(self, Res
::Def(DefKind
::Ctor(_
, CtorKind
::Const
), _
) | Res
::SelfCtor(..))