Stabilize `const_waker`
Closes: https://github.com/rust-lang/rust/issues/102012.
For `local_waker` and `context_ext` related things, I just ~~moved them to dedicated feature gates and reused their own tracking issue (maybe it's better to open a new one later, but at least they should not be tracked under https://github.com/rust-lang/rust/issues/102012 from the beginning IMO.)~~ reused their own feature gates as suggested by ``@tgross35.``
``@rustbot`` label: +T-libs-api
r? libs-api
add `is_multiple_of` for unsigned integer types
tracking issue: https://github.com/rust-lang/rust/issues/128101
This adds the `.is_multiple_of` method on unsigned integers.
Returns `true` if `self` is an integer multiple of `rhs`, and false otherwise.
This function is equivalent to `self % rhs == 0`, except that it will not panic for `rhs == 0`. Instead, `0.is_multiple_of(0) == true`, and for any non-zero `n`, `n.is_multiple_of(0) == false`.
Stabilize const `{integer}::from_str_radix` i.e. `const_int_from_str`
This PR stabilizes the feature `const_int_from_str`.
- ACP Issue: rust-lang/libs-team#74
- Implementation PR: rust-lang/rust#99322
- Part of Tracking Issue: rust-lang/rust#59133
API Change Diff:
```diff
impl {integer} {
- pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
+ pub const fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
}
impl ParseIntError {
- pub fn kind(&self) -> &IntErrorKind;
+ pub const fn kind(&self) -> &IntErrorKind;
}
```
This makes it easier to parse integers at compile-time, e.g.
the example from the Tracking Issue:
```rust
env!("SOMETHING").parse::<usize>().unwrap()
```
could now be achived with
```rust
match usize::from_str_radix(env!("SOMETHING"), 10) {
Ok(val) => val,
Err(err) => panic!("Invalid value for SOMETHING environment variable."),
}
```
rather than having to depend on a library that implements or manually implement the parsing at compile-time.
---
Checklist based on [Libs Stabilization Guide - When there's const involved](https://std-dev-guide.rust-lang.org/development/stabilization.html#when-theres-const-involved)
I am treating this as a [partial stabilization](https://std-dev-guide.rust-lang.org/development/stabilization.html#partial-stabilizations) as it shares a tracking issue (and is rather small), so directly opening the partial stabilization PR for the subset (feature `const_int_from_str`) being stabilized.
- [x] ping Constant Evaluation WG
- [x] no unsafe involved
- [x] no `#[allow_internal_unstable]`
- [ ] usage of `intrinsic::const_eval_select` rust-lang/rust#124625 in `from_str_radix_assert` to change the error message between compile-time and run-time
- [ ] [rust-labg/libs-api FCP](https://github.com/rust-lang/rust/pull/124941#issuecomment-2207021921)
This is possible now that inline const blocks are stable; the idea was
even mentioned as an alternative when `uninit_array()` was added:
<https://github.com/rust-lang/rust/pull/65580#issuecomment-544200681>
> if it’s stabilized soon enough maybe it’s not worth having a
> standard library method that will be replaceable with
> `let buffer = [MaybeUninit::<T>::uninit(); $N];`
Const array repetition and inline const blocks are now stable (in the
next release), so that circumstance has come to pass, and we no longer
have reason to want `uninit_array()` other than convenience. Therefore,
let’s evaluate the inconvenience by not using `uninit_array()` in
the standard library, before potentially deleting it entirely.
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 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.
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.`
The addition of `core::iter::zip` (#82917) set a precedent for adding
plain functions for iterator adaptors. Adding `chain` makes it a little
easier to `chain` two iterators.
```
for (x, y) in chain(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().chain(ys) {}
```
- `slice::sort` -> driftsort
https://github.com/Voultapher/sort-research-rs/blob/main/writeup/driftsort_introduction/text.md
- `slice::sort_unstable` -> ipnsort
https://github.com/Voultapher/sort-research-rs/blob/main/writeup/ipnsort_introduction/text.md
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.
In addition the implementation of `select_nth_unstable` is also adapted
as it uses `slice::sort_unstable` internals.
Add `Ord::cmp` for primitives as a `BinOp` in MIR
Update: most of this OP was written months ago. See https://github.com/rust-lang/rust/pull/118310#issuecomment-2016940014 below for where we got to recently that made it ready for review.
---
There are dozens of reasonable ways to implement `Ord::cmp` for integers using comparison, bit-ops, and branches. Those differences are irrelevant at the rust level, however, so we can make things better by adding `BinOp::Cmp` at the MIR level:
1. Exactly how to implement it is left up to the backends, so LLVM can use whatever pattern its optimizer best recognizes and cranelift can use whichever pattern codegens the fastest.
2. By not inlining those details for every use of `cmp`, we drastically reduce the amount of MIR generated for `derive`d `PartialOrd`, while also making it more amenable to MIR-level optimizations.
Having extremely careful `if` ordering to μoptimize resource usage on broadwell (#63767) is great, but it really feels to me like libcore is the wrong place to put that logic. Similarly, using subtraction [tricks](https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign) (#105840) is arguably even nicer, but depends on the optimizer understanding it (https://github.com/llvm/llvm-project/issues/73417) to be practical. Or maybe [bitor is better than add](https://discourse.llvm.org/t/representing-in-ir/67369/2?u=scottmcm)? But maybe only on a future version that [has `or disjoint` support](https://discourse.llvm.org/t/rfc-add-or-disjoint-flag/75036?u=scottmcm)? And just because one of those forms happens to be good for LLVM, there's no guarantee that it'd be the same form that GCC or Cranelift would rather see -- especially given their very different optimizers. Not to mention that if LLVM gets a spaceship intrinsic -- [which it should](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Suboptimal.20inlining.20in.20std.20function.20.60binary_search.60/near/404250586) -- we'll need at least a rustc intrinsic to be able to call it.
As for simplifying it in Rust, we now regularly inline `{integer}::partial_cmp`, but it's quite a large amount of IR. The best way to see that is with 8811efa88b (diff-d134c32d028fbe2bf835fef2df9aca9d13332dd82284ff21ee7ebf717bfa4765R113) -- I added a new pre-codegen MIR test for a simple 3-tuple struct, and this PR change it from 36 locals and 26 basic blocks down to 24 locals and 8 basic blocks. Even better, as soon as the construct-`Some`-then-match-it-in-same-BB noise is cleaned up, this'll expose the `Cmp == 0` branches clearly in MIR, so that an InstCombine (#105808) can simplify that to just a `BinOp::Eq` and thus fix some of our generated code perf issues. (Tracking that through today's `if a < b { Less } else if a == b { Equal } else { Greater }` would be *much* harder.)
---
r? `@ghost`
But first I should check that perf is ok with this
~~...and my true nemesis, tidy.~~
core: add Duration constructors
Add more `Duration` constructors.
Tracking issue: #120301.
These match similar convenience constructors available on both `chrono::Duration` and `time::Duration`.
What's the best ordering for these with respect to the existing constructors?
stabilise array methods
Closes#76118
Stabilises the remaining array methods
FCP is yet to be carried out for this
There wasn't a clear consensus on the naming, but all the other alternatives had some flaws as discussed in the tracking issue and there was a silence on this issue for a year