about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs27
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_middle/src/hir/map/collector.rs29
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
4 files changed, 35 insertions, 28 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 80b95b99b16..f95ad9f3a9b 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -41,7 +41,9 @@ use rustc_ast::visit;
 use rustc_ast::{self as ast, *};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::captures::Captures;
+use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{struct_span_err, Applicability};
 use rustc_hir as hir;
@@ -467,7 +469,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
         }
 
-        hir::OwnerInfo { node, attrs, bodies, trait_map }
+        let (hash, node_hash) = self.hash_body(node, &bodies);
+
+        hir::OwnerInfo { hash, node_hash, node, attrs, bodies, trait_map }
+    }
+
+    /// Hash the HIR node twice, one deep and one shallow hash.  This allows to differentiate
+    /// queries which depend on the full HIR tree and those which only depend on the item signature.
+    fn hash_body(
+        &mut self,
+        node: hir::OwnerNode<'hir>,
+        bodies: &IndexVec<hir::ItemLocalId, Option<&'hir hir::Body<'hir>>>,
+    ) -> (Fingerprint, Fingerprint) {
+        let mut hcx = self.resolver.create_stable_hashing_context();
+        let mut stable_hasher = StableHasher::new();
+        hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
+            node.hash_stable(hcx, &mut stable_hasher)
+        });
+        let full_hash = stable_hasher.finish();
+        let mut stable_hasher = StableHasher::new();
+        hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
+            node.hash_stable(hcx, &mut stable_hasher)
+        });
+        let node_hash = stable_hasher.finish();
+        (full_hash, node_hash)
     }
 
     /// This method allocates a new `HirId` for the given `NodeId` and stores it in
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1d1c0a0de13..44652d0198f 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -9,6 +9,7 @@ use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, TraitObject
 pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
 pub use rustc_ast::{CaptureBy, Movability, Mutability};
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::vec::IndexVec;
 use rustc_macros::HashStable_Generic;
@@ -670,6 +671,10 @@ pub struct OwnerInfo<'hir> {
     /// Map indicating what traits are in scope for places where this
     /// is relevant; generated by resolve.
     pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
+    /// Pre-computed hash of the full HIR.
+    pub hash: Fingerprint,
+    /// Pre-computed hash of the top node.
+    pub node_hash: Fingerprint,
 }
 
 /// The top-level data structure that stores the entire contents of
diff --git a/compiler/rustc_middle/src/hir/map/collector.rs b/compiler/rustc_middle/src/hir/map/collector.rs
index 80e48a4f74b..2499ef8bc60 100644
--- a/compiler/rustc_middle/src/hir/map/collector.rs
+++ b/compiler/rustc_middle/src/hir/map/collector.rs
@@ -1,9 +1,7 @@
 use crate::arena::Arena;
 use crate::hir::map::Map;
 use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
-use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::def_id::CRATE_DEF_ID;
@@ -11,7 +9,6 @@ use rustc_hir::definitions;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::*;
 use rustc_index::vec::{Idx, IndexVec};
-use rustc_query_system::ich::StableHashingContext;
 use rustc_session::Session;
 use rustc_span::source_map::SourceMap;
 use rustc_span::{Span, DUMMY_SP};
@@ -37,8 +34,6 @@ pub(super) struct NodeCollector<'a, 'hir> {
     current_dep_node_owner: LocalDefId,
 
     definitions: &'a definitions::Definitions,
-
-    hcx: StableHashingContext<'a>,
 }
 
 fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
@@ -51,27 +46,12 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
     map[k] = Some(v);
 }
 
-fn hash_body<'s, 'hir: 's>(
-    hcx: &mut StableHashingContext<'s>,
-    item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
-    hash_bodies: bool,
-    owner: LocalDefId,
-    bodies: &'hir IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
-) -> Fingerprint {
-    let mut stable_hasher = StableHasher::new();
-    hcx.with_hir_bodies(hash_bodies, owner, bodies, |hcx| {
-        item_like.hash_stable(hcx, &mut stable_hasher)
-    });
-    stable_hasher.finish()
-}
-
 impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
     pub(super) fn root(
         sess: &'a Session,
         arena: &'hir Arena<'hir>,
         krate: &'hir Crate<'hir>,
         definitions: &'a definitions::Definitions,
-        hcx: StableHashingContext<'a>,
     ) -> NodeCollector<'a, 'hir> {
         let mut collector = NodeCollector {
             arena,
@@ -80,7 +60,6 @@ impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
             parent_node: hir::CRATE_HIR_ID,
             current_dep_node_owner: CRATE_DEF_ID,
             definitions,
-            hcx,
             map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
             parenting: FxHashMap::default(),
         };
@@ -97,10 +76,10 @@ impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
         let mut nodes = IndexVec::new();
         nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
 
-        let bodies = &self.krate.owners[owner].as_ref().unwrap().bodies;
-
-        let hash = hash_body(&mut self.hcx, node, true, owner, bodies);
-        let node_hash = hash_body(&mut self.hcx, node, false, owner, bodies);
+        let info = self.krate.owners[owner].as_ref().unwrap();
+        let hash = info.hash;
+        let node_hash = info.node_hash;
+        let bodies = &info.bodies;
 
         debug_assert!(self.map[owner].is_none());
         self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, node_hash, nodes, bodies }));
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 8c11fd8a280..89f4ec4d9f6 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1071,13 +1071,11 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tc
     let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
 
     // We can access untracked state since we are an eval_always query.
-    let hcx = tcx.create_stable_hashing_context();
     let mut collector = NodeCollector::root(
         tcx.sess,
         &**tcx.arena,
         tcx.untracked_crate,
         &tcx.untracked_resolutions.definitions,
-        hcx,
     );
     let top_mod = tcx.untracked_crate.module();
     collector.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);