summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2020-07-10 19:00:38 +0200
committerMark Rousskov <mark.simulacrum@gmail.com>2020-08-07 11:54:46 -0400
commit83f16cb66a40f0a009fedb1017863f6cebb2d992 (patch)
tree1784c3df91672d32ff08bd819c5d23ac23387abd
parent34c9ac319282f93e148df27db030a99f5a9402f0 (diff)
downloadrust-83f16cb66a40f0a009fedb1017863f6cebb2d992.tar.gz
rust-83f16cb66a40f0a009fedb1017863f6cebb2d992.zip
Don't panic if the lhs of a div by zero is not statically known
-rw-r--r--src/librustc_mir/transform/const_prop.rs26
-rw-r--r--src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs11
-rw-r--r--src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr14
3 files changed, 42 insertions, 9 deletions
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index fbe3377d875..237a5a64f8b 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -484,7 +484,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         lint: &'static lint::Lint,
         source_info: SourceInfo,
         message: &'static str,
-        panic: AssertKind<ConstInt>,
+        panic: AssertKind<impl std::fmt::Debug>,
     ) -> Option<()> {
         let lint_root = self.lint_root(source_info)?;
         self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| {
@@ -1004,11 +1004,27 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                     let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected));
                     let value_const = self.ecx.read_scalar(value).unwrap();
                     if expected != value_const {
+                        enum DbgVal<T> {
+                            Val(T),
+                            Underscore,
+                        }
+                        impl<T: std::fmt::Debug> std::fmt::Debug for DbgVal<T> {
+                            fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                                match self {
+                                    Self::Val(val) => val.fmt(fmt),
+                                    Self::Underscore => fmt.write_str("_"),
+                                }
+                            }
+                        }
                         let mut eval_to_int = |op| {
-                            let op = self
-                                .eval_operand(op, source_info)
-                                .expect("if we got here, it must be const");
-                            self.ecx.read_immediate(op).unwrap().to_const_int()
+                            // This can be `None` if the lhs wasn't const propagated and we just
+                            // triggered the assert on the value of the rhs.
+                            match self.eval_operand(op, source_info) {
+                                Some(op) => {
+                                    DbgVal::Val(self.ecx.read_immediate(op).unwrap().to_const_int())
+                                }
+                                None => DbgVal::Underscore,
+                            }
                         };
                         let msg = match msg {
                             AssertKind::DivisionByZero(op) => {
diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
index 5f2d5e80243..d19cf00eb9c 100644
--- a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
+++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
@@ -1,9 +1,12 @@
 // check-pass
 
+// compile-flags: --crate-type lib
+
+#![warn(unconditional_panic)]
+
 pub struct Fixed64(i64);
 
-pub fn div(f: Fixed64) {
-    f.0 / 0;
+// HACK: this test passes only because this is a const fn that is written to metadata
+pub const fn div(f: Fixed64) {
+    f.0 / 0; //~ WARN will panic at runtime
 }
-
-fn main() {}
diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr
new file mode 100644
index 00000000000..e2a3e4db8ab
--- /dev/null
+++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr
@@ -0,0 +1,14 @@
+warning: this operation will panic at runtime
+  --> $DIR/ice-assert-fail-div-by-zero.rs:11:5
+   |
+LL |     f.0 / 0;
+   |     ^^^^^^^ attempt to divide _ by zero
+   |
+note: the lint level is defined here
+  --> $DIR/ice-assert-fail-div-by-zero.rs:5:9
+   |
+LL | #![warn(unconditional_panic)]
+   |         ^^^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+