mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-24 22:44:26 +00:00
incr.comp.: Make sure traits_in_scope results are hashed in a stable way.
This commit is contained in:
parent
54996837a3
commit
3b75a3dfea
@ -168,6 +168,11 @@ impl<'gcx> StableHashingContext<'gcx> {
|
|||||||
self.definitions.def_path_hash(def_index)
|
self.definitions.def_path_hash(def_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
|
||||||
|
self.definitions.node_to_hir_id(node_id)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hash_spans(&self) -> bool {
|
pub fn hash_spans(&self) -> bool {
|
||||||
self.hash_spans
|
self.hash_spans
|
||||||
|
@ -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 {
|
impl_stable_hash_for!(struct hir::Freevar {
|
||||||
def,
|
def,
|
||||||
span
|
span
|
||||||
|
@ -50,8 +50,8 @@ use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap};
|
|||||||
use util::nodemap::{FxHashMap, FxHashSet};
|
use util::nodemap::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
|
use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
|
||||||
StableHasher, StableHasherResult};
|
StableHasher, StableHasherResult,
|
||||||
|
StableVec};
|
||||||
use arena::{TypedArena, DroplessArena};
|
use arena::{TypedArena, DroplessArena};
|
||||||
use rustc_const_math::{ConstInt, ConstUsize};
|
use rustc_const_math::{ConstInt, ConstUsize};
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
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
|
/// Map indicating what traits are in scope for places where this
|
||||||
/// is relevant; generated by resolve.
|
/// 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 produced by name resolution.
|
||||||
export_map: FxHashMap<DefId, Rc<Vec<Export>>>,
|
export_map: FxHashMap<DefId, Rc<Vec<Export>>>,
|
||||||
@ -1081,15 +1083,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
None
|
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();
|
let mut trait_map = FxHashMap();
|
||||||
for (k, v) in resolutions.trait_map {
|
for (k, v) in resolutions.trait_map {
|
||||||
let hir_id = hir.node_to_hir_id(k);
|
let hir_id = hir.node_to_hir_id(k);
|
||||||
let map = trait_map.entry(hir_id.owner)
|
let map = trait_map.entry(hir_id.owner)
|
||||||
.or_insert_with(|| Rc::new(FxHashMap()));
|
.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();
|
let mut defs = FxHashMap();
|
||||||
for (k, v) in named_region_map.defs {
|
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)
|
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)
|
self.in_scope_traits_map(id.owner)
|
||||||
.and_then(|map| map.get(&id.local_id).cloned())
|
.and_then(|map| map.get(&id.local_id).cloned())
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ use rustc_data_structures::indexed_set::IdxSetBuf;
|
|||||||
use rustc_back::PanicStrategy;
|
use rustc_back::PanicStrategy;
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
use rustc_data_structures::stable_hasher::StableVec;
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@ -259,7 +260,7 @@ define_maps! { <'tcx>
|
|||||||
|
|
||||||
[] fn specializes: specializes_node((DefId, DefId)) -> bool,
|
[] fn specializes: specializes_node((DefId, DefId)) -> bool,
|
||||||
[] fn in_scope_traits_map: InScopeTraits(DefIndex)
|
[] 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 module_exports: ModuleExports(DefId) -> Option<Rc<Vec<Export>>>,
|
||||||
[] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>,
|
[] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>,
|
||||||
|
|
||||||
|
@ -558,3 +558,35 @@ pub fn hash_stable_hashmap<HCX, K, V, R, SK, F, W>(
|
|||||||
entries.hash_stable(hcx, hasher);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user