mirror of https://github.com/rust-lang/rust.git
Auto merge of #94487 - oli-obk:stable_hash_ty, r=fee1-dead
Also cache the stable hash of interned Predicates continuation of https://github.com/rust-lang/rust/pull/94299 This is a small perf improvement and shares more code between `Ty` and `Predicate`
This commit is contained in:
commit
bddad597fe
|
@ -89,7 +89,7 @@ macro_rules! arena_types {
|
||||||
|
|
||||||
// Interned types
|
// Interned types
|
||||||
[] tys: rustc_data_structures::intern::WithStableHash<rustc_middle::ty::TyS<'tcx>>,
|
[] tys: rustc_data_structures::intern::WithStableHash<rustc_middle::ty::TyS<'tcx>>,
|
||||||
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
|
[] predicates: rustc_data_structures::intern::WithStableHash<rustc_middle::ty::PredicateS<'tcx>>,
|
||||||
[] consts: rustc_middle::ty::ConstS<'tcx>,
|
[] consts: rustc_middle::ty::ConstS<'tcx>,
|
||||||
|
|
||||||
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
||||||
|
|
|
@ -142,7 +142,7 @@ pub struct CtxtInterners<'tcx> {
|
||||||
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
|
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
|
||||||
region: InternedSet<'tcx, RegionKind<'tcx>>,
|
region: InternedSet<'tcx, RegionKind<'tcx>>,
|
||||||
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
|
poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>,
|
||||||
predicate: InternedSet<'tcx, PredicateS<'tcx>>,
|
predicate: InternedSet<'tcx, WithStableHash<PredicateS<'tcx>>>,
|
||||||
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
|
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
|
||||||
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
||||||
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
||||||
|
@ -190,20 +190,8 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||||
self.type_
|
self.type_
|
||||||
.intern(kind, |kind| {
|
.intern(kind, |kind| {
|
||||||
let flags = super::flags::FlagComputation::for_kind(&kind);
|
let flags = super::flags::FlagComputation::for_kind(&kind);
|
||||||
|
let stable_hash =
|
||||||
// It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
|
self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind);
|
||||||
// Without incremental, we rarely stable-hash types, so let's not do it proactively.
|
|
||||||
let stable_hash = if flags.flags.intersects(TypeFlags::NEEDS_INFER)
|
|
||||||
|| sess.opts.incremental.is_none()
|
|
||||||
{
|
|
||||||
Fingerprint::ZERO
|
|
||||||
} else {
|
|
||||||
let mut hasher = StableHasher::new();
|
|
||||||
let mut hcx =
|
|
||||||
StableHashingContext::new(sess, definitions, cstore, source_span);
|
|
||||||
kind.hash_stable(&mut hcx, &mut hasher);
|
|
||||||
hasher.finish()
|
|
||||||
};
|
|
||||||
|
|
||||||
let ty_struct = TyS {
|
let ty_struct = TyS {
|
||||||
kind,
|
kind,
|
||||||
|
@ -219,20 +207,54 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stable_hash<'a, T: HashStable<StableHashingContext<'a>>>(
|
||||||
|
&self,
|
||||||
|
flags: &ty::flags::FlagComputation,
|
||||||
|
sess: &'a Session,
|
||||||
|
definitions: &'a rustc_hir::definitions::Definitions,
|
||||||
|
cstore: &'a CrateStoreDyn,
|
||||||
|
source_span: &'a IndexVec<LocalDefId, Span>,
|
||||||
|
val: &T,
|
||||||
|
) -> Fingerprint {
|
||||||
|
// It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them.
|
||||||
|
// Without incremental, we rarely stable-hash types, so let's not do it proactively.
|
||||||
|
if flags.flags.intersects(TypeFlags::NEEDS_INFER) || sess.opts.incremental.is_none() {
|
||||||
|
Fingerprint::ZERO
|
||||||
|
} else {
|
||||||
|
let mut hasher = StableHasher::new();
|
||||||
|
let mut hcx = StableHashingContext::new(sess, definitions, cstore, source_span);
|
||||||
|
val.hash_stable(&mut hcx, &mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
fn intern_predicate(
|
||||||
|
&self,
|
||||||
|
kind: Binder<'tcx, PredicateKind<'tcx>>,
|
||||||
|
sess: &Session,
|
||||||
|
definitions: &rustc_hir::definitions::Definitions,
|
||||||
|
cstore: &CrateStoreDyn,
|
||||||
|
source_span: &IndexVec<LocalDefId, Span>,
|
||||||
|
) -> Predicate<'tcx> {
|
||||||
Predicate(Interned::new_unchecked(
|
Predicate(Interned::new_unchecked(
|
||||||
self.predicate
|
self.predicate
|
||||||
.intern(kind, |kind| {
|
.intern(kind, |kind| {
|
||||||
let flags = super::flags::FlagComputation::for_predicate(kind);
|
let flags = super::flags::FlagComputation::for_predicate(kind);
|
||||||
|
|
||||||
|
let stable_hash =
|
||||||
|
self.stable_hash(&flags, sess, definitions, cstore, source_span, &kind);
|
||||||
|
|
||||||
let predicate_struct = PredicateS {
|
let predicate_struct = PredicateS {
|
||||||
kind,
|
kind,
|
||||||
flags: flags.flags,
|
flags: flags.flags,
|
||||||
outer_exclusive_binder: flags.outer_exclusive_binder,
|
outer_exclusive_binder: flags.outer_exclusive_binder,
|
||||||
};
|
};
|
||||||
|
|
||||||
InternedInSet(self.arena.alloc(predicate_struct))
|
InternedInSet(
|
||||||
|
self.arena
|
||||||
|
.alloc(WithStableHash { internee: predicate_struct, stable_hash }),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.0,
|
.0,
|
||||||
))
|
))
|
||||||
|
@ -2168,23 +2190,25 @@ impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash<TyS<'tcx>>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateS<'tcx>> {
|
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>>
|
||||||
|
for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>>
|
||||||
|
{
|
||||||
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
|
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
|
||||||
&self.0.kind
|
&self.0.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateS<'tcx>> {
|
impl<'tcx> PartialEq for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>> {
|
||||||
fn eq(&self, other: &InternedInSet<'tcx, PredicateS<'tcx>>) -> bool {
|
fn eq(&self, other: &InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>>) -> bool {
|
||||||
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
|
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
|
||||||
// `x == y`.
|
// `x == y`.
|
||||||
self.0.kind == other.0.kind
|
self.0.kind == other.0.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Eq for InternedInSet<'tcx, PredicateS<'tcx>> {}
|
impl<'tcx> Eq for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>> {}
|
||||||
|
|
||||||
impl<'tcx> Hash for InternedInSet<'tcx, PredicateS<'tcx>> {
|
impl<'tcx> Hash for InternedInSet<'tcx, WithStableHash<PredicateS<'tcx>>> {
|
||||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||||
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
|
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
|
||||||
self.0.kind.hash(s)
|
self.0.kind.hash(s)
|
||||||
|
@ -2386,7 +2410,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
||||||
self.interners.intern_predicate(binder)
|
self.interners.intern_predicate(
|
||||||
|
binder,
|
||||||
|
self.sess,
|
||||||
|
&self.definitions.read(),
|
||||||
|
&*self.untracked_resolutions.cstore,
|
||||||
|
// This is only used to create a stable hashing context.
|
||||||
|
&self.untracked_resolutions.source_span,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -548,9 +548,9 @@ pub(crate) struct PredicateS<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this rather than `PredicateS`, whenever possible.
|
/// Use this rather than `PredicateS`, whenever possible.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
|
||||||
#[rustc_pass_by_value]
|
#[rustc_pass_by_value]
|
||||||
pub struct Predicate<'tcx>(Interned<'tcx, PredicateS<'tcx>>);
|
pub struct Predicate<'tcx>(Interned<'tcx, WithStableHash<PredicateS<'tcx>>>);
|
||||||
|
|
||||||
impl<'tcx> Predicate<'tcx> {
|
impl<'tcx> Predicate<'tcx> {
|
||||||
/// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
|
/// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
|
||||||
|
@ -631,7 +631,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for PredicateS<'tcx> {
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
let PredicateS {
|
let PredicateS {
|
||||||
ref kind,
|
ref kind,
|
||||||
|
@ -640,7 +640,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
||||||
// also contained in `kind`, so no need to hash them.
|
// also contained in `kind`, so no need to hash them.
|
||||||
flags: _,
|
flags: _,
|
||||||
outer_exclusive_binder: _,
|
outer_exclusive_binder: _,
|
||||||
} = self.0.0;
|
} = self;
|
||||||
|
|
||||||
kind.hash_stable(hcx, hasher);
|
kind.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue