diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2020-07-16 11:18:50 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-16 11:18:50 -0700 |
| commit | a80559f472d9baa4d22359a400d5c0f5852e548d (patch) | |
| tree | d3b72b3230a8287e11fb602018d9b4e1d3defbd7 | |
| parent | 5d5455bf3da2722749cf3361b42eac16e27d42cc (diff) | |
| parent | 703f6803db4b2014486a1c7230bc965fd75a672e (diff) | |
| download | rust-a80559f472d9baa4d22359a400d5c0f5852e548d.tar.gz rust-a80559f472d9baa4d22359a400d5c0f5852e548d.zip | |
Rollup merge of #74221 - oli-obk:const_prop_ice, r=wesleywiser
Don't panic if the lhs of a div by zero is not statically known Fixes #73993 for real this time r? @wesleywiser
| -rw-r--r-- | src/librustc_mir/transform/const_prop.rs | 26 | ||||
| -rw-r--r-- | src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs | 11 | ||||
| -rw-r--r-- | src/test/ui/const_prop/ice-assert-fail-div-by-zero.stderr | 14 |
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 + |
