about summary refs log tree commit diff
diff options
context:
space:
mode:
authorxizheyin <xizheyin@smail.nju.edu.cn>2025-03-26 11:31:58 +0800
committerxizheyin <xizheyin@smail.nju.edu.cn>2025-03-27 13:05:18 +0800
commita34c42fefabc774af2d8b2c5a5a100c0697d2ba9 (patch)
tree25d45e97d1377f789a5e541f6034483041f3e514
parent89625360ec4fa11bdc073a74607c7ff0f624fb96 (diff)
downloadrust-a34c42fefabc774af2d8b2c5a5a100c0697d2ba9.tar.gz
rust-a34c42fefabc774af2d8b2c5a5a100c0697d2ba9.zip
Expect an array when expected and acutal types are both arrays during cast
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs39
-rw-r--r--tests/ui/cast/cast-array-issue-138836.rs2
-rw-r--r--tests/ui/cast/cast-array-issue-138836.stderr9
-rw-r--r--tests/ui/consts/const-cast-wrong-type.rs2
-rw-r--r--tests/ui/consts/const-cast-wrong-type.stderr6
5 files changed, 28 insertions, 30 deletions
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 8f5fddd19d7..b19d9efe2c6 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -1042,30 +1042,31 @@ impl<'a, 'tcx> CastCheck<'tcx> {
         m_cast: ty::TypeAndMut<'tcx>,
     ) -> Result<CastKind, CastError<'tcx>> {
         // array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
-        if m_expr.mutbl >= m_cast.mutbl {
-            if let ty::Array(ety, _) = m_expr.ty.kind() {
-                // 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.
-
-                // 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);
-                fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
-                    .unwrap_or_else(|_| {
-                        bug!(
+        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.
+
+            // 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);
+            fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
+                .unwrap_or_else(|_| {
+                    bug!(
                         "could not cast from reference to array to pointer to array ({:?} to {:?})",
                         self.expr_ty,
                         array_ptr_type,
                     )
-                    });
+                });
 
-                // this will report a type mismatch if needed
-                fcx.demand_eqtype(self.span, *ety, m_cast.ty);
-                return Ok(CastKind::ArrayPtrCast);
-            }
+            // this will report a type mismatch if needed
+            fcx.demand_eqtype(self.span, *ety, m_cast.ty);
+            return Ok(CastKind::ArrayPtrCast);
         }
 
         Err(CastError::IllegalCast)
diff --git a/tests/ui/cast/cast-array-issue-138836.rs b/tests/ui/cast/cast-array-issue-138836.rs
index 6fd65d5878a..3f8098e76fd 100644
--- a/tests/ui/cast/cast-array-issue-138836.rs
+++ b/tests/ui/cast/cast-array-issue-138836.rs
@@ -1,5 +1,5 @@
 fn main() {
     let a: [u8; 3] = [1,2,3];
     let b = &a;
-    let c = b as *const [u32; 3]; //~ ERROR mismatched types [E0308]
+    let c = b as *const [u32; 3]; //~ ERROR casting `&[u8; 3]` as `*const [u32; 3]` is invalid
 }
diff --git a/tests/ui/cast/cast-array-issue-138836.stderr b/tests/ui/cast/cast-array-issue-138836.stderr
index fe20d429a49..309474c29f9 100644
--- a/tests/ui/cast/cast-array-issue-138836.stderr
+++ b/tests/ui/cast/cast-array-issue-138836.stderr
@@ -1,12 +1,9 @@
-error[E0308]: mismatched types
+error[E0606]: casting `&[u8; 3]` as `*const [u32; 3]` is invalid
   --> $DIR/cast-array-issue-138836.rs:4:13
    |
 LL |     let c = b as *const [u32; 3];
-   |             ^^^^^^^^^^^^^^^^^^^^ expected `[u8; 3]`, found `[u32; 3]`
-   |
-   = note: expected array `[u8; 3]`
-              found array `[u32; 3]`
+   |             ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0606`.
diff --git a/tests/ui/consts/const-cast-wrong-type.rs b/tests/ui/consts/const-cast-wrong-type.rs
index 6e055a2bcd3..9936a660936 100644
--- a/tests/ui/consts/const-cast-wrong-type.rs
+++ b/tests/ui/consts/const-cast-wrong-type.rs
@@ -1,5 +1,5 @@
 const a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8];
-const b: *const i8 = &a as *const i8; //~ ERROR mismatched types
+const b: *const i8 = &a as *const i8; //~ ERROR casting `&[u8; 3]` as `*const i8` is invalid
 
 fn main() {
 }
diff --git a/tests/ui/consts/const-cast-wrong-type.stderr b/tests/ui/consts/const-cast-wrong-type.stderr
index 44361f15d8a..0730bac2235 100644
--- a/tests/ui/consts/const-cast-wrong-type.stderr
+++ b/tests/ui/consts/const-cast-wrong-type.stderr
@@ -1,9 +1,9 @@
-error[E0308]: mismatched types
+error[E0606]: casting `&[u8; 3]` as `*const i8` is invalid
   --> $DIR/const-cast-wrong-type.rs:2:22
    |
 LL | const b: *const i8 = &a as *const i8;
-   |                      ^^^^^^^^^^^^^^^ expected `u8`, found `i8`
+   |                      ^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0606`.