From 861448b426d2cc62a4f62cf173591f9bc7a6c7a3 Mon Sep 17 00:00:00 2001
From: ouz-a <ouz.agz@gmail.com>
Date: Fri, 22 Sep 2023 13:31:26 +0300
Subject: [PATCH] make unsized cast illegal

---
 compiler/rustc_hir_typeck/src/cast.rs    | 5 +++--
 tests/ui/cast/unsized-struct-cast.rs     | 6 ++++++
 tests/ui/cast/unsized-struct-cast.stderr | 9 +++++++++
 3 files changed, 18 insertions(+), 2 deletions(-)
 create mode 100644 tests/ui/cast/unsized-struct-cast.rs
 create mode 100644 tests/ui/cast/unsized-struct-cast.stderr

diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index fa779701e61..57cd88afcdc 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -725,6 +725,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             },
                             // array-ptr-cast
                             Ptr(mt) => {
+                                if !fcx.type_is_sized_modulo_regions(fcx.param_env, mt.ty) {
+                                    return Err(CastError::IllegalCast);
+                                }
                                 self.check_ref_cast(fcx, TypeAndMut { mutbl, ty: inner_ty }, mt)
                             }
                             _ => Err(CastError::NonScalar),
@@ -735,7 +738,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             }
             _ => return Err(CastError::NonScalar),
         };
-
         if let ty::Adt(adt_def, _) = *self.expr_ty.kind() {
             if adt_def.did().krate != LOCAL_CRATE {
                 if adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive) {
@@ -743,7 +745,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 }
             }
         }
-
         match (t_from, t_cast) {
             // These types have invariants! can't cast into them.
             (_, Int(CEnum) | FnPtr) => Err(CastError::NonScalar),
diff --git a/tests/ui/cast/unsized-struct-cast.rs b/tests/ui/cast/unsized-struct-cast.rs
new file mode 100644
index 00000000000..52bb6cedcd6
--- /dev/null
+++ b/tests/ui/cast/unsized-struct-cast.rs
@@ -0,0 +1,6 @@
+pub struct Data([u8]);
+
+fn main(){
+    const _: *const Data = &[] as *const Data;
+    //~^ ERROR: casting `&[_; 0]` as `*const Data` is invalid
+}
diff --git a/tests/ui/cast/unsized-struct-cast.stderr b/tests/ui/cast/unsized-struct-cast.stderr
new file mode 100644
index 00000000000..79b3d973c32
--- /dev/null
+++ b/tests/ui/cast/unsized-struct-cast.stderr
@@ -0,0 +1,9 @@
+error[E0606]: casting `&[_; 0]` as `*const Data` is invalid
+  --> $DIR/unsized-struct-cast.rs:4:28
+   |
+LL |     const _: *const Data = &[] as *const Data;
+   |                            ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0606`.