Skip to content

Commit

Permalink
Rollup merge of rust-lang#77122 - ecstatic-morse:const-fn-arithmetic,…
Browse files Browse the repository at this point in the history
… r=RalfJung,oli-obk

Add `#![feature(const_fn_floating_point_arithmetic)]`

cc rust-lang#76618

This is a template for splitting up `const_fn` into granular feature gates. I think this will make it easier, both for us and for users, to track stabilization of each individual feature. We don't *have* to do this, however. We could also keep stabilizing things out from under `const_fn`.

cc @rust-lang/wg-const-eval
r? @oli-obk
  • Loading branch information
RalfJung authored Sep 26, 2020
2 parents 04c4696 + 659028f commit 273317d
Show file tree
Hide file tree
Showing 18 changed files with 159 additions and 84 deletions.
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 @@ -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,
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

0 comments on commit 273317d

Please sign in to comment.