]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/interpret/operator.rs
trailing full stops
[rust.git] / src / librustc_mir / interpret / operator.rs
index b4edee72a4d19bb901406d5fc9c94e70ac5bd7e4..02dc3c01036d0bc3c99f74c582b3d68e9cb8fecc 100644 (file)
@@ -2,7 +2,7 @@
 use rustc::ty::{self, layout::TyLayout};
 use syntax::ast::FloatTy;
 use rustc_apfloat::Float;
-use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar};
+use rustc::mir::interpret::{InterpResult, Scalar};
 
 use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
 
@@ -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<fn(i128, i128) -> (i128, bool)> = match bin_op {
-                Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
-                Rem if r == 0 => return err!(Panic(PanicMessage::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!(Panic(PanicMessage::DivisionByZero)),
-                    Rem if r == 0 => return err!(Panic(PanicMessage::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),
         }
     }