Clarify UB in `get_unchecked(_mut)`
Inspired by #116915, it was unclear to me what exactly "out-of-bounds index" means in `get_unchecked`.
One could [potentially](https://rust.godbolt.org/z/hxM764orW) interpret it that `get_unchecked` is just another way to write `offset`, but I think `get_unchecked(len)` is supposed to be UB even though `.offet(len)` is well-defined (as is `.get_unchecked(..len)`), so write that more directly in the docs.
**libs-api folks**: Can you confirm whether this is what you expect this to mean? And is the situation any different for `<*const [T]>::get_unchecked`?
Refactor the if/else checking on cmp::Ordering variants to a
"branchless" reassignment of left and right. This change results
in fewer branches and instructions.
The branchy Hoare partition `partition_equal` as part of `slice::sort_unstable`
has a bug that makes it perform a comparison of the last element twice.
Measuring inputs with a Zipfian distribution with characterizing exponent s ==
1.0, yields a ~0.05% reduction in the total number of comparisons performed.
This makes it so that all the matchers that match against paths use the
definition path instead of the export path. This removes all duplication
around `std`/`alloc`/`core`.
This is not necessarily optimal because we now depend on internal
implementation details like `core::ops::control_flow::ControlFlow`,
which is not very nice and probably not acceptable for a stable
`on_unimplemented`.
An alternative would be to just string-replace normalize away
`alloc`/`core` to `std` as a special case, keeping the export paths but
making it so that we're still fully standard library flavor agnostic.
Implement `slice::split_once` and `slice::rsplit_once`
Feature gate is `slice_split_once` and tracking issue is #112811. These are equivalents to the existing `str::split_once` and `str::rsplit_once` methods.
Make useless_ptr_null_checks smarter about some std functions
This teaches the `useless_ptr_null_checks` lint that some std functions can't ever return null pointers, because they need to point to valid data, get references as input, etc.
This is achieved by introducing an `#[rustc_never_returns_null_ptr]` attribute and adding it to these std functions (gated behind bootstrap `cfg_attr`).
Later on, the attribute could maybe be used to tell LLVM that the returned pointer is never null. I don't expect much impact of that though, as the functions are pretty shallow and usually the input data is already never null.
Follow-up of PR #113657Fixes#114442
slice::from_raw_parts: mention no-wrap-around condition
Cc https://github.com/rust-lang/rust/issues/83996. This probably needs to be mentioned in more places, so I am not closing that issue, but this here should help at least.
Update runtime guarantee for `select_nth_unstable`
#106933 changed the runtime guarantee for `select_nth_unstable` from O(n) to O(n log n), since the old guarantee wasn't actually met by the implementation at the time. Now with #107522, `select_nth_unstable` should be truly linear in runtime, so we can revert its runtime guarantee to O(n). Since #106933 was considered a bug fix, this will probably need an FCP because it counts as a new API guarantee.
r? `@Amanieu`
Add Median of Medians fallback to introselect
Fixes#102451.
This PR is a follow up to #106997. It adds a Fast Deterministic Selection implementation as a fallback to the introselect algorithm used by `select_nth_unstable`. This allows it to guarantee O(n) worst case running time, while maintaining good performance in all cases.
This would fix#102451, which was opened because the `select_nth_unstable` docs falsely claimed that it had O(n) worst case performance, even though it was actually quadratic in the worst case. #106997 improved the worst case complexity to O(n log n) by using heapsort as a fallback, and this PR further improves it to O(n) (this would also make #106933 unnecessary).
It also improves the actual runtime if the fallback gets called: Using a pathological input of size `1 << 19` (see the playground link in #102451), calculating the median is roughly 3x faster using fast deterministic selection as a fallback than it is using heapsort.
The downside to this is less code reuse between the sorting and selection algorithms, but I don't think it's that bad. The additional algorithms are ~250 LOC with no `unsafe` blocks (I tried using unsafe to avoid bounds checks but it didn't noticeably improve the performance).
I also let it fuzz for a while against the current `select_nth_unstable` implementation to ensure correctness, and it seems to still fulfill all the necessary postconditions.
cc `@scottmcm` who reviewed #106997
Use code with reliable branchless code-gen for slice::sort merge
The recent LLVM 16 update changes code-gen to be not branchless anymore, in the slice::sort implementation merge function. This improves performance by 30% for random patterns, restoring the performance to the state with LLVM 15.
Fixes#111559
The recent LLVM 16 update changes code-gen to be not branchless anymore, in the
slice::sort implementation merge function. This improves performance by 30% for
random patterns, restoring the performance to the state with LLVM 15.
Stabilize const slice::split_at
This stabilizes the use of the following method in const context:
```rust
impl<T> [T] {
pub const fn split_at(&self, mid: usize) -> (&[T], &[T]);
}
```
cc tracking issue #101158