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