about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2017-06-07 10:45:20 +0200
committerMichael Woerister <michaelwoerister@posteo.net>2017-06-07 12:11:40 +0200
commit8b36d3308effcc013c9c4aea9d83fa1d8bd540c1 (patch)
tree91b415d64cbbb720a39a66d8ab477e2e7d2e6bfd
parent12e5b699a493e3d67698a9a42c82f686684c32af (diff)
downloadrust-8b36d3308effcc013c9c4aea9d83fa1d8bd540c1.tar.gz
rust-8b36d3308effcc013c9c4aea9d83fa1d8bd540c1.zip
Allocate DefIndices for global crate metadata.
This allows for treating global crate metadata the same as regular metadata with regard to incr. comp.
-rw-r--r--src/librustc/dep_graph/dep_node.rs17
-rw-r--r--src/librustc/dep_graph/mod.rs1
-rw-r--r--src/librustc/hir/map/definitions.rs118
-rw-r--r--src/librustc/middle/cstore.rs8
-rw-r--r--src/librustc/ty/item_path.rs3
-rw-r--r--src/librustc_incremental/persist/data.rs4
-rw-r--r--src/librustc_incremental/persist/hash.rs37
-rw-r--r--src/librustc_incremental/persist/save.rs6
-rw-r--r--src/librustc_metadata/creader.rs8
-rw-r--r--src/librustc_metadata/cstore.rs11
-rw-r--r--src/librustc_metadata/cstore_impl.rs4
-rw-r--r--src/librustc_metadata/decoder.rs19
-rw-r--r--src/librustc_metadata/encoder.rs40
-rw-r--r--src/librustc_metadata/index_builder.rs2
14 files changed, 159 insertions, 119 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 1a0f89a1e53..1571cf344ed 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -53,9 +53,6 @@ pub enum DepNode<D: Clone + Debug> {
     /// in an extern crate.
     MetaData(D),
 
-    /// Represents some piece of metadata global to its crate.
-    GlobalMetaData(D, GlobalMetaDataKind),
-
     /// Represents some artifact that we save to disk. Note that these
     /// do not have a def-id as part of their identifier.
     WorkProduct(WorkProductId),
@@ -309,7 +306,6 @@ impl<D: Clone + Debug> DepNode<D> {
             ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies),
             ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic),
             IsMirAvailable(ref d) => op(d).map(IsMirAvailable),
-            GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)),
         }
     }
 }
@@ -330,16 +326,3 @@ impl WorkProductId {
         WorkProductId(hasher.finish())
     }
 }
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub enum GlobalMetaDataKind {
-    Krate,
-    CrateDeps,
-    DylibDependencyFormats,
-    LangItems,
-    LangItemsMissing,
-    NativeLibraries,
-    CodeMap,
-    Impls,
-    ExportedSymbols,
-}
diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs
index 822b61df7a4..809bed939f5 100644
--- a/src/librustc/dep_graph/mod.rs
+++ b/src/librustc/dep_graph/mod.rs
@@ -22,7 +22,6 @@ mod thread;
 pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
 pub use self::dep_node::DepNode;
 pub use self::dep_node::WorkProductId;
-pub use self::dep_node::GlobalMetaDataKind;
 pub use self::graph::DepGraph;
 pub use self::graph::WorkProduct;
 pub use self::query::DepGraphQuery;
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index ced0f351c9e..ae43035f3b2 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -15,7 +15,8 @@
 //! expressions) that are mostly just leftovers.
 
 use hir;
