use std::cell::RefCell;
use std::hash::Hash;
+use std::sync::Arc;
use rustc::dep_graph::DepNode;
use rustc::hir;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ich::{Fingerprint, StableHashingContext};
use rustc::ty::TyCtxt;
+use rustc::util::common::record_time;
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_data_structures::fx::FxHashMap;
-use rustc::util::common::record_time;
+use rustc_data_structures::accumulate_vec::AccumulateVec;
pub type IchHasher = StableHasher<Fingerprint>;
}
}
+ pub fn get(&self, k: &DepNode<DefId>) -> Option<&Fingerprint> {
+ self.hashes.get(k)
+ }
+
pub fn insert(&mut self, k: DepNode<DefId>, v: Fingerprint) -> Option<Fingerprint> {
self.hashes.insert(k, v)
}
item_like: T)
where T: HashStable<StableHashingContext<'a, 'tcx>>
{
+ if !hash_bodies && !self.hcx.tcx().sess.opts.build_dep_graph() {
+ // If we just need the hashes in order to compute the SVH, we don't
+ // need have two hashes per item. Just the one containing also the
+ // item's body is sufficient.
+ return
+ }
+
let mut hasher = IchHasher::new();
self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| {
item_like.hash_stable(hcx, &mut hasher);
let hcx = &mut self.hcx;
let mut item_hashes: Vec<_> =
self.hashes.iter()
- .map(|(item_dep_node, &item_hash)| {
- // convert from a DepNode<DefId> tp a
- // DepNode<u64> where the u64 is the
- // hash of the def-id's def-path:
- let item_dep_node =
- item_dep_node.map_def(|&did| Some(hcx.def_path_hash(did)))
- .unwrap();
- (item_dep_node, item_hash)
+ .filter_map(|(item_dep_node, &item_hash)| {
+ // This `match` determines what kinds of nodes
+ // go into the SVH:
+ match *item_dep_node {
+ DepNode::Hir(_) |
+ DepNode::HirBody(_) => {
+ // We want to incoporate these into the
+ // SVH.
+ }
+ DepNode::FileMap(..) => {
+ // These don't make a semantic
+ // difference, filter them out.
+ return None
+ }
+ DepNode::AllLocalTraitImpls => {
+ // These are already covered by hashing
+ // the HIR.
+ return None
+ }
+ ref other => {
+ bug!("Found unexpected DepNode during \
+ SVH computation: {:?}",
+ other)
+ }
+ }
+
+ // Convert from a DepNode<DefId> to a
+ // DepNode<u64> where the u64 is the hash of
+ // the def-id's def-path:
+ let item_dep_node =
+ item_dep_node.map_def(|&did| Some(hcx.def_path_hash(did)))
+ .unwrap();
+ Some((item_dep_node, item_hash))
})
.collect();
- item_hashes.sort(); // avoid artificial dependencies on item ordering
+ item_hashes.sort_unstable(); // avoid artificial dependencies on item ordering
item_hashes.hash(&mut crate_state);
}
true,
(module, (span, attrs)));
}
+
+ fn compute_and_store_ich_for_trait_impls(&mut self, krate: &'tcx hir::Crate)
+ {
+ let tcx = self.hcx.tcx();
+
+ let mut impls: Vec<(Fingerprint, Fingerprint)> = krate
+ .trait_impls
+ .iter()
+ .map(|(&trait_id, impls)| {
+ let trait_id = tcx.def_path_hash(trait_id);
+ let mut impls: AccumulateVec<[_; 32]> = impls
+ .iter()
+ .map(|&node_id| {
+ let def_id = tcx.hir.local_def_id(node_id);
+ tcx.def_path_hash(def_id)
+ })
+ .collect();
+
+ impls.sort_unstable();
+ let mut hasher = StableHasher::new();
+ impls.hash_stable(&mut self.hcx, &mut hasher);
+ (trait_id, hasher.finish())
+ })
+ .collect();
+
+ impls.sort_unstable();
+
+ let mut default_impls: AccumulateVec<[_; 32]> = krate
+ .trait_default_impl
+ .iter()
+ .map(|(&trait_def_id, &impl_node_id)| {
+ let impl_def_id = tcx.hir.local_def_id(impl_node_id);
+ (tcx.def_path_hash(trait_def_id), tcx.def_path_hash(impl_def_id))
+ })
+ .collect();
+
+ default_impls.sort_unstable();
+
+ let mut hasher = StableHasher::new();
+ impls.hash_stable(&mut self.hcx, &mut hasher);
+
+ self.hashes.insert(DepNode::AllLocalTraitImpls, hasher.finish());
+ }
}
impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> {
}
}
+
+
pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> IncrementalHashesMap {
let _ignore = tcx.dep_graph.in_ignore();
visitor.compute_and_store_ich_for_item_like(DepNode::Hir(def_id), false, macro_def);
visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def);
}
+
+ for filemap in tcx.sess
+ .codemap()
+ .files_untracked()
+ .iter()
+ .filter(|fm| !fm.is_imported()) {
+ assert_eq!(LOCAL_CRATE.as_u32(), filemap.crate_of_origin);
+ let def_id = DefId {
+ krate: LOCAL_CRATE,
+ index: CRATE_DEF_INDEX,
+ };
+ let name = Arc::new(filemap.name.clone());
+ let dep_node = DepNode::FileMap(def_id, name);
+ let mut hasher = IchHasher::new();
+ filemap.hash_stable(&mut visitor.hcx, &mut hasher);
+ let fingerprint = hasher.finish();
+ visitor.hashes.insert(dep_node, fingerprint);
+ }
+
+ visitor.compute_and_store_ich_for_trait_impls(krate);
});
tcx.sess.perf_stats.incr_comp_hashes_count.set(visitor.hashes.len() as u64);