MIRI says `reverse` is UB, so replace it with something LLVM can vectorize
For small types with padding, the current implementation is UB because it does integer operations on uninit values.
```
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:836:5
|
836 | / uint_impl! { u32, u32, i32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
837 | | "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
| |________________________________________________________________________________________________^ using uninitialized data, but this operation requires initialized memory
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: inside `core::num::<impl u32>::rotate_left` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/uint_macros.rs:211:13
= note: inside `core::slice::<impl [Foo]>::reverse` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/mod.rs:701:58
```
<https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=340739f22ca5b457e1da6f361768edc6>
But LLVM has gotten smarter since I wrote the previous implementation in 2017, so this PR removes all the manual magic and just writes it in such a way that LLVM will vectorize. This code is much simpler and has very little `unsafe`, and is actually faster to boot!
If you're curious to see the codegen: <https://rust.godbolt.org/z/Pcn13Y9E3>
Before:
```
running 7 tests
test slice::reverse_simd_f64x4 ... bench: 17,940 ns/iter (+/- 481) = 58448 MB/s
test slice::reverse_u128 ... bench: 17,758 ns/iter (+/- 205) = 59048 MB/s
test slice::reverse_u16 ... bench: 158,234 ns/iter (+/- 6,876) = 6626 MB/s
test slice::reverse_u32 ... bench: 62,047 ns/iter (+/- 1,117) = 16899 MB/s
test slice::reverse_u64 ... bench: 31,582 ns/iter (+/- 552) = 33201 MB/s
test slice::reverse_u8 ... bench: 81,253 ns/iter (+/- 1,510) = 12905 MB/s
test slice::reverse_u8x3 ... bench: 270,615 ns/iter (+/- 11,463) = 3874 MB/s
```
After:
```
running 7 tests
test slice::reverse_simd_f64x4 ... bench: 17,731 ns/iter (+/- 306) = 59137 MB/s
test slice::reverse_u128 ... bench: 17,919 ns/iter (+/- 239) = 58517 MB/s
test slice::reverse_u16 ... bench: 43,160 ns/iter (+/- 607) = 24295 MB/s
test slice::reverse_u32 ... bench: 21,065 ns/iter (+/- 371) = 49778 MB/s
test slice::reverse_u64 ... bench: 21,118 ns/iter (+/- 482) = 49653 MB/s
test slice::reverse_u8 ... bench: 76,878 ns/iter (+/- 1,688) = 13639 MB/s
test slice::reverse_u8x3 ... bench: 264,723 ns/iter (+/- 5,544) = 3961 MB/s
```
Those are the existing benches, <14a2fd640e/library/alloc/benches/slice.rs (L322-L346)>
stabilize format args capture
Works as expected, and there are widespread reports of success with it, as well as interest in it.
RFC: rust-lang/rfcs#2795
Tracking issue: https://github.com/rust-lang/rust/issues/67984
Addressing items from the tracking issue:
- We don't support capturing arguments from a non-literal format string like `format_args!(concat!(...))`. We could add that in a future enhancement, or we can decide that it isn't supported (as suggested in https://github.com/rust-lang/rust/issues/67984#issuecomment-801394736 ).
- I've updated the documentation.
- `panic!` now supports capture as well.
- There are potentially opportunities to further improve diagnostics for invalid usage, such as if it looks like the user tried to use an expression rather than a variable. However, such cases are all already caught and provide reasonable syntax errors now, and we can always provided even friendlier diagnostics in the future.
Fix ld64 flags
- The `-exported_symbols_list` argument appears to be malformed for `ld64` (if you are not going through `clang`).
- The `-dynamiclib` argument isn't support for `ld64`. It should be guarded behind a compiler flag.
These problems are fixed by these changes. I have also refactored the way linker arguments are generated to be ld/compiler agnostic and therefore less error prone.
These changes are necessary to support cross-compilation to darwin targets.
Implement diagnostic for String conversion
This is my first real contribution to rustc, any feedback is highly appreciated.
This should fix https://github.com/rust-lang/rust/issues/89856
Thanks to `@estebank` for guiding me.
Change paths for `dist` command to match the components they generate
Before, you could have the confusing situation where the command to
generate a component had no relation to the name of that component (e.g.
the `rustc` component was generated with `src/librustc`). This changes
the name to make them match up.
Optimize BinaryHeap::extend from Vec
This improves the performance of extending `BinaryHeap`s from vectors directly. Future work may involve extending this optimization to other, similar, cases where the length of the added elements is well-known, but this is not yet done in this PR.
Generate documentation in rustc `rustc_index::newtype_index` macro
The macro now documents all generated items. Documentation notes possible panics and unsafety.
Remove unneeded FIXMEs comments in search index generation
Original comment:
> Instead of recreating a new `vec` for each arguments, we re-use the same. The impact on performance should be minor but worth a try.
After testing it, we reached the conclusion that the code readability drop wasn't worth the almost unnoticeable performance improvement.
r? `@camelid`
This commit refactors linker argument generation to leverage a helper
function that abstracts away details governing how these arguments are
transformed and provided to the linker.
This fixes the misuse of the `-exported_symbols_list` when an ld-like
linker is used rather than a compiler. A compiler would expect
`-Wl,-exported_symbols_list,path` but ld would expect
`-exported_symbols_list` and `path` as two seperate arguments. Prior
to this change, an ld-like linker was given
`-exported_symbols_list,path`.
Linker arguments must transformed when Rust is interacting with the
linker through a compiler. This commit introduces a helper function
that abstracts away details of this transformation.
Fix trait object error code
closes#90768
I `grep`:d and changed the occurrences that seemed relevant. Please let me know what you think and if anything is missing!
Stabilize `const_raw_ptr_deref` for `*const T`
This stabilizes dereferencing immutable raw pointers in const contexts.
It does not stabilize `*mut T` dereferencing. This is behind the
same feature gate as mutable references.
closes https://github.com/rust-lang/rust/issues/51911
Make RawVec private to alloc
RawVec was previously exposed for compiler-internal use (libarena specifically) in 1acbb0a935
Since it is unstable, doc-hidden and has no associated tracking issue it was never meant for public use. And since
it is no longer used outside alloc itself it can be made private again.
Also remove some functions that are dead due to lack of internal users.
Before, you could have the confusing situation where the command to
generate a component had no relation to the name of that component (e.g.
the `rustc` component was generated with `src/librustc`). This changes
the name to make them match up.
proc_macro: Add an expand_expr method to TokenStream
This feature is aimed at giving proc macros access to powers similar to those used by builtin macros such as `format_args!` or `concat!`. These macros are able to accept macros in place of string literal parameters, such as the format string, as they perform recursive macro expansion while being expanded.
This can be especially useful in many cases thanks to helper macros like `concat!`, `stringify!` and `include_str!` which are often used to construct string literals at compile-time in user code.
For now, this method only allows expanding macros which produce literals, although more expressions will be supported before the method is stabilized.
In earlier versions of this PR, this method exclusively returned `Literal`, and spans on returned literals were stripped of expansion context before being returned to be as conservative as possible about permission leakage. The method's naming has been generalized to eventually support arbitrary expressions, and the context stripping has been removed (https://github.com/rust-lang/rust/pull/87264#discussion_r674863279), which should allow for more general APIs like "format_args_implicits" (https://github.com/rust-lang/rust/issues/67984) to be supported as well.
## API Surface
```rust
impl TokenStream {
pub fn expand_expr(&self) -> Result<TokenStream, ExpandError>;
}
#[non_exhaustive]
pub struct ExpandError;
impl Debug for ExpandError { ... }
impl Display for ExpandError { ... }
impl Error for ExpandError {}
impl !Send for ExpandError {}
impl !Sync for ExpandError {}
```
Re-enable `copy[_nonoverlapping]()` debug-checks
This commit re-enables the debug checks for valid usages of the two functions `copy()` and `copy_nonoverlapping()`. Those checks were commented out in #79684 in order to make the functions const. All that's been left was a FIXME, that could not be resolved until there is was way to only do the checks at runtime.
Since #89247 there is such a way: `const_eval_select()`. This commit uses that new intrinsic in order to either do nothing (at compile time) or to do the old checks (at runtime).
The change itself is rather small: in order to make the checks usable with `const_eval_select`, they are moved into a local function (one for `copy` and one for `copy_nonoverlapping` to keep symmetry).
The change does not break referential transparency, as there is nothing you can do at compile time, which you cannot do on runtime without getting undefined behavior. The CTFE-engine won't allow missuses. The other way round is also fine.
I've refactored the code to use `#[cfg(debug_assertions)]` on the new items. If that is not desired, the second commit can be dropped.
I haven't added any checks, as I currently don't know, how to test this properly.
Closes#90012.
cc `@rust-lang/lang,` `@rust-lang/libs` and `@rust-lang/wg-const-eval` (as those teams are linked in the issue above).
pub use core::simd;
A portable abstraction over SIMD has been a major pursuit in recent years for several programming languages. In Rust, `std::arch` offers explicit SIMD acceleration via compiler intrinsics, but it does so at the cost of having to individually maintain each and every single such API, and is almost completely `unsafe` to use. `core::simd` offers safe abstractions that are resolved to the appropriate SIMD instructions by LLVM during compilation, including scalar instructions if that is all that is available.
`core::simd` is enabled by the `#![portable_simd]` nightly feature tracked in https://github.com/rust-lang/rust/issues/86656 and is introduced here by pulling in the https://github.com/rust-lang/portable-simd repository as a subtree. We built the repository out-of-tree to allow faster compilation and a stochastic test suite backed by the proptest crate to verify that different targets, features, and optimizations produce the same result, so that using this library does not introduce any surprises. As these tests are technically non-deterministic, and thus can introduce overly interesting Heisenbugs if included in the rustc CI, they are visible in the commit history of the subtree but do nothing here. Some tests **are** introduced via the documentation, but these use deterministic asserts.
There are multiple unsolved problems with the library at the current moment, including a want for better documentation, technical issues with LLVM scalarizing and lowering to libm, room for improvement for the APIs, and so far I have not added the necessary plumbing for allowing the more experimental or libm-dependent APIs to be used. However, I thought it would be prudent to open this for review in its current condition, as it is both usable and it is likely I am going to learn something else needs to be fixed when bors tries this out.
The major types are
- `core::simd::Simd<T, N>`
- `core::simd::Mask<T, N>`
There is also the `LaneCount` struct, which, together with the SimdElement and SupportedLaneCount traits, limit the implementation's maximum support to vectors we know will actually compile and provide supporting logic for bitmasks. I'm hoping to simplify at least some of these out of the way as the compiler and library evolve.
These tests just verify some basic APIs of core::simd function, and
guarantees that attempting to access the wrong things doesn't work.
The majority of tests are stochastic, and so remain upstream, but
a few deterministic tests arrive in the subtree as doc tests.
This enables programmers to use a safe alternative to the current
`extern "platform-intrinsics"` API for writing portable SIMD code.
This is `#![feature(portable_simd)]` as tracked in #86656
This feature is aimed at giving proc macros access to powers similar to
those used by builtin macros such as `format_args!` or `concat!`. These
macros are able to accept macros in place of string literal parameters,
such as the format string, as they perform recursive macro expansion
while being expanded.
This can be especially useful in many cases thanks to helper macros like
`concat!`, `stringify!` and `include_str!` which are often used to
construct string literals at compile-time in user code.
For now, this method only allows expanding macros which produce
literals, although more expresisons will be supported before the method
is stabilized.
Document `unreachable!` custom panic message
The `unreachable!` docs previously did not mention that there was a second form, `unreachable!("message")` that could be used to specify a custom panic message,
The docs now mention this feature in the same wording as currently used for `unimplemented!`:
https://doc.rust-lang.org/core/macro.unimplemented.html#panics
Add more comments to explain the code to generate the search index
Fixes#90766.
I tried to put comments when the code wasn't easy to understand at first sight and added more documentation on the recursive function. Please tell me if I misused the terminology or if comments can be improved or added into other places.
r? `@notriddle`
Shorten Span of unused macro lints
The span has been reduced to the actual ident of the macro, instead of linting the
*whole* macro.
Closes#90745
r? ``@estebank``