Skip to content

Commit

Permalink
Ensure the canonical_param_env_cache does not contain inconsistent in…
Browse files Browse the repository at this point in the history
…formation about the defining anchor
  • Loading branch information
oli-obk committed Apr 2, 2024
1 parent 4cde24d commit 52ab386
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
8 changes: 6 additions & 2 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ impl<'tcx> InferCtxt<'tcx> {
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
Expand All @@ -60,6 +59,8 @@ impl<'tcx> InferCtxt<'tcx> {
},
);

param_env.defining_opaque_types = self.defining_opaque_types;

Canonicalizer::canonicalize_with_base(
param_env,
value,
Expand Down Expand Up @@ -611,6 +612,9 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
.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,
Expand Down
15 changes: 10 additions & 5 deletions compiler/rustc_middle/src/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -312,7 +311,6 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
key: ty::ParamEnv<'tcx>,
defining_opaque_types: &'tcx ty::List<LocalDefId>,
state: &mut OriginalQueryValues<'tcx>,
canonicalize_op: fn(
TyCtxt<'tcx>,
Expand All @@ -327,7 +325,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
max_universe: ty::UniverseIndex::ROOT,
variables: List::empty(),
value: key,
defining_opaque_types,
defining_opaque_types: ty::List::empty(),
};
}

Expand All @@ -338,12 +336,19 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
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)));
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/impl-trait/different_where_bounds.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 52ab386

Please sign in to comment.