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

Tracking issue for release notes of #128596: stabilize const_fn_floating_point_arithmetic #129567

Closed
1 of 4 tasks
rustbot opened this issue Aug 25, 2024 · 7 comments
Closed
1 of 4 tasks
Labels
I-release-nominated Nominated for the release team. relnotes Marks issues that should be documented in the release notes of the next release. relnotes-tracking-issue Marks issues tracking what text to put in release notes. T-lang Relevant to the language team, which will review and decide on the PR/issue. WG-const-eval Working group: Const evaluation
Milestone

Comments

@rustbot
Copy link
Collaborator

rustbot commented Aug 25, 2024

This issue tracks the release notes text for #128596.

  • Issue is nominated for the responsible team (and T-release nomination is removed).
  • Proposed text is drafted by team responsible for underlying change.
  • Issue is nominated for release team review of clarity for wider audience.
  • Release team includes text in release notes/blog posts.

Release notes text:

The section title will be de-duplicated by the release team with other release notes issues.
Prefer to use the standard titles from previous releases.
More than one section can be included if needed.

# Language
- [Stabilize floating-point arithmetic in `const fn`](https://github.com/rust-lang/rust/pull/128596)

Release blog section (if any, leave blank if no section is expected):

### Resolving the semantics of NaN-producing floating-point operations

Operations on floating-point values (of type `f32` and `f64`) are famously subtle. One of the reasons for this is the existence of "NaN values": this is short for "Not a Number", and is used to represent e.g. the result of `0.0 / 0.0`. What makes NaN values subtle is that more than one possible NaN value exists: a NaN value has a sign that can be checked with `f.is_sign_positive()`, and it has a "payload" that can be extracted with `f.to_bits()`. Despite very successful efforts to standardize the behavior of floating-point operations across hardware architectures, the details of when a NaN is positive or negative and what its exact payload is differ across architectures. To make matters even more complicated, Rust and its LLVM backend apply optimizations to floating-point operations when the exact numeric result is guaranteed not to change, but those optimizations can change which NaN value is produced. For instance, `f * 1.0` may be optimized to just `f`. However, if `f` is a NaN, this can change the exact bit pattern of the result!

With this release, Rust standardizes on a set of rules for how NaN values behave. This set of rules is *not* fully deterministic, which means that the result of operations like `(0.0 / 0.0).is_sign_positive()` can differ depending on the hardware architecture, optimization levels, and the surrounding code. Code that aims to be fully portable should avoid using `to_bits` and should use `f.signum() == 1.0` instead of `f.is_sign_positive()`. However, the rules are carefully chosen to still allow advanced optimization techniques such as NaN boxing to be realized in Rust code. For more details on what the exact rules are, check out our [documentation](https://doc.rust-lang.org/std/primitive.f32.html#nan-bit-patterns).

With the semantics for NaN values settled, this release also permits the use of floating-point operations in `const fn`. Due to the reasons described above, operations like `(0.0 / 0.0).is_sign_positive()` can produce a different result when executed at compile-time vs at run-time; this is not a bug and code must not rely on a `const fn` always producing the exact same result.
@rustbot rustbot added I-release-nominated Nominated for the release team. relnotes Marks issues that should be documented in the release notes of the next release. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 25, 2024
@Mark-Simulacrum Mark-Simulacrum added this to the 1.82.0 milestone Aug 25, 2024
@Mark-Simulacrum Mark-Simulacrum added I-lang-nominated Nominated for discussion during a lang team meeting. WG-const-eval Working group: Const evaluation and removed I-release-nominated Nominated for the release team. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 25, 2024
@traviscross
Copy link
Contributor

traviscross commented Aug 28, 2024

@RalfJung: What do you think?

cc @rust-lang/lang

@RalfJung
Copy link
Member

RalfJung commented Aug 28, 2024

Who decides whether there'll be a release blog section? I don't know yet whether I will have time to draft one, but if I do I'd rather not see that effort wasted.

@traviscross
Copy link
Contributor

I would assume that T-release would take a cue from e.g. lang about what's important enough to mention. This one seems it would be. But there will actually be quite a bit worth mentioning in Rust 1.82. Not sure if we have a word count limit.

@rust-lang/release: What do you think about RalfJ's question?

@RalfJung
Copy link
Member

#129559 will also be in 1.82, so there could be a joint relnotes section on float semantics. Cc @beetrees @tgross35

Resolving the semantics of NaN-producing floating-point operations

Operations on floating-point values (of type f32 and f64) are famously subtle. One of the reasons for this is the existence of "NaN values": this is short for "Not a Number", and is used to represent e.g. the result of 0.0 / 0.0. What makes NaN values subtle is that more than one possible NaN value exists: a NaN value has a sign that can be checked with f.is_sign_positive(), and it has a "payload" that can be extracted with f.to_bits(). Despite very successful efforts to standardize the behavior of floating-point operations across hardware architectures, the details of when a NaN is positive or negative and what its exact payload is differ across architectures. To make matters even more complicated, Rust and its LLVM backend apply optimizations to floating-point operations when the exact numeric result is guaranteed not to change, but those optimizations can change which NaN value is produced. For instance, f * 1.0 may be optimized to just f. However, if f is a NaN, this can change the exact bit pattern of the result!

With this release, Rust standardizes on a set of rules for how NaN values behave. This set of rules is not fully deterministic, which means that the result of operations like (0.0 / 0.0).is_sign_positive() can differ depending on the hardware architecture, optimization levels, and the surrounding code. Code that aims to be fully portable should avoid using to_bits and should use f.signum() == 1.0 instead of f.is_sign_positive(). However, the rules are carefully chosen to still allow advanced optimization techniques such as NaN boxing to be realized in Rust code. For more details on what the exact rules are, check out our documentation.

With the semantics for NaN values settled, this release also permits the use of floating-point operations in const fn. Due to the reasons described above, operations like (0.0 / 0.0).is_sign_positive() can produce a different result when executed at compile-time vs at run-time; this is not a bug and code must not rely on a const fn always producing the exact same result.

@traviscross
Copy link
Contributor

This sounds great and hits the right mark in terms of giving background and broadly useful information that it'd be good for all Rust programmers to know.

@Mark-Simulacrum Mark-Simulacrum added the relnotes-tracking-issue Marks issues tracking what text to put in release notes. label Sep 6, 2024
@traviscross traviscross added T-lang Relevant to the language team, which will review and decide on the PR/issue. relnotes Marks issues that should be documented in the release notes of the next release. I-release-nominated Nominated for the release team. relnotes-tracking-issue Marks issues tracking what text to put in release notes. and removed relnotes Marks issues that should be documented in the release notes of the next release. I-lang-nominated Nominated for discussion during a lang team meeting. relnotes-tracking-issue Marks issues tracking what text to put in release notes. labels Sep 24, 2024
@RalfJung
Copy link
Member

The release is out... will the bot close all the issues at some point or what's the plan for that?

@cuviper
Copy link
Member

cuviper commented Oct 19, 2024

If a bot hasn't done it already, I won't hold my breath for it. Let me see if I can mass close them...

@cuviper cuviper closed this as completed Oct 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-release-nominated Nominated for the release team. relnotes Marks issues that should be documented in the release notes of the next release. relnotes-tracking-issue Marks issues tracking what text to put in release notes. T-lang Relevant to the language team, which will review and decide on the PR/issue. WG-const-eval Working group: Const evaluation
Projects
None yet
Development

No branches or pull requests

5 participants