about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-05-07 00:29:25 +0000
committerGitHub <noreply@github.com>2025-05-07 00:29:25 +0000
commit3d8ef7afcab3dd91b6234065b954ce83daa37f40 (patch)
tree11fd68aa37b5f878ac22128b5a3d42e76f5654c5
parent8984d650e123d5130ba5662fa59d138e926d44ed (diff)
parent636a138cdae2da2b261a54681a2910ce21ed8019 (diff)
downloadrust-3d8ef7afcab3dd91b6234065b954ce83daa37f40.tar.gz
rust-3d8ef7afcab3dd91b6234065b954ce83daa37f40.zip
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
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs15
-rw-r--r--tests/ui/cast/cast-alias-of-array-to-element.rs22
2 files changed, 29 insertions, 8 deletions
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index caf36ba47bd..5bfc3e810d9 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<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);
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 00000000000..124d0e0346f
--- /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 <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() {}