about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs11
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs8
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs4
-rw-r--r--tests/crashes/121176.rs9
-rw-r--r--tests/crashes/139872.rs12
-rw-r--r--tests/crashes/140332.rs7
-rw-r--r--tests/ui/mir/static-by-value-dyn.rs14
-rw-r--r--tests/ui/mir/static-by-value-dyn.stderr19
-rw-r--r--tests/ui/mir/static-by-value-slice.rs13
-rw-r--r--tests/ui/mir/static-by-value-slice.stderr33
-rw-r--r--tests/ui/mir/static-by-value-str.rs17
-rw-r--r--tests/ui/mir/static-by-value-str.stderr30
12 files changed, 146 insertions, 31 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 21afd082a05..2c779489272 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -243,6 +243,17 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for ImmTy<'tcx, Prov> {
 }
 
 impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
+    #[inline(always)]
+    pub fn try_from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Option<Self> {
+        let matches_abi = match (imm, layout.backend_repr) {
+            (Immediate::Scalar(..), BackendRepr::Scalar(..)) => true,
+            (Immediate::ScalarPair(..), BackendRepr::ScalarPair(..)) => true,
+            (Immediate::Uninit, _) => layout.is_sized(),
+            _ => false,
+        };
+        if matches_abi { Some(ImmTy { imm, layout }) } else { None }
+    }
+
     #[inline]
     pub fn from_scalar(val: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
         debug_assert!(layout.backend_repr.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout");
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index e2284729efd..a8cfe276b49 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -314,6 +314,14 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
 // These are defined here because they produce a place.
 impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
     #[inline(always)]
+    pub fn try_as_immediate(&self) -> Option<ImmTy<'tcx, Prov>> {
+        match self.op() {
+            Operand::Indirect(_) => None,
+            Operand::Immediate(imm) => ImmTy::try_from_immediate(*imm, self.layout),
+        }
+    }
+
+    #[inline(always)]
     pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
         match self.op() {
             Operand::Indirect(mplace) => Left(MPlaceTy { mplace: *mplace, layout: self.layout }),
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 481c7941909..cebbc404923 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -263,9 +263,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         // manually normalized.
         let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?;
 
-        self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?
-            .as_mplace_or_imm()
-            .right()
+        self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?.try_as_immediate()
     }
 
     /// Returns the value, if any, of evaluating `place`.
diff --git a/tests/crashes/121176.rs b/tests/crashes/121176.rs
deleted file mode 100644
index 4d82e51de8f..00000000000
--- a/tests/crashes/121176.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #121176
-//@ needs-rustc-debug-assertions
-use std::fmt::Debug;
-
-static STATIC_1: dyn Debug + Sync = *();
-
-fn main() {
-    println!("{:?}", &STATIC_1);
-}
diff --git a/tests/crashes/139872.rs b/tests/crashes/139872.rs
deleted file mode 100644
index c3cb8e3c8d6..00000000000
--- a/tests/crashes/139872.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: #139872
-
-enum E {
-    V16(u16),
-    V32(u32),
-}
-
-static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
-
-pub fn main() {
-    let (_, n, _) = C;
-}
diff --git a/tests/crashes/140332.rs b/tests/crashes/140332.rs
deleted file mode 100644
index f5322fa023d..00000000000
--- a/tests/crashes/140332.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ known-bug: #140332
-
-static mut S: [i8] = ["Some thing"; 1];
-
-fn main() {
-    assert_eq!(S, [0; 1]);
-}
diff --git a/tests/ui/mir/static-by-value-dyn.rs b/tests/ui/mir/static-by-value-dyn.rs
new file mode 100644
index 00000000000..f1154ef0860
--- /dev/null
+++ b/tests/ui/mir/static-by-value-dyn.rs
@@ -0,0 +1,14 @@
+//! Regression test for #121176
+//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
+//! which ICEs with unsized statics.
+//@ needs-rustc-debug-assertions
+
+use std::fmt::Debug;
+
+static STATIC_1: dyn Debug + Sync = *();
+//~^ ERROR the size for values of type `(dyn Debug + Sync + 'static)` cannot be known
+//~| ERROR type `()` cannot be dereferenced
+
+fn main() {
+    println!("{:?}", &STATIC_1);
+}
diff --git a/tests/ui/mir/static-by-value-dyn.stderr b/tests/ui/mir/static-by-value-dyn.stderr
new file mode 100644
index 00000000000..25ed81326f4
--- /dev/null
+++ b/tests/ui/mir/static-by-value-dyn.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
+  --> $DIR/static-by-value-dyn.rs:8:1
+   |
+LL | static STATIC_1: dyn Debug + Sync = *();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
+   = note: statics and constants must have a statically known size
+
+error[E0614]: type `()` cannot be dereferenced
+  --> $DIR/static-by-value-dyn.rs:8:37
+   |
+LL | static STATIC_1: dyn Debug + Sync = *();
+   |                                     ^^^ can't be dereferenced
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0614.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/mir/static-by-value-slice.rs b/tests/ui/mir/static-by-value-slice.rs
new file mode 100644
index 00000000000..d4165781eae
--- /dev/null
+++ b/tests/ui/mir/static-by-value-slice.rs
@@ -0,0 +1,13 @@
+//! Regression test for #140332
+//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
+//! which ICEs with unsized statics.
+
+static mut S: [i8] = ["Some thing"; 1];
+//~^ ERROR the size for values of type `[i8]` cannot be known
+//~| ERROR mismatched types
+//~| ERROR mismatched types
+
+fn main() {
+    assert_eq!(S, [0; 1]);
+    //~^ ERROR use of mutable static is unsafe
+}
diff --git a/tests/ui/mir/static-by-value-slice.stderr b/tests/ui/mir/static-by-value-slice.stderr
new file mode 100644
index 00000000000..c5c760b4fe5
--- /dev/null
+++ b/tests/ui/mir/static-by-value-slice.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
+  --> $DIR/static-by-value-slice.rs:5:1
+   |
+LL | static mut S: [i8] = ["Some thing"; 1];
+   | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[i8]`
+   = note: statics and constants must have a statically known size
+
+error[E0308]: mismatched types
+  --> $DIR/static-by-value-slice.rs:5:23
+   |
+LL | static mut S: [i8] = ["Some thing"; 1];
+   |                       ^^^^^^^^^^^^ expected `i8`, found `&str`
+
+error[E0308]: mismatched types
+  --> $DIR/static-by-value-slice.rs:5:22
+   |
+LL | static mut S: [i8] = ["Some thing"; 1];
+   |                      ^^^^^^^^^^^^^^^^^ expected `[i8]`, found `[i8; 1]`
+
+error[E0133]: use of mutable static is unsafe and requires unsafe function or block
+  --> $DIR/static-by-value-slice.rs:11:16
+   |
+LL |     assert_eq!(S, [0; 1]);
+   |                ^ use of mutable static
+   |
+   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0133, E0277, E0308.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/mir/static-by-value-str.rs b/tests/ui/mir/static-by-value-str.rs
new file mode 100644
index 00000000000..07de2a5e65c
--- /dev/null
+++ b/tests/ui/mir/static-by-value-str.rs
@@ -0,0 +1,17 @@
+//! Regression test for #139872
+//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
+//! which ICEs with unsized statics.
+
+enum E {
+    V16(u16),
+    V32(u32),
+}
+
+static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
+//~^ ERROR the size for values of type `str` cannot be known
+//~| ERROR the size for values of type `str` cannot be known
+//~| ERROR mismatched types
+
+pub fn main() {
+    let (_, n, _) = C;
+}
diff --git a/tests/ui/mir/static-by-value-str.stderr b/tests/ui/mir/static-by-value-str.stderr
new file mode 100644
index 00000000000..6988c7d8857
--- /dev/null
+++ b/tests/ui/mir/static-by-value-str.stderr
@@ -0,0 +1,30 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/static-by-value-str.rs:10:1
+   |
+LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
+   | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str`
+   = note: required because it appears within the type `(E, u16, str)`
+   = note: statics and constants must have a statically known size
+
+error[E0308]: mismatched types
+  --> $DIR/static-by-value-str.rs:10:52
+   |
+LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
+   |                                                    ^^^^^ expected `str`, found integer
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/static-by-value-str.rs:10:27
+   |
+LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str`
+   = note: required because it appears within the type `(E, u16, str)`
+   = note: tuples must have a statically known size to be initialized
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.