X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_mir%2Finterpret%2Foperator.rs;h=02dc3c01036d0bc3c99f74c582b3d68e9cb8fecc;hb=5fa443ddee30bd2489d0368ee553c416ccc48a5b;hp=20180c9cba542423aeaa53acc00b77e23c245692;hpb=0b680cfce544ff9a59d720020e397c4bf3346650;p=rust.git diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 20180c9cba5..02dc3c01036 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -155,7 +155,7 @@ fn binary_int_op( r, right_layout.ty ); - return err!(Unimplemented(msg)); + throw_unsup!(Unimplemented(msg)) } // Operations that need special treatment for signed integers @@ -173,8 +173,8 @@ fn binary_int_op( return Ok((Scalar::from_bool(op(&l, &r)), false)); } let op: Option (i128, bool)> = match bin_op { - Div if r == 0 => return err!(DivisionByZero), - Rem if r == 0 => return err!(RemainderByZero), + Div if r == 0 => throw_panic!(DivisionByZero), + Rem if r == 0 => throw_panic!(RemainderByZero), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), Add => Some(i128::overflowing_add), @@ -231,8 +231,8 @@ fn binary_int_op( Add => u128::overflowing_add, Sub => u128::overflowing_sub, Mul => u128::overflowing_mul, - Div if r == 0 => return err!(DivisionByZero), - Rem if r == 0 => return err!(RemainderByZero), + Div if r == 0 => throw_panic!(DivisionByZero), + Rem if r == 0 => throw_panic!(RemainderByZero), Div => u128::overflowing_div, Rem => u128::overflowing_rem, _ => bug!(), @@ -250,7 +250,7 @@ fn binary_int_op( r, right_layout.ty, ); - return err!(Unimplemented(msg)); + throw_unsup!(Unimplemented(msg)) } }; @@ -290,30 +290,29 @@ pub fn binary_op( FloatTy::F64 => self.binary_float_op(bin_op, left.to_f64()?, right.to_f64()?), }) } - _ => { - // Must be integer(-like) types. Don't forget about == on fn pointers. - assert!( - left.layout.ty.is_integral() || - left.layout.ty.is_unsafe_ptr() || left.layout.ty.is_fn_ptr(), - "Unexpected LHS type {:?} for BinOp {:?}", left.layout.ty, bin_op); + _ if left.layout.ty.is_integral() => { + // the RHS type can be different, e.g. for shifts -- but it has to be integral, too assert!( - right.layout.ty.is_integral() || - right.layout.ty.is_unsafe_ptr() || right.layout.ty.is_fn_ptr(), - "Unexpected RHS type {:?} for BinOp {:?}", right.layout.ty, bin_op); - - // Handle operations that support pointer values - if left.to_scalar_ptr()?.is_ptr() || - right.to_scalar_ptr()?.is_ptr() || - bin_op == mir::BinOp::Offset - { - return M::ptr_op(self, bin_op, left, right); - } + right.layout.ty.is_integral(), + "Unexpected types for BinOp: {:?} {:?} {:?}", + left.layout.ty, bin_op, right.layout.ty + ); - // Everything else only works with "proper" bits - let l = left.to_bits().expect("we checked is_ptr"); - let r = right.to_bits().expect("we checked is_ptr"); + let l = self.force_bits(left.to_scalar()?, left.layout.size)?; + let r = self.force_bits(right.to_scalar()?, right.layout.size)?; self.binary_int_op(bin_op, l, left.layout, r, right.layout) } + _ if left.layout.ty.is_any_ptr() => { + // The RHS type must be the same *or an integer type* (for `Offset`). + assert!( + right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), + "Unexpected types for BinOp: {:?} {:?} {:?}", + left.layout.ty, bin_op, right.layout.ty + ); + + M::binary_ptr_op(self, bin_op, left, right) + } + _ => bug!("Invalid MIR: bad LHS type for binop: {:?}", left.layout.ty), } }