diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index caf36ba47bd75..5bfc3e810d9fd 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -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> { // 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); diff --git a/tests/ui/cast/cast-alias-of-array-to-element.rs b/tests/ui/cast/cast-alias-of-array-to-element.rs new file mode 100644 index 0000000000000..124d0e0346f07 --- /dev/null +++ b/tests/ui/cast/cast-alias-of-array-to-element.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Regression test for . +// Test that we structually normalize in the hacky `&[T; N] -> *const T` in cast. + +trait Mirror { + type Assoc: ?Sized; +} +impl 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() {}