]> git.lizzy.rs Git - rust.git/commitdiff
Put floating point arithmetic behind its own feature gate
authorDylan MacKenzie <ecstaticmorse@gmail.com>
Wed, 23 Sep 2020 18:54:11 +0000 (11:54 -0700)
committerDylan MacKenzie <ecstaticmorse@gmail.com>
Fri, 25 Sep 2020 17:37:52 +0000 (10:37 -0700)
This refactors handling of `Rvalue::{Unary,Binary}Op` in the
const-checker. Now we `span_bug` if there's an unexpected type in a
primitive operation. This also allows unary negation on
`char` values through the const-checker because it makes the code a bit
cleaner. `char` does not actually support these operations, and if it
did, we could evaluate them at compile-time.

compiler/rustc_mir/src/transform/check_consts/validation.rs

index dc28ba46d7cbbe0cf7fca6a3c9e1e24fbd34c7b3..73725c7b98eeee87f4b0a3a9dbf0a7feaf28b65e 100644 (file)
@@ -540,8 +540,12 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
 
             Rvalue::UnaryOp(_, ref operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                if !(ty.is_integral() || ty.is_bool()) {
-                    self.check_op(ops::NonPrimitiveOp)
+                if is_int_bool_or_char(ty) {
+                    // Int, bool, and char operations are fine.
+                } else if ty.is_floating_point() {
+                    self.check_op(ops::FloatingPointOp);
+                } else {
+                    span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
                 }
             }
 
@@ -550,7 +554,9 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                 let lhs_ty = lhs.ty(self.body, self.tcx);
                 let rhs_ty = rhs.ty(self.body, self.tcx);
 
-                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs_ty.kind() {
+                if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
+                    // Int, bool, and char operations are fine.
+                } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
                     assert_eq!(lhs_ty, rhs_ty);
                     assert!(
                         op == BinOp::Eq
@@ -563,12 +569,15 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
                     );
 
                     self.check_op(ops::RawPtrComparison);
-                }
-
-                if !(lhs_ty.is_integral() || lhs_ty.is_bool() || lhs_ty.is_char())
-                    || !(rhs_ty.is_integral() || rhs_ty.is_bool() || rhs_ty.is_char())
-                {
-                    self.check_op(ops::NonPrimitiveOp)
+                } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
+                    self.check_op(ops::FloatingPointOp);
+                } else {
+                    span_bug!(
+                        self.span,
+                        "non-primitive type in `Rvalue::BinaryOp`: {:?} ⚬ {:?}",
+                        lhs_ty,
+                        rhs_ty
+                    );
                 }
             }
         }
@@ -867,3 +876,7 @@ fn place_as_reborrow(
         }
     })
 }
+
+fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
+    ty.is_bool() || ty.is_integral() || ty.is_char()
+}