-use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace};
+use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace,
+                  CRATE_DEF_INDEX};
 use ich::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -396,6 +397,11 @@ pub enum DefPathData {
     ImplTrait,
     /// A `typeof` type node.
     Typeof,
+
+    /// GlobalMetaData identifies a piece of crate metadata that is global to
+    /// a whole crate (as opposed to just one item). GlobalMetaData components
+    /// are only supposed to show up right below the crate root.
+    GlobalMetaData(Ident)
 }
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
@@ -427,8 +433,8 @@ impl Definitions {
 
     /// Get the number of definitions.
     pub fn def_index_counts_lo_hi(&self) -> (usize, usize) {
-        (self.def_index_to_node[DefIndexAddressSpace::Low.index()].len(),
-         self.def_index_to_node[DefIndexAddressSpace::High.index()].len())
+        (self.table.index_to_key[DefIndexAddressSpace::Low.index()].len(),
+         self.table.index_to_key[DefIndexAddressSpace::High.index()].len())
     }
 
     pub fn def_key(&self, index: DefIndex) -> DefKey {
@@ -469,7 +475,12 @@ impl Definitions {
         if def_id.krate == LOCAL_CRATE {
             let space_index = def_id.index.address_space().index();
             let array_index = def_id.index.as_array_index();
-            Some(self.def_index_to_node[space_index][array_index])
+            let node_id = self.def_index_to_node[space_index][array_index];
+            if node_id != ast::DUMMY_NODE_ID {
+                Some(node_id)
+            } else {
+                None
+            }
         } else {
             None
         }
@@ -498,12 +509,16 @@ impl Definitions {
 
         // Create the definition.
         let address_space = super::ITEM_LIKE_SPACE;
-        let index = self.table.allocate(key, def_path_hash, address_space);
+        let root_index = self.table.allocate(key, def_path_hash, address_space);
+        assert_eq!(root_index, CRATE_DEF_INDEX);
         assert!(self.def_index_to_node[address_space.index()].is_empty());
         self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID);
-        self.node_to_def_index.insert(ast::CRATE_NODE_ID, index);
+        self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
 
-        index
+        // Allocate some other DefIndices that always must exist.
+        GlobalMetaDataKind::allocate_def_indices(self);
+
+        root_index
     }
 
     /// Add a definition with a parent definition.
@@ -550,13 +565,19 @@ impl Definitions {
         assert_eq!(index.as_array_index(),
                    self.def_index_to_node[address_space.index()].len());
         self.def_index_to_node[address_space.index()].push(node_id);
+
+        // Some things for which we allocate DefIndices don't correspond to
+        // anything in the AST, so they don't have a NodeId. For these cases
+        // we don't need a mapping from NodeId to DefIndex.
+        if node_id != ast::DUMMY_NODE_ID {
+            debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
+            self.node_to_def_index.insert(node_id, index);
+        }
+
         if expansion.is_modern() {
             self.expansions.insert(index, expansion);
         }
 
-        debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
-        self.node_to_def_index.insert(node_id, index);
-
         index
     }
 
@@ -594,7 +615,8 @@ impl DefPathData {
             LifetimeDef(ident) |
             EnumVariant(ident) |
             Binding(ident) |
-            Field(ident) => Some(ident),
+            Field(ident) |
+            GlobalMetaData(ident) => Some(ident),
 
             Impl |
             CrateRoot |
@@ -622,7 +644,8 @@ impl DefPathData {
             LifetimeDef(ident) |
             EnumVariant(ident) |
             Binding(ident) |
-            Field(ident) => {
+            Field(ident) |
+            GlobalMetaData(ident) => {
                 return ident.name.as_str();
             }
 
@@ -667,3 +690,74 @@ impl ::std::hash::Hash for DefPathData {
         }
     }
 }
+
+
+// We define the GlobalMetaDataKind enum with this macro because we want to
+// make sure that we exhaustively iterate over all variants when registering
+// the corresponding DefIndices in the DefTable.
+macro_rules! define_global_metadata_kind {
+    (pub enum GlobalMetaDataKind {
+        $($variant:ident),*
+    }) => (
+        #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
+                 RustcEncodable, RustcDecodable)]
+        pub enum GlobalMetaDataKind {
+            $($variant),*
+        }
+
+        impl GlobalMetaDataKind {
+            fn allocate_def_indices(definitions: &mut Definitions) {
+                $({
+                    let instance = GlobalMetaDataKind::$variant;
+                    definitions.create_def_with_parent(
+                        CRATE_DEF_INDEX,
+                        ast::DUMMY_NODE_ID,
+                        DefPathData::GlobalMetaData(instance.ident()),
+                        DefIndexAddressSpace::High,
+                        Mark::root()
+                    );
+
+                    // Make sure calling def_index does not crash.
+                    instance.def_index(&definitions.table);
+                })*
+            }
+
+            pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
+                let def_key = DefKey {
+                    parent: Some(CRATE_DEF_INDEX),
+                    disambiguated_data: DisambiguatedDefPathData {
+                        data: DefPathData::GlobalMetaData(self.ident()),
+                        disambiguator: 0,
+                    }
+                };
+
+                def_path_table.key_to_index[&def_key]
+            }
+
+            fn ident(&self) -> Ident {
+
+                let string = match *self {
+                    $(
+                        GlobalMetaDataKind::$variant => {
+                            concat!("{{GlobalMetaData::", stringify!($variant), "}}")
+                        }
+                    )*
+                };
+
+                Ident::from_str(string)
+            }
+        }
+    )
+}
+
+define_global_metadata_kind!(pub enum GlobalMetaDataKind {
+    Krate,
+    CrateDeps,
+    DylibDependencyFormats,
+    LangItems,
+    LangItemsMissing,
+    NativeLibraries,
+    CodeMap,
+    Impls,
+    ExportedSymbols
+});
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 71b066c6688..57b8c7f8c16 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -23,7 +23,6 @@
 // probably get a better home if someone can find one.
 
 use hir::def;
