Rollup merge of #140713 - compiler-errors:check_ref_cast, r=lcnr

Structurally resolve in `check_ref_cast` in new solver

Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/203

r? lcnr
This commit is contained in:
Jacob Pratt 2025-05-07 00:29:25 +00:00 committed by GitHub
commit 3d8ef7afca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 8 deletions

View File

@ -1051,20 +1051,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
fn check_ref_cast(
&self,
fcx: &FnCtxt<'a, 'tcx>,
m_expr: ty::TypeAndMut<'tcx>,
m_cast: ty::TypeAndMut<'tcx>,
mut m_expr: ty::TypeAndMut<'tcx>,
mut m_cast: ty::TypeAndMut<'tcx>,
) -> Result<CastKind, CastError<'tcx>> {
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
m_expr.ty = fcx.try_structurally_resolve_type(self.expr_span, m_expr.ty);
m_cast.ty = fcx.try_structurally_resolve_type(self.cast_span, m_cast.ty);
if m_expr.mutbl >= m_cast.mutbl
&& let ty::Array(ety, _) = m_expr.ty.kind()
&& fcx.can_eq(fcx.param_env, *ety, m_cast.ty)
{
// Due to the limitations of LLVM global constants,
// region pointers end up pointing at copies of
// vector elements instead of the original values.
// To allow raw pointers to work correctly, we
// need to special-case obtaining a raw pointer
// from a region pointer to a vector.
// Due to historical reasons we allow directly casting references of
// arrays into raw pointers of their element type.
// Coerce to a raw pointer so that we generate RawPtr in MIR.
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);

View File

@ -0,0 +1,22 @@
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/203>.
// Test that we structually normalize in the hacky `&[T; N] -> *const T` in cast.
trait Mirror {
type Assoc: ?Sized;
}
impl<T: ?Sized> Mirror for T {
type Assoc = T;
}
struct W<'a>(&'a <[f32; 0] as Mirror>::Assoc);
fn foo(x: W<'_>) -> *const f32 {
x.0 as *const f32
}
fn main() {}