|
15 | 15 | //! expressions) that are mostly just leftovers.
|
16 | 16 |
|
17 | 17 | use hir;
|
18 |
| -use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace}; |
| 18 | +use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace, |
| 19 | + CRATE_DEF_INDEX}; |
19 | 20 | use ich::Fingerprint;
|
20 | 21 | use rustc_data_structures::fx::FxHashMap;
|
21 | 22 | use rustc_data_structures::indexed_vec::IndexVec;
|
@@ -396,6 +397,11 @@ pub enum DefPathData {
|
396 | 397 | ImplTrait,
|
397 | 398 | /// A `typeof` type node.
|
398 | 399 | Typeof,
|
| 400 | + |
| 401 | + /// GlobalMetaData identifies a piece of crate metadata that is global to |
| 402 | + /// a whole crate (as opposed to just one item). GlobalMetaData components |
| 403 | + /// are only supposed to show up right below the crate root. |
| 404 | + GlobalMetaData(Ident) |
399 | 405 | }
|
400 | 406 |
|
401 | 407 | #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
|
@@ -427,8 +433,8 @@ impl Definitions {
|
427 | 433 |
|
428 | 434 | /// Get the number of definitions.
|
429 | 435 | pub fn def_index_counts_lo_hi(&self) -> (usize, usize) {
|
430 |
| - (self.def_index_to_node[DefIndexAddressSpace::Low.index()].len(), |
431 |
| - self.def_index_to_node[DefIndexAddressSpace::High.index()].len()) |
| 436 | + (self.table.index_to_key[DefIndexAddressSpace::Low.index()].len(), |
| 437 | + self.table.index_to_key[DefIndexAddressSpace::High.index()].len()) |
432 | 438 | }
|
433 | 439 |
|
434 | 440 | pub fn def_key(&self, index: DefIndex) -> DefKey {
|
@@ -469,7 +475,12 @@ impl Definitions {
|
469 | 475 | if def_id.krate == LOCAL_CRATE {
|
470 | 476 | let space_index = def_id.index.address_space().index();
|
471 | 477 | let array_index = def_id.index.as_array_index();
|
472 |
| - Some(self.def_index_to_node[space_index][array_index]) |
| 478 | + let node_id = self.def_index_to_node[space_index][array_index]; |
| 479 | + if node_id != ast::DUMMY_NODE_ID { |
| 480 | + Some(node_id) |
| 481 | + } else { |
| 482 | + None |
| 483 | + } |
473 | 484 | } else {
|
474 | 485 | None
|
475 | 486 | }
|
@@ -498,12 +509,16 @@ impl Definitions {
|
498 | 509 |
|
499 | 510 | // Create the definition.
|
500 | 511 | let address_space = super::ITEM_LIKE_SPACE;
|
501 |
| - let index = self.table.allocate(key, def_path_hash, address_space); |
| 512 | + let root_index = self.table.allocate(key, def_path_hash, address_space); |
| 513 | + assert_eq!(root_index, CRATE_DEF_INDEX); |
502 | 514 | assert!(self.def_index_to_node[address_space.index()].is_empty());
|
503 | 515 | self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID);
|
504 |
| - self.node_to_def_index.insert(ast::CRATE_NODE_ID, index); |
| 516 | + self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index); |
505 | 517 |
|
506 |
| - index |
| 518 | + // Allocate some other DefIndices that always must exist. |
| 519 | + GlobalMetaDataKind::allocate_def_indices(self); |
| 520 | + |
| 521 | + root_index |
507 | 522 | }
|
508 | 523 |
|
509 | 524 | /// Add a definition with a parent definition.
|
@@ -550,13 +565,19 @@ impl Definitions {
|
550 | 565 | assert_eq!(index.as_array_index(),
|
551 | 566 | self.def_index_to_node[address_space.index()].len());
|
552 | 567 | self.def_index_to_node[address_space.index()].push(node_id);
|
| 568 | + |
| 569 | + // Some things for which we allocate DefIndices don't correspond to |
| 570 | + // anything in the AST, so they don't have a NodeId. For these cases |
| 571 | + // we don't need a mapping from NodeId to DefIndex. |
| 572 | + if node_id != ast::DUMMY_NODE_ID { |
| 573 | + debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id); |
| 574 | + self.node_to_def_index.insert(node_id, index); |
| 575 | + } |
| 576 | + |
553 | 577 | if expansion.is_modern() {
|
554 | 578 | self.expansions.insert(index, expansion);
|
555 | 579 | }
|
556 | 580 |
|
557 |
| - debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id); |
558 |
| - self.node_to_def_index.insert(node_id, index); |
559 |
| - |
560 | 581 | index
|
561 | 582 | }
|
562 | 583 |
|
@@ -594,7 +615,8 @@ impl DefPathData {
|
594 | 615 | LifetimeDef(ident) |
|
595 | 616 | EnumVariant(ident) |
|
596 | 617 | Binding(ident) |
|
597 |
| - Field(ident) => Some(ident), |
| 618 | + Field(ident) | |
| 619 | + GlobalMetaData(ident) => Some(ident), |
598 | 620 |
|
599 | 621 | Impl |
|
600 | 622 | CrateRoot |
|
@@ -622,7 +644,8 @@ impl DefPathData {
|
622 | 644 | LifetimeDef(ident) |
|
623 | 645 | EnumVariant(ident) |
|
624 | 646 | Binding(ident) |
|
625 |
| - Field(ident) => { |
| 647 | + Field(ident) | |
| 648 | + GlobalMetaData(ident) => { |
626 | 649 | return ident.name.as_str();
|
627 | 650 | }
|
628 | 651 |
|
@@ -667,3 +690,74 @@ impl ::std::hash::Hash for DefPathData {
|
667 | 690 | }
|
668 | 691 | }
|
669 | 692 | }
|
| 693 | + |
| 694 | + |
| 695 | +// We define the GlobalMetaDataKind enum with this macro because we want to |
| 696 | +// make sure that we exhaustively iterate over all variants when registering |
| 697 | +// the corresponding DefIndices in the DefTable. |
| 698 | +macro_rules! define_global_metadata_kind { |
| 699 | + (pub enum GlobalMetaDataKind { |
| 700 | + $($variant:ident),* |
| 701 | + }) => ( |
| 702 | + #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, |
| 703 | + RustcEncodable, RustcDecodable)] |
| 704 | + pub enum GlobalMetaDataKind { |
| 705 | + $($variant),* |
| 706 | + } |
| 707 | + |
| 708 | + impl GlobalMetaDataKind { |
| 709 | + fn allocate_def_indices(definitions: &mut Definitions) { |
| 710 | + $({ |
| 711 | + let instance = GlobalMetaDataKind::$variant; |
| 712 | + definitions.create_def_with_parent( |
| 713 | + CRATE_DEF_INDEX, |
| 714 | + ast::DUMMY_NODE_ID, |
| 715 | + DefPathData::GlobalMetaData(instance.ident()), |
| 716 | + DefIndexAddressSpace::High, |
| 717 | + Mark::root() |
| 718 | + ); |
| 719 | + |
| 720 | + // Make sure calling def_index does not crash. |
| 721 | + instance.def_index(&definitions.table); |
| 722 | + })* |
| 723 | + } |
| 724 | + |
| 725 | + pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex { |
| 726 | + let def_key = DefKey { |
| 727 | + parent: Some(CRATE_DEF_INDEX), |
| 728 | + disambiguated_data: DisambiguatedDefPathData { |
| 729 | + data: DefPathData::GlobalMetaData(self.ident()), |
| 730 | + disambiguator: 0, |
| 731 | + } |
| 732 | + }; |
| 733 | + |
| 734 | + def_path_table.key_to_index[&def_key] |
| 735 | + } |
| 736 | + |
| 737 | + fn ident(&self) -> Ident { |
| 738 | + |
| 739 | + let string = match *self { |
| 740 | + $( |
| 741 | + GlobalMetaDataKind::$variant => { |
| 742 | + concat!("{{GlobalMetaData::", stringify!($variant), "}}") |
| 743 | + } |
| 744 | + )* |
| 745 | + }; |
| 746 | + |
| 747 | + Ident::from_str(string) |
| 748 | + } |
| 749 | + } |
| 750 | + ) |
| 751 | +} |
| 752 | + |
| 753 | +define_global_metadata_kind!(pub enum GlobalMetaDataKind { |
| 754 | + Krate, |
| 755 | + CrateDeps, |
| 756 | + DylibDependencyFormats, |
| 757 | + LangItems, |
| 758 | + LangItemsMissing, |
| 759 | + NativeLibraries, |
| 760 | + CodeMap, |
| 761 | + Impls, |
| 762 | + ExportedSymbols |
| 763 | +}); |
0 commit comments