Auto merge of #43743 - michaelwoerister:gcx-tcx-switcheroo, r=eddyb
Some assorted region hashing fixes. This PR contains three changes. 1. It changes what we implement `HashStable` for. Previously, the trait was implemented for things in the local `TyCtxt`. That was OK, since we only invoked hashing with a `TyCtxt<'_, 'tcx, 'tcx>` where there is no difference. With query result hashing this becomes a problem though. So we now implement `HashStable` for things in `'gcx`. 2. The PR makes the regular `HashStable` implementation *not* anonymize late-bound regions anymore. It's a waste of computing resources and it's not clear that it would always be correct to do so. 3. The PR adds an option for stable hashing to treat all regions as erased and uses this new option when computing the `TypeId`. This should help with https://github.com/rust-lang/rust/issues/41875. I did not add a test case for (3) since that's not possible yet. But it looks like @zackmdavis has something in the pipeline there `:)`. r? @eddyb
This commit is contained in:
commit
73c3f55a3e
@ -33,7 +33,7 @@ impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
|
||||
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::Terminator<'tcx> {
|
||||
for mir::Terminator<'gcx> {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
@ -125,7 +125,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::P
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::TerminatorKind<'tcx> {
|
||||
for mir::TerminatorKind<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -186,7 +186,7 @@ for mir::TerminatorKind<'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::AssertMessage<'tcx> {
|
||||
for mir::AssertMessage<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -207,7 +207,7 @@ for mir::AssertMessage<'tcx> {
|
||||
impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::StatementKind<'tcx> {
|
||||
for mir::StatementKind<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -244,7 +244,7 @@ for mir::StatementKind<'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::ValidationOperand<'tcx, T>
|
||||
for mir::ValidationOperand<'gcx, T>
|
||||
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
@ -260,7 +260,7 @@ impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
|
||||
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(extent) });
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::L
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::Projection<'tcx, B, V, T>
|
||||
for mir::Projection<'gcx, B, V, T>
|
||||
where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
|
||||
V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
|
||||
T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
@ -299,7 +299,7 @@ for mir::Projection<'tcx, B, V, T>
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::ProjectionElem<'tcx, V, T>
|
||||
for mir::ProjectionElem<'gcx, V, T>
|
||||
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
|
||||
T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
{
|
||||
@ -335,7 +335,7 @@ for mir::ProjectionElem<'tcx, V, T>
|
||||
|
||||
impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -352,7 +352,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::O
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -413,7 +413,7 @@ impl_stable_hash_for!(enum mir::CastKind {
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for mir::AggregateKind<'tcx> {
|
||||
for mir::AggregateKind<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -469,7 +469,7 @@ impl_stable_hash_for!(enum mir::NullOp {
|
||||
|
||||
impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
|
@ -20,7 +20,7 @@ use syntax_pos::symbol::InternedString;
|
||||
use ty;
|
||||
|
||||
impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for &'tcx ty::Slice<T>
|
||||
for &'gcx ty::Slice<T>
|
||||
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
@ -30,7 +30,7 @@ for &'tcx ty::Slice<T>
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::subst::Kind<'tcx> {
|
||||
for ty::subst::Kind<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -55,6 +55,11 @@ for ty::RegionKind {
|
||||
db.depth.hash_stable(hcx, hasher);
|
||||
i.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
|
||||
db.depth.hash_stable(hcx, hasher);
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
name.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
index.hash_stable(hcx, hasher);
|
||||
@ -76,7 +81,7 @@ for ty::RegionKind {
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::adjustment::AutoBorrow<'tcx> {
|
||||
for ty::adjustment::AutoBorrow<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -94,7 +99,7 @@ for ty::adjustment::AutoBorrow<'tcx> {
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::adjustment::Adjust<'tcx> {
|
||||
for ty::adjustment::Adjust<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -128,7 +133,7 @@ impl_stable_hash_for!(enum ty::BorrowKind {
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::UpvarCapture<'tcx> {
|
||||
for ty::UpvarCapture<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -150,12 +155,13 @@ impl_stable_hash_for!(struct ty::FnSig<'tcx> {
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Binder<T>
|
||||
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + ty::fold::TypeFoldable<'tcx>
|
||||
where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
hcx.tcx().anonymize_late_bound_regions(self).0.hash_stable(hcx, hasher);
|
||||
let ty::Binder(ref inner) = *self;
|
||||
inner.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +196,7 @@ impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty }
|
||||
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
|
||||
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Predicate<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Predicate<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -256,7 +262,7 @@ impl_stable_hash_for!(struct ty::FieldDef {
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ::middle::const_val::ConstVal<'tcx> {
|
||||
for ::middle::const_val::ConstVal<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -483,7 +489,7 @@ impl_stable_hash_for!(enum ty::BoundRegion {
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::TypeVariants<'tcx>
|
||||
for ty::TypeVariants<'gcx>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
@ -574,7 +580,7 @@ impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::ExistentialPredicate<'tcx>
|
||||
for ty::ExistentialPredicate<'gcx>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
@ -607,7 +613,7 @@ impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
|
||||
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
|
||||
for ty::TypeckTables<'tcx> {
|
||||
for ty::TypeckTables<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
@ -687,7 +693,7 @@ impl_stable_hash_for!(struct ty::Instance<'tcx> {
|
||||
substs
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::InstanceDef<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::InstanceDef<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
|
@ -73,10 +73,10 @@ macro_rules! __impl_stable_hash_field {
|
||||
#[macro_export]
|
||||
macro_rules! impl_stable_hash_for {
|
||||
(enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => {
|
||||
impl<'a, 'gcx, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'gcx, 'tcx>> for $enum_name {
|
||||
impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $enum_name {
|
||||
#[inline]
|
||||
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
||||
__ctx: &mut $crate::ich::StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
__ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>,
|
||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
||||
use $enum_name::*;
|
||||
::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
|
||||
@ -92,10 +92,10 @@ macro_rules! impl_stable_hash_for {
|
||||
}
|
||||
};
|
||||
(struct $struct_name:path { $($field:ident),* }) => {
|
||||
impl<'a, 'gcx, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'gcx, 'tcx>> for $struct_name {
|
||||
impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $struct_name {
|
||||
#[inline]
|
||||
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
||||
__ctx: &mut $crate::ich::StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
__ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>,
|
||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
||||
let $struct_name {
|
||||
$(ref $field),*
|
||||
@ -106,10 +106,10 @@ macro_rules! impl_stable_hash_for {
|
||||
}
|
||||
};
|
||||
(tuple_struct $struct_name:path { $($field:ident),* }) => {
|
||||
impl<'a, 'gcx, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'gcx, 'tcx>> for $struct_name {
|
||||
impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $struct_name {
|
||||
#[inline]
|
||||
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
||||
__ctx: &mut $crate::ich::StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
__ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>,
|
||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
||||
let $struct_name (
|
||||
$(ref $field),*
|
||||
@ -125,11 +125,11 @@ macro_rules! impl_stable_hash_for {
|
||||
macro_rules! impl_stable_hash_for_spanned {
|
||||
($T:path) => (
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ::syntax::codemap::Spanned<$T>
|
||||
impl<'a, 'tcx, 'lcx> HashStable<StableHashingContext<'a, 'tcx, 'lcx>> for ::syntax::codemap::Spanned<$T>
|
||||
{
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hcx: &mut StableHashingContext<'a, 'tcx, 'lcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
self.node.hash_stable(hcx, hasher);
|
||||
self.span.hash_stable(hcx, hasher);
|
||||
|
@ -498,7 +498,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TyS<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TyS<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
|
@ -214,6 +214,11 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
let mut hasher = StableHasher::new();
|
||||
let mut hcx = StableHashingContext::new(self);
|
||||
|
||||
// We want the type_id be independent of the types free regions, so we
|
||||
// erase them. The erase_regions() call will also anonymize bound
|
||||
// regions, which is desirable too.
|
||||
let ty = self.erase_regions(&ty);
|
||||
|
||||
hcx.while_hashing_spans(false, |hcx| {
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
ty.hash_stable(hcx, &mut hasher);
|
||||
|
@ -45,6 +45,11 @@ fn main() {
|
||||
assert!(g != h);
|
||||
assert!(g != i);
|
||||
assert!(h != i);
|
||||
|
||||
// Make sure lifetime anonymization handles nesting correctly
|
||||
let j = TypeId::of::<fn(for<'a> fn(&'a isize) -> &'a usize)>();
|
||||
let k = TypeId::of::<fn(for<'b> fn(&'b isize) -> &'b usize)>();
|
||||
assert_eq!(j, k);
|
||||
}
|
||||
// Boxed unboxed closures
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user