Add `const` support for float rounding methods
# Add `const` support for float rounding methods
This PR makes the following float rounding methods `const`:
- `f64::{floor, ceil, trunc, round, round_ties_even}`
- and the corresponding methods for `f16`, `f32` and `f128`
Tracking issue: https://github.com/rust-lang/rust/issues/141555
## Procedure
I followed c09ed3e767 as closely as I could in making float methods `const`, and also received great guidance from https://internals.rust-lang.org/t/const-rounding-methods-in-float-types/22957/3?u=ruancomelli.
## Note
This is my first code contribution to the Rust project, so please let me know if I missed anything - I'd be more than happy to revise and learn more. Thank you for taking the time to review it!
std: clarify Clone trait documentation about duplication semantics
Closesrust-lang/rust#141138
The change explicitly explains that cloning behavior varies by type and clarifies that smart pointers (`Arc`, `Rc`) share the same underlying data. I've also added an example of cloning to Arc.
`slice.get(i)` should use a slice projection in MIR, like `slice[i]` does
`slice[i]` is built-in magic, so ends up being quite different from `slice.get(i)` in MIR, even though they're both doing nearly identical operations -- checking the length of the slice then getting a ref/ptr to the element if it's in-bounds.
This PR adds a `slice_get_unchecked` intrinsic for `impl SliceIndex for usize` to use to fix that, so it no longer needs to do a bunch of lines of pointer math and instead just gets the obvious single statement. (This is *not* used for the range versions, since `slice[i..]` and `slice[..k]` can't use the mir Slice projection as they're using fenceposts, not indices.)
I originally tried to do this with some kind of GVN pattern, but realized that I'm pretty sure it's not legal to optimize `BinOp::Offset` to `PlaceElem::Index` without an extremely complicated condition. Basically, the problem is that the `Index` projection on a dereferenced slice pointer *cares about the metadata*, since it's UB to `PlaceElem::Index` outside the range described by the metadata. But then you cast the fat pointer to a thin pointer then offset it, that *ignores* the slice length metadata, so it's possible to write things that are legal with `Offset` but would be UB if translated in the obvious way to `Index`. Checking (or even determining) the necessary conditions for that would be complicated and error-prone, whereas this intrinsic-based approach is quite straight-forward.
Zero backend changes, because it just lowers to MIR, so it's already supported naturally by CTFE/Miri/cg_llvm/cg_clif.
In the previous description it said there was a TOCTOU race but did not
explain exactly what the problem was. I sat down with the CVE, reviewed
its text, and created this explanation. This context should hopefully
help people understand the actual risk as-such.
Incidentally, it also fixes the capitalization on the name of Redox OS.
Add const support for the float rounding methods floor, ceil, trunc,
fract, round and round_ties_even.
This works by moving the calculation logic from
src/tools/miri/src/intrinsics/mod.rs
into
compiler/rustc_const_eval/src/interpret/intrinsics.rs.
All relevant method definitions were adjusted to include the `const`
keyword for all supported float types: f16, f32, f64 and f128.
The constness is hidden behind the feature gate
feature(const_float_round_methods)
which is tracked in
https://github.com/rust-lang/rust/issues/141555
This commit is a squash of the following commits:
- test: add tests that we expect to pass when float rounding becomes const
- feat: make float rounding methods `const`
- fix: replace `rustc_allow_const_fn_unstable(core_intrinsics)` attribute with `#[rustc_const_unstable(feature = "f128", issue = "116909")]` in `library/core/src/num/f128.rs`
- revert: undo update to `library/stdarch`
- refactor: replace multiple `float_<mode>_intrinsic` rounding methods with a single, parametrized one
- fix: add `#[cfg(not(bootstrap))]` to new const method tests
- test: add extra sign tests to check `+0.0` and `-0.0`
- revert: undo accidental changes to `round` docs
- fix: gate `const` float round method behind `const_float_round_methods`
- fix: remove unnecessary `#![feature(const_float_methods)]`
- fix: remove unnecessary `#![feature(const_float_methods)]` [2]
- revert: undo changes to `tests/ui/consts/const-eval/float_methods.rs`
- fix: adjust after rebase
- test: fix float tests
- test: add tests for `fract`
- chore: add commented-out `const_float_round_methods` feature gates to `f16` and `f128`
- fix: adjust NaN when rounding floats
- chore: add FIXME comment for de-duplicating float tests
- test: remove unnecessary test file `tests/ui/consts/const-eval/float_methods.rs`
- test: fix tests after upstream simplification of how float tests are run
Rollup of 8 pull requests
Successful merges:
- rust-lang/rust#140787 (Note expr being cast when encounter NonScalar cast error)
- rust-lang/rust#141112 (std: note that `std::str::from_utf8*` functions are aliases to `<str>::from_utf8*` methods)
- rust-lang/rust#141646 (Document what `distcheck` is intended to exercise)
- rust-lang/rust#141740 (Hir item kind field order)
- rust-lang/rust#141793 (`tests/ui`: A New Order [1/N])
- rust-lang/rust#141805 (Update `compiler-builtins` to 0.1.160)
- rust-lang/rust#141815 (Enable non-leaf Frame Pointers for mingw-w64 Arm64 Windows)
- rust-lang/rust#141819 (Fixes for building windows-gnullvm hosts)
r? `@ghost`
`@rustbot` modify labels: rollup
Do not move thread-locals before dropping
Fixesrust-lang/rust#140816. I also (potentially) improved the speed of `get_or_init` a bit by having an explicit hot/cold path.
We still move the value before dropping in the event of a recursive initialization (leading to double-initialization with one value being silently dropped). This is the old behavior, but changing this to panic instead would involve changing tests and also the other OS-specific `thread_local/os.rs` implementation, which is more than I'd like in this PR.
This commit improves the Clone trait documentation to address confusion
around what "duplication" means for different types, especially for smart
pointers like Arc<Mutex<T>>.
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
core: begin deduplicating pointer docs
this also cleans up two inconsistancies:
1. both doctests on the ::add methods were actually calling the const version.
2. on of the ::offset methods was missing a line of clarification.
part of https://github.com/rust-lang/rust/issues/139190
Implement ((un)checked_)exact_div methods for integers
tracking issue: #139911
I see that there might still be some bikeshedding to be done, so if people want changes to this implementation, I'm happy to make those. I did also see that there was a previous attempt at this PR (#116632), but I'm not sure why it got closed.
Add Range parameter to `BTreeMap::extract_if` and `BTreeSet::extract_if`
This new parameter was requested in the btree_extract_if tracking issue: https://github.com/rust-lang/rust/issues/70530#issuecomment-2486566328
I attempted to follow the style used by `Vec::extract_if`.
Before:
```rust
impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
#[unstable(feature = "btree_extract_if", issue = "70530")]
pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F, A>
where
K: Ord,
F: FnMut(&K, &mut V) -> bool;
}
```
After:
```rust
impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
#[unstable(feature = "btree_extract_if", issue = "70530")]
pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, K, V, R, F, A>
where
K: Ord,
R: RangeBounds<K>,
F: FnMut(&K, &mut V) -> bool;
}
```
Related: #70530
—
While I believe I have adjusted all of the necessary bits, as this is my first attempt to contribute to Rust, I may have overlooked something out of ignorance, but if you can point out any oversight, I shall attempt to remedy it.
float: Replace some approximate assertions with exact
As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:
* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`
This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.
[1]: https://github.com/rust-lang/rust/pull/138087#issuecomment-2842069281
The first commit is a small bit of macro cleanup.
try-job: aarch64-gnu
try-job: x86_64-gnu-aux
atomic_load intrinsic: use const generic parameter for ordering
We have a gazillion intrinsics for the atomics because we encode the ordering into the intrinsic name rather than making it a parameter. This is particularly bad for those operations that take two orderings. Let's fix that!
This PR only converts `load`, to see if there's any feedback that would fundamentally change the strategy we pursue for the const generic intrinsics.
The first two commits are preparation and could be a separate PR if you prefer.
`@BoxyUwU` -- I hope this is a use of const generics that is unlikely to explode? All we need is a const generic of enum type. We could funnel it through an integer if we had to but an enum is obviously nicer...
`@bjorn3` it seems like the cranelift backend entirely ignores the ordering?
`assert_eq!` ignores the sign of zero, but for any tests involving zeros
we do care about this sign. Replace `assert_eq!` with `assert_biteq!`
everywhere possible for float tests to ensure we don't miss this.
`assert_biteq!` is also updated to check equality on non-NaNs, to catch
the unlikely case that bitwise equality works but our `==`
implementation is broken.
There is one notable output change: we were asserting that
`(-0.0).fract()` and `(-1.0).fract()` both return -0.0, but both
actually return +0.0.
As was mentioned at [1], we currently use `assert_approx_eq` for testing
some math functions that guarantee exact results. Replace approximate
assertions with exact ones for the following:
* `ceil`
* `floor`
* `fract`
* `from_bits`
* `mul_add`
* `round_ties_even`
* `round`
* `trunc`
This likely wasn't done in the past to avoid writing out exact decimals
that don't match the intuitive answer (e.g. 1.3 - 1.0 = 0.300...004),
but ensuring our results are accurate seems more important here.
[1]: https://github.com/rust-lang/rust/pull/138087#issuecomment-2842069281
Add `loongarch64` with `d` feature to `f32::midpoint` fast path
This patch enables the optimized implementation of `f32::midpoint` for `loongarch64` targets that support the `d`feature. Targets with reliable 64-bit float support can safely use the faster and more accurate computation via `f64`, avoiding the fallback branchy version.
float: Disable `total_cmp` sNaN tests for `f16`
There is an LLVM bug with lowering of basic `f16` operations that mean a round trip via `__extendhfsf2` and `__truncsfhf2` may happen for simple `abs` calls or bitcasts [1]. This is problematic because the round trip quiets signaling NaNs. For most operations this is acceptable, but it is causing `total_cmp` tests to fail unless optimizations are enabled.
Disable `total_cmp` tests involving signaling NaNs until this issue is resolved.
Fixes: https://github.com/rust-lang/rustc_codegen_cranelift/issues/1578
Fixes: https://github.com/rust-lang/rust/issues/141503
[1]: https://github.com/llvm/llvm-project/issues/104915
The float modules in `std` are currently top-level but for `core`, they
are nested within the `num` directory and referenced by `#[path = ...]`.
For consistency, adjust `std` to use the same structure as `core`.
Also change the `f16` and `f128` gates from outer attributes to inner
attributes like `core` has.
Do not get proc_macro from the sysroot in rustc
With the stage0 refactor the proc_macro version found in the sysroot will no longer always match the proc_macro version that proc-macros get compiled with by the rustc executable that uses this proc_macro. This will cause problems as soon as the ABI of the bridge gets changed to implement new features or change the way existing features work.
To fix this, this commit changes rustc crates to depend directly on the local version of proc_macro which will also be used in the sysroot that rustc will build.
Add `rustc_diagnostic_item` to `sys::Mutex` methods
For an ongoing project for adding a concurrency model checker to Miri we need to be able to intercept locking/unlocking operations on standard library mutexes.
This PR adds diagnostic items to the relevant calls `lock`, `try_lock` and `unlock` for the `sys::Mutex` implementation on the targets we care about.
This PR also makes the internals of `pthread::Mutex` less public, to reduce the chance of anyone locking/unlocking a mutex without going through the intercepted methods.
r? ``@RalfJung``
clean up old rintf leftovers
As usual stdarch needed special treatment due to https://github.com/rust-lang/stdarch/issues/1655, and apparently I forgot to clean up these leftovers here. They can be removed now.
Path::with_extension: show that it adds an extension where one did no…
…t exist
I think the times I encountered this, I had to check first if files without extensions were added, since all examples only had files with existing extensions.
Also, this replaced example already has a similar example below.
Test(fs): Fix `test_eq_windows_file_type` for Windows 7
Would otherwise fail on:
```
thread 'fs::tests::test_eq_windows_file_type' panicked at library/std/src/test_helpers.rs:53:20:
called `Result::unwrap()` on an `Err` value: Os { code: 5, kind: PermissionDenied, message: "Access is denied." }
```
This came from the read-only attribute set on the test file. In order to fix this, instead of simply disabling the test, the attribute is reset before the test's end so it may still run successfully.
`@rustbot` label T-libs A-filesystem A-testsuite O-windows-7 O-windows-msvc
This patch enables the optimized implementation of `f32::midpoint` for
`loongarch64` targets that support the `d`feature. Targets with reliable
64-bit float support can safely use the faster and more accurate computation
via `f64`, avoiding the fallback branchy version.
Split `autodiff` into `autodiff_forward` and `autodiff_reverse`
This PR splits `#[autodiff]` macro so `#[autodiff(df, Reverse, args)]` would become `#[autodiff_reverse(df, args)]` and `#[autodiff(df, Forward, args)]` would become `#[autodiff_forwad(df, args)]`.
Add data_ptr method to Mutex and RwLock
Implementation of https://github.com/rust-lang/rust/issues/140368 / https://github.com/rust-lang/libs-team/issues/531.
I tried to write a useful safety section about when it is safe to read or write through the returned pointers, but couldn't come up with something nice. Hoping this PR is still useful without that. I'm happy to add any doc strings other people come up with if needed before merge, of course.
Unresolved questions:
- Return a `LockResult` or not?
- Return `*mut T` like existing APIs (`Cell::as_ptr` / `MaybeUninit::as[_mut]_ptr` / `Vec::as_ptr` / ...) or be more precise and return `NonNull<T>`?