-use dep_graph::DepNode;
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::map as hir_map;
 use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData,
@@ -190,15 +189,14 @@ pub struct EncodedMetadataHash {
 /// upstream crate.
 #[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
 pub struct EncodedMetadataHashes {
-    pub entry_hashes: Vec<EncodedMetadataHash>,
-    pub global_hashes: Vec<(DepNode<()>, ich::Fingerprint)>,
+    // Stable content hashes for things in crate metadata, indexed by DefIndex.
+    pub hashes: Vec<EncodedMetadataHash>,
 }
 
 impl EncodedMetadataHashes {
     pub fn new() -> EncodedMetadataHashes {
         EncodedMetadataHashes {
-            entry_hashes: Vec::new(),
-            global_hashes: Vec::new(),
+            hashes: Vec::new(),
         }
     }
 }
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 78536b53ba8..503177e437b 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -197,7 +197,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             data @ DefPathData::ClosureExpr |
             data @ DefPathData::Binding(..) |
             data @ DefPathData::ImplTrait |
-            data @ DefPathData::Typeof => {
+            data @ DefPathData::Typeof |
+            data @ DefPathData::GlobalMetaData(..) => {
                 let parent_def_id = self.parent_def_id(def_id).unwrap();
                 self.push_item_path(buffer, parent_def_id);
                 buffer.push(&data.as_interned_str());
diff --git a/src/librustc_incremental/persist/data.rs b/src/librustc_incremental/persist/data.rs
index 4669bb866d4..96b7de94daf 100644
--- a/src/librustc_incremental/persist/data.rs
+++ b/src/librustc_incremental/persist/data.rs
@@ -126,10 +126,6 @@ pub struct SerializedMetadataHashes {
     /// (matching the one found in this structure).
     pub entry_hashes: Vec<EncodedMetadataHash>,
 
-    /// This map contains fingerprints that are not specific to some DefId but
-    /// describe something global to the whole crate.
-    pub global_hashes: Vec<(DepNode<()>, Fingerprint)>,
-
     /// For each DefIndex (as it occurs in SerializedMetadataHash), this
     /// map stores the DefPathIndex (as it occurs in DefIdDirectory), so
     /// that we can find the new DefId for a SerializedMetadataHash in a
diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs
index 6ab280be470..4a2dd274aae 100644
--- a/src/librustc_incremental/persist/hash.rs
+++ b/src/librustc_incremental/persist/hash.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use rustc::dep_graph::DepNode;
-use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir::svh::Svh;
 use rustc::ich::Fingerprint;
 use rustc::ty::TyCtxt;
@@ -29,9 +29,8 @@ use std::fmt::Debug;
 pub struct HashContext<'a, 'tcx: 'a> {
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
     incremental_hashes_map: &'a IncrementalHashesMap,
-    item_metadata_hashes: FxHashMap<DefId, Fingerprint>,
+    metadata_hashes: FxHashMap<DefId, Fingerprint>,
     crate_hashes: FxHashMap<CrateNum, Svh>,
-    global_metadata_hashes: FxHashMap<DepNode<DefId>, Fingerprint>,
 }
 
 impl<'a, 'tcx> HashContext<'a, 'tcx> {
@@ -41,9 +40,8 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
         HashContext {
             tcx: tcx,
             incremental_hashes_map: incremental_hashes_map,
-            item_metadata_hashes: FxHashMap(),
+            metadata_hashes: FxHashMap(),
             crate_hashes: FxHashMap(),
-            global_metadata_hashes: FxHashMap(),
         }
     }
 
@@ -53,8 +51,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
             DepNode::Hir(_) |
             DepNode::HirBody(_) =>
                 true,
-            DepNode::MetaData(def_id) |
-            DepNode::GlobalMetaData(def_id, _) => !def_id.is_local(),
+            DepNode::MetaData(def_id) => !def_id.is_local(),
             _ => false,
         }
     }
@@ -83,13 +80,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
             DepNode::MetaData(def_id) if !def_id.is_local() => {
                 Some(self.metadata_hash(def_id,
                                         def_id.krate,
-                                        |this| &mut this.item_metadata_hashes))
-            }
-
-            DepNode::GlobalMetaData(def_id, kind) => {
-                Some(self.metadata_hash(DepNode::GlobalMetaData(def_id, kind),
-                                        def_id.krate,
-                                        |this| &mut this.global_metadata_hashes))
+                                        |this| &mut this.metadata_hashes))
             }
 
             _ => {
@@ -217,27 +208,11 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
             let def_id = DefId { krate: cnum, index: serialized_hash.def_index };
 
             // record the hash for this dep-node
-            let old = self.item_metadata_hashes.insert(def_id, serialized_hash.hash);
+            let old = self.metadata_hashes.insert(def_id, serialized_hash.hash);
             debug!("load_from_data: def_id={:?} hash={}", def_id, serialized_hash.hash);
             assert!(old.is_none(), "already have hash for {:?}", def_id);
         }
 
-        for (dep_node, fingerprint) in serialized_hashes.global_hashes {
-            // Here we need to remap the CrateNum in the DepNode.
-            let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
-            let dep_node = match dep_node {
-                DepNode::GlobalMetaData(_, kind) => DepNode::GlobalMetaData(def_id, kind),
-                other => {
-                    bug!("unexpected DepNode variant: {:?}", other)
-                }
-            };
-
-            // record the hash for this dep-node
-            debug!("load_from_data: def_node={:?} hash={}", dep_node, fingerprint);
-            let old = self.global_metadata_hashes.insert(dep_node.clone(), fingerprint);
-            assert!(old.is_none(), "already have hash for {:?}", dep_node);
-        }
-
         Ok(())
     }
 }
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index 6d717d6f409..01db756f9de 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -255,9 +255,11 @@ pub fn encode_metadata_hashes(tcx: TyCtxt,
                               current_metadata_hashes: &mut FxHashMap<DefId, Fingerprint>,
                               encoder: &mut Encoder)
                               -> io::Result<()> {
+    assert_eq!(metadata_hashes.hashes.len(),
+        metadata_hashes.hashes.iter().map(|x| (x.def_index, ())).collect::<FxHashMap<_,_>>().len());
+
     let mut serialized_hashes = SerializedMetadataHashes {
-        entry_hashes: metadata_hashes.entry_hashes.to_vec(),
-        global_hashes: metadata_hashes.global_hashes.to_vec(),
+        entry_hashes: metadata_hashes.hashes.to_vec(),
         index_map: FxHashMap()
     };
 
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 51f152991fd..c1b57a543a4 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -14,8 +14,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
 use locator::{self, CratePaths};
 use schema::{CrateRoot, Tracked};
 
-use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
-use rustc::hir::def_id::{DefId, CrateNum, DefIndex, CRATE_DEF_INDEX};
+use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::DepKind;
 use rustc::session::Session;
@@ -516,14 +515,11 @@ impl<'a> CrateLoader<'a> {
             return cstore::CrateNumMap::new();
         }
 
-        let dep_node = DepNode::GlobalMetaData(DefId { krate, index: CRATE_DEF_INDEX },
-                                               GlobalMetaDataKind::CrateDeps);
-
         // The map from crate numbers in the crate we're resolving to local crate numbers.
         // We map 0 and all other holes in the map to our parent crate. The "additional"
         // self-dependencies should be harmless.
         ::std::iter::once(krate).chain(crate_root.crate_deps
-                                                 .get(&self.sess.dep_graph, dep_node)
+                                                 .get_untracked()
                                                  .decode(metadata)
                                                  .map(|dep| {
             debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 5066b927c11..ed67616e58f 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -13,9 +13,9 @@
 
 use schema::{self, Tracked};
 
-use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
+use rustc::dep_graph::DepGraph;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
-use rustc::hir::map::definitions::DefPathTable;
+use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
 use rustc_back::PanicStrategy;
@@ -304,12 +304,7 @@ impl CrateMetadata {
     }
 
     pub fn panic_strategy(&self, dep_graph: &DepGraph) -> PanicStrategy {
-        let def_id = DefId {
-            krate: self.cnum,
-            index: CRATE_DEF_INDEX,
-        };
-        let dep_node = DepNode::GlobalMetaData(def_id, GlobalMetaDataKind::Krate);
-
+        let dep_node = self.metadata_dep_node(GlobalMetaDataKind::Krate);
         self.root
             .panic_strategy
             .get(dep_graph, dep_node)
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index dcc55846b53..60cc03f7b79 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -23,9 +23,9 @@ use rustc::ty::{self, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 
-use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
+use rustc::dep_graph::{DepNode};
 use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData, DefPathHash};
-use rustc::hir::map::definitions::DefPathTable;
+use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
 use rustc::util::nodemap::{NodeSet, DefIdMap};
 use rustc_back::PanicStrategy;
 
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 91470f238ec..a095fdd5084 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -13,8 +13,9 @@
 use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
 use schema::*;
 
-use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind};
+use rustc::dep_graph::{DepGraph, DepNode};
 use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
+use rustc::hir::map::definitions::GlobalMetaDataKind;
 use rustc::hir;
 
 use rustc::middle::cstore::LinkagePreference;
@@ -993,12 +994,8 @@ impl<'a, 'tcx> CrateMetadata {
     pub fn get_dylib_dependency_formats(&self,
                                         dep_graph: &DepGraph)
                                         -> Vec<(CrateNum, LinkagePreference)> {
-        let def_id = DefId {
-            krate: self.cnum,
-            index: CRATE_DEF_INDEX,
-        };
-        let dep_node = DepNode::GlobalMetaData(def_id,
-                                               GlobalMetaDataKind::DylibDependencyFormats);
+        let dep_node =
+            self.metadata_dep_node(GlobalMetaDataKind::DylibDependencyFormats);
         self.root
             .dylib_dependency_formats
             .get(dep_graph, dep_node)
@@ -1198,11 +1195,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     pub fn metadata_dep_node(&self, kind: GlobalMetaDataKind) -> DepNode<DefId> {
-        let def_id = DefId {
-            krate: self.cnum,
-            index: CRATE_DEF_INDEX,
-        };
-
-        DepNode::GlobalMetaData(def_id, kind)
+        let def_index = kind.def_index(&self.def_path_table);
+        DepNode::MetaData(self.local_def_id(def_index))
     }
 }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index a02a82dfe69..2a504c4c077 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -14,10 +14,10 @@ use isolated_encoder::IsolatedEncoder;
 use schema::*;
 
 use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary,
-                            EncodedMetadata, EncodedMetadataHashes};
+                            EncodedMetadata, EncodedMetadataHashes,
+                            EncodedMetadataHash};
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE};
-use rustc::hir::map::definitions::DefPathTable;
-use rustc::dep_graph::{DepNode, GlobalMetaDataKind};
+use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
 use rustc::ich::Fingerprint;
 use rustc::middle::dependency_format::Linkage;
 use rustc::middle::lang_items;
@@ -244,7 +244,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     // Encodes something that corresponds to a single DepNode::GlobalMetaData
     // and registers the Fingerprint in the `metadata_hashes` map.
     pub fn tracked<'x, DATA, R>(&'x mut self,
-                                dep_node: DepNode<()>,
+                                def_index: DefIndex,
                                 op: fn(&mut IsolatedEncoder<'x, 'a, 'tcx>, DATA) -> R,
                                 data: DATA)
                                 -> Tracked<R> {
@@ -253,7 +253,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let (fingerprint, this) = entry_builder.finish();
 
         if let Some(fingerprint) = fingerprint {
-            this.metadata_hashes.global_hashes.push((dep_node, fingerprint));
+            this.metadata_hashes.hashes.push(EncodedMetadataHash {
+                def_index,
+                hash: fingerprint,
+            })
         }
 
         Tracked::new(ret)
@@ -322,12 +325,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
         let mut i = self.position();
 
+        let tcx = self.tcx;
+        let global_metadata_def_index = move |kind: GlobalMetaDataKind| {
+            kind.def_index(tcx.hir.definitions().def_path_table())
+        };
+
         let crate_deps = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::CrateDeps),
+            global_metadata_def_index(GlobalMetaDataKind::CrateDeps),
             IsolatedEncoder::encode_crate_deps,
             ());
         let dylib_dependency_formats = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::DylibDependencyFormats),
