diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2024-04-02 13:07:13 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2024-04-08 15:08:06 +0000 |
| commit | dc97b1eb587fe2db207bfe8c2e914034ab9b9306 (patch) | |
| tree | 368577450fda42d73eb32d308388fec3a3a594a6 | |
| parent | c8dfb594061d129e3c7cef7cf4b15ab3c0ab5931 (diff) | |
| download | rust-dc97b1eb587fe2db207bfe8c2e914034ab9b9306.tar.gz rust-dc97b1eb587fe2db207bfe8c2e914034ab9b9306.zip | |
Ensure the canonical_param_env_cache does not contain inconsistent information about the defining anchor
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/canonicalizer.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/infer/canonical.rs | 15 | ||||
| -rw-r--r-- | tests/ui/impl-trait/different_where_bounds.rs | 27 |
3 files changed, 43 insertions, 7 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 9986fdfd15d..2cbf32dca98 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -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 @@ -60,6 +59,8 @@ impl<'tcx> InferCtxt<'tcx> { }, ); + param_env.defining_opaque_types = self.defining_opaque_types; + Canonicalizer::canonicalize_with_base( param_env, value, @@ -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, diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index fac132686f8..62d7b7c28d1 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -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 @@ 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>, @@ -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(), }; } @@ -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))); diff --git a/tests/ui/impl-trait/different_where_bounds.rs b/tests/ui/impl-trait/different_where_bounds.rs new file mode 100644 index 00000000000..87ae6db2822 --- /dev/null +++ b/tests/ui/impl-trait/different_where_bounds.rs @@ -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() {} |
