about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2024-04-26 22:51:16 -0400
committerBen Kimock <kimockb@gmail.com>2024-04-26 23:06:21 -0400
commit82cc02a60bc09e31afa6cead8994a9e86b2a8012 (patch)
tree67c085ffe65b0dcb69741ad7a8f77ef3540db501
parentef8b9dcf23700f2e2265317611460d3a65c19eff (diff)
downloadrust-82cc02a60bc09e31afa6cead8994a9e86b2a8012.tar.gz
rust-82cc02a60bc09e31afa6cead8994a9e86b2a8012.zip
Do not ICE on invalid consts when walking mono-reachable blocks
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs9
-rw-r--r--tests/ui/consts/mono-reachable-invalid-const.rs23
-rw-r--r--tests/ui/consts/mono-reachable-invalid-const.stderr29
3 files changed, 55 insertions, 6 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 43e4e8216e1..8555aa48c30 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -701,10 +701,7 @@ impl<'tcx> Body<'tcx> {
                 env,
                 crate::ty::EarlyBinder::bind(constant.const_),
             );
-            let Some(bits) = mono_literal.try_eval_bits(tcx, env) else {
-                bug!("Couldn't evaluate constant {:?} in mono {:?}", constant, instance);
-            };
-            bits
+            mono_literal.try_eval_bits(tcx, env)
         };
 
         let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {
@@ -714,7 +711,7 @@ impl<'tcx> Body<'tcx> {
         // If this is a SwitchInt(const _), then we can just evaluate the constant and return.
         let discr = match discr {
             Operand::Constant(constant) => {
-                let bits = eval_mono_const(constant);
+                let bits = eval_mono_const(constant)?;
                 return Some((bits, targets));
             }
             Operand::Move(place) | Operand::Copy(place) => place,
@@ -748,7 +745,7 @@ impl<'tcx> Body<'tcx> {
         match rvalue {
             Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)),
             Rvalue::Use(Operand::Constant(constant)) => {
-                let bits = eval_mono_const(constant);
+                let bits = eval_mono_const(constant)?;
                 Some((bits, targets))
             }
             _ => None,
diff --git a/tests/ui/consts/mono-reachable-invalid-const.rs b/tests/ui/consts/mono-reachable-invalid-const.rs
new file mode 100644
index 00000000000..aabdb071bc9
--- /dev/null
+++ b/tests/ui/consts/mono-reachable-invalid-const.rs
@@ -0,0 +1,23 @@
+//@ build-fail
+
+struct Bar<const BITS: usize>;
+
+impl<const BITS: usize> Bar<BITS> {
+    const ASSERT: bool = {
+        let b = std::convert::identity(1);
+        ["oops"][b]; //~ ERROR evaluation of `Bar::<0>::ASSERT` failed
+        true
+    };
+
+    fn assert() {
+        let val = Self::ASSERT;
+        if val {
+            std::convert::identity(val);
+        }
+    }
+}
+
+
+fn main() {
+    Bar::<0>::assert();
+}
diff --git a/tests/ui/consts/mono-reachable-invalid-const.stderr b/tests/ui/consts/mono-reachable-invalid-const.stderr
new file mode 100644
index 00000000000..6b7b25b59b8
--- /dev/null
+++ b/tests/ui/consts/mono-reachable-invalid-const.stderr
@@ -0,0 +1,29 @@
+error[E0080]: evaluation of `Bar::<0>::ASSERT` failed
+  --> $DIR/mono-reachable-invalid-const.rs:8:9
+   |
+LL |         ["oops"][b];
+   |         ^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+note: erroneous constant encountered
+  --> $DIR/mono-reachable-invalid-const.rs:13:19
+   |
+LL |         let val = Self::ASSERT;
+   |                   ^^^^^^^^^^^^
+
+note: erroneous constant encountered
+  --> $DIR/mono-reachable-invalid-const.rs:13:19
+   |
+LL |         let val = Self::ASSERT;
+   |                   ^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: the above error was encountered while instantiating `fn Bar::<0>::assert`
+  --> $DIR/mono-reachable-invalid-const.rs:22:5
+   |
+LL |     Bar::<0>::assert();
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.