diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index ad958c1f282e7..35e2b38e1ab55 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Unnormalized, Variance}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypingEnv, Unnormalized, Variance}; use rustc_trait_selection::traits::ObligationCtxt; /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. @@ -43,5 +43,10 @@ pub fn relate_types<'tcx>( Ok(()) => {} Err(_) => return false, }; - ocx.evaluate_obligations_error_on_ambiguity().is_empty() + + if ocx.evaluate_obligations_error_on_ambiguity().is_empty() { + infcx.leak_check(ty::UniverseIndex::ROOT, None).is_ok() + } else { + false + } } diff --git a/tests/ui/consts/const-eval/equal-up-to-leak-check-different-layout.rs b/tests/ui/consts/const-eval/equal-up-to-leak-check-different-layout.rs new file mode 100644 index 0000000000000..e986c2a80a53f --- /dev/null +++ b/tests/ui/consts/const-eval/equal-up-to-leak-check-different-layout.rs @@ -0,0 +1,33 @@ +//@ check-pass + +// Regression test for #155477. We previously didn't detect higher-ranked region +// errors when checking whether types are equal in `rustc_const_eval::relate_types`, that +// then caused us to trigger an assert that equal types have the same layout. + +use std::mem::transmute; + +type F1 = for<'a> fn(&'a ()); +type F2 = fn(&'static ()); + +trait Trait { + type Assoc; +} + +impl Trait for F1 { + type Assoc = i64; +} +#[expect(coherence_leak_check)] +impl Trait for F2 { + type Assoc = [i32; 2]; +} + +struct Thing(T::Assoc); + +const fn foo(x: Thing) -> Thing { + // This transmute is legal: The two types have the same size. + unsafe { transmute(x) } +} + +fn main() { + const { foo(Thing(1i64)); } +}