Ensure the canonical_param_env_cache does not contain inconsistent information about the defining anchor
This commit is contained in:
parent
c8dfb59406
commit
dc97b1eb58
@ -42,10 +42,9 @@ pub fn canonicalize_query<V>(
|
||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let (param_env, value) = value.into_parts();
|
||||
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
|
||||
let mut param_env = self.tcx.canonical_param_env_cache.get_or_insert(
|
||||
self.tcx,
|
||||
param_env,
|
||||
self.defining_opaque_types,
|
||||
query_state,
|
||||
|tcx, param_env, query_state| {
|
||||
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
|
||||
@ -60,6 +59,8 @@ pub fn canonicalize_query<V>(
|
||||
},
|
||||
);
|
||||
|
||||
param_env.defining_opaque_types = self.defining_opaque_types;
|
||||
|
||||
Canonicalizer::canonicalize_with_base(
|
||||
param_env,
|
||||
value,
|
||||
@ -611,6 +612,9 @@ fn canonicalize_with_base<U, V>(
|
||||
.max()
|
||||
.unwrap_or(ty::UniverseIndex::ROOT);
|
||||
|
||||
assert!(
|
||||
!infcx.is_some_and(|infcx| infcx.defining_opaque_types != base.defining_opaque_types)
|
||||
);
|
||||
Canonical {
|
||||
max_universe,
|
||||
variables: canonical_variables,
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_type_ir::Canonical as IrCanonical;
|
||||
use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo;
|
||||
@ -312,7 +311,6 @@ pub fn get_or_insert(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnv<'tcx>,
|
||||
defining_opaque_types: &'tcx ty::List<LocalDefId>,
|
||||
state: &mut OriginalQueryValues<'tcx>,
|
||||
canonicalize_op: fn(
|
||||
TyCtxt<'tcx>,
|
||||
@ -327,7 +325,7 @@ pub fn get_or_insert(
|
||||
max_universe: ty::UniverseIndex::ROOT,
|
||||
variables: List::empty(),
|
||||
value: key,
|
||||
defining_opaque_types,
|
||||
defining_opaque_types: ty::List::empty(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -338,12 +336,19 @@ pub fn get_or_insert(
|
||||
match self.map.borrow().entry(key) {
|
||||
Entry::Occupied(e) => {
|
||||
let (canonical, var_values) = e.get();
|
||||
if cfg!(debug_assertions) {
|
||||
let mut state = state.clone();
|
||||
let rerun_canonical = canonicalize_op(tcx, key, &mut state);
|
||||
assert_eq!(rerun_canonical, *canonical);
|
||||
let OriginalQueryValues { var_values: rerun_var_values, universe_map } = state;
|
||||
assert_eq!(universe_map.len(), 1);
|
||||
assert_eq!(**var_values, *rerun_var_values);
|
||||
}
|
||||
state.var_values.extend_from_slice(var_values);
|
||||
*canonical
|
||||
}
|
||||
Entry::Vacant(e) => {
|
||||
let mut canonical = canonicalize_op(tcx, key, state);
|
||||
canonical.defining_opaque_types = defining_opaque_types;
|
||||
let canonical = canonicalize_op(tcx, key, state);
|
||||
let OriginalQueryValues { var_values, universe_map } = state;
|
||||
assert_eq!(universe_map.len(), 1);
|
||||
e.insert((canonical, tcx.arena.alloc_slice(var_values)));
|
||||
|
27
tests/ui/impl-trait/different_where_bounds.rs
Normal file
27
tests/ui/impl-trait/different_where_bounds.rs
Normal file
@ -0,0 +1,27 @@
|
||||
//! This test checks that the param env canonicalization cache
|
||||
//! does not end up with inconsistent values.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
pub fn poison1() -> impl Sized
|
||||
where
|
||||
(): 'static,
|
||||
{
|
||||
}
|
||||
pub fn poison2() -> impl Sized
|
||||
where
|
||||
(): 'static,
|
||||
{
|
||||
define_by_query((poison2, ()));
|
||||
}
|
||||
pub fn poison3() -> impl Sized
|
||||
where
|
||||
(): 'static,
|
||||
{
|
||||
}
|
||||
|
||||
trait Query {}
|
||||
impl<Out, F: Fn() -> Out> Query for (F, Out) {}
|
||||
fn define_by_query(_: impl Query) {}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user