1
Fork 0

Move stable hash from TyS into a datastructure that can be shared with other interned types.

This commit is contained in:
Oli Scherer 2022-03-01 14:51:08 +00:00
parent df20355fa9
commit 00c24dd8ce
8 changed files with 140 additions and 64 deletions

View file

@ -31,8 +31,8 @@ use crate::ty::util::Discr;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::{HashStable, NodeIdHashingMode, StableHasher};
use rustc_data_structures::intern::{InTy, Interned};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@ -433,32 +433,28 @@ crate struct TyS<'tcx> {
/// De Bruijn indices within the type are contained within `0..D`
/// (exclusive).
outer_exclusive_binder: ty::DebruijnIndex,
/// The stable hash of the type. This way hashing of types will not have to work
/// on the address of the type anymore, but can instead just read this field
stable_hash: Fingerprint,
}
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(TyS<'_>, 56);
static_assert_size!(TyS<'_>, 40);
/// Use this rather than `TyS`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[rustc_diagnostic_item = "Ty"]
#[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
pub struct Ty<'tcx>(Interned<'tcx, InTy<TyS<'tcx>>>);
// Statics only used for internal testing.
pub static BOOL_TY: Ty<'static> = Ty(Interned::new_unchecked(&BOOL_TYS));
static BOOL_TYS: TyS<'static> = TyS {
pub static BOOL_TY: Ty<'static> =
Ty(Interned::new_unchecked(&InTy { internee: BOOL_TYS, stable_hash: Fingerprint::ZERO }));
const BOOL_TYS: TyS<'static> = TyS {
kind: ty::Bool,
flags: TypeFlags::empty(),
outer_exclusive_binder: DebruijnIndex::from_usize(0),
stable_hash: Fingerprint::ZERO,
};
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Ty<'tcx> {
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
let TyS {
kind,
@ -468,28 +464,9 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Ty<'tcx> {
flags: _,
outer_exclusive_binder: _,
} = self;
stable_hash,
} = self.0.0;
if *stable_hash == Fingerprint::ZERO {
// No cached hash available. This can only mean that incremental is disabled.
// We don't cache stable hashes in non-incremental mode, because they are used
// so rarely that the performance actually suffers.
let stable_hash: Fingerprint = {
let mut hasher = StableHasher::new();
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
kind.hash_stable(hcx, &mut hasher)
})
});
hasher.finish()
};
stable_hash.hash_stable(hcx, hasher);
} else {
stable_hash.hash_stable(hcx, hasher);
}
kind.hash_stable(hcx, hasher)
}
}