+            global_metadata_def_index(GlobalMetaDataKind::DylibDependencyFormats),
             IsolatedEncoder::encode_dylib_dependency_formats,
             ());
         let dep_bytes = self.position() - i;
@@ -335,12 +343,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // Encode the language items.
         i = self.position();
         let lang_items = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::LangItems),
+            global_metadata_def_index(GlobalMetaDataKind::LangItems),
             IsolatedEncoder::encode_lang_items,
             ());
 
         let lang_items_missing = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::LangItemsMissing),
+            global_metadata_def_index(GlobalMetaDataKind::LangItemsMissing),
             IsolatedEncoder::encode_lang_items_missing,
             ());
         let lang_item_bytes = self.position() - i;
@@ -348,7 +356,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // Encode the native libraries used
         i = self.position();
         let native_libraries = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::NativeLibraries),
+            global_metadata_def_index(GlobalMetaDataKind::NativeLibraries),
             IsolatedEncoder::encode_native_libraries,
             ());
         let native_lib_bytes = self.position() - i;
@@ -366,7 +374,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // Encode the def IDs of impls, for coherence checking.
         i = self.position();
         let impls = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::Impls),
+            global_metadata_def_index(GlobalMetaDataKind::Impls),
             IsolatedEncoder::encode_impls,
             ());
         let impl_bytes = self.position() - i;
@@ -374,7 +382,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         // Encode exported symbols info.
         i = self.position();
         let exported_symbols = self.tracked(
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::ExportedSymbols),
+            global_metadata_def_index(GlobalMetaDataKind::ExportedSymbols),
             IsolatedEncoder::encode_exported_symbols,
             self.exported_symbols);
         let exported_symbols_bytes = self.position() - i;
@@ -422,10 +430,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let total_bytes = self.position();
 
-        self.metadata_hashes.global_hashes.push((
-            DepNode::GlobalMetaData((), GlobalMetaDataKind::Krate),
-            Fingerprint::from_smaller_hash(link_meta.crate_hash.as_u64())
-        ));
+        self.metadata_hashes.hashes.push(EncodedMetadataHash {
+            def_index: global_metadata_def_index(GlobalMetaDataKind::Krate),
+            hash: Fingerprint::from_smaller_hash(link_meta.crate_hash.as_u64())
+        });
 
         if self.tcx.sess.meta_stats() {
             let mut zero_bytes = 0;
diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs
index 478202aeba4..2db9c6a4ff8 100644
--- a/src/librustc_metadata/index_builder.rs
+++ b/src/librustc_metadata/index_builder.rs
@@ -135,7 +135,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
 
         let (fingerprint, ecx) = entry_builder.finish();
         if let Some(hash) = fingerprint {
-            ecx.metadata_hashes.entry_hashes.push(EncodedMetadataHash {
+            ecx.metadata_hashes.hashes.push(EncodedMetadataHash {
                 def_index: id.index,
                 hash: hash,
             });