diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-08-20 11:52:01 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-08-20 11:52:01 -0400 |
| commit | 0595a3a8fa762af28caf4cec9eecd59ea3003163 (patch) | |
| tree | 1ffad9698c595e0f147034724429d87df335cbe0 /src | |
| parent | 6bd80d11163771293ea7bf75a4513af76b754a41 (diff) | |
| download | rust-0595a3a8fa762af28caf4cec9eecd59ea3003163.tar.gz rust-0595a3a8fa762af28caf4cec9eecd59ea3003163.zip | |
hash the traits-in-scope determinstically
Experimentally, this fixes the poor re-use observed in libsyntex-syntax. I'm not sure how to make a regression test for this, though, given the non-deterministic nature of it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_incremental/calculate_svh/svh_visitor.rs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index c06b223ce21..1e00e0fc562 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -25,25 +25,33 @@ use rustc::hir::def::{Def, PathResolution}; use rustc::hir::def_id::DefId; use rustc::hir::intravisit as visit; use rustc::hir::intravisit::{Visitor, FnKind}; -use rustc::hir::map::DefPath; use rustc::ty::TyCtxt; +use rustc::util::nodemap::DefIdMap; use std::hash::{Hash, SipHasher}; pub struct StrictVersionHashVisitor<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub st: &'a mut SipHasher, + + // collect a deterministic hash of def-ids that we have seen + def_id_hashes: DefIdMap<u64>, } impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> { pub fn new(st: &'a mut SipHasher, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { - StrictVersionHashVisitor { st: st, tcx: tcx } + StrictVersionHashVisitor { st: st, tcx: tcx, def_id_hashes: DefIdMap() } } - fn hash_def_path(&mut self, path: &DefPath) { - path.deterministic_hash_to(self.tcx, self.st); + fn compute_def_id_hash(&mut self, def_id: DefId) -> u64 { + let tcx = self.tcx; + *self.def_id_hashes.entry(def_id) + .or_insert_with(|| { + let def_path = tcx.def_path(def_id); + def_path.deterministic_hash(tcx) + }) } } @@ -376,15 +384,22 @@ impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> { if let Some(traits) = self.tcx.trait_map.get(&id) { debug!("hash_resolve: id={:?} traits={:?} st={:?}", id, traits, self.st); traits.len().hash(self.st); - for candidate in traits { - self.hash_def_id(candidate.def_id); - } + + // The ordering of the candidates is not fixed. So we hash + // the def-ids and then sort them and hash the collection. + let mut candidates: Vec<_> = + traits.iter() + .map(|&TraitCandidate { def_id, import_id: _ }| { + self.compute_def_id_hash(def_id) + }) + .collect(); + candidates.sort(); + candidates.hash(self.st); } } fn hash_def_id(&mut self, def_id: DefId) { - let def_path = self.tcx.def_path(def_id); - self.hash_def_path(&def_path); + self.compute_def_id_hash(def_id).hash(self.st); } fn hash_partial_def(&mut self, def: &PathResolution) { |
