about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2021-09-19 22:07:12 +0200
committerCamille GILLOT <gillot.camille@gmail.com>2021-10-10 00:05:49 +0200
commit0431fdb11312ae324c73e4dab1e5be5c45164678 (patch)
tree39aae5d9d2e9ea4bb171848f327abf4dfd9e0e29
parent41e80b85cf05e6373b589b876d3ee65823196406 (diff)
downloadrust-0431fdb11312ae324c73e4dab1e5be5c45164678.tar.gz
rust-0431fdb11312ae324c73e4dab1e5be5c45164678.zip
Compute full HIR hash during lowering.
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs23
-rw-r--r--compiler/rustc_hir/src/hir.rs3
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs18
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs45
-rw-r--r--compiler/rustc_middle/src/query/mod.rs1
-rw-r--r--compiler/rustc_query_system/src/ich/impls_hir.rs36
6 files changed, 69 insertions, 57 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 9ba3d0446dd..84aeb78a0aa 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -399,6 +399,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             hir::OwnerNode::Crate(lctx.arena.alloc(module))
         });
 
+        let hir_hash = self.compute_hir_hash();
+
         let mut def_id_to_hir_id = IndexVec::default();
 
         for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
@@ -412,10 +414,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
 
-        let krate = hir::Crate { owners: self.owners };
+        let krate = hir::Crate { owners: self.owners, hir_hash };
         self.arena.alloc(krate)
     }
 
+    fn compute_hir_hash(&mut self) -> Fingerprint {
+        let definitions = self.resolver.definitions();
+        let mut hir_body_nodes: Vec<_> = self
+            .owners
+            .iter_enumerated()
+            .filter_map(|(def_id, info)| {
+                let info = info.as_ref()?;
+                let def_path_hash = definitions.def_path_hash(def_id);
+                Some((def_path_hash, info))
+            })
+            .collect();
+        hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
+
+        let mut stable_hasher = StableHasher::new();
+        let mut hcx = self.resolver.create_stable_hashing_context();
+        hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
+        stable_hasher.finish()
+    }
+
     fn with_hir_id_owner(
         &mut self,
         owner: NodeId,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index bb5c0bc1889..6cbea732c99 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -702,7 +702,7 @@ pub struct OwnerNodes<'tcx> {
     pub bodies: IndexVec<ItemLocalId, Option<&'tcx Body<'tcx>>>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, HashStable_Generic)]
 pub struct OwnerInfo<'hir> {
     /// Contents of the HIR.
     pub nodes: OwnerNodes<'hir>,
@@ -734,6 +734,7 @@ impl<'tcx> OwnerInfo<'tcx> {
 #[derive(Debug)]
 pub struct Crate<'hir> {
     pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
+    pub hir_hash: Fingerprint,
 }
 
 /// A block of statements `{ .. }`, which may have a label (in this case the
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index da2aeb9b311..3c9fe93b67d 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -1,8 +1,8 @@
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
 
 use crate::hir::{
-    AttributeMap, BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId,
-    Mod, OwnerNodes, TraitItem, TraitItemId, Ty, VisibilityKind,
+    AttributeMap, BodyId, Crate, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item,
+    ItemId, Mod, OwnerNodes, TraitCandidate, TraitItem, TraitItemId, Ty, VisibilityKind,
 };
 use crate::hir_id::{HirId, ItemLocalId};
 use rustc_span::def_id::DefPathHash;
@@ -21,6 +21,7 @@ pub trait HashStableContext:
     fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
     fn hash_hir_visibility_kind(&mut self, _: &VisibilityKind<'_>, hasher: &mut StableHasher);
     fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F);
+    fn hash_hir_trait_candidate(&mut self, _: &TraitCandidate, hasher: &mut StableHasher);
 }
 
 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
@@ -227,3 +228,16 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx>
         hash.hash_stable(hcx, hasher);
     }
 }
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        let Crate { owners: _, hir_hash } = self;
+        hir_hash.hash_stable(hcx, hasher)
+    }
+}
+
+impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitCandidate {
+    fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
+        hcx.hash_hir_trait_candidate(self, hasher)
+    }
+}
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index af4c0e4843d..c8d6ecf6940 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1066,18 +1066,8 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
 
 pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
     debug_assert_eq!(crate_num, LOCAL_CRATE);
