diff options
| author | Michael Woerister <michaelwoerister@posteo> | 2017-09-14 17:40:37 +0200 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo> | 2017-09-20 11:21:25 +0200 |
| commit | 3b75a3dfeaf8261bd59343792b3650550be86c95 (patch) | |
| tree | 61d2b82a1873d96daf3c85c7fe312c114adbcc8e | |
| parent | 54996837a399421f8d691c6901eea5ab20a30f46 (diff) | |
| download | rust-3b75a3dfeaf8261bd59343792b3650550be86c95.tar.gz rust-3b75a3dfeaf8261bd59343792b3650550be86c95.zip | |
incr.comp.: Make sure traits_in_scope results are hashed in a stable way.
| -rw-r--r-- | src/librustc/ich/hcx.rs | 5 | ||||
| -rw-r--r-- | src/librustc/ich/impls_hir.rs | 19 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 17 | ||||
| -rw-r--r-- | src/librustc/ty/maps/mod.rs | 3 | ||||
| -rw-r--r-- | src/librustc_data_structures/stable_hasher.rs | 32 |
5 files changed, 67 insertions, 9 deletions
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 64fc63002da..36d2454eacc 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -169,6 +169,11 @@ impl<'gcx> StableHashingContext<'gcx> { } #[inline] + pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId { + self.definitions.node_to_hir_id(node_id) + } + + #[inline] pub fn hash_spans(&self) -> bool { self.hash_spans } diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 9582b03ce1c..ee4e2536e46 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1160,6 +1160,25 @@ for hir::TraitCandidate { } } +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::TraitCandidate { + type KeyType = (DefPathHash, Option<(DefPathHash, hir::ItemLocalId)>); + + fn to_stable_hash_key(&self, + hcx: &StableHashingContext<'gcx>) + -> Self::KeyType { + let hir::TraitCandidate { + def_id, + import_id, + } = *self; + + let import_id = import_id.map(|node_id| hcx.node_to_hir_id(node_id)) + .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), + hir_id.local_id)); + (hcx.def_path_hash(def_id), import_id) + } +} + + impl_stable_hash_for!(struct hir::Freevar { def, span diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 874bb426dc5..cccdaed6eca 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -50,8 +50,8 @@ use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap}; use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, - StableHasher, StableHasherResult}; - + StableHasher, StableHasherResult, + StableVec}; use arena::{TypedArena, DroplessArena}; use rustc_const_math::{ConstInt, ConstUsize}; use rustc_data_structures::indexed_vec::IndexVec; @@ -828,7 +828,9 @@ pub struct GlobalCtxt<'tcx> { /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. - trait_map: FxHashMap<DefIndex, Rc<FxHashMap<ItemLocalId, Rc<Vec<TraitCandidate>>>>>, + trait_map: FxHashMap<DefIndex, + Rc<FxHashMap<ItemLocalId, + Rc<StableVec<TraitCandidate>>>>>, /// Export map produced by name resolution. export_map: FxHashMap<DefId, Rc<Vec<Export>>>, @@ -1081,15 +1083,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { None }; - // FIXME(mw): Each of the Vecs in the trait_map should be brought into - // a deterministic order here. Otherwise we might end up with - // unnecessarily unstable incr. comp. hashes. let mut trait_map = FxHashMap(); for (k, v) in resolutions.trait_map { let hir_id = hir.node_to_hir_id(k); let map = trait_map.entry(hir_id.owner) .or_insert_with(|| Rc::new(FxHashMap())); - Rc::get_mut(map).unwrap().insert(hir_id.local_id, Rc::new(v)); + Rc::get_mut(map).unwrap() + .insert(hir_id.local_id, + Rc::new(StableVec::new(v))); } let mut defs = FxHashMap(); for (k, v) in named_region_map.defs { @@ -2103,7 +2104,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { lint::struct_lint_level(self.sess, lint, level, src, None, msg) } - pub fn in_scope_traits(self, id: HirId) -> Option<Rc<Vec<TraitCandidate>>> { + pub fn in_scope_traits(self, id: HirId) -> Option<Rc<StableVec<TraitCandidate>>> { self.in_scope_traits_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) } diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index c08ad68eddd..7a8cecbf812 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -42,6 +42,7 @@ use rustc_data_structures::indexed_set::IdxSetBuf; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::StableVec; use std::cell::{RefCell, Cell}; use std::ops::Deref; @@ -259,7 +260,7 @@ define_maps! { <'tcx> [] fn specializes: specializes_node((DefId, DefId)) -> bool, [] fn in_scope_traits_map: InScopeTraits(DefIndex) - -> Option<Rc<FxHashMap<ItemLocalId, Rc<Vec<TraitCandidate>>>>>, + -> Option<Rc<FxHashMap<ItemLocalId, Rc<StableVec<TraitCandidate>>>>>, [] fn module_exports: ModuleExports(DefId) -> Option<Rc<Vec<Export>>>, [] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>, diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index f6b23af2f73..a5df250b338 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -558,3 +558,35 @@ pub fn hash_stable_hashmap<HCX, K, V, R, SK, F, W>( entries.hash_stable(hcx, hasher); } +pub struct StableVec<T>(Vec<T>); + +impl<T> StableVec<T> { + + pub fn new(v: Vec<T>) -> Self { + StableVec(v) + } +} + +impl<T> ::std::ops::Deref for StableVec<T> { + type Target = Vec<T>; + + fn deref(&self) -> &Vec<T> { + &self.0 + } +} + +impl<T, HCX> HashStable<HCX> for StableVec<T> + where T: HashStable<HCX> + ToStableHashKey<HCX> +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut HCX, + hasher: &mut StableHasher<W>) { + let StableVec(ref v) = *self; + + let mut sorted: Vec<_> = v.iter() + .map(|x| x.to_stable_hash_key(hcx)) + .collect(); + sorted.sort_unstable(); + sorted.hash_stable(hcx, hasher); + } +} |
