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