Skip to content

Commit 0595a3a

Browse files
committed
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.
1 parent 6bd80d1 commit 0595a3a

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

src/librustc_incremental/calculate_svh/svh_visitor.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,33 @@ use rustc::hir::def::{Def, PathResolution};
2525
use rustc::hir::def_id::DefId;
2626
use rustc::hir::intravisit as visit;
2727
use rustc::hir::intravisit::{Visitor, FnKind};
28-
use rustc::hir::map::DefPath;
2928
use rustc::ty::TyCtxt;
29+
use rustc::util::nodemap::DefIdMap;
3030

3131
use std::hash::{Hash, SipHasher};
3232

3333
pub struct StrictVersionHashVisitor<'a, 'tcx: 'a> {
3434
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
3535
pub st: &'a mut SipHasher,
36+
37+
// collect a deterministic hash of def-ids that we have seen
38+
def_id_hashes: DefIdMap<u64>,
3639
}
3740

3841
impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> {
3942
pub fn new(st: &'a mut SipHasher,
4043
tcx: TyCtxt<'a, 'tcx, 'tcx>)
4144
-> Self {
42-
StrictVersionHashVisitor { st: st, tcx: tcx }
45+
StrictVersionHashVisitor { st: st, tcx: tcx, def_id_hashes: DefIdMap() }
4346
}
4447

45-
fn hash_def_path(&mut self, path: &DefPath) {
46-
path.deterministic_hash_to(self.tcx, self.st);
48+
fn compute_def_id_hash(&mut self, def_id: DefId) -> u64 {
49+
let tcx = self.tcx;
50+
*self.def_id_hashes.entry(def_id)
51+
.or_insert_with(|| {
52+
let def_path = tcx.def_path(def_id);
53+
def_path.deterministic_hash(tcx)
54+
})
4755
}
4856
}
4957

@@ -376,15 +384,22 @@ impl<'a, 'tcx> StrictVersionHashVisitor<'a, 'tcx> {
376384
if let Some(traits) = self.tcx.trait_map.get(&id) {
377385
debug!("hash_resolve: id={:?} traits={:?} st={:?}", id, traits, self.st);
378386
traits.len().hash(self.st);
379-
for candidate in traits {
380-
self.hash_def_id(candidate.def_id);
381-
}
387+
388+
// The ordering of the candidates is not fixed. So we hash
389+
// the def-ids and then sort them and hash the collection.
390+
let mut candidates: Vec<_> =
391+
traits.iter()
392+
.map(|&TraitCandidate { def_id, import_id: _ }| {
393+
self.compute_def_id_hash(def_id)
394+
})
395+
.collect();
396+
candidates.sort();
397+
candidates.hash(self.st);
382398
}
383399
}
384400

385401
fn hash_def_id(&mut self, def_id: DefId) {
386-
let def_path = self.tcx.def_path(def_id);
387-
self.hash_def_path(&def_path);
402+
self.compute_def_id_hash(def_id).hash(self.st);
388403
}
389404

390405
fn hash_partial_def(&mut self, def: &PathResolution) {

0 commit comments

Comments
 (0)