std: refactor the TLS implementation
As discovered by Mara in #110897, our TLS implementation is a total mess. In the past months, I have simplified the actual macros and their expansions, but the majority of the complexity comes from the platform-specific support code needed to create keys and register destructors. In keeping with #117276, I have therefore moved all of the `thread_local_key`/`thread_local_dtor` modules to the `thread_local` module in `sys` and merged them into a new structure, so that future porters of `std` can simply mix-and-match the existing code instead of having to copy the same (bad) implementation everywhere. The new structure should become obvious when looking at `sys/thread_local/mod.rs`.
Unfortunately, the documentation changes associated with the refactoring have made this PR rather large. That said, this contains no functional changes except for two small ones:
* the key-based destructor fallback now, by virtue of sharing the implementation used by macOS and others, stores its list in a `#[thread_local]` static instead of in the key, eliminating one indirection layer and drastically simplifying its code.
* I've switched over ZKVM (tier 3) to use the same implementation as WebAssembly, as the implementation was just a way worse version of that
Please let me know if I can make this easier to review! I know these large PRs aren't optimal, but I couldn't think of any good intermediate steps.
`@rustbot` label +A-thread-locals
Update docs for AtomicBool/U8/I8 with regard to alignment
Fixes#126084.
Since `AtomicBool`/`AtomicU8`/`AtomicI8` are guaranteed to have size == 1, and Rust guarantees that `size % align == 0`, they also must have alignment equal to 1, so some current docs are contradictory/confusing when describing their alignment requirements.
Specifically:
* Fix `AtomicBool::from_ptr` claiming that `align_of::<AtomicBool>() > align_of::<bool>()` on some platforms. (same for `AtomicU8::from_ptr`/`AtomicI8::from_ptr`)
* Explicitly state that `AtomicU8`/`AtomicI8` have the same alignment as `u8`/`i8` (in addition to size and bit validity)
* (internal) Change the `if_not_8_bit` macro to be `if_8_bit` and to allow an "if-else"-like structure, instead of just "if"-like.
---
I opted to leave the "`ptr` must be aligned" wording in `from_ptr`'s docs and just clarify that it is always satsified, instead of just removing the wording entirely. If that is instead preferred I can do that.
std::unix::fs: copy simplification for apple.
since we do support from macOs Sierra, we avoid the little runtime overhead with the fclonefileat symbol check.
Rollup of 3 pull requests
Successful merges:
- #126140 (Rename `std::fs::try_exists` to `std::fs::exists` and stabilize fs_try_exists)
- #126318 (Add a `x perf` command for integrating bootstrap with `rustc-perf`)
- #126552 (Remove use of const traits (and `feature(effects)`) from stdlib)
r? `@ghost`
`@rustbot` modify labels: rollup
Remove use of const traits (and `feature(effects)`) from stdlib
The current uses are already unsound because they are using non-const impls in const contexts. We can reintroduce them by reverting the commit in this PR, after #120639 lands.
Also, make `effects` an incomplete feature.
cc `@rust-lang/project-const-traits`
r? `@compiler-errors`
Generalize `{Rc,Arc}::make_mut()` to unsized types.
* `{Rc,Arc}::make_mut()` now accept any type implementing the new unstable trait `core::clone::CloneToUninit`.
* `CloneToUninit` is implemented for `T: Clone` and for `[T] where T: Clone`.
* `CloneToUninit` is a generalization of the existing internal trait `alloc::alloc::WriteCloneIntoRaw`.
* New feature gate: `clone_to_uninit`
This allows performing `make_mut()` on `Rc<[T]>` and `Arc<[T]>`, which was not previously possible.
---
Previous PR description, now obsolete:
> Add `{Rc, Arc}::make_mut_slice()`
>
> These functions behave identically to `make_mut()`, but operate on `Arc<[T]>` instead of `Arc<T>`.
>
> This allows performing the operation on slices, which was not previously possible because `make_mut()` requires `T: Clone` (and slices, being `!Sized`, do not and currently cannot implement `Clone`).
>
> Feature gate: `make_mut_slice`
try-job: test-various
This requires introducing a new internal type `RcUninit` (and
`ArcUninit`), which can own an `RcBox<T>` without requiring it to be
initialized, sized, or a slice. This is similar to `UniqueRc`, but
`UniqueRc` doesn't support the allocator parameter, and there is no
`UniqueArc`.
This trait allows cloning DSTs, but is unsafe to implement and use
because it writes to possibly-uninitialized memory which must be of the
correct size, and must initialize that memory.
It is only implemented for `T: Clone` and `[T] where T: Clone`, but
additional implementations could be provided for specific `dyn Trait`
or custom-DST types.
Stop using `unlikely` in `strict_*` methods
The `strict_*` methods don't need (un)likely, because the `overflow_panic` calls are all `#[cold]`, [meaning](https://llvm.org/docs/LangRef.html#function-attributes) that LLVM knows any branch to them is unlikely without us needing to say so.
r? libs
Add PidFd::{kill, wait, try_wait}
#117957 changed `Child` kill/wait/try_wait to use its pidfd instead of the pid, when one is available.
This PR extracts those implementations and makes them available on `PidFd` directly.
The `PidFd` implementations differ significantly from the corresponding `Child` methods:
* the methods can be called after the child has been reaped, which will result in an error but will be safe. This state is not observable in `Child` unless something stole the zombie child
* the `ExitStatus` is not kept, meaning that only the first time a wait succeeds it will be returned
* `wait` does not close stdin
* `wait` only requires `&self` instead of `&mut self` since there is no state to maintain and subsequent calls are safe
Tracking issue: #82971
As long as a pidfd is on a child it can be safely reaped. Taking it
would mean the child would now have to be awaited through its pid, but could also
be awaited through the pidfd. This could then suffer from a recycling race.
Rollup of 8 pull requests
Successful merges:
- #126125 (Improve conflict marker recovery)
- #126481 (Add `powerpc-unknown-openbsd` maintenance status)
- #126613 (Print the tested value in int_log tests)
- #126617 (Expand `avx512_target_feature` to include VEX variants)
- #126700 (Make edition dependent `:expr` macro fragment act like the edition-dependent `:pat` fragment does)
- #126707 (Pass target to inaccessible-temp-dir rmake test)
- #126767 (`StaticForeignItem` and `StaticItem` are the same)
- #126774 (Fix another assertion failure for some Expect diagnostics.)
r? `@ghost`
`@rustbot` modify labels: rollup
Print the tested value in int_log tests
Tiny change - from the failures in https://github.com/rust-lang/rust/pull/125016, it would have been nice to see what the tested values were. Update the assertion messages.
It's unnecessary when that arm leads to a `#[cold]` panic anyway, since controlling branch likihood is what `#[cold]` is all about.
(And, well, it's unclear whether `unlikely!` even works these days anyway.)
Account for things that optimize out in inlining costs
This updates the MIR inlining `CostChecker` to have both bonuses and penalties, rather than just penalties.
That lets us add bonuses for some things where we want to encourage inlining without risking wrapping into a gigantic cost. For example, `switchInt(const …)` we give an inlining bonus because codegen will actually eliminate the branch (and associated dead blocks) once it's monomorphized, so measuring both sides of the branch gives an unrealistically-high cost to it. Similarly, an `unreachable` terminator gets a small bonus, because whatever branch leads there doesn't actually exist post-codegen.
Replace sort implementations
This PR replaces the sort implementations with tailor-made ones that strike a balance of run-time, compile-time and binary-size, yielding run-time and compile-time improvements. Regressing binary-size for `slice::sort` while improving it for `slice::sort_unstable`. All while upholding the existing soft and hard safety guarantees, and even extending the soft guarantees, detecting strict weak ordering violations with a high chance and reporting it to users via a panic.
* `slice::sort` -> driftsort [design document](https://github.com/Voultapher/sort-research-rs/blob/main/writeup/driftsort_introduction/text.md), includes detailed benchmarks and analysis.
* `slice::sort_unstable` -> ipnsort [design document](https://github.com/Voultapher/sort-research-rs/blob/main/writeup/ipnsort_introduction/text.md), includes detailed benchmarks and analysis.
#### Why should we change the sort implementations?
In the [2023 Rust survey](https://blog.rust-lang.org/2024/02/19/2023-Rust-Annual-Survey-2023-results.html#challenges), one of the questions was: "In your opinion, how should work on the following aspects of Rust be prioritized?". The second place was "Runtime performance" and the third one "Compile Times". This PR aims to improve both.
#### Why is this one big PR and not multiple?
* The current documentation gives performance recommendations for `slice::sort` and `slice::sort_unstable`. If for example only one of them were to be changed, this advice would be misleading for some Rust versions. By replacing them atomically, the advice remains largely unchanged, and users don't have to change their code.
* driftsort and ipnsort share a substantial part of their implementations.
* The implementation of `select_nth_unstable` uses internals of `slice::sort_unstable`, which makes it impractical to split changes.
---
This PR is a collaboration with `@orlp.`
Remove `feature(const_closures)` from libcore
This is an incomplete feature and apparently it has no uses in `core`. Incomplete features should generally not be used in our standard library.
Clean up some comments near `use` declarations
#125443 will reformat all `use` declarations in the repository. There are a few edge cases involving comments on `use` declarations that require care. This PR cleans up some clumsy comment cases, taking us a step closer to #125443 being able to merge.
r? ``@lqd``
Make Option::as_[mut_]slice const
These two functions can both be made `const`. I have added them to the `const_option_ext` feature, #91930. I don't believe there is anything blocking stabilization of `as_slice`, but `as_mut_slice` contains mutable references so depends on `const_mut_refs`.
Stabilise `c_unwind`
Fix#74990Fix#115285 (that's also where FCP is happening)
Marking as draft PR for now due to `compiler_builtins` issues
r? `@Amanieu`
reword the hint::blackbox non-guarantees
People were tripped up by the "precludes", interpreting it that this function must not ever be used in cryptographic contexts rather than the std lib merely making zero promises about it being fit-for-purpose.
What remains unchanged is that if someone does try to use it *despite the warnings* then it is on them to pin their compiler versions and verify the assembly of every single binary build they do.
Most modules have such a blank line, but some don't. Inserting the blank
line makes it clearer that the `//!` comments are describing the entire
module, rather than the `use` declaration(s) that immediately follows.
This makes their intent and expected location clearer. We see some
examples where these comments were not clearly separate from `use`
declarations, which made it hard to understand what the comment is
describing.
People were tripped up by the "precludes", interpreting it that this function
must not ever be used in cryptographic contexts rather than the std lib merely
making zero promises about it being fit-for-purpose.
What remains unchanged is that if someone does try to use it *despite the warnings*
then it is on them to pin their compiler versions and verify the assembly of every
single binary build they do.