]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_hir/src/def.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / compiler / rustc_hir / src / def.rs
CommitLineData
dfeec247 1use crate::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
e1599b0c 2use crate::hir;
e1599b0c 3
3dfed10e
XL
4use rustc_ast as ast;
5use rustc_ast::NodeId;
dfeec247
XL
6use rustc_macros::HashStable_Generic;
7use rustc_span::hygiene::MacroKind;
1a4d82fc 8
1b1a35ee 9use std::array::IntoIter;
e1599b0c 10use std::fmt::Debug;
94b46f34 11
48663c56 12/// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
3dfed10e 13#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
dfeec247 14#[derive(HashStable_Generic)]
532ac7d7 15pub enum CtorOf {
48663c56 16 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit struct.
532ac7d7 17 Struct,
48663c56 18 /// This `DefKind::Ctor` is a synthesized constructor of a tuple or unit variant.
532ac7d7
XL
19 Variant,
20}
21
3dfed10e 22#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
dfeec247 23#[derive(HashStable_Generic)]
c30ab7b3 24pub enum CtorKind {
041b39d2 25 /// Constructor function automatically created by a tuple struct/variant.
c30ab7b3 26 Fn,
041b39d2 27 /// Constructor constant automatically created by a unit struct/variant.
c30ab7b3 28 Const,
041b39d2 29 /// Unusable name in value namespace created by a struct variant.
c30ab7b3
SL
30 Fictive,
31}
32
3dfed10e 33#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
dfeec247 34#[derive(HashStable_Generic)]
b7449926
XL
35pub enum NonMacroAttrKind {
36 /// Single-segment attribute defined by the language (`#[inline]`)
37 Builtin,
38 /// Multi-segment custom attribute living in a "tool module" (`#[rustfmt::skip]`).
39 Tool,
40 /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
41 DeriveHelper,
fc512014
XL
42 /// Single-segment custom attribute registered by a derive macro
43 /// but used before that derive macro was expanded (deprecated).
44 DeriveHelperCompat,
60c5eb7d
XL
45 /// Single-segment custom attribute registered with `#[register_attr]`.
46 Registered,
b7449926
XL
47}
48
3dfed10e 49#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
dfeec247 50#[derive(HashStable_Generic)]
48663c56 51pub enum DefKind {
c30ab7b3 52 // Type namespace
48663c56
XL
53 Mod,
54 /// Refers to the struct itself, `DefKind::Ctor` refers to its constructor if it exists.
55 Struct,
56 Union,
57 Enum,
58 /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists.
59 Variant,
60 Trait,
8faf50e0 61 /// `type Foo = Bar;`
48663c56
XL
62 TyAlias,
63 ForeignTy,
64 TraitAlias,
dc9dc135 65 AssocTy,
48663c56
XL
66 TyParam,
67
68 // Value namespace
69 Fn,
70 Const,
71 ConstParam,
72 Static,
73 /// Refers to the struct or enum variant's constructor.
74 Ctor(CtorOf, CtorKind),
ba9703b0 75 AssocFn,
dc9dc135 76 AssocConst,
48663c56
XL
77
78 // Macro namespace
79 Macro(MacroKind),
f9f354fc
XL
80
81 // Not namespaced (or they are, but we don't treat them so)
82 ExternCrate,
83 Use,
84 ForeignMod,
85 AnonConst,
f035d41b 86 OpaqueTy,
f9f354fc
XL
87 Field,
88 LifetimeParam,
89 GlobalAsm,
90 Impl,
91 Closure,
92 Generator,
48663c56
XL
93}
94
95impl DefKind {
416331ca 96 pub fn descr(self, def_id: DefId) -> &'static str {
48663c56
XL
97 match self {
98 DefKind::Fn => "function",
dfeec247
XL
99 DefKind::Mod if def_id.index == CRATE_DEF_INDEX && def_id.krate != LOCAL_CRATE => {
100 "crate"
101 }
48663c56
XL
102 DefKind::Mod => "module",
103 DefKind::Static => "static",
104 DefKind::Enum => "enum",
105 DefKind::Variant => "variant",
106 DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",
107 DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",
108 DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant",
109 DefKind::Struct => "struct",
110 DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
111 DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
dfeec247
XL
112 DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => {
113 panic!("impossible struct constructor")
114 }
416331ca 115 DefKind::OpaqueTy => "opaque type",
48663c56
XL
116 DefKind::TyAlias => "type alias",
117 DefKind::TraitAlias => "trait alias",
dc9dc135 118 DefKind::AssocTy => "associated type",
48663c56
XL
119 DefKind::Union => "union",
120 DefKind::Trait => "trait",
121 DefKind::ForeignTy => "foreign type",
ba9703b0 122 DefKind::AssocFn => "associated function",
48663c56 123 DefKind::Const => "constant",
dc9dc135 124 DefKind::AssocConst => "associated constant",
48663c56
XL
125 DefKind::TyParam => "type parameter",
126 DefKind::ConstParam => "const parameter",
127 DefKind::Macro(macro_kind) => macro_kind.descr(),
f9f354fc
XL
128 DefKind::LifetimeParam => "lifetime parameter",
129 DefKind::Use => "import",
130 DefKind::ForeignMod => "foreign module",
131 DefKind::AnonConst => "constant expression",
132 DefKind::Field => "field",
133 DefKind::Impl => "implementation",
134 DefKind::Closure => "closure",
135 DefKind::Generator => "generator",
136 DefKind::ExternCrate => "extern crate",
137 DefKind::GlobalAsm => "global assembly block",
48663c56
XL
138 }
139 }
140
e1599b0c 141 /// Gets an English article for the definition.
48663c56
XL
142 pub fn article(&self) -> &'static str {
143 match *self {
dc9dc135
XL
144 DefKind::AssocTy
145 | DefKind::AssocConst
ba9703b0 146 | DefKind::AssocFn
48663c56 147 | DefKind::Enum
f9f354fc
XL
148 | DefKind::OpaqueTy
149 | DefKind::Impl
150 | DefKind::Use
151 | DefKind::ExternCrate => "an",
48663c56
XL
152 DefKind::Macro(macro_kind) => macro_kind.article(),
153 _ => "a",
154 }
155 }
60c5eb7d 156
3dfed10e 157 pub fn ns(&self) -> Option<Namespace> {
60c5eb7d
XL
158 match self {
159 DefKind::Mod
160 | DefKind::Struct
161 | DefKind::Union
162 | DefKind::Enum
163 | DefKind::Variant
164 | DefKind::Trait
165 | DefKind::OpaqueTy
166 | DefKind::TyAlias
167 | DefKind::ForeignTy
168 | DefKind::TraitAlias
169 | DefKind::AssocTy
3dfed10e 170 | DefKind::TyParam => Some(Namespace::TypeNS),
60c5eb7d
XL
171
172 DefKind::Fn
173 | DefKind::Const
174 | DefKind::ConstParam
175 | DefKind::Static
176 | DefKind::Ctor(..)
ba9703b0 177 | DefKind::AssocFn
3dfed10e 178 | DefKind::AssocConst => Some(Namespace::ValueNS),
60c5eb7d 179
3dfed10e 180 DefKind::Macro(..) => Some(Namespace::MacroNS),
f9f354fc
XL
181
182 // Not namespaced.
183 DefKind::AnonConst
184 | DefKind::Field
185 | DefKind::LifetimeParam
186 | DefKind::ExternCrate
187 | DefKind::Closure
188 | DefKind::Generator
189 | DefKind::Use
190 | DefKind::ForeignMod
191 | DefKind::GlobalAsm
3dfed10e 192 | DefKind::Impl => None,
60c5eb7d
XL
193 }
194 }
48663c56
XL
195}
196
ba9703b0 197/// The resolution of a path or export.
3dfed10e 198#[derive(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
dfeec247 199#[derive(HashStable_Generic)]
48663c56
XL
200pub enum Res<Id = hir::HirId> {
201 Def(DefKind, DefId),
202
203 // Type namespace
7453a54e 204 PrimTy(hir::PrimTy),
1b1a35ee
XL
205 /// `Self`, with both an optional trait and impl `DefId`.
206 ///
207 /// HACK(min_const_generics): impl self types also have an optional requirement to not mention
208 /// any generic parameters to allow the following with `min_const_generics`:
209 /// ```rust
210 /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] {} }
211 /// ```
29967ef6
XL
212 /// We do however allow `Self` in repeat expression even if it is generic to not break code
213 /// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint.
1b1a35ee 214 ///
29967ef6 215 /// FIXME(lazy_normalization_consts): Remove this bodge once that feature is stable.
1b1a35ee 216 SelfTy(Option<DefId> /* trait */, Option<(DefId, bool)> /* impl */),
0731742a 217 ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
1a4d82fc 218
c30ab7b3 219 // Value namespace
dfeec247 220 SelfCtor(DefId /* impl */), // `DefId` refers to the impl
48663c56 221 Local(Id),
c30ab7b3 222
476ff2be 223 // Macro namespace
0731742a 224 NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
cc61c64b 225
48663c56 226 // All namespaces
7453a54e 227 Err,
c34b1796
AL
228}
229
48663c56
XL
230/// The result of resolving a path before lowering to HIR,
231/// with "module" segments resolved and associated item
232/// segments deferred to type checking.
233/// `base_res` is the resolution of the resolved part of the
8bb4bdeb
XL
234/// path, `unresolved_segments` is the number of unresolved
235/// segments.
c34b1796 236///
ff7c6d11
XL
237/// ```text
238/// module::Type::AssocX::AssocY::MethodOrAssocType
239/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48663c56 240/// base_res unresolved_segments = 3
ff7c6d11
XL
241///
242/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
243/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
48663c56 244/// base_res unresolved_segments = 2
ff7c6d11 245/// ```
c34b1796 246#[derive(Copy, Clone, Debug)]
48663c56
XL
247pub struct PartialRes {
248 base_res: Res<NodeId>,
8bb4bdeb 249 unresolved_segments: usize,
c34b1796
AL
250}
251
48663c56
XL
252impl PartialRes {
253 #[inline]
254 pub fn new(base_res: Res<NodeId>) -> Self {
255 PartialRes { base_res, unresolved_segments: 0 }
8bb4bdeb
XL
256 }
257
48663c56
XL
258 #[inline]
259 pub fn with_unresolved_segments(base_res: Res<NodeId>, mut unresolved_segments: usize) -> Self {
dfeec247
XL
260 if base_res == Res::Err {
261 unresolved_segments = 0
262 }
48663c56 263 PartialRes { base_res, unresolved_segments }
8bb4bdeb
XL
264 }
265
266 #[inline]
48663c56
XL
267 pub fn base_res(&self) -> Res<NodeId> {
268 self.base_res
8bb4bdeb
XL
269 }
270
271 #[inline]
272 pub fn unresolved_segments(&self) -> usize {
273 self.unresolved_segments
3157f602 274 }
1a4d82fc
JJ
275}
276
94b46f34
XL
277/// Different kinds of symbols don't influence each other.
278///
279/// Therefore, they have a separate universe (namespace).
280#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
281pub enum Namespace {
282 TypeNS,
283 ValueNS,
284 MacroNS,
285}
286
8faf50e0
XL
287impl Namespace {
288 pub fn descr(self) -> &'static str {
289 match self {
dfeec247
XL
290 Self::TypeNS => "type",
291 Self::ValueNS => "value",
292 Self::MacroNS => "macro",
8faf50e0
XL
293 }
294 }
295}
296
94b46f34
XL
297/// Just a helper ‒ separate structure for each namespace.
298#[derive(Copy, Clone, Default, Debug)]
299pub struct PerNS<T> {
300 pub value_ns: T,
301 pub type_ns: T,
302 pub macro_ns: T,
303}
304
305impl<T> PerNS<T> {
306 pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> PerNS<U> {
dfeec247 307 PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
94b46f34 308 }
1b1a35ee
XL
309
310 pub fn into_iter(self) -> IntoIter<T, 3> {
311 IntoIter::new([self.value_ns, self.type_ns, self.macro_ns])
312 }
313
314 pub fn iter(&self) -> IntoIter<&T, 3> {
315 IntoIter::new([&self.value_ns, &self.type_ns, &self.macro_ns])
316 }
94b46f34
XL
317}
318
319impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
320 type Output = T;
0731742a 321
94b46f34
XL
322 fn index(&self, ns: Namespace) -> &T {
323 match ns {
dfeec247
XL
324 Namespace::ValueNS => &self.value_ns,
325 Namespace::TypeNS => &self.type_ns,
326 Namespace::MacroNS => &self.macro_ns,
94b46f34
XL
327 }
328 }
329}
330
331impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
332 fn index_mut(&mut self, ns: Namespace) -> &mut T {
333 match ns {
dfeec247
XL
334 Namespace::ValueNS => &mut self.value_ns,
335 Namespace::TypeNS => &mut self.type_ns,
336 Namespace::MacroNS => &mut self.macro_ns,
94b46f34
XL
337 }
338 }
339}
340
341impl<T> PerNS<Option<T>> {
9fa01778 342 /// Returns `true` if all the items in this collection are `None`.
94b46f34
XL
343 pub fn is_empty(&self) -> bool {
344 self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none()
345 }
346
347 /// Returns an iterator over the items which are `Some`.
dfeec247 348 pub fn present_items(self) -> impl Iterator<Item = T> {
29967ef6 349 IntoIter::new([self.type_ns, self.value_ns, self.macro_ns]).filter_map(|it| it)
48663c56
XL
350 }
351}
352
c30ab7b3
SL
353impl CtorKind {
354 pub fn from_ast(vdata: &ast::VariantData) -> CtorKind {
355 match *vdata {
356 ast::VariantData::Tuple(..) => CtorKind::Fn,
357 ast::VariantData::Unit(..) => CtorKind::Const,
358 ast::VariantData::Struct(..) => CtorKind::Fictive,
359 }
360 }
0731742a 361
dfeec247 362 pub fn from_hir(vdata: &hir::VariantData<'_>) -> CtorKind {
c30ab7b3
SL
363 match *vdata {
364 hir::VariantData::Tuple(..) => CtorKind::Fn,
365 hir::VariantData::Unit(..) => CtorKind::Const,
366 hir::VariantData::Struct(..) => CtorKind::Fictive,
367 }
368 }
1a4d82fc
JJ
369}
370
b7449926 371impl NonMacroAttrKind {
69743fb6 372 pub fn descr(self) -> &'static str {
b7449926
XL
373 match self {
374 NonMacroAttrKind::Builtin => "built-in attribute",
375 NonMacroAttrKind::Tool => "tool attribute",
fc512014
XL
376 NonMacroAttrKind::DeriveHelper | NonMacroAttrKind::DeriveHelperCompat => {
377 "derive helper attribute"
378 }
60c5eb7d
XL
379 NonMacroAttrKind::Registered => "explicitly registered attribute",
380 }
381 }
382
383 pub fn article(self) -> &'static str {
384 match self {
385 NonMacroAttrKind::Registered => "an",
386 _ => "a",
387 }
388 }
389
390 /// Users of some attributes cannot mark them as used, so they are considered always used.
391 pub fn is_used(self) -> bool {
392 match self {
fc512014
XL
393 NonMacroAttrKind::Tool
394 | NonMacroAttrKind::DeriveHelper
395 | NonMacroAttrKind::DeriveHelperCompat => true,
dfeec247 396 NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false,
b7449926
XL
397 }
398 }
399}
400
48663c56 401impl<Id> Res<Id> {
e1599b0c 402 /// Return the `DefId` of this `Def` if it has an ID, else panic.
48663c56
XL
403 pub fn def_id(&self) -> DefId
404 where
405 Id: Debug,
406 {
dfeec247
XL
407 self.opt_def_id()
408 .unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {:?}", self))
13cf67c4
XL
409 }
410
e1599b0c 411 /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
13cf67c4 412 pub fn opt_def_id(&self) -> Option<DefId> {
1a4d82fc 413 match *self {
48663c56
XL
414 Res::Def(_, id) => Some(id),
415
dfeec247
XL
416 Res::Local(..)
417 | Res::PrimTy(..)
418 | Res::SelfTy(..)
419 | Res::SelfCtor(..)
420 | Res::ToolMod
421 | Res::NonMacroAttr(..)
422 | Res::Err => None,
1a4d82fc
JJ
423 }
424 }
425
48663c56 426 /// Return the `DefId` of this `Res` if it represents a module.
9fa01778
XL
427 pub fn mod_def_id(&self) -> Option<DefId> {
428 match *self {
48663c56 429 Res::Def(DefKind::Mod, id) => Some(id),
9fa01778
XL
430 _ => None,
431 }
432 }
433
48663c56
XL
434 /// A human readable name for the res kind ("function", "module", etc.).
435 pub fn descr(&self) -> &'static str {
54a0048b 436 match *self {
416331ca 437 Res::Def(kind, def_id) => kind.descr(def_id),
48663c56
XL
438 Res::SelfCtor(..) => "self constructor",
439 Res::PrimTy(..) => "builtin type",
440 Res::Local(..) => "local variable",
48663c56
XL
441 Res::SelfTy(..) => "self type",
442 Res::ToolMod => "tool module",
443 Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
444 Res::Err => "unresolved item",
54a0048b
SL
445 }
446 }
13cf67c4 447
e1599b0c 448 /// Gets an English article for the `Res`.
13cf67c4
XL
449 pub fn article(&self) -> &'static str {
450 match *self {
48663c56 451 Res::Def(kind, _) => kind.article(),
60c5eb7d 452 Res::NonMacroAttr(kind) => kind.article(),
48663c56 453 Res::Err => "an",
13cf67c4
XL
454 _ => "a",
455 }
456 }
48663c56
XL
457
458 pub fn map_id<R>(self, mut map: impl FnMut(Id) -> R) -> Res<R> {
459 match self {
460 Res::Def(kind, id) => Res::Def(kind, id),
461 Res::SelfCtor(id) => Res::SelfCtor(id),
462 Res::PrimTy(id) => Res::PrimTy(id),
463 Res::Local(id) => Res::Local(map(id)),
48663c56
XL
464 Res::SelfTy(a, b) => Res::SelfTy(a, b),
465 Res::ToolMod => Res::ToolMod,
466 Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
467 Res::Err => Res::Err,
468 }
469 }
416331ca
XL
470
471 pub fn macro_kind(self) -> Option<MacroKind> {
472 match self {
473 Res::Def(DefKind::Macro(kind), _) => Some(kind),
474 Res::NonMacroAttr(..) => Some(MacroKind::Attr),
475 _ => None,
476 }
477 }
60c5eb7d 478
1b1a35ee
XL
479 /// Returns `None` if this is `Res::Err`
480 pub fn ns(&self) -> Option<Namespace> {
60c5eb7d 481 match self {
1b1a35ee
XL
482 Res::Def(kind, ..) => kind.ns(),
483 Res::PrimTy(..) | Res::SelfTy(..) | Res::ToolMod => Some(Namespace::TypeNS),
484 Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
485 Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
486 Res::Err => None,
60c5eb7d
XL
487 }
488 }
1b1a35ee
XL
489
490 /// Always returns `true` if `self` is `Res::Err`
491 pub fn matches_ns(&self, ns: Namespace) -> bool {
492 self.ns().map_or(true, |actual_ns| actual_ns == ns)
493 }
29967ef6
XL
494
495 /// Returns whether such a resolved path can occur in a tuple struct/variant pattern
496 pub fn expected_in_tuple_struct_pat(&self) -> bool {
497 matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..))
498 }
1a4d82fc 499}