1 use crate::def_id
::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}
;
6 use rustc_macros
::HashStable_Generic
;
7 use rustc_span
::hygiene
::MacroKind
;
9 use std
::array
::IntoIter
;
12 /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
13 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
14 #[derive(HashStable_Generic)]
16 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
18 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
22 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
23 #[derive(HashStable_Generic)]
25 /// Constructor function automatically created by a tuple struct/variant.
27 /// Constructor constant automatically created by a unit struct/variant.
29 /// Unusable name in value namespace created by a struct variant.
33 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
34 #[derive(HashStable_Generic)]
35 pub enum NonMacroAttrKind
{
36 /// Single-segment attribute defined by the language (`#[inline]`)
38 /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
40 /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
42 /// Single-segment custom attribute registered with `#[register_attr]`.
46 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
47 #[derive(HashStable_Generic)]
51 /// Refers to the struct itself, `DefKind::Ctor` refers to its constructor if it exists.
55 /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
70 /// Refers to the struct or enum variant's constructor.
71 Ctor(CtorOf
, CtorKind
),
78 // Not namespaced (or they are, but we don't treat them so)
93 pub fn descr(self, def_id
: DefId
) -> &'
static str {
95 DefKind
::Fn
=> "function",
96 DefKind
::Mod
if def_id
.index
== CRATE_DEF_INDEX
&& def_id
.krate
!= LOCAL_CRATE
=> {
99 DefKind
::Mod
=> "module",
100 DefKind
::Static
=> "static",
101 DefKind
::Enum
=> "enum",
102 DefKind
::Variant
=> "variant",
103 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Fn
) => "tuple variant",
104 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Const
) => "unit variant",
105 DefKind
::Ctor(CtorOf
::Variant
, CtorKind
::Fictive
) => "struct variant",
106 DefKind
::Struct
=> "struct",
107 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Fn
) => "tuple struct",
108 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Const
) => "unit struct",
109 DefKind
::Ctor(CtorOf
::Struct
, CtorKind
::Fictive
) => {
110 panic
!("impossible struct constructor")
112 DefKind
::OpaqueTy
=> "opaque type",
113 DefKind
::TyAlias
=> "type alias",
114 DefKind
::TraitAlias
=> "trait alias",
115 DefKind
::AssocTy
=> "associated type",
116 DefKind
::Union
=> "union",
117 DefKind
::Trait
=> "trait",
118 DefKind
::ForeignTy
=> "foreign type",
119 DefKind
::AssocFn
=> "associated function",
120 DefKind
::Const
=> "constant",
121 DefKind
::AssocConst
=> "associated constant",
122 DefKind
::TyParam
=> "type parameter",
123 DefKind
::ConstParam
=> "const parameter",
124 DefKind
::Macro(macro_kind
) => macro_kind
.descr(),
125 DefKind
::LifetimeParam
=> "lifetime parameter",
126 DefKind
::Use
=> "import",
127 DefKind
::ForeignMod
=> "foreign module",
128 DefKind
::AnonConst
=> "constant expression",
129 DefKind
::Field
=> "field",
130 DefKind
::Impl
=> "implementation",
131 DefKind
::Closure
=> "closure",
132 DefKind
::Generator
=> "generator",
133 DefKind
::ExternCrate
=> "extern crate",
134 DefKind
::GlobalAsm
=> "global assembly block",
138 /// Gets an English article for the definition.
139 pub fn article(&self) -> &'
static str {
142 | DefKind
::AssocConst
148 | DefKind
::ExternCrate
=> "an",
149 DefKind
::Macro(macro_kind
) => macro_kind
.article(),
154 pub fn ns(&self) -> Option
<Namespace
> {
165 | DefKind
::TraitAlias
167 | DefKind
::TyParam
=> Some(Namespace
::TypeNS
),
171 | DefKind
::ConstParam
175 | DefKind
::AssocConst
=> Some(Namespace
::ValueNS
),
177 DefKind
::Macro(..) => Some(Namespace
::MacroNS
),
182 | DefKind
::LifetimeParam
183 | DefKind
::ExternCrate
187 | DefKind
::ForeignMod
189 | DefKind
::Impl
=> None
,
194 /// The resolution of a path or export.
195 #[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
196 #[derive(HashStable_Generic)]
197 pub enum Res
<Id
= hir
::HirId
> {
202 /// `Self`, with both an optional trait and impl `DefId`.
204 /// HACK(min_const_generics): impl self types also have an optional requirement to not mention
205 /// any generic parameters to allow the following with `min_const_generics`:
207 /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] {} }
209 /// We do however allow `Self` in repeat expression even if it is generic to not break code
210 /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint.
212 /// FIXME(lazy_normalization_consts): Remove this bodge once that feature is stable.
213 SelfTy(Option
<DefId
> /* trait */, Option
<(DefId
, bool
)> /* impl */),
214 ToolMod
, // e.g., `rustfmt` in `#[rustfmt::skip]`
217 SelfCtor(DefId
/* impl */), // `DefId` refers to the impl
221 NonMacroAttr(NonMacroAttrKind
), // e.g., `#[inline]` or `#[rustfmt::skip]`
227 /// The result of resolving a path before lowering to HIR,
228 /// with "module" segments resolved and associated item
229 /// segments deferred to type checking.
230 /// `base_res` is the resolution of the resolved part of the
231 /// path, `unresolved_segments` is the number of unresolved
235 /// module::Type::AssocX::AssocY::MethodOrAssocType
236 /// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
237 /// base_res unresolved_segments = 3
239 /// <T as Trait>::AssocX::AssocY::MethodOrAssocType
240 /// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
241 /// base_res unresolved_segments = 2
243 #[derive(Copy, Clone, Debug)]
244 pub struct PartialRes
{
245 base_res
: Res
<NodeId
>,
246 unresolved_segments
: usize,
251 pub fn new(base_res
: Res
<NodeId
>) -> Self {
252 PartialRes { base_res, unresolved_segments: 0 }
256 pub fn with_unresolved_segments(base_res
: Res
<NodeId
>, mut unresolved_segments
: usize) -> Self {
257 if base_res
== Res
::Err
{
258 unresolved_segments
= 0
260 PartialRes { base_res, unresolved_segments }
264 pub fn base_res(&self) -> Res
<NodeId
> {
269 pub fn unresolved_segments(&self) -> usize {
270 self.unresolved_segments
274 /// Different kinds of symbols don't influence each other.
276 /// Therefore, they have a separate universe (namespace).
277 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
285 pub fn descr(self) -> &'
static str {
287 Self::TypeNS
=> "type",
288 Self::ValueNS
=> "value",
289 Self::MacroNS
=> "macro",
294 /// Just a helper ‒ separate structure for each namespace.
295 #[derive(Copy, Clone, Default, Debug)]
296 pub struct PerNS
<T
> {
303 pub fn map
<U
, F
: FnMut(T
) -> U
>(self, mut f
: F
) -> PerNS
<U
> {
304 PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
307 pub fn into_iter(self) -> IntoIter
<T
, 3> {
308 IntoIter
::new([self.value_ns
, self.type_ns
, self.macro_ns
])
311 pub fn iter(&self) -> IntoIter
<&T
, 3> {
312 IntoIter
::new([&self.value_ns
, &self.type_ns
, &self.macro_ns
])
316 impl<T
> ::std
::ops
::Index
<Namespace
> for PerNS
<T
> {
319 fn index(&self, ns
: Namespace
) -> &T
{
321 Namespace
::ValueNS
=> &self.value_ns
,
322 Namespace
::TypeNS
=> &self.type_ns
,
323 Namespace
::MacroNS
=> &self.macro_ns
,
328 impl<T
> ::std
::ops
::IndexMut
<Namespace
> for PerNS
<T
> {
329 fn index_mut(&mut self, ns
: Namespace
) -> &mut T
{
331 Namespace
::ValueNS
=> &mut self.value_ns
,
332 Namespace
::TypeNS
=> &mut self.type_ns
,
333 Namespace
::MacroNS
=> &mut self.macro_ns
,
338 impl<T
> PerNS
<Option
<T
>> {
339 /// Returns `true` if all the items in this collection are `None`.
340 pub fn is_empty(&self) -> bool
{
341 self.type_ns
.is_none() && self.value_ns
.is_none() && self.macro_ns
.is_none()
344 /// Returns an iterator over the items which are `Some`.
345 pub fn present_items(self) -> impl Iterator
<Item
= T
> {
346 IntoIter
::new([self.type_ns
, self.value_ns
, self.macro_ns
]).filter_map(|it
| it
)
351 pub fn from_ast(vdata
: &ast
::VariantData
) -> CtorKind
{
353 ast
::VariantData
::Tuple(..) => CtorKind
::Fn
,
354 ast
::VariantData
::Unit(..) => CtorKind
::Const
,
355 ast
::VariantData
::Struct(..) => CtorKind
::Fictive
,
359 pub fn from_hir(vdata
: &hir
::VariantData
<'_
>) -> CtorKind
{
361 hir
::VariantData
::Tuple(..) => CtorKind
::Fn
,
362 hir
::VariantData
::Unit(..) => CtorKind
::Const
,
363 hir
::VariantData
::Struct(..) => CtorKind
::Fictive
,
368 impl NonMacroAttrKind
{
369 pub fn descr(self) -> &'
static str {
371 NonMacroAttrKind
::Builtin
=> "built-in attribute",
372 NonMacroAttrKind
::Tool
=> "tool attribute",
373 NonMacroAttrKind
::DeriveHelper
=> "derive helper attribute",
374 NonMacroAttrKind
::Registered
=> "explicitly registered attribute",
378 pub fn article(self) -> &'
static str {
380 NonMacroAttrKind
::Registered
=> "an",
385 /// Users of some attributes cannot mark them as used, so they are considered always used.
386 pub fn is_used(self) -> bool
{
388 NonMacroAttrKind
::Tool
| NonMacroAttrKind
::DeriveHelper
=> true,
389 NonMacroAttrKind
::Builtin
| NonMacroAttrKind
::Registered
=> false,
395 /// Return the `DefId` of this `Def` if it has an ID, else panic.
396 pub fn def_id(&self) -> DefId
401 .unwrap_or_else(|| panic
!("attempted .def_id() on invalid res: {:?}", self))
404 /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
405 pub fn opt_def_id(&self) -> Option
<DefId
> {
407 Res
::Def(_
, id
) => Some(id
),
414 | Res
::NonMacroAttr(..)
419 /// Return the `DefId` of this `Res` if it represents a module.
420 pub fn mod_def_id(&self) -> Option
<DefId
> {
422 Res
::Def(DefKind
::Mod
, id
) => Some(id
),
427 /// A human readable name for the res kind ("function", "module", etc.).
428 pub fn descr(&self) -> &'
static str {
430 Res
::Def(kind
, def_id
) => kind
.descr(def_id
),
431 Res
::SelfCtor(..) => "self constructor",
432 Res
::PrimTy(..) => "builtin type",
433 Res
::Local(..) => "local variable",
434 Res
::SelfTy(..) => "self type",
435 Res
::ToolMod
=> "tool module",
436 Res
::NonMacroAttr(attr_kind
) => attr_kind
.descr(),
437 Res
::Err
=> "unresolved item",
441 /// Gets an English article for the `Res`.
442 pub fn article(&self) -> &'
static str {
444 Res
::Def(kind
, _
) => kind
.article(),
445 Res
::NonMacroAttr(kind
) => kind
.article(),
451 pub fn map_id
<R
>(self, mut map
: impl FnMut(Id
) -> R
) -> Res
<R
> {
453 Res
::Def(kind
, id
) => Res
::Def(kind
, id
),
454 Res
::SelfCtor(id
) => Res
::SelfCtor(id
),
455 Res
::PrimTy(id
) => Res
::PrimTy(id
),
456 Res
::Local(id
) => Res
::Local(map(id
)),
457 Res
::SelfTy(a
, b
) => Res
::SelfTy(a
, b
),
458 Res
::ToolMod
=> Res
::ToolMod
,
459 Res
::NonMacroAttr(attr_kind
) => Res
::NonMacroAttr(attr_kind
),
460 Res
::Err
=> Res
::Err
,
464 pub fn macro_kind(self) -> Option
<MacroKind
> {
466 Res
::Def(DefKind
::Macro(kind
), _
) => Some(kind
),
467 Res
::NonMacroAttr(..) => Some(MacroKind
::Attr
),
472 /// Returns `None` if this is `Res::Err`
473 pub fn ns(&self) -> Option
<Namespace
> {
475 Res
::Def(kind
, ..) => kind
.ns(),
476 Res
::PrimTy(..) | Res
::SelfTy(..) | Res
::ToolMod
=> Some(Namespace
::TypeNS
),
477 Res
::SelfCtor(..) | Res
::Local(..) => Some(Namespace
::ValueNS
),
478 Res
::NonMacroAttr(..) => Some(Namespace
::MacroNS
),
483 /// Always returns `true` if `self` is `Res::Err`
484 pub fn matches_ns(&self, ns
: Namespace
) -> bool
{
485 self.ns().map_or(true, |actual_ns
| actual_ns
== ns
)
488 /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
489 pub fn expected_in_tuple_struct_pat(&self) -> bool
{
490 matches
!(self, Res
::Def(DefKind
::Ctor(_
, CtorKind
::Fn
), _
) | Res
::SelfCtor(..))