Skip to content

Commit 3b544e7

Browse files
authored
Rollup merge of #77122 - ecstatic-morse:const-fn-arithmetic, r=RalfJung,oli-obk
Add `#![feature(const_fn_floating_point_arithmetic)]` cc #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
2 parents ac8169d + 659028f commit 3b544e7

18 files changed

+159
-84
lines changed

compiler/rustc_feature/src/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,9 @@ declare_features! (
584584
/// Allows non trivial generic constants which have to be manually propageted upwards.
585585
(active, const_evaluatable_checked, "1.48.0", Some(76560), None),
586586

587+
/// Allows basic arithmetic on floating point types in a `const fn`.
588+
(active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
589+
587590
// -------------------------------------------------------------------------
588591
// feature-group-end: actual feature gates
589592
// -------------------------------------------------------------------------

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

+24
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,30 @@ impl NonConstOp for Abort {
112112
}
113113
}
114114

115+
#[derive(Debug)]
116+
pub struct FloatingPointOp;
117+
impl NonConstOp for FloatingPointOp {
118+
const STOPS_CONST_CHECKING: bool = true;
119+
120+
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
121+
if ccx.const_kind() == hir::ConstContext::ConstFn {
122+
Status::Unstable(sym::const_fn_floating_point_arithmetic)
123+
} else {
124+
Status::Allowed
125+
}
126+
}
127+
128+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
129+
feature_err(
130+
&ccx.tcx.sess.parse_sess,
131+
sym::const_fn_floating_point_arithmetic,
132+
span,
133+
&format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
134+
)
135+
.emit();
136+
}
137+
}
138+
115139
#[derive(Debug)]
116140
pub struct NonPrimitiveOp;
117141
impl NonConstOp for NonPrimitiveOp {

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+
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ symbols! {
352352
const_evaluatable_checked,
353353
const_extern_fn,
354354
const_fn,
355+
const_fn_floating_point_arithmetic,
355356
const_fn_transmute,
356357
const_fn_union,
357358
const_generics,

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#![feature(const_pin)]
8383
#![feature(const_fn_union)]
8484
#![feature(const_fn)]
85+
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
8586
#![feature(const_generics)]
8687
#![feature(const_option)]
8788
#![feature(const_precise_live_drops)]

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@
236236
#![feature(clamp)]
237237
#![feature(concat_idents)]
238238
#![feature(const_cstr_unchecked)]
239+
#![cfg_attr(not(bootstrap), feature(const_fn_floating_point_arithmetic))]
239240
#![feature(const_fn_transmute)]
240241
#![feature(const_fn)]
241242
#![feature(const_ip)]

src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const extern fn unsize(x: &[u8; 3]) -> &[u8] { x }
44
const unsafe extern "C" fn closure() -> fn() { || {} }
55
//~^ ERROR function pointers in const fn are unstable
66
const unsafe extern fn use_float() { 1.0 + 1.0; }
7-
//~^ ERROR only int, `bool` and `char` operations are stable in const fn
7+
//~^ ERROR floating point arithmetic
88
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
99
//~^ ERROR casting pointers to integers
1010

src/test/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr

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

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

1919
error[E0658]: casting pointers to integers in constant functions is unstable
2020
--> $DIR/const-extern-fn-min-const-fn.rs:8:48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: fatal error triggered by #[rustc_error]
2+
--> $DIR/const_fn_floating_point_arithmetic.rs:20:1
3+
|
4+
LL | fn main() {}
5+
| ^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// gate-test-const_fn_floating_point_arithmetic
2+
3+
// revisions: stock gated
4+
5+
#![feature(rustc_attrs)]
6+
#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))]
7+
8+
const fn add(f: f32) -> f32 { f + 2.0 }
9+
//[stock]~^ floating point arithmetic
10+
const fn sub(f: f32) -> f32 { 2.0 - f }
11+
//[stock]~^ floating point arithmetic
12+
const fn mul(f: f32, g: f32) -> f32 { f * g }
13+
//[stock]~^ floating point arithmetic
14+
const fn div(f: f32, g: f32) -> f32 { f / g }
15+
//[stock]~^ floating point arithmetic
16+
const fn neg(f: f32) -> f32 { -f }
17+
//[stock]~^ floating point arithmetic
18+
19+
#[rustc_error]
20+
fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error[E0658]: floating point arithmetic is not allowed in constant functions
2+
--> $DIR/const_fn_floating_point_arithmetic.rs:8:31
3+
|
4+
LL | const fn add(f: f32) -> f32 { f + 2.0 }
5+
| ^^^^^^^
6+
|
7+
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
8+
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
9+
10+
error[E0658]: floating point arithmetic is not allowed in constant functions
11+
--> $DIR/const_fn_floating_point_arithmetic.rs:10:31
12+
|
13+
LL | const fn sub(f: f32) -> f32 { 2.0 - f }
14+
| ^^^^^^^
15+
|
16+
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
17+
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
18+
19+
error[E0658]: floating point arithmetic is not allowed in constant functions
20+
--> $DIR/const_fn_floating_point_arithmetic.rs:12:39
21+
|
22+
LL | const fn mul(f: f32, g: f32) -> f32 { f * g }
23+
| ^^^^^
24+
|
25+
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
26+
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
27+
28+
error[E0658]: floating point arithmetic is not allowed in constant functions
29+
--> $DIR/const_fn_floating_point_arithmetic.rs:14:39
30+
|
31+
LL | const fn div(f: f32, g: f32) -> f32 { f / g }
32+
| ^^^^^
33+
|
34+
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
35+
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
36+
37+
error[E0658]: floating point arithmetic is not allowed in constant functions
38+
--> $DIR/const_fn_floating_point_arithmetic.rs:16:31
39+
|
40+
LL | const fn neg(f: f32) -> f32 { -f }
41+
| ^^
42+
|
43+
= note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
44+
= help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
45+
46+
error: aborting due to 5 previous errors
47+
48+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/consts/const_let_eq_float.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// build-pass (FIXME(62277): could be check-pass?)
1+
// run-pass
22

3-
#![feature(const_fn)]
3+
#![feature(const_fn_floating_point_arithmetic)]
44

55
struct Foo<T>(T);
66
struct Bar<T> { x: T }

src/test/ui/consts/min_const_fn/min_const_fn.rs

-8
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,6 @@ const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
7777
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
7878
const fn foo11_2<T: Send>(t: T) -> T { t }
7979
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
80-
const fn foo19(f: f32) -> f32 { f * 2.0 }
81-
//~^ ERROR int, `bool` and `char` operations
82-
const fn foo19_2(f: f32) -> f32 { 2.0 - f }
83-
//~^ ERROR int, `bool` and `char` operations
84-
const fn foo19_3(f: f32) -> f32 { -f }
85-
//~^ ERROR int, `bool` and `char` operations
86-
const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
87-
//~^ ERROR int, `bool` and `char` operations
8880

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

0 commit comments

Comments
 (0)