From 6739299d18a16851140bc6b24b8eeae31e3d5878 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 1 Mar 2022 20:02:59 -0500 Subject: [PATCH] Miri/CTFE: properly treat overflow in (signed) division/rem as UB --- .../src/interpret/intrinsics.rs | 12 ++------ .../src/interpret/operator.rs | 18 +++++++----- .../rustc_middle/src/mir/interpret/error.rs | 6 ++++ .../rustc_mir_transform/src/const_prop.rs | 11 +++++++- library/core/tests/num/wrapping.rs | 10 +++++++ src/test/ui/consts/const-int-unchecked.stderr | 4 +-- .../issue-8460-const.noopt.stderr | 28 +++++++++---------- .../issue-8460-const.opt.stderr | 28 +++++++++---------- ...8460-const.opt_with_overflow_checks.stderr | 28 +++++++++---------- .../ui/numbers-arithmetic/issue-8460-const.rs | 24 ++++++++-------- 10 files changed, 93 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d6f856a6f0a70..bf7e811c76f8e 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -500,15 +500,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let (res, overflow, _ty) = self.overflowing_binary_op(BinOp::Rem, &a, &b)?; - if overflow || res.assert_bits(a.layout.size) != 0 { - // Then, check if `b` is -1, which is the "MIN / -1" case. - let minus1 = Scalar::from_int(-1, dest.layout.size); - let b_scalar = b.to_scalar().unwrap(); - if b_scalar == minus1 { - throw_ub_format!("exact_div: result of dividing MIN by -1 cannot be represented") - } else { - throw_ub_format!("exact_div: {} cannot be divided by {} without remainder", a, b,) - } + assert!(!overflow); // All overflow is UB, so this should never return on overflow. + if res.assert_bits(a.layout.size) != 0 { + throw_ub_format!("exact_div: {} cannot be divided by {} without remainder", a, b) } // `Rem` says this is all right, so we can let `Div` do its job. self.binop_ignore_overflow(BinOp::Div, &a, &b, dest) diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 48c90e1881a9a..079ce9f07b8e1 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -196,16 +196,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => None, }; if let Some(op) = op { + let l = self.sign_extend(l, left_layout) as i128; let r = self.sign_extend(r, right_layout) as i128; - // We need a special check for overflowing remainder: - // "int_min % -1" overflows and returns 0, but after casting things to a larger int - // type it does *not* overflow nor give an unrepresentable result! - if bin_op == Rem { - if r == -1 && l == (1 << (size.bits() - 1)) { - return Ok((Scalar::from_int(0, size), true, left_layout.ty)); + + // We need a special check for overflowing Rem and Div since they are *UB* + // on overflow, which can happen with "int_min $OP -1". + if matches!(bin_op, Rem | Div) { + if l == size.signed_int_min() && r == -1 { + if bin_op == Rem { + throw_ub!(RemainderOverflow) + } else { + throw_ub!(DivisionOverflow) + } } } - let l = self.sign_extend(l, left_layout) as i128; let (result, oflo) = op(l, r); // This may be out-of-bounds for the result type, so we have to truncate ourselves. diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 31468ce73bfc5..389d31ea0c472 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -233,6 +233,10 @@ pub enum UndefinedBehaviorInfo<'tcx> { DivisionByZero, /// Something was "remainded" by 0 (x % 0). RemainderByZero, + /// Signed division overflowed (INT_MIN / -1). + DivisionOverflow, + /// Signed remainder overflowed (INT_MIN % -1). + RemainderOverflow, /// Overflowing inbounds pointer arithmetic. PointerArithOverflow, /// Invalid metadata in a wide pointer (using `str` to avoid allocations). @@ -310,6 +314,8 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { } DivisionByZero => write!(f, "dividing by zero"), RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"), + DivisionOverflow => write!(f, "overflow in signed division (dividing MIN by -1)"), + RemainderOverflow => write!(f, "overflow in signed remainder (dividing MIN by -1)"), PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"), InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg), InvalidVtableDropFn(sig) => write!( diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 6075f572a651c..b724b527c7dfb 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -1200,12 +1200,21 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { AssertKind::RemainderByZero(op) => { Some(AssertKind::RemainderByZero(eval_to_int(op))) } + AssertKind::Overflow(bin_op @ (BinOp::Div | BinOp::Rem), op1, op2) => { + // Division overflow is *UB* in the MIR, and different than the + // other overflow checks. + Some(AssertKind::Overflow( + *bin_op, + eval_to_int(op1), + eval_to_int(op2), + )) + } AssertKind::BoundsCheck { ref len, ref index } => { let len = eval_to_int(len); let index = eval_to_int(index); Some(AssertKind::BoundsCheck { len, index }) } - // Overflow is are already covered by checks on the binary operators. + // Remaining overflow errors are already covered by checks on the binary operators. AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => None, // Need proper const propagator for these. _ => None, diff --git a/library/core/tests/num/wrapping.rs b/library/core/tests/num/wrapping.rs index c4fb321ef26cf..8ded139a1809f 100644 --- a/library/core/tests/num/wrapping.rs +++ b/library/core/tests/num/wrapping.rs @@ -308,3 +308,13 @@ fn wrapping_int_api() { } } } + +#[test] +fn wrapping_const() { + // Specifically the wrapping behavior of division and remainder is subtle, + // see https://github.com/rust-lang/rust/pull/94512. + const _: () = { + assert!(i32::MIN.wrapping_div(-1) == i32::MIN); + assert!(i32::MIN.wrapping_rem(-1) == 0); + }; +} diff --git a/src/test/ui/consts/const-int-unchecked.stderr b/src/test/ui/consts/const-int-unchecked.stderr index 22e8c8dabc970..ad880d56d904d 100644 --- a/src/test/ui/consts/const-int-unchecked.stderr +++ b/src/test/ui/consts/const-int-unchecked.stderr @@ -266,7 +266,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:134:25 | LL | const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow executing `unchecked_div` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow in signed division (dividing MIN by -1) error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:137:25 @@ -278,7 +278,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:139:25 | LL | const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::MIN, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow executing `unchecked_rem` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow in signed remainder (dividing MIN by -1) error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:144:25 diff --git a/src/test/ui/numbers-arithmetic/issue-8460-const.noopt.stderr b/src/test/ui/numbers-arithmetic/issue-8460-const.noopt.stderr index d94c7742de301..e2eee1ccdc98c 100644 --- a/src/test/ui/numbers-arithmetic/issue-8460-const.noopt.stderr +++ b/src/test/ui/numbers-arithmetic/issue-8460-const.noopt.stderr @@ -1,36 +1,36 @@ -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ attempt to compute `isize::MIN / -1_isize`, which would overflow | - = note: `#[deny(arithmetic_overflow)]` on by default + = note: `#[deny(unconditional_panic)]` on by default -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:15:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ attempt to compute `i8::MIN / -1_i8`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:17:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i16::MIN / -1_i16`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i32::MIN / -1_i32`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:21:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i64::MIN / -1_i64`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:23:36 | LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err()); @@ -41,8 +41,6 @@ error: this operation will panic at runtime | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide `1_isize` by zero - | - = note: `#[deny(unconditional_panic)]` on by default error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:27:36 @@ -74,37 +72,37 @@ error: this operation will panic at runtime LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err()); | ^^^^^^^^^ attempt to divide `1_i128` by zero -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:37:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ attempt to compute the remainder of `isize::MIN % -1_isize`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:39:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ attempt to compute the remainder of `i8::MIN % -1_i8`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:41:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i16::MIN % -1_i16`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:43:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i32::MIN % -1_i32`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:45:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:47:36 | LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err()); diff --git a/src/test/ui/numbers-arithmetic/issue-8460-const.opt.stderr b/src/test/ui/numbers-arithmetic/issue-8460-const.opt.stderr index d94c7742de301..e2eee1ccdc98c 100644 --- a/src/test/ui/numbers-arithmetic/issue-8460-const.opt.stderr +++ b/src/test/ui/numbers-arithmetic/issue-8460-const.opt.stderr @@ -1,36 +1,36 @@ -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ attempt to compute `isize::MIN / -1_isize`, which would overflow | - = note: `#[deny(arithmetic_overflow)]` on by default + = note: `#[deny(unconditional_panic)]` on by default -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:15:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ attempt to compute `i8::MIN / -1_i8`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:17:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i16::MIN / -1_i16`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i32::MIN / -1_i32`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:21:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i64::MIN / -1_i64`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:23:36 | LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err()); @@ -41,8 +41,6 @@ error: this operation will panic at runtime | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide `1_isize` by zero - | - = note: `#[deny(unconditional_panic)]` on by default error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:27:36 @@ -74,37 +72,37 @@ error: this operation will panic at runtime LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err()); | ^^^^^^^^^ attempt to divide `1_i128` by zero -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:37:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ attempt to compute the remainder of `isize::MIN % -1_isize`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:39:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ attempt to compute the remainder of `i8::MIN % -1_i8`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:41:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i16::MIN % -1_i16`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:43:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i32::MIN % -1_i32`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:45:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:47:36 | LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err()); diff --git a/src/test/ui/numbers-arithmetic/issue-8460-const.opt_with_overflow_checks.stderr b/src/test/ui/numbers-arithmetic/issue-8460-const.opt_with_overflow_checks.stderr index d94c7742de301..e2eee1ccdc98c 100644 --- a/src/test/ui/numbers-arithmetic/issue-8460-const.opt_with_overflow_checks.stderr +++ b/src/test/ui/numbers-arithmetic/issue-8460-const.opt_with_overflow_checks.stderr @@ -1,36 +1,36 @@ -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ attempt to compute `isize::MIN / -1_isize`, which would overflow | - = note: `#[deny(arithmetic_overflow)]` on by default + = note: `#[deny(unconditional_panic)]` on by default -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:15:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ attempt to compute `i8::MIN / -1_i8`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:17:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i16::MIN / -1_i16`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i32::MIN / -1_i32`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:21:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute `i64::MIN / -1_i64`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:23:36 | LL | assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err()); @@ -41,8 +41,6 @@ error: this operation will panic at runtime | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide `1_isize` by zero - | - = note: `#[deny(unconditional_panic)]` on by default error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:27:36 @@ -74,37 +72,37 @@ error: this operation will panic at runtime LL | assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err()); | ^^^^^^^^^ attempt to divide `1_i128` by zero -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:37:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ attempt to compute the remainder of `isize::MIN % -1_isize`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:39:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ attempt to compute the remainder of `i8::MIN % -1_i8`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:41:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i16::MIN % -1_i16`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:43:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i32::MIN % -1_i32`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:45:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ attempt to compute the remainder of `i64::MIN % -1_i64`, which would overflow -error: this arithmetic operation will overflow +error: this operation will panic at runtime --> $DIR/issue-8460-const.rs:47:36 | LL | assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err()); diff --git a/src/test/ui/numbers-arithmetic/issue-8460-const.rs b/src/test/ui/numbers-arithmetic/issue-8460-const.rs index dc754666c8e1f..8cad6deb3db5e 100644 --- a/src/test/ui/numbers-arithmetic/issue-8460-const.rs +++ b/src/test/ui/numbers-arithmetic/issue-8460-const.rs @@ -11,17 +11,17 @@ use std::thread; fn main() { assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); //~^ ERROR operation will panic assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); @@ -35,17 +35,17 @@ fn main() { assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err()); //~^ ERROR operation will panic assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err()); - //~^ ERROR arithmetic operation will overflow + //~^ ERROR operation will panic assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); //~^ ERROR operation will panic assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());