Skip to content

Commit 2049052

Browse files
Put floating point arithmetic behind its own feature gate
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.
1 parent 0d2521a commit 2049052

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

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

+22-9
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
540540

541541
Rvalue::UnaryOp(_, ref operand) => {
542542
let ty = operand.ty(self.body, self.tcx);
543-
if !(ty.is_integral() || ty.is_bool()) {
544-
self.check_op(ops::NonPrimitiveOp)
543+
if is_int_bool_or_char(ty) {
544+
// Int, bool, and char operations are fine.
545+
} else if ty.is_floating_point() {
546+
self.check_op(ops::FloatingPointOp);
547+
} else {
548+
span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
545549
}
546550
}
547551

@@ -550,7 +554,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
550554
let lhs_ty = lhs.ty(self.body, self.tcx);
551555
let rhs_ty = rhs.ty(self.body, self.tcx);
552556

553-
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs_ty.kind() {
557+
if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
558+
// Int, bool, and char operations are fine.
559+
} else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
554560
assert_eq!(lhs_ty, rhs_ty);
555561
assert!(
556562
op == BinOp::Eq
@@ -563,12 +569,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
563569
);
564570

565571
self.check_op(ops::RawPtrComparison);
566-
}
567-
568-
if !(lhs_ty.is_integral() || lhs_ty.is_bool() || lhs_ty.is_char())
569-
|| !(rhs_ty.is_integral() || rhs_ty.is_bool() || rhs_ty.is_char())
570-
{
571-
self.check_op(ops::NonPrimitiveOp)
572+
} else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
573+
self.check_op(ops::FloatingPointOp);
574+
} else {
575+
span_bug!(
576+
self.span,
577+
"non-primitive type in `Rvalue::BinaryOp`: {:?} ⚬ {:?}",
578+
lhs_ty,
579+
rhs_ty
580+
);
572581
}
573582
}
574583
}
@@ -867,3 +876,7 @@ fn place_as_reborrow(
867876
}
868877
})
869878
}
879+
880+
fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
881+
ty.is_bool() || ty.is_integral() || ty.is_char()
882+
}

0 commit comments

Comments
 (0)