Repository navigation
Tracking issue for #![feature(const_fn_floating_point_arithmetic)] #57241
Copy link
Copy link
Closed
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCE-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.Call for participation: Hard difficulty. Experience needed to fix: A lot.S-tracking-design-concernsStatus: There are blocking design concerns.Status: There are blocking design concerns.T-langRelevant to the language teamRelevant to the language teamneeds-rfcThis change is large or controversial enough that it should have an RFC accepted before doing it.This change is large or controversial enough that it should have an RFC accepted before doing it.
Description
Sub-tracking issue for rust-lang/rfcs#911.
This tracks arithmetic for floating point types in const fn. These operations are already stable in const/static, and are also being promoted on stable (&(1.2*2.1) has lifetime 'static). However, in all of these situations, the code is definitely executed at compile-time -- only const fn code could be executed both at compile-time and run-time, making possible differences in FP behavior observable. Also see #77745.
Open Questions
- Must a
const fnbehave exactly the same at runtime as at compile-time? #77745: Must aconst fnbehave exactly the same at runtime as at compile-time? - See Our floating point semantics were a mess unsafe-code-guidelines#237 for a collection of issues around floating-point semantics.
Reacted by Clint Armstrong, Jonas Platte, Charles Samborski, José Luis Cruz, Eyal Kalderon, Anna Harren, anderejd, tesuji, Jason Miller, Innokentii Meleshchenko and 57 more
Reacted by Michael Kirk, Evgeniy Dushistov, Felipe S. S. Schneider, ben, musjj, lokka30, FancyFlame and Luracasmus
Metadata
Metadata
Assignees
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCE-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.Call for participation: Hard difficulty. Experience needed to fix: A lot.S-tracking-design-concernsStatus: There are blocking design concerns.Status: There are blocking design concerns.T-langRelevant to the language teamRelevant to the language teamneeds-rfcThis change is large or controversial enough that it should have an RFC accepted before doing it.This change is large or controversial enough that it should have an RFC accepted before doing it.
Activity
burrbull commentedon Feb 9, 2019
Can
from_bits/to_bitsbe madeconst fnin respect that #53535 ?RalfJung commentedon Jun 13, 2020
One problem with stabilizing floats in consts is that their run-time semantics are broken, and likely unsound: #55131, #73288.
[-]Tracking issue for floating point arithmetic in `const fn`[/-][+]Tracking issue for floating point arithmetic in `const fn` (part of const_fn feature gate)[/+][-]Tracking issue for floating point arithmetic in `const fn` (part of const_fn feature gate)[/-][+]Tracking issue for floating point arithmetic in `const fn` (`const_fn_floating_point_arithmetic`)[/+][-]Tracking issue for floating point arithmetic in `const fn` (`const_fn_floating_point_arithmetic`)[/-][+]Tracking issue for `#![feature(const_fn_floating_point_arithmetic)]`[/+]mqudsi commentedon Feb 18, 2021
While one concern with const evaluation of floating point math is that the results may differ from the hardware (I think we are still using the host fpu for a lot of f32/f64 stuff in miri) there is a huge benefit to adding const evaluation of floating point arithmetic for no_std environments where runtime (soft or hard) fp math may be unavailable altogether.
In this context, constant evaluation can be a huge boon to embedded developers and significantly raise both ergonomics and code quality by allowing for compile-time substitution of static expressions involving floating point math based off of literal constant parameters without requiring opaque f32/f64 values followed by an outdated comment saying “this is the result of the computation of ....” and without requiring lookup tables that will take up room in the ROM without ever being accessed because the ultimate results are computed dynamically and plugged in at compile-time.
This isn’t even arch-specific, eg currently there’s no way to use f64::powf64 without std except via the intrinsic, but that’s not marked const and shouldn’t be anywhere near the current version of core... except it’s actually perfectly fine to use in core/no_std if evaluated at compile-time (and only at compile-time). Would enabling something like that at compile time require an alternative implementation of the intrinsic or a full restructuring of the std/no_std primitives altogether?
RalfJung commentedon Feb 18, 2021
CTFE never uses the host FPU. (Miri-the-tool sometimes does but that is not relevant here.) Floats during CTFE are implemented entirely via "softfloats", i.e., a software-only implementation of IEEE floating point semantics. This means the result is the same no matter the host you use to compile. However, the result might still be different from what would happen on the target since the IEEE float spec doesn't always uniquely determine what happens (in particular around NaNs), and since some targets are not IEEE-compliant.
powis not available during CTFE even unstably, since our softlofat library does not supportpow(or at least I couldn't find any support for this operation). So to getpowinconsteven just on nightly (disregarding all the issues that currently block stabilization), someone would have to first implementpowin softfloats.RalfJung commentedon Feb 18, 2021
All the issues around floating-point semantics aside, we do allow floating-point operations in
constoutsideconst fn. We also promote floating-point operations, so e.g.&(1.0*2.0)will be evaluated at compile time. So we basically already have to live with whatever our CTFE floating-point semantics are, and we have to be careful with changing it. I don't immediately see how allowing the same operations inconst fnwould make things any worse... @oli-obk was disallowing this inconst fnjust done out of abundance of caution, or was there some other concern?oli-obk commentedon Feb 18, 2021
Entirely done out of an abundance of caution. We just didn't want to have any discussion at min_const_fn stabilization time, so we avoided it. The only argument against stabilization is that running the same const fn at runtime and at compile time can yield different results, so technically optimizing away a const fn call by evaluating it at optimization time could change program behaviour. There are much worse things (like missing heap allocations) so I think we can safely ignore this argument and just assume that no one can make optimizations that solely depend on the constness of a function.
RalfJung commentedon Feb 18, 2021
Doesn't ConstProp already use CTFE floats to optimize runtime code?
Also, if this is considered "changing program behavior", that would mean Rust floats would not be specified as "IEEE floats" but as "whatever-the-target-does floats". I don't think that decision was ever made, was it? It would arguably mean that Miri and CTFE are buggy if they diverge from the target behavior.
If Rust is specified as using IEEE floats, then the NaN bits are not specified, and it's okay for them to come out either way. With this view, there is no change in program behavior, just a different non-deterministic choice being made.
42 remaining items
workingjubilee commentedon Mar 3, 2023
My current goal regarding solving this issue is to make progress on allowing
to_bitsandfrom_bitsinconst fn, without addressing any of the other issues involved, and without entailing e.g. resolving const-time NaN semantics or anything like that. This will allow people to build what solutions they may on top of that.clarfonthey commentedon Mar 4, 2023
+1 to allowing
from_bitsandto_bits; for a ratio library I've been working on I craft anf64by hand since I don't trust hardware to round correctly and having to transmute the result is the only unsafe code in the whole thing.Encode rem values derived from pixels using `rems_from_px` (#9367)
matklad commentedon Jun 16, 2024
One small stabilizable subset is
is_nanfunction --- regardless of which NaN value a particular implementation uses, they all agree on the set of values considered NaN.In my use-case (implementing something like
NonNanF64),is_nanis the onlyconst fnI need.nikomatsakis commentedon Jun 17, 2024
oli-obk commentedon Jun 18, 2024
I would prefer to just go all in and land rust-lang/rfcs#3514
Adding exceptions for individual functions requires extra logic and will just cause us to spend a lot of time on discussing individual items
edit: I "made progress" on that RFC by pinging all the T-lang members that have unchecked boxes 😆
RalfJung commentedon Aug 3, 2024
We're finally moving ahead with stabilization here. :)
#128596
[-]Tracking issue for `#![feature(const_fn_floating_point_arithmetic)]`[/-][+]low quality[/+][-]low quality[/-][+]Tracking issue for `#![feature(const_fn_floating_point_arithmetic)]`[/+]Rollup merge of rust-lang#128596 - RalfJung:const_fn_floating_point_a…
Rollup merge of rust-lang#128596 - RalfJung:const_fn_floating_point_a…
Unrolled build for rust-lang#128596
Rollup merge of #128596 - RalfJung:const_fn_floating_point_arithmetic…
Encode rem values derived from pixels using `rems_from_px` (#9367)