Optimize `is_ascii` for `str` and `[u8]` further
Replace the existing optimized function with one that enables auto-vectorization.
This is especially beneficial on x86-64 as `pmovmskb` can be emitted with careful structuring of the code. The instruction can detect non-ASCII characters one vector register width at a time instead of the current `usize` at a time check.
The resulting implementation is completely safe.
`case00_libcore` is the current implementation, `case04_while_loop` is this PR.
```
benchmarks:
ascii::is_ascii_slice::long::case00_libcore 22.25/iter +/- 1.09
ascii::is_ascii_slice::long::case04_while_loop 6.78/iter +/- 0.92
ascii::is_ascii_slice::medium::case00_libcore 2.81/iter +/- 0.39
ascii::is_ascii_slice::medium::case04_while_loop 1.56/iter +/- 0.78
ascii::is_ascii_slice::short::case00_libcore 5.55/iter +/- 0.85
ascii::is_ascii_slice::short::case04_while_loop 3.75/iter +/- 0.22
ascii::is_ascii_slice::unaligned_both_long::case00_libcore 26.59/iter +/- 0.66
ascii::is_ascii_slice::unaligned_both_long::case04_while_loop 5.78/iter +/- 0.16
ascii::is_ascii_slice::unaligned_both_medium::case00_libcore 2.97/iter +/- 0.32
ascii::is_ascii_slice::unaligned_both_medium::case04_while_loop 2.41/iter +/- 0.10
ascii::is_ascii_slice::unaligned_head_long::case00_libcore 23.71/iter +/- 0.79
ascii::is_ascii_slice::unaligned_head_long::case04_while_loop 7.83/iter +/- 1.31
ascii::is_ascii_slice::unaligned_head_medium::case00_libcore 3.69/iter +/- 0.54
ascii::is_ascii_slice::unaligned_head_medium::case04_while_loop 7.05/iter +/- 0.32
ascii::is_ascii_slice::unaligned_tail_long::case00_libcore 24.44/iter +/- 1.41
ascii::is_ascii_slice::unaligned_tail_long::case04_while_loop 5.12/iter +/- 0.18
ascii::is_ascii_slice::unaligned_tail_medium::case00_libcore 3.24/iter +/- 0.40
ascii::is_ascii_slice::unaligned_tail_medium::case04_while_loop 2.86/iter +/- 0.14
```
`unaligned_head_medium` is the main regression in the benchmarks. It is a 32 byte string being sliced `bytes[1..]`.
The first commit can be used to run the benchmarks against the current core implementation.
Previous implementation was done in #74066
---
Two potential drawbacks of this implementation are that it increases instruction count and may regress other platforms/architectures. The benches here may also be too artificial to glean much insight from.
https://rust.godbolt.org/z/G9znGfY36
Improve prose around into_slice example of IterMut
Having a part without modification and one with seems redundant, since `into_slice` is only called for the part without. I have brought the modification into the remaining part, although it perhaps does not add much (or only distracts?).
Rename `elem_offset` to `element_offset`
Tracking issue: #126769
Renames `slice::elem_offset` to `slice::element_offset` and improves the documentation of it and its related methods.
The current documentation can be misinterpreted (as explained [here](https://github.com/rust-lang/rust/issues/126769#issuecomment-2453363897)).
Mark `slice::copy_from_slice` unstably const
Tracking issue #131415
I used `const_eval_select` for runtime and const panic functions because const formatting isn't available yet.
Bump boostrap compiler to new beta
Currently failing due to something about the const stability checks and `panic!`. I'm not sure why though since I wasn't able to see any PRs merged in the past few days that would result in a `cfg(bootstrap)` that shouldn't be removed. cc `@RalfJung` #131349
Use consistent wording in docs, use is zero instead of is 0
In documentation, wording of _"`rhs` is zero"_ and _"`rhs` is 0"_ is intermixed. This is especially visible [here](https://doc.rust-lang.org/std/primitive.usize.html#method.div_ceil).
This changes all occurrences to _"`rhs` is zero"_ for better readability.
That is, differentiate between out-of-bounds and overlapping indices, and remove the generic parameter `N`.
I also exported `GetManyMutError` from `alloc` (and `std`), which was apparently forgotten.
Changing the error to carry additional details means LLVM no longer generates separate short-circuiting branches for the checks, instead it generates one branch at the end. I therefore changed the code to use early returns to make LLVM generate jumps. Benchmark results between the approaches are somewhat mixed, but I chose this approach because it is significantly faster with ranges and also faster with `unwrap()`.
Add `as_array` and `as_mut_array` conversion methods to slices.
Tracking issue: #133508
This PR unstably implements the `as_array` and `as_mut_array` converters to `[T]`, `*const [T]`, and `*mut [T]`.
Support ranges in `<[T]>::get_many_mut()`
As per T-libs-api decision in #104642.
I implemented that with a separate trait and not within `SliceIndex`, because doing that via `SliceIndex` requires adding support for range types that are (almost) always overlapping e.g. `RangeFrom`, and also adding fake support code for `impl SliceIndex<str>`.
An inconvenience that I ran into was that slice indexing takes the index by value, but I only have it by reference. I could change slice indexing to take by ref, but this is pretty much the hottest code ever so I'm afraid to touch it. Instead I added a requirement for `Clone` (which all index types implement anyway) and cloned. This is an internal requirement the user won't see and the clone should always be optimized away.
I also implemented `Clone`, `PartialEq` and `Eq` for the error type, since I noticed it does not do that when writing the tests and other errors in std seem to implement them. I didn't implement `Copy` because maybe we will want to put something non-`Copy` there.
I implemented that with a separate trait and not within `SliceIndex`, because doing that via `SliceIndex` requires adding support for range types that are (almost) always overlapping e.g. `RangeFrom`, and also adding fake support code for `impl SliceIndex<str>`.
An inconvenience that I ran into was that slice indexing takes the index by value, but I only have it by reference. I could change slice indexing to take by ref, but this is pretty much the hottest code ever so I'm afraid to touch it. Instead I added a requirement for `Clone` (which all index types implement anyway) and cloned. This is an internal requirement the user won't see and the clone should always be optimized away.
I also implemented `Clone`, `PartialEq` and `Eq` for the error type, since I noticed it does not do that when writing the tests and other errors in std seem to implement them. I didn't implement `Copy` because maybe we will want to put something non-`Copy` there.
Use attributes for `dangling_pointers_from_temporaries` lint
Checking for dangling pointers by function name isn't ideal, and leaves out certain pointer-returning methods that don't follow the `as_ptr` naming convention. Using an attribute for this lint cleans things up and allows more thorough coverage of other methods, such as `UnsafeCell::get()`.
The new `is_ascii` function is optimized to use the
`pmovmskb` vector instruction which tests the high bit in a lane.
This corresponds to the same check of whether a byte is ASCII so
ASCII validity checking can be vectorized. This instruction
does not exist on other platforms so it is likely to regress performance
and is gated to all(target_arch = "x86_64", target_feature = "sse2").
Add codegen test
Remove crate::mem import for functions included in the prelude
remove const-support for align_offset and is_aligned
As part of the recent discussion to stabilize `ptr.is_null()` in const context, the general vibe was that it's okay for a const function to panic when the same operation would work at runtime (that's just a case of "dynamically detecting that something is not supported as a const operation"), but it is *not* okay for a const function to just return a different result.
Following that, `is_aligned` and `is_aligned_to` have their const status revoked in this PR, since they do return actively wrong results at const time. In the future we can consider having a new intrinsic or so that can check whether a pointer is "guaranteed to be aligned", but the current implementation based on `align_offset` does not have the behavior we want.
In fact `align_offset` itself behaves quite strangely in const, and that support needs a bunch of special hacks. That doesn't seem worth it. Instead, the users that can fall back to a different implementation should just use const_eval_select directly, and everything else should not be made const-callable. So this PR does exactly that, and entirely removes const support for align_offset.
Closes some tracking issues by removing the associated features:
Closes https://github.com/rust-lang/rust/issues/90962
Closes https://github.com/rust-lang/rust/issues/104203
Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
Yeet the `effects` feature, move it onto `const_trait_impl`
This PR merges the `effects` feature into the `const_trait_impl` feature. There's really no need to have two feature gates for one feature.
After this PR, if `const_trait_impl` **is** enabled:
* Users can use and define const traits
* `HostEffect` const conditions will be enforced on the HIR
* We re-check the predicates in MIR just to make sure that we don't "leak" anything during MIR lowering
And if `const_trait_impl` **is not** enabled:
* Users cannot use nor define const traits
* `HostEffect` const conditions are not enforced on the HIR
* We will raise a const validation error if we call a function that has any const conditions (i.e. const traits and functions with any `~const` in their where clasues)
This should be the last step for us to be able to enable const traits in the standard library. We still need to re-constify `Drop` and `Destruct` and stuff for const traits to be particularly *useful* for some cases, but this is a good step :D
r? fee1-dead
cc `@rust-lang/project-const-traits`
Operations like is_aligned would return actively wrong results at compile-time,
i.e. calling it on the same pointer at compiletime and runtime could yield
different results. That's no good.
Instead of having hacks to make align_offset kind-of work in const-eval, just
use const_eval_select in the few places where it makes sense, which also ensures
those places are all aware they need to make sure the fallback behavior is
consistent.