-    let mut hir_body_nodes: Vec<_> = tcx
-        .untracked_resolutions
-        .definitions
-        .def_path_table()
-        .all_def_path_hashes_and_def_ids()
-        .filter_map(|(def_path_hash, local_def_index)| {
-            let def_id = LocalDefId { local_def_index };
-            let hash = tcx.hir_crate(()).owners[def_id].as_ref()?.nodes.hash;
-            Some((def_path_hash, hash, def_id))
-        })
-        .collect();
-    hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
+    let krate = tcx.hir_crate(());
+    let hir_body_hash = krate.hir_hash;
 
     let upstream_crates = upstream_crates(tcx);
 
@@ -1099,22 +1089,25 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
 
     let mut hcx = tcx.create_stable_hashing_context();
     let mut stable_hasher = StableHasher::new();
-    for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
-        def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);
-        fingerprint.hash_stable(&mut hcx, &mut stable_hasher);
-        tcx.untracked_crate.owners[*def_id]
-            .as_ref()
-            .unwrap()
-            .attrs
-            .hash_stable(&mut hcx, &mut stable_hasher);
-        if tcx.sess.opts.debugging_opts.incremental_relative_spans {
-            let span = tcx.untracked_resolutions.definitions.def_span(*def_id);
-            debug_assert_eq!(span.parent(), None);
-            span.hash_stable(&mut hcx, &mut stable_hasher);
-        }
-    }
+    hir_body_hash.hash_stable(&mut hcx, &mut stable_hasher);
     upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
     source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
+    if tcx.sess.opts.debugging_opts.incremental_relative_spans {
+        let definitions = &tcx.untracked_resolutions.definitions;
+        let mut owner_spans: Vec<_> = krate
+            .owners
+            .iter_enumerated()
+            .filter_map(|(def_id, info)| {
+                let _ = info.as_ref()?;
+                let def_path_hash = definitions.def_path_hash(def_id);
+                let span = definitions.def_span(def_id);
+                debug_assert_eq!(span.parent(), None);
+                Some((def_path_hash, span))
+            })
+            .collect();
+        owner_spans.sort_unstable_by_key(|bn| bn.0);
+        owner_spans.hash_stable(&mut hcx, &mut stable_hasher);
+    }
     tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
     tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher);
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index eb4cc7c750c..4ffe76fed1c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -36,7 +36,6 @@ rustc_queries! {
     /// prefer wrappers like `tcx.visit_all_items_in_krate()`.
     query hir_crate(key: ()) -> &'tcx Crate<'tcx> {
         eval_always
-        no_hash
         desc { "get the crate HIR" }
     }
 
diff --git a/compiler/rustc_query_system/src/ich/impls_hir.rs b/compiler/rustc_query_system/src/ich/impls_hir.rs
index dc208b36f93..24f3a2e7de0 100644
--- a/compiler/rustc_query_system/src/ich/impls_hir.rs
+++ b/compiler/rustc_query_system/src/ich/impls_hir.rs
@@ -6,8 +6,6 @@ use crate::ich::{NodeIdHashingMode, StableHashingContext};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
 use rustc_hir as hir;
-use rustc_hir::definitions::DefPathHash;
-use smallvec::SmallVec;
 use std::mem;
 
 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
@@ -121,6 +119,16 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
 
         self.node_id_hashing_mode = prev_hash_node_ids;
     }
+
+    #[inline]
+    fn hash_hir_trait_candidate(&mut self, tc: &hir::TraitCandidate, hasher: &mut StableHasher) {
+        self.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            let hir::TraitCandidate { def_id, import_ids } = tc;
+
+            def_id.hash_stable(hcx, hasher);
+            import_ids.hash_stable(hcx, hasher);
+        });
+    }
 }
 
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
@@ -135,27 +143,3 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
         });
     }
 }
-
-impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
-            let hir::TraitCandidate { def_id, import_ids } = self;
-
-            def_id.hash_stable(hcx, hasher);
-            import_ids.hash_stable(hcx, hasher);
-        });
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
-    type KeyType = (DefPathHash, SmallVec<[DefPathHash; 1]>);
-
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
-        let hir::TraitCandidate { def_id, import_ids } = self;
-
-        (
-            hcx.def_path_hash(*def_id),
-            import_ids.iter().map(|def_id| hcx.local_def_path_hash(*def_id)).collect(),
-        )
-    }
-}