about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-09-22 23:12:36 +0200
committerGitHub <noreply@github.com>2023-09-22 23:12:36 +0200
commita38f2309fc7148ba94c136bfe28bbcfc4a8495d7 (patch)
tree3dd499e9eec05aea754d8e9ef1638dc64f3f1359
parente6f4b35d9f8f512b71a99dab774e2276322720f3 (diff)
parent861448b426d2cc62a4f62cf173591f9bc7a6c7a3 (diff)
Rollup merge of #116056 - ouz-a:wide_ice, r=compiler-errors
Make unsized casts illegal

Weirdly enough this https://github.com/rust-lang/rust/issues/115998 issue seems to exist since Rust 1.0 (couldn't check before that) but it's only recently been noticed. This change makes those casts illegal.

Fixes https://github.com/rust-lang/rust/issues/115998
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs5
-rw-r--r--tests/ui/cast/unsized-struct-cast.rs6
-rw-r--r--tests/ui/cast/unsized-struct-cast.stderr9
3 files changed, 18 insertions, 2 deletions
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`.