Skip to content

Commit

Permalink
Unrolled build for rust-lang#128596
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#128596 - RalfJung:const_fn_floating_point_arithmetic, r=nnethercote

stabilize const_fn_floating_point_arithmetic

Part of rust-lang#128288
Fixes rust-lang#57241

The existing test `tests/ui/consts/const_let_eq_float.rs`  ([link](https://github.com/RalfJung/rust/blob/const_fn_floating_point_arithmetic/tests/ui/consts/const_let_eq_float.rs)) covers the basics, and also Miri has extensive tests covering the interpreter's float machinery. Also, that machinery can already be used on stable inside `const`/`static` initializers, just not inside `const fn`.

This was explicitly called out in rust-lang/rfcs#3514 so in a sense t-lang just recently already FCP'd this, but let's hear from them whether they want another FCP for the stabilization here or whether that was covered by the FCP for the RFC.
Cc ``@rust-lang/lang``

### Open items

- [x] Update the Reference: rust-lang/reference#1566
  • Loading branch information
rust-timer authored Aug 25, 2024
2 parents 697d953 + ebfa3e3 commit e265baf
Show file tree
Hide file tree
Showing 27 changed files with 92 additions and 257 deletions.
16 changes: 6 additions & 10 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,10 +575,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

Rvalue::UnaryOp(_, operand) => {
let ty = operand.ty(self.body, self.tcx);
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);
if is_int_bool_float_or_char(ty) {
// Int, bool, float, and char operations are fine.
} else {
span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
}
Expand All @@ -588,8 +586,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let lhs_ty = lhs.ty(self.body, self.tcx);
let rhs_ty = rhs.ty(self.body, self.tcx);

if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
// Int, bool, and char operations are fine.
if is_int_bool_float_or_char(lhs_ty) && is_int_bool_float_or_char(rhs_ty) {
// Int, bool, float, and char operations are fine.
} else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
assert_matches!(
op,
Expand All @@ -603,8 +601,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
);

self.check_op(ops::RawPtrComparison);
} else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
self.check_op(ops::FloatingPointOp);
} else {
span_bug!(
self.span,
Expand Down Expand Up @@ -1009,8 +1005,8 @@ fn place_as_reborrow<'tcx>(
}
}

fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
ty.is_bool() || ty.is_integral() || ty.is_char()
fn is_int_bool_float_or_char(ty: Ty<'_>) -> bool {
ty.is_bool() || ty.is_integral() || ty.is_char() || ty.is_floating_point()
}

fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
Expand Down
44 changes: 6 additions & 38 deletions compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,28 +55,6 @@ pub trait NonConstOp<'tcx>: std::fmt::Debug {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx>;
}

#[derive(Debug)]
pub struct FloatingPointOp;
impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
if ccx.const_kind() == hir::ConstContext::ConstFn {
Status::Unstable(sym::const_fn_floating_point_arithmetic)
} else {
Status::Allowed
}
}

#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
feature_err(
&ccx.tcx.sess,
sym::const_fn_floating_point_arithmetic,
span,
format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
)
}
}

/// A function call where the callee is a pointer.
#[derive(Debug)]
pub struct FnCallIndirect;
Expand Down Expand Up @@ -440,22 +418,12 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
DiagImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
// FIXME: Maybe a more elegant solution to this if else case
if let hir::ConstContext::Static(_) = ccx.const_kind() {
ccx.dcx().create_err(errors::InteriorMutableDataRefer {
span,
opt_help: true,
kind: ccx.const_kind(),
teach: ccx.tcx.sess.teach(E0492),
})
} else {
ccx.dcx().create_err(errors::InteriorMutableDataRefer {
span,
opt_help: false,
kind: ccx.const_kind(),
teach: ccx.tcx.sess.teach(E0492),
})
}
ccx.dcx().create_err(errors::InteriorMutableDataRefer {
span,
opt_help: matches!(ccx.const_kind(), hir::ConstContext::Static(_)),
kind: ccx.const_kind(),
teach: ccx.tcx.sess.teach(E0492),
})
}
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ declare_features! (
(accepted, conservative_impl_trait, "1.26.0", Some(34511)),
/// Allows calling constructor functions in `const fn`.
(accepted, const_constructor, "1.40.0", Some(61456)),
/// Allows basic arithmetic on floating point types in a `const fn`.
(accepted, const_fn_floating_point_arithmetic, "CURRENT_RUSTC_VERSION", Some(57241)),
/// Allows using and casting function pointers in a `const fn`.
(accepted, const_fn_fn_ptr_basics, "1.61.0", Some(57563)),
/// Allows trait bounds in `const fn`.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,6 @@ declare_features! (
(incomplete, const_closures, "1.68.0", Some(106003)),
/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
(unstable, const_extern_fn, "1.40.0", Some(64926)),
/// Allows basic arithmetic on floating point types in a `const fn`.
(unstable, const_fn_floating_point_arithmetic, "1.48.0", Some(57241)),
/// Allows `for _ in _` loops in const contexts.
(unstable, const_for, "1.56.0", Some(87575)),
/// Allows using `&mut` in constant functions.
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(asm_const))]
#![cfg_attr(bootstrap, feature(const_fn_floating_point_arithmetic))]
#![cfg_attr(bootstrap, feature(min_exhaustive_patterns))]
#![feature(abi_unadjusted)]
#![feature(adt_const_params)]
Expand All @@ -202,7 +203,6 @@
#![feature(cfg_sanitize)]
#![feature(cfg_target_has_atomic)]
#![feature(cfg_target_has_atomic_equal_alignment)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_for)]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/floating_point_abs.fixed
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]

/// Allow suboptimal ops in constant context
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/floating_point_abs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]

/// Allow suboptimal ops in constant context
Expand Down
16 changes: 8 additions & 8 deletions src/tools/clippy/tests/ui/floating_point_abs.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: manual implementation of `abs` method
--> tests/ui/floating_point_abs.rs:15:5
--> tests/ui/floating_point_abs.rs:14:5
|
LL | if num >= 0.0 { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
Expand All @@ -8,43 +8,43 @@ LL | if num >= 0.0 { num } else { -num }
= help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`

error: manual implementation of `abs` method
--> tests/ui/floating_point_abs.rs:19:5
--> tests/ui/floating_point_abs.rs:18:5
|
LL | if 0.0 < num { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`

error: manual implementation of `abs` method
--> tests/ui/floating_point_abs.rs:23:5
--> tests/ui/floating_point_abs.rs:22:5
|
LL | if a.a > 0.0 { a.a } else { -a.a }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`

error: manual implementation of `abs` method
--> tests/ui/floating_point_abs.rs:27:5
--> tests/ui/floating_point_abs.rs:26:5
|
LL | if 0.0 >= num { -num } else { num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`

error: manual implementation of `abs` method
--> tests/ui/floating_point_abs.rs:31:5
--> tests/ui/floating_point_abs.rs:30:5
|
LL | if a.a < 0.0 { -a.a } else { a.a }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`

error: manual implementation of negation of `abs` method
--> tests/ui/floating_point_abs.rs:35:5
--> tests/ui/floating_point_abs.rs:34:5
|
LL | if num < 0.0 { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`

error: manual implementation of negation of `abs` method
--> tests/ui/floating_point_abs.rs:39:5
--> tests/ui/floating_point_abs.rs:38:5
|
LL | if 0.0 >= num { num } else { -num }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`

error: manual implementation of negation of `abs` method
--> tests/ui/floating_point_abs.rs:44:12
--> tests/ui/floating_point_abs.rs:43:12
|
LL | a: if a.a >= 0.0 { -a.a } else { a.a },
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()`
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/floating_point_mul_add.fixed
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]

/// Allow suboptimal_ops in constant context
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/floating_point_mul_add.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]

/// Allow suboptimal_ops in constant context
Expand Down
26 changes: 13 additions & 13 deletions src/tools/clippy/tests/ui/floating_point_mul_add.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:20:13
--> tests/ui/floating_point_mul_add.rs:19:13
|
LL | let _ = a * b + c;
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
Expand All @@ -8,73 +8,73 @@ LL | let _ = a * b + c;
= help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:21:13
--> tests/ui/floating_point_mul_add.rs:20:13
|
LL | let _ = a * b - c;
| ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:22:13
--> tests/ui/floating_point_mul_add.rs:21:13
|
LL | let _ = c + a * b;
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:23:13
--> tests/ui/floating_point_mul_add.rs:22:13
|
LL | let _ = c - a * b;
| ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:24:13
--> tests/ui/floating_point_mul_add.rs:23:13
|
LL | let _ = a + 2.0 * 4.0;
| ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:25:13
--> tests/ui/floating_point_mul_add.rs:24:13
|
LL | let _ = a + 2. * 4.;
| ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:27:13
--> tests/ui/floating_point_mul_add.rs:26:13
|
LL | let _ = (a * b) + c;
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:28:13
--> tests/ui/floating_point_mul_add.rs:27:13
|
LL | let _ = c + (a * b);
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:29:13
--> tests/ui/floating_point_mul_add.rs:28:13
|
LL | let _ = a * b * c + d;
| ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:31:13
--> tests/ui/floating_point_mul_add.rs:30:13
|
LL | let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:32:13
--> tests/ui/floating_point_mul_add.rs:31:13
|
LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:34:13
--> tests/ui/floating_point_mul_add.rs:33:13
|
LL | let _ = (a * a + b).sqrt();
| ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`

error: multiply and add expressions can be calculated more efficiently and accurately
--> tests/ui/floating_point_mul_add.rs:37:13
--> tests/ui/floating_point_mul_add.rs:36:13
|
LL | let _ = a - (b * u as f64);
| ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/floating_point_rad.fixed
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]

/// Allow suboptimal_flops in constant context
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/floating_point_rad.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(const_fn_floating_point_arithmetic)]
#![warn(clippy::suboptimal_flops)]

/// Allow suboptimal_flops in constant context
Expand Down
16 changes: 8 additions & 8 deletions src/tools/clippy/tests/ui/floating_point_rad.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: conversion to radians can be done more accurately
--> tests/ui/floating_point_rad.rs:11:13
--> tests/ui/floating_point_rad.rs:10:13
|
LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()`
Expand All @@ -8,43 +8,43 @@ LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0;
= help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`

error: conversion to degrees can be done more accurately
--> tests/ui/floating_point_rad.rs:12:13
--> tests/ui/floating_point_rad.rs:11:13
|
LL | let _ = degrees as f64 * 180.0 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()`

error: conversion to degrees can be done more accurately
--> tests/ui/floating_point_rad.rs:17:13
--> tests/ui/floating_point_rad.rs:16:13
|
LL | let _ = x * 180f32 / std::f32::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`

error: conversion to degrees can be done more accurately
--> tests/ui/floating_point_rad.rs:18:13
--> tests/ui/floating_point_rad.rs:17:13
|
LL | let _ = 90. * 180f64 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()`

error: conversion to degrees can be done more accurately
--> tests/ui/floating_point_rad.rs:19:13
--> tests/ui/floating_point_rad.rs:18:13
|
LL | let _ = 90.5 * 180f64 / std::f64::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()`

error: conversion to radians can be done more accurately
--> tests/ui/floating_point_rad.rs:20:13
--> tests/ui/floating_point_rad.rs:19:13
|
LL | let _ = x * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`

error: conversion to radians can be done more accurately
--> tests/ui/floating_point_rad.rs:21:13
--> tests/ui/floating_point_rad.rs:20:13
|
LL | let _ = 90. * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()`

error: conversion to radians can be done more accurately
--> tests/ui/floating_point_rad.rs:22:13
--> tests/ui/floating_point_rad.rs:21:13
|
LL | let _ = 90.5 * std::f32::consts::PI / 180f32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#![feature(const_extern_fn)]

const extern "C" fn unsize(x: &[u8; 3]) -> &[u8] { x }
const unsafe extern "C" fn closure() -> fn() { || {} }
const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
//~^ ERROR floating point arithmetic
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
//~^ ERROR pointers cannot be cast to integers

Expand Down
Loading

0 comments on commit e265baf

Please sign in to comment.