diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_feature/src/active.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/ops.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 |
4 files changed, 50 insertions, 9 deletions
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 6452bda293e..17b9e1ee7e8 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -584,6 +584,9 @@ declare_features! ( /// Allows non trivial generic constants which have to be manually propageted upwards. (active, const_evaluatable_checked, "1.48.0", Some(76560), None), + /// Allows basic arithmetic on floating point types in a `const fn`. + (active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 496e620dd9d..1d741085853 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -113,6 +113,30 @@ impl NonConstOp for Abort { } #[derive(Debug)] +pub struct FloatingPointOp; +impl NonConstOp for FloatingPointOp { + const STOPS_CONST_CHECKING: bool = true; + + fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { + if ccx.const_kind() == hir::ConstContext::ConstFn { + Status::Unstable(sym::const_fn_floating_point_arithmetic) + } else { + Status::Allowed + } + } + + fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) { + feature_err( + &ccx.tcx.sess.parse_sess, + sym::const_fn_floating_point_arithmetic, + span, + &format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()), + ) + .emit(); + } +} + +#[derive(Debug)] pub struct NonPrimitiveOp; impl NonConstOp for NonPrimitiveOp { const STOPS_CONST_CHECKING: bool = true; diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index dc28ba46d7c..73725c7b98e 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -540,8 +540,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { 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 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { 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 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { ); 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() +} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 602bb4a44a9..12134a85f45 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -352,6 +352,7 @@ symbols! { const_evaluatable_checked, const_extern_fn, const_fn, + const_fn_floating_point_arithmetic, const_fn_transmute, const_fn_union, const_generics, |
