Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add #![feature(const_fn_floating_point_arithmetic)] #77122

Merged
merged 6 commits into from
Sep 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// -------------------------------------------------------------------------
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,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 {
Expand Down
31 changes: 22 additions & 9 deletions compiler/rustc_mir/src/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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
Expand All @@ -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
);
}
}
}
Expand Down Expand Up @@ -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()
}
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ symbols! {
const_evaluatable_checked,
const_extern_fn,
const_fn,
const_fn_floating_point_arithmetic,
const_fn_transmute,
const_fn_union,
const_generics,
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#![feature(const_pin)]
#![feature(const_fn_union)]
#![feature(const_fn)]
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
#![feature(const_generics)]
#![feature(const_option)]
#![feature(const_precise_live_drops)]
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@
#![feature(clamp)]
#![feature(concat_idents)]
#![feature(const_cstr_unchecked)]
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
#![feature(const_fn_transmute)]
#![feature(const_fn)]
#![feature(const_ip)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
const unsafe extern "C" fn closure() -> fn() { || {} }
//~^ ERROR function pointers in const fn are unstable
const unsafe extern fn use_float() { 1.0 + 1.0; }
//~^ ERROR only int, `bool` and `char` operations are stable in const fn
//~^ ERROR floating point arithmetic
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
//~^ ERROR casting pointers to integers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ LL | const unsafe extern "C" fn closure() -> fn() { || {} }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable

error[E0723]: only int, `bool` and `char` operations are stable in const fn
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const-extern-fn-min-const-fn.rs:6:38
|
LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
| ^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable

error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/const-extern-fn-min-const-fn.rs:8:48
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: fatal error triggered by #[rustc_error]
--> $DIR/const_fn_floating_point_arithmetic.rs:20:1
|
LL | fn main() {}
| ^^^^^^^^^

error: aborting due to previous error

20 changes: 20 additions & 0 deletions src/test/ui/consts/const_fn_floating_point_arithmetic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// gate-test-const_fn_floating_point_arithmetic

// revisions: stock gated

#![feature(rustc_attrs)]
#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))]

const fn add(f: f32) -> f32 { f + 2.0 }
//[stock]~^ floating point arithmetic
const fn sub(f: f32) -> f32 { 2.0 - f }
//[stock]~^ floating point arithmetic
const fn mul(f: f32, g: f32) -> f32 { f * g }
//[stock]~^ floating point arithmetic
const fn div(f: f32, g: f32) -> f32 { f / g }
//[stock]~^ floating point arithmetic
const fn neg(f: f32) -> f32 { -f }
//[stock]~^ floating point arithmetic

#[rustc_error]
fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
48 changes: 48 additions & 0 deletions src/test/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:8:31
|
LL | const fn add(f: f32) -> f32 { f + 2.0 }
| ^^^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable

error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:10:31
|
LL | const fn sub(f: f32) -> f32 { 2.0 - f }
| ^^^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable

error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:12:39
|
LL | const fn mul(f: f32, g: f32) -> f32 { f * g }
| ^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable

error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:14:39
|
LL | const fn div(f: f32, g: f32) -> f32 { f / g }
| ^^^^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable

error[E0658]: floating point arithmetic is not allowed in constant functions
--> $DIR/const_fn_floating_point_arithmetic.rs:16:31
|
LL | const fn neg(f: f32) -> f32 { -f }
| ^^
|
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0658`.
4 changes: 2 additions & 2 deletions src/test/ui/consts/const_let_eq_float.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// build-pass (FIXME(62277): could be check-pass?)
// run-pass

#![feature(const_fn)]
#![feature(const_fn_floating_point_arithmetic)]

struct Foo<T>(T);
struct Bar<T> { x: T }
Expand Down
8 changes: 0 additions & 8 deletions src/test/ui/consts/min_const_fn/min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,6 @@ const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo11_2<T: Send>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo19(f: f32) -> f32 { f * 2.0 }
//~^ ERROR int, `bool` and `char` operations
const fn foo19_2(f: f32) -> f32 { 2.0 - f }
//~^ ERROR int, `bool` and `char` operations
const fn foo19_3(f: f32) -> f32 { -f }
//~^ ERROR int, `bool` and `char` operations
const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
//~^ ERROR int, `bool` and `char` operations

static BAR: u32 = 42;
const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics
Expand Down
Loading