Move stable hash from TyS into a datastructure that can be shared with other interned types.
This commit is contained in:
parent
df20355fa9
commit
00c24dd8ce
8 changed files with 140 additions and 64 deletions
|
@ -4,6 +4,8 @@ use std::hash::{Hash, Hasher};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
use crate::fingerprint::Fingerprint;
|
||||||
|
|
||||||
mod private {
|
mod private {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct PrivateZst;
|
pub struct PrivateZst;
|
||||||
|
@ -108,5 +110,76 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A helper trait so that `Interned` things can cache stable hashes reproducibly.
|
||||||
|
pub trait InternedHashingContext {
|
||||||
|
fn with_def_path_and_no_spans(&mut self, f: impl FnOnce(&mut Self));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct InTy<T> {
|
||||||
|
pub internee: T,
|
||||||
|
pub stable_hash: Fingerprint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: PartialEq> PartialEq for InTy<T> {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.internee.eq(&other.internee)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Eq> Eq for InTy<T> {}
|
||||||
|
|
||||||
|
impl<T: Ord> PartialOrd for InTy<T> {
|
||||||
|
fn partial_cmp(&self, other: &InTy<T>) -> Option<Ordering> {
|
||||||
|
Some(self.internee.cmp(&other.internee))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Ord> Ord for InTy<T> {
|
||||||
|
fn cmp(&self, other: &InTy<T>) -> Ordering {
|
||||||
|
self.internee.cmp(&other.internee)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for InTy<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
&self.internee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Hash> Hash for InTy<T> {
|
||||||
|
#[inline]
|
||||||
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||||
|
self.internee.hash(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: HashStable<CTX>, CTX: InternedHashingContext> HashStable<CTX> for InTy<T> {
|
||||||
|
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
|
let stable_hash = self.stable_hash;
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
// We need to build the hash as if we cached it and then hash that hash, as
|
||||||
|
// otherwise the hashes will differ between cached and non-cached mode.
|
||||||
|
let stable_hash: Fingerprint = {
|
||||||
|
let mut hasher = StableHasher::new();
|
||||||
|
hcx.with_def_path_and_no_spans(|hcx| self.internee.hash_stable(hcx, &mut hasher));
|
||||||
|
hasher.finish()
|
||||||
|
};
|
||||||
|
stable_hash.hash_stable(hcx, hasher);
|
||||||
|
} else {
|
||||||
|
stable_hash.hash_stable(hcx, hasher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
|
@ -87,7 +87,7 @@ macro_rules! arena_types {
|
||||||
[] hir_id_set: rustc_hir::HirIdSet,
|
[] hir_id_set: rustc_hir::HirIdSet,
|
||||||
|
|
||||||
// Interned types
|
// Interned types
|
||||||
[] tys: rustc_middle::ty::TyS<'tcx>,
|
[] tys: rustc_data_structures::intern::InTy<rustc_middle::ty::TyS<'tcx>>,
|
||||||
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
|
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
|
||||||
[] consts: rustc_middle::ty::ConstS<'tcx>,
|
[] consts: rustc_middle::ty::ConstS<'tcx>,
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::ty::{
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::{InTy, Interned};
|
||||||
use rustc_data_structures::memmap::Mmap;
|
use rustc_data_structures::memmap::Mmap;
|
||||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||||
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
||||||
|
@ -105,7 +105,7 @@ pub struct CtxtInterners<'tcx> {
|
||||||
|
|
||||||
// Specifically use a speedy hash algorithm for these hash sets, since
|
// Specifically use a speedy hash algorithm for these hash sets, since
|
||||||
// they're accessed quite often.
|
// they're accessed quite often.
|
||||||
type_: InternedSet<'tcx, TyS<'tcx>>,
|
type_: InternedSet<'tcx, InTy<TyS<'tcx>>>,
|
||||||
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
|
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
|
||||||
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
|
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
|
||||||
region: InternedSet<'tcx, RegionKind>,
|
region: InternedSet<'tcx, RegionKind>,
|
||||||
|
@ -178,10 +178,9 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||||
kind,
|
kind,
|
||||||
flags: flags.flags,
|
flags: flags.flags,
|
||||||
outer_exclusive_binder: flags.outer_exclusive_binder,
|
outer_exclusive_binder: flags.outer_exclusive_binder,
|
||||||
stable_hash,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
InternedInSet(self.arena.alloc(ty_struct))
|
InternedInSet(self.arena.alloc(InTy { internee: ty_struct, stable_hash }))
|
||||||
})
|
})
|
||||||
.0,
|
.0,
|
||||||
))
|
))
|
||||||
|
@ -2048,23 +2047,23 @@ impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(rustc::usage_of_ty_tykind)]
|
#[allow(rustc::usage_of_ty_tykind)]
|
||||||
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, TyS<'tcx>> {
|
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, InTy<TyS<'tcx>>> {
|
||||||
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
|
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
|
||||||
&self.0.kind
|
&self.0.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PartialEq for InternedInSet<'tcx, TyS<'tcx>> {
|
impl<'tcx> PartialEq for InternedInSet<'tcx, InTy<TyS<'tcx>>> {
|
||||||
fn eq(&self, other: &InternedInSet<'tcx, TyS<'tcx>>) -> bool {
|
fn eq(&self, other: &InternedInSet<'tcx, InTy<TyS<'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, TyS<'tcx>> {}
|
impl<'tcx> Eq for InternedInSet<'tcx, InTy<TyS<'tcx>>> {}
|
||||||
|
|
||||||
impl<'tcx> Hash for InternedInSet<'tcx, TyS<'tcx>> {
|
impl<'tcx> Hash for InternedInSet<'tcx, InTy<TyS<'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)
|
||||||
|
|
|
@ -31,8 +31,8 @@ use crate::ty::util::Discr;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::{InTy, Interned};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, NodeIdHashingMode, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
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`
|
/// De Bruijn indices within the type are contained within `0..D`
|
||||||
/// (exclusive).
|
/// (exclusive).
|
||||||
outer_exclusive_binder: ty::DebruijnIndex,
|
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.
|
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
#[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.
|
/// 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_diagnostic_item = "Ty"]
|
||||||
#[rustc_pass_by_value]
|
#[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.
|
// Statics only used for internal testing.
|
||||||
pub static BOOL_TY: Ty<'static> = Ty(Interned::new_unchecked(&BOOL_TYS));
|
pub static BOOL_TY: Ty<'static> =
|
||||||
static BOOL_TYS: TyS<'static> = TyS {
|
Ty(Interned::new_unchecked(&InTy { internee: BOOL_TYS, stable_hash: Fingerprint::ZERO }));
|
||||||
|
const BOOL_TYS: TyS<'static> = TyS {
|
||||||
kind: ty::Bool,
|
kind: ty::Bool,
|
||||||
flags: TypeFlags::empty(),
|
flags: TypeFlags::empty(),
|
||||||
outer_exclusive_binder: DebruijnIndex::from_usize(0),
|
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) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
let TyS {
|
let TyS {
|
||||||
kind,
|
kind,
|
||||||
|
@ -468,28 +464,9 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Ty<'tcx> {
|
||||||
flags: _,
|
flags: _,
|
||||||
|
|
||||||
outer_exclusive_binder: _,
|
outer_exclusive_binder: _,
|
||||||
|
} = self;
|
||||||
|
|
||||||
stable_hash,
|
kind.hash_stable(hcx, hasher)
|
||||||
} = 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||||
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
|
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_apfloat::ieee::{Double, Single};
|
use rustc_apfloat::ieee::{Double, Single};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::{InTy, Interned};
|
||||||
use rustc_data_structures::sso::SsoHashSet;
|
use rustc_data_structures::sso::SsoHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
|
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
|
||||||
|
@ -1266,18 +1266,29 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
ty::Ref(
|
ty::Ref(
|
||||||
_,
|
_,
|
||||||
Ty(Interned(
|
Ty(Interned(
|
||||||
ty::TyS {
|
InTy {
|
||||||
kind:
|
internee:
|
||||||
ty::Array(
|
ty::TyS {
|
||||||
Ty(Interned(ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, _)),
|
kind:
|
||||||
ty::Const(Interned(
|
ty::Array(
|
||||||
ty::ConstS {
|
Ty(Interned(
|
||||||
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
|
InTy {
|
||||||
..
|
internee:
|
||||||
},
|
ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. },
|
||||||
_,
|
..
|
||||||
)),
|
},
|
||||||
),
|
_,
|
||||||
|
)),
|
||||||
|
ty::Const(Interned(
|
||||||
|
ty::ConstS {
|
||||||
|
val: ty::ConstKind::Value(ConstValue::Scalar(int)),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
..
|
||||||
|
},
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
_,
|
_,
|
||||||
|
@ -1439,7 +1450,11 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
// Byte/string slices, printed as (byte) string literals.
|
// Byte/string slices, printed as (byte) string literals.
|
||||||
(
|
(
|
||||||
ConstValue::Slice { data, start, end },
|
ConstValue::Slice { data, start, end },
|
||||||
ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Slice(t), .. }, _)), _),
|
ty::Ref(
|
||||||
|
_,
|
||||||
|
Ty(Interned(InTy { internee: ty::TyS { kind: ty::Slice(t), .. }, .. }, _)),
|
||||||
|
_,
|
||||||
|
),
|
||||||
) if *t == u8_type => {
|
) if *t == u8_type => {
|
||||||
// The `inspect` here is okay since we checked the bounds, and there are
|
// The `inspect` here is okay since we checked the bounds, and there are
|
||||||
// no relocations (we have an active slice reference here). We don't use
|
// no relocations (we have an active slice reference here). We don't use
|
||||||
|
@ -1450,7 +1465,11 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
ConstValue::Slice { data, start, end },
|
ConstValue::Slice { data, start, end },
|
||||||
ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Str, .. }, _)), _),
|
ty::Ref(
|
||||||
|
_,
|
||||||
|
Ty(Interned(InTy { internee: ty::TyS { kind: ty::Str, .. }, .. }, _)),
|
||||||
|
_,
|
||||||
|
),
|
||||||
) => {
|
) => {
|
||||||
// The `inspect` here is okay since we checked the bounds, and there are no
|
// The `inspect` here is okay since we checked the bounds, and there are no
|
||||||
// relocations (we have an active `str` reference here). We don't use this
|
// relocations (we have an active `str` reference here). We don't use this
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor}
|
||||||
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
||||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||||
|
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::{InTy, Interned};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
use rustc_serialize::{self, Decodable, Encodable};
|
use rustc_serialize::{self, Decodable, Encodable};
|
||||||
|
@ -85,7 +85,7 @@ impl<'tcx> GenericArgKind<'tcx> {
|
||||||
GenericArgKind::Type(ty) => {
|
GenericArgKind::Type(ty) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(ty.0.0) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(ty.0.0) & TAG_MASK, 0);
|
||||||
(TYPE_TAG, ty.0.0 as *const ty::TyS<'tcx> as usize)
|
(TYPE_TAG, ty.0.0 as *const InTy<ty::TyS<'tcx>> as usize)
|
||||||
}
|
}
|
||||||
GenericArgKind::Const(ct) => {
|
GenericArgKind::Const(ct) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
|
@ -154,7 +154,7 @@ impl<'tcx> GenericArg<'tcx> {
|
||||||
&*((ptr & !TAG_MASK) as *const ty::RegionKind),
|
&*((ptr & !TAG_MASK) as *const ty::RegionKind),
|
||||||
))),
|
))),
|
||||||
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
|
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const ty::TyS<'tcx>),
|
&*((ptr & !TAG_MASK) as *const InTy<ty::TyS<'tcx>>),
|
||||||
))),
|
))),
|
||||||
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
|
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
|
&*((ptr & !TAG_MASK) as *const ty::ConstS<'tcx>),
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_apfloat::Float as _;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_attr::{self as attr, SignedInt, UnsignedInt};
|
use rustc_attr::{self as attr, SignedInt, UnsignedInt};
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::{InTy, Interned};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -427,7 +427,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
!impl_generics.region_param(ebr, self).pure_wrt_drop
|
!impl_generics.region_param(ebr, self).pure_wrt_drop
|
||||||
}
|
}
|
||||||
GenericArgKind::Type(Ty(Interned(
|
GenericArgKind::Type(Ty(Interned(
|
||||||
ty::TyS { kind: ty::Param(ref pt), .. },
|
InTy { internee: ty::TyS { kind: ty::Param(ref pt), .. }, .. },
|
||||||
_,
|
_,
|
||||||
))) => !impl_generics.type_param(pt, self).pure_wrt_drop,
|
))) => !impl_generics.type_param(pt, self).pure_wrt_drop,
|
||||||
GenericArgKind::Const(Const(Interned(
|
GenericArgKind::Const(Const(Interned(
|
||||||
|
|
|
@ -231,4 +231,12 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> rustc_data_structures::intern::InternedHashingContext for StableHashingContext<'a> {
|
||||||
|
fn with_def_path_and_no_spans(&mut self, f: impl FnOnce(&mut Self)) {
|
||||||
|
self.while_hashing_spans(false, |hcx| {
|
||||||
|
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| f(hcx))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}
|
impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue