]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/map/definitions.rs
Rollup merge of #64895 - davidtwco:issue-64130-async-error-definition, r=nikomatsakis
[rust.git] / src / librustc / hir / map / definitions.rs
1 //! For each definition, we track the following data. A definition
2 //! here is defined somewhat circularly as "something with a `DefId`",
3 //! but it generally corresponds to things like structs, enums, etc.
4 //! There are also some rather random cases (like const initializer
5 //! expressions) that are mostly just leftovers.
6
7 use crate::hir;
8 use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, CRATE_DEF_INDEX};
9 use crate::ich::Fingerprint;
10 use crate::session::CrateDisambiguator;
11 use crate::util::nodemap::NodeMap;
12
13 use rustc_data_structures::fx::FxHashMap;
14 use rustc_index::vec::{IndexVec};
15 use rustc_data_structures::stable_hasher::StableHasher;
16 use std::borrow::Borrow;
17 use std::fmt::Write;
18 use std::hash::Hash;
19 use syntax::ast;
20 use syntax::ext::hygiene::ExpnId;
21 use syntax::symbol::{Symbol, sym, InternedString};
22 use syntax_pos::{Span, DUMMY_SP};
23
24 /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
25 /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
26 /// stores the `DefIndex` of its parent.
27 /// There is one `DefPathTable` for each crate.
28 #[derive(Clone, Default, RustcDecodable, RustcEncodable)]
29 pub struct DefPathTable {
30     index_to_key: Vec<DefKey>,
31     def_path_hashes: Vec<DefPathHash>,
32 }
33
34 impl DefPathTable {
35     fn allocate(&mut self,
36                 key: DefKey,
37                 def_path_hash: DefPathHash)
38                 -> DefIndex {
39         let index = {
40             let index = DefIndex::from(self.index_to_key.len());
41             debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
42             self.index_to_key.push(key);
43             index
44         };
45         self.def_path_hashes.push(def_path_hash);
46         debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
47         index
48     }
49
50     pub fn next_id(&self) -> DefIndex {
51         DefIndex::from(self.index_to_key.len())
52     }
53
54     #[inline(always)]
55     pub fn def_key(&self, index: DefIndex) -> DefKey {
56         self.index_to_key[index.index()].clone()
57     }
58
59     #[inline(always)]
60     pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
61         let ret = self.def_path_hashes[index.index()];
62         debug!("def_path_hash({:?}) = {:?}", index, ret);
63         return ret
64     }
65
66     pub fn add_def_path_hashes_to(&self,
67                                   cnum: CrateNum,
68                                   out: &mut FxHashMap<DefPathHash, DefId>) {
69         out.extend(
70             self.def_path_hashes
71                 .iter()
72                 .enumerate()
73                 .map(|(index, &hash)| {
74                     let def_id = DefId {
75                         krate: cnum,
76                         index: DefIndex::from(index),
77                     };
78                     (hash, def_id)
79                 })
80         );
81     }
82
83     pub fn size(&self) -> usize {
84         self.index_to_key.len()
85     }
86 }
87
88 /// The definition table containing node definitions.
89 /// It holds the `DefPathTable` for local `DefId`s/`DefPath`s and it also stores a
90 /// mapping from `NodeId`s to local `DefId`s.
91 #[derive(Clone, Default)]
92 pub struct Definitions {
93     table: DefPathTable,
94     node_to_def_index: NodeMap<DefIndex>,
95     def_index_to_node: Vec<ast::NodeId>,
96     pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
97     /// If `ExpnId` is an ID of some macro expansion,
98     /// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
99     parent_modules_of_macro_defs: FxHashMap<ExpnId, DefId>,
100     /// Item with a given `DefIndex` was defined during macro expansion with ID `ExpnId`.
101     expansions_that_defined: FxHashMap<DefIndex, ExpnId>,
102     next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
103     def_index_to_span: FxHashMap<DefIndex, Span>,
104     /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
105     /// we know what parent node that fragment should be attached to thanks to this table.
106     invocation_parents: FxHashMap<ExpnId, DefIndex>,
107     /// Indices of unnamed struct or variant fields with unresolved attributes.
108     pub(super) placeholder_field_indices: NodeMap<usize>,
109 }
110
111 /// A unique identifier that we can use to lookup a definition
112 /// precisely. It combines the index of the definition's parent (if
113 /// any) with a `DisambiguatedDefPathData`.
114 #[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
115 pub struct DefKey {
116     /// The parent path.
117     pub parent: Option<DefIndex>,
118
119     /// The identifier of this node.
120     pub disambiguated_data: DisambiguatedDefPathData,
121 }
122
123 impl DefKey {
124     fn compute_stable_hash(&self, parent_hash: DefPathHash) -> DefPathHash {
125         let mut hasher = StableHasher::new();
126
127         // We hash a `0u8` here to disambiguate between regular `DefPath` hashes,
128         // and the special "root_parent" below.
129         0u8.hash(&mut hasher);
130         parent_hash.hash(&mut hasher);
131
132         let DisambiguatedDefPathData {
133             ref data,
134             disambiguator,
135         } = self.disambiguated_data;
136
137         ::std::mem::discriminant(data).hash(&mut hasher);
138         if let Some(name) = data.get_opt_name() {
139             name.hash(&mut hasher);
140         }
141
142         disambiguator.hash(&mut hasher);
143
144         DefPathHash(hasher.finish())
145     }
146
147     fn root_parent_stable_hash(crate_name: &str,
148                                crate_disambiguator: CrateDisambiguator)
149                                -> DefPathHash {
150         let mut hasher = StableHasher::new();
151         // Disambiguate this from a regular `DefPath` hash; see `compute_stable_hash()` above.
152         1u8.hash(&mut hasher);
153         crate_name.hash(&mut hasher);
154         crate_disambiguator.hash(&mut hasher);
155         DefPathHash(hasher.finish())
156     }
157 }
158
159 /// A pair of `DefPathData` and an integer disambiguator. The integer is
160 /// normally `0`, but in the event that there are multiple defs with the
161 /// same `parent` and `data`, we use this field to disambiguate
162 /// between them. This introduces some artificial ordering dependency
163 /// but means that if you have, e.g., two impls for the same type in
164 /// the same module, they do get distinct `DefId`s.
165 #[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
166 pub struct DisambiguatedDefPathData {
167     pub data: DefPathData,
168     pub disambiguator: u32
169 }
170
171 #[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
172 pub struct DefPath {
173     /// The path leading from the crate root to the item.
174     pub data: Vec<DisambiguatedDefPathData>,
175
176     /// The crate root this path is relative to.
177     pub krate: CrateNum,
178 }
179
180 impl DefPath {
181     pub fn is_local(&self) -> bool {
182         self.krate == LOCAL_CRATE
183     }
184
185     pub fn make<FN>(krate: CrateNum,
186                     start_index: DefIndex,
187                     mut get_key: FN) -> DefPath
188         where FN: FnMut(DefIndex) -> DefKey
189     {
190         let mut data = vec![];
191         let mut index = Some(start_index);
192         loop {
193             debug!("DefPath::make: krate={:?} index={:?}", krate, index);
194             let p = index.unwrap();
195             let key = get_key(p);
196             debug!("DefPath::make: key={:?}", key);
197             match key.disambiguated_data.data {
198                 DefPathData::CrateRoot => {
199                     assert!(key.parent.is_none());
200                     break;
201                 }
202                 _ => {
203                     data.push(key.disambiguated_data);
204                     index = key.parent;
205                 }
206             }
207         }
208         data.reverse();
209         DefPath { data: data, krate: krate }
210     }
211
212     /// Returns a string representation of the `DefPath` without
213     /// the crate-prefix. This method is useful if you don't have
214     /// a `TyCtxt` available.
215     pub fn to_string_no_crate(&self) -> String {
216         let mut s = String::with_capacity(self.data.len() * 16);
217
218         for component in &self.data {
219             write!(s,
220                    "::{}[{}]",
221                    component.data.as_interned_str(),
222                    component.disambiguator)
223                 .unwrap();
224         }
225
226         s
227     }
228
229     /// Returns a filename-friendly string for the `DefPath`, with the
230     /// crate-prefix.
231     pub fn to_string_friendly<F>(&self, crate_imported_name: F) -> String
232         where F: FnOnce(CrateNum) -> Symbol
233     {
234         let crate_name_str = crate_imported_name(self.krate).as_str();
235         let mut s = String::with_capacity(crate_name_str.len() + self.data.len() * 16);
236
237         write!(s, "::{}", crate_name_str).unwrap();
238
239         for component in &self.data {
240             if component.disambiguator == 0 {
241                 write!(s, "::{}", component.data.as_interned_str()).unwrap();
242             } else {
243                 write!(s,
244                        "{}[{}]",
245                        component.data.as_interned_str(),
246                        component.disambiguator)
247                        .unwrap();
248             }
249         }
250
251         s
252     }
253
254     /// Returns a filename-friendly string of the `DefPath`, without
255     /// the crate-prefix. This method is useful if you don't have
256     /// a `TyCtxt` available.
257     pub fn to_filename_friendly_no_crate(&self) -> String {
258         let mut s = String::with_capacity(self.data.len() * 16);
259
260         let mut opt_delimiter = None;
261         for component in &self.data {
262             opt_delimiter.map(|d| s.push(d));
263             opt_delimiter = Some('-');
264             if component.disambiguator == 0 {
265                 write!(s, "{}", component.data.as_interned_str()).unwrap();
266             } else {
267                 write!(s,
268                        "{}[{}]",
269                        component.data.as_interned_str(),
270                        component.disambiguator)
271                        .unwrap();
272             }
273         }
274         s
275     }
276 }
277
278 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
279 pub enum DefPathData {
280     // Root: these should only be used for the root nodes, because
281     // they are treated specially by the `def_path` function.
282
283     /// The crate root (marker).
284     CrateRoot,
285     // Catch-all for random `DefId` things like `DUMMY_NODE_ID`.
286     Misc,
287
288     // Different kinds of items and item-like things:
289
290     /// An impl.
291     Impl,
292     /// Something in the type namespace.
293     TypeNs(InternedString),
294     /// Something in the value namespace.
295     ValueNs(InternedString),
296     /// Something in the macro namespace.
297     MacroNs(InternedString),
298     /// Something in the lifetime namespace.
299     LifetimeNs(InternedString),
300     /// A closure expression.
301     ClosureExpr,
302
303     // Subportions of items:
304
305     /// Implicit constructor for a unit or tuple-like struct or enum variant.
306     Ctor,
307     /// A constant expression (see `{ast,hir}::AnonConst`).
308     AnonConst,
309     /// An `impl Trait` type node.
310     ImplTrait,
311     /// Identifies a piece of crate metadata that is global to a whole crate
312     /// (as opposed to just one item). `GlobalMetaData` components are only
313     /// supposed to show up right below the crate root.
314     GlobalMetaData(InternedString),
315 }
316
317 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
318          RustcEncodable, RustcDecodable)]
319 pub struct DefPathHash(pub Fingerprint);
320
321 impl_stable_hash_for!(tuple_struct DefPathHash { fingerprint });
322
323 impl Borrow<Fingerprint> for DefPathHash {
324     #[inline]
325     fn borrow(&self) -> &Fingerprint {
326         &self.0
327     }
328 }
329
330 impl Definitions {
331     pub fn def_path_table(&self) -> &DefPathTable {
332         &self.table
333     }
334
335     /// Gets the number of definitions.
336     pub fn def_index_count(&self) -> usize {
337         self.table.index_to_key.len()
338     }
339
340     pub fn def_key(&self, index: DefIndex) -> DefKey {
341         self.table.def_key(index)
342     }
343
344     #[inline(always)]
345     pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
346         self.table.def_path_hash(index)
347     }
348
349     /// Returns the path from the crate root to `index`. The root
350     /// nodes are not included in the path (i.e., this will be an
351     /// empty vector for the crate root). For an inlined item, this
352     /// will be the path of the item in the external crate (but the
353     /// path will begin with the path to the external crate).
354     pub fn def_path(&self, index: DefIndex) -> DefPath {
355         DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
356     }
357
358     #[inline]
359     pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
360         self.node_to_def_index.get(&node).cloned()
361     }
362
363     #[inline]
364     pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
365         self.opt_def_index(node).map(DefId::local)
366     }
367
368     #[inline]
369     pub fn local_def_id(&self, node: ast::NodeId) -> DefId {
370         self.opt_local_def_id(node).unwrap()
371     }
372
373     #[inline]
374     pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
375         if def_id.krate == LOCAL_CRATE {
376             let node_id = self.def_index_to_node[def_id.index.index()];
377             if node_id != ast::DUMMY_NODE_ID {
378                 return Some(node_id);
379             }
380         }
381         None
382     }
383
384     #[inline]
385     pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
386         if def_id.krate == LOCAL_CRATE {
387             let hir_id = self.def_index_to_hir_id(def_id.index);
388             if hir_id != hir::DUMMY_HIR_ID {
389                 Some(hir_id)
390             } else {
391                 None
392             }
393         } else {
394             None
395         }
396     }
397
398     #[inline]
399     pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
400         self.node_to_hir_id[node_id]
401     }
402
403     #[inline]
404     pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
405         let node_id = self.def_index_to_node[def_index.index()];
406         self.node_to_hir_id[node_id]
407     }
408
409     /// Retrieves the span of the given `DefId` if `DefId` is in the local crate, the span exists
410     /// and it's not `DUMMY_SP`.
411     #[inline]
412     pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
413         if def_id.krate == LOCAL_CRATE {
414             self.def_index_to_span.get(&def_id.index).cloned()
415         } else {
416             None
417         }
418     }
419
420     /// Adds a root definition (no parent) and a few other reserved definitions.
421     pub fn create_root_def(&mut self,
422                            crate_name: &str,
423                            crate_disambiguator: CrateDisambiguator)
424                            -> DefIndex {
425         let key = DefKey {
426             parent: None,
427             disambiguated_data: DisambiguatedDefPathData {
428                 data: DefPathData::CrateRoot,
429                 disambiguator: 0
430             }
431         };
432
433         let parent_hash = DefKey::root_parent_stable_hash(crate_name,
434                                                           crate_disambiguator);
435         let def_path_hash = key.compute_stable_hash(parent_hash);
436
437         // Create the definition.
438         let root_index = self.table.allocate(key, def_path_hash);
439         assert_eq!(root_index, CRATE_DEF_INDEX);
440         assert!(self.def_index_to_node.is_empty());
441         self.def_index_to_node.push(ast::CRATE_NODE_ID);
442         self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
443         self.set_invocation_parent(ExpnId::root(), root_index);
444
445         // Allocate some other `DefIndex`es that always must exist.
446         GlobalMetaDataKind::allocate_def_indices(self);
447
448         root_index
449     }
450
451     /// Adds a definition with a parent definition.
452     pub fn create_def_with_parent(&mut self,
453                                   parent: DefIndex,
454                                   node_id: ast::NodeId,
455                                   data: DefPathData,
456                                   expn_id: ExpnId,
457                                   span: Span)
458                                   -> DefIndex {
459         debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
460                parent, node_id, data);
461
462         assert!(!self.node_to_def_index.contains_key(&node_id),
463                 "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
464                 node_id,
465                 data,
466                 self.table.def_key(self.node_to_def_index[&node_id]));
467
468         // The root node must be created with `create_root_def()`.
469         assert!(data != DefPathData::CrateRoot);
470
471         // Find the next free disambiguator for this key.
472         let disambiguator = {
473             let next_disamb = self.next_disambiguator.entry((parent, data.clone())).or_insert(0);
474             let disambiguator = *next_disamb;
475             *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow");
476             disambiguator
477         };
478
479         let key = DefKey {
480             parent: Some(parent),
481             disambiguated_data: DisambiguatedDefPathData {
482                 data, disambiguator
483             }
484         };
485
486         let parent_hash = self.table.def_path_hash(parent);
487         let def_path_hash = key.compute_stable_hash(parent_hash);
488
489         debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
490
491         // Create the definition.
492         let index = self.table.allocate(key, def_path_hash);
493         assert_eq!(index.index(), self.def_index_to_node.len());
494         self.def_index_to_node.push(node_id);
495
496         // Some things for which we allocate `DefIndex`es don't correspond to
497         // anything in the AST, so they don't have a `NodeId`. For these cases
498         // we don't need a mapping from `NodeId` to `DefIndex`.
499         if node_id != ast::DUMMY_NODE_ID {
500             debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
501             self.node_to_def_index.insert(node_id, index);
502         }
503
504         if expn_id != ExpnId::root() {
505             self.expansions_that_defined.insert(index, expn_id);
506         }
507
508         // The span is added if it isn't dummy.
509         if !span.is_dummy() {
510             self.def_index_to_span.insert(index, span);
511         }
512
513         index
514     }
515
516     /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during
517     /// AST to HIR lowering.
518     pub fn init_node_id_to_hir_id_mapping(&mut self,
519                                           mapping: IndexVec<ast::NodeId, hir::HirId>) {
520         assert!(self.node_to_hir_id.is_empty(),
521                 "trying to initialize `NodeId` -> `HirId` mapping twice");
522         self.node_to_hir_id = mapping;
523     }
524
525     pub fn expansion_that_defined(&self, index: DefIndex) -> ExpnId {
526         self.expansions_that_defined.get(&index).cloned().unwrap_or(ExpnId::root())
527     }
528
529     pub fn parent_module_of_macro_def(&self, expn_id: ExpnId) -> DefId {
530         self.parent_modules_of_macro_defs[&expn_id]
531     }
532
533     pub fn add_parent_module_of_macro_def(&mut self, expn_id: ExpnId, module: DefId) {
534         self.parent_modules_of_macro_defs.insert(expn_id, module);
535     }
536
537     pub fn invocation_parent(&self, invoc_id: ExpnId) -> DefIndex {
538         self.invocation_parents[&invoc_id]
539     }
540
541     pub fn set_invocation_parent(&mut self, invoc_id: ExpnId, parent: DefIndex) {
542         let old_parent = self.invocation_parents.insert(invoc_id, parent);
543         assert!(old_parent.is_none(), "parent `DefIndex` is reset for an invocation");
544     }
545 }
546
547 impl DefPathData {
548     pub fn get_opt_name(&self) -> Option<InternedString> {
549         use self::DefPathData::*;
550         match *self {
551             TypeNs(name) |
552             ValueNs(name) |
553             MacroNs(name) |
554             LifetimeNs(name) |
555             GlobalMetaData(name) => Some(name),
556
557             Impl |
558             CrateRoot |
559             Misc |
560             ClosureExpr |
561             Ctor |
562             AnonConst |
563             ImplTrait => None
564         }
565     }
566
567     pub fn as_interned_str(&self) -> InternedString {
568         use self::DefPathData::*;
569         let s = match *self {
570             TypeNs(name) |
571             ValueNs(name) |
572             MacroNs(name) |
573             LifetimeNs(name) |
574             GlobalMetaData(name) => {
575                 return name
576             }
577             // Note that this does not show up in user print-outs.
578             CrateRoot => sym::double_braced_crate,
579             Impl => sym::double_braced_impl,
580             Misc => sym::double_braced_misc,
581             ClosureExpr => sym::double_braced_closure,
582             Ctor => sym::double_braced_constructor,
583             AnonConst => sym::double_braced_constant,
584             ImplTrait => sym::double_braced_opaque,
585         };
586
587         s.as_interned_str()
588     }
589
590     pub fn to_string(&self) -> String {
591         self.as_interned_str().to_string()
592     }
593 }
594
595 // We define the `GlobalMetaDataKind` enum with this macro because we want to
596 // make sure that we exhaustively iterate over all variants when registering
597 // the corresponding `DefIndex`es in the `DefTable`.
598 macro_rules! define_global_metadata_kind {
599     (pub enum GlobalMetaDataKind {
600         $($variant:ident),*
601     }) => (
602         #[derive(Clone, Copy, Debug, Hash, RustcEncodable, RustcDecodable)]
603         pub enum GlobalMetaDataKind {
604             $($variant),*
605         }
606
607         impl GlobalMetaDataKind {
608             fn allocate_def_indices(definitions: &mut Definitions) {
609                 $({
610                     let instance = GlobalMetaDataKind::$variant;
611                     definitions.create_def_with_parent(
612                         CRATE_DEF_INDEX,
613                         ast::DUMMY_NODE_ID,
614                         DefPathData::GlobalMetaData(instance.name().as_interned_str()),
615                         ExpnId::root(),
616                         DUMMY_SP
617                     );
618
619                     // Make sure calling `def_index` does not crash.
620                     instance.def_index(&definitions.table);
621                 })*
622             }
623
624             pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
625                 let def_key = DefKey {
626                     parent: Some(CRATE_DEF_INDEX),
627                     disambiguated_data: DisambiguatedDefPathData {
628                         data: DefPathData::GlobalMetaData(self.name().as_interned_str()),
629                         disambiguator: 0,
630                     }
631                 };
632
633                 // These `DefKey`s are all right after the root,
634                 // so a linear search is fine.
635                 let index = def_path_table.index_to_key
636                                           .iter()
637                                           .position(|k| *k == def_key)
638                                           .unwrap();
639
640                 DefIndex::from(index)
641             }
642
643             fn name(&self) -> Symbol {
644
645                 let string = match *self {
646                     $(
647                         GlobalMetaDataKind::$variant => {
648                             concat!("{{GlobalMetaData::", stringify!($variant), "}}")
649                         }
650                     )*
651                 };
652
653                 Symbol::intern(string)
654             }
655         }
656     )
657 }
658
659 define_global_metadata_kind!(pub enum GlobalMetaDataKind {
660     Krate,
661     CrateDeps,
662     DylibDependencyFormats,
663     LangItems,
664     LangItemsMissing,
665     NativeLibraries,
666     SourceMap,
667     Impls,
668     ExportedSymbols
669 });