Skip to content

Commit dc97b1e

Browse files
committed
Ensure the canonical_param_env_cache does not contain inconsistent information about the defining anchor
1 parent c8dfb59 commit dc97b1e

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,9 @@ impl<'tcx> InferCtxt<'tcx> {
4242
V: TypeFoldable<TyCtxt<'tcx>>,
4343
{
4444
let (param_env, value) = value.into_parts();
45-
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
45+
let mut param_env = self.tcx.canonical_param_env_cache.get_or_insert(
4646
self.tcx,
4747
param_env,
48-
self.defining_opaque_types,
4948
query_state,
5049
|tcx, param_env, query_state| {
5150
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
@@ -60,6 +59,8 @@ impl<'tcx> InferCtxt<'tcx> {
6059
},
6160
);
6261

62+
param_env.defining_opaque_types = self.defining_opaque_types;
63+
6364
Canonicalizer::canonicalize_with_base(
6465
param_env,
6566
value,
@@ -611,6 +612,9 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
611612
.max()
612613
.unwrap_or(ty::UniverseIndex::ROOT);
613614

615+
assert!(
616+
!infcx.is_some_and(|infcx| infcx.defining_opaque_types != base.defining_opaque_types)
617+
);
614618
Canonical {
615619
max_universe,
616620
variables: canonical_variables,

compiler/rustc_middle/src/infer/canonical.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
2424
use rustc_data_structures::fx::FxHashMap;
2525
use rustc_data_structures::sync::Lock;
26-
use rustc_hir::def_id::LocalDefId;
2726
use rustc_macros::HashStable;
2827
use rustc_type_ir::Canonical as IrCanonical;
2928
use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo;
@@ -312,7 +311,6 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
312311
&self,
313312
tcx: TyCtxt<'tcx>,
314313
key: ty::ParamEnv<'tcx>,
315-
defining_opaque_types: &'tcx ty::List<LocalDefId>,
316314
state: &mut OriginalQueryValues<'tcx>,
317315
canonicalize_op: fn(
318316
TyCtxt<'tcx>,
@@ -327,7 +325,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
327325
max_universe: ty::UniverseIndex::ROOT,
328326
variables: List::empty(),
329327
value: key,
330-
defining_opaque_types,
328+
defining_opaque_types: ty::List::empty(),
331329
};
332330
}
333331

@@ -338,12 +336,19 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
338336
match self.map.borrow().entry(key) {
339337
Entry::Occupied(e) => {
340338
let (canonical, var_values) = e.get();
339+
if cfg!(debug_assertions) {
340+
let mut state = state.clone();
341+
let rerun_canonical = canonicalize_op(tcx, key, &mut state);
342+
assert_eq!(rerun_canonical, *canonical);
343+
let OriginalQueryValues { var_values: rerun_var_values, universe_map } = state;
344+
assert_eq!(universe_map.len(), 1);
345+
assert_eq!(**var_values, *rerun_var_values);
346+
}
341347
state.var_values.extend_from_slice(var_values);
342348
*canonical
343349
}
344350
Entry::Vacant(e) => {
345-
let mut canonical = canonicalize_op(tcx, key, state);
346-
canonical.defining_opaque_types = defining_opaque_types;
351+
let canonical = canonicalize_op(tcx, key, state);
347352
let OriginalQueryValues { var_values, universe_map } = state;
348353
assert_eq!(universe_map.len(), 1);
349354
e.insert((canonical, tcx.arena.alloc_slice(var_values)));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! This test checks that the param env canonicalization cache
2+
//! does not end up with inconsistent values.
3+
4+
//@ check-pass
5+
6+
pub fn poison1() -> impl Sized
7+
where
8+
(): 'static,
9+
{
10+
}
11+
pub fn poison2() -> impl Sized
12+
where
13+
(): 'static,
14+
{
15+
define_by_query((poison2, ()));
16+
}
17+
pub fn poison3() -> impl Sized
18+
where
19+
(): 'static,
20+
{
21+
}
22+
23+
trait Query {}
24+
impl<Out, F: Fn() -> Out> Query for (F, Out) {}
25+
fn define_by_query(_: impl Query) {}
26+
27+
fn main() {}

0 commit comments

Comments
 (0)