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