This adds method similar to `MaybeUninit::write` main difference being
it returns owned `Box`. This can be used to elide copy from stack
safely, however it's not currently tested that the optimization actually
occurs.
Analogous methods are not provided for `Rc` and `Arc` as those need to
handle the possibility of sharing. Some version of them may be added in
the future.
This was discussed in #63291 which this change extends.
Bump compiler_builtins to 0.1.55 to bring in fixes for targets lackin…
…g atomic support.
This fixes a "Cannot select" LLVM error when compiling `compiler_builtins` for targets lacking atomics, like MSP430. Se https://github.com/rust-lang/compiler-builtins/issues/441 for more info. This PR is a more general version of #91248.
Introduce `RawVec::reserve_for_push`.
If `Vec::push`'s capacity check fails it calls `RawVec::reserve`, which
then also does a capacity check.
This commit introduces `reserve_for_push` which skips the redundant
capacity check, for some slight compile time speed-ups.
I tried lots of minor variations on this, e.g. different inlining
attributes. This was the best one I could find.
r? `@ghost`
CTFE: support assert_zero_valid and assert_uninit_valid
This ensures the implementation of all three type-based assert_ intrinsics remains consistent in Miri.
`assert_inhabited` recently got stabilized in https://github.com/rust-lang/rust/pull/90896 (meaning stable `const fn` can call it), so do the same with these other intrinsics.
Cc ```@rust-lang/wg-const-eval```
All callers already check that the buffer is full before calling
`grow()`. This is where it makes the most sense, since `grow()` is
`inline(never)` and we don't want to pay for a function call just for
that check.
It could also be argued that it would be correct to call `grow()` even
if the buffer wasn't full yet.
This change breaks no code since `grow()` is not `pub`.
Eliminate bunch of copies of error codepath from Utf8LossyChunksIter
Using a macro to stamp out 7 identical copies of the nontrivial slicing logic to exit this loop didn't seem like a necessary use of a macro. The early return case can be handled by `break` without practically any changes to the logic inside the loop.
All this code is from early 2014 (#12062—nearly 8 years ago; pre-1.0) so it's possible there were compiler limitations that forced the macro way at the time.
Confirmed that `x.py bench library/alloc --stage 0 --test-args from_utf8_lossy` is unaffected on my machine.
If `Vec::push`'s capacity check fails it calls `RawVec::reserve`, which
then also does a capacity check.
This commit introduces `reserve_for_push` which skips the redundant
capacity check, for some slight compile time speed-ups.
I tried lots of minor variations on this, e.g. different inlining
attributes. This was the best one I could find.
This commit is intended to follow the stabilization disposition of the
FCP that has now finished in #84223. This stabilizes the ability to flag
thread local initializers as `const` expressions which enables the macro
to generate more efficient code for accessing it, notably removing
runtime checks for initialization.
More information can also be found in #84223 as well as the tests where
the feature usage was removed in this PR.
Closes#84223
Stabilize some `MaybeUninit` behavior as const
This stabilizes the `MaybeUninit::as_ptr`, `MaybeUninit::assume_init`, and `MaybeUninit::assume_init_ref` as `const fn`. `MaybeUninit::as_mut_ptr` has been moved to a new flag: `const_maybe_uninit_as_mut_ptr`, which is blocked on #57349. `MaybeUninit::slice_assume_init_ref` can be `const fn` when the method is stabilized in general.
The relevant intrinsic has been stabilized as `const` as well, though this isn't user-visible. Due to the seemingly unrelated feature name I performed `rg const_assert_type` and found no other instances of it being used.
r? `@oli-obk`
`@rustbot` label: +A-const-fn +S-waiting-on-review +T-libs-api
Eliminate an unreachable codepath from String::from_utf8_lossy
`Utf8Lossy`'s `Iterator` implementation ensures that only the **final** chunk has an empty slice for `broken`:
dd549dcab4/library/core/src/str/lossy.rs (L46-L47)
Thus the only way the **first** chunk could have an empty `broken` is if it is the **final** chunk, i.e. there is only one chunk total. And the only way that there could be one chunk total with an empty `broken` is if the whole input is valid utf8 and non-empty.
That condition has already been handled by an early return, so at the point that the first `REPLACEMENT` is being pushed, it's impossible for `first_broken` to be empty.
Fix Iterator::advance_by contract inconsistency
The `advance_by(n)` docs state that in the error case `Err(k)` that k is always less than n.
It also states that `advance_by(0)` may return `Err(0)` to indicate an exhausted iterator.
These statements are inconsistent.
Since only one implementation (Skip) actually made use of that I changed it to return Ok(()) in that case too.
While adding some tests I also found a bug in `Take::advance_back_by`.
Expand `available_parallelism` docs in anticipation of cgroup quota support
The "fixed" in "fixed steady state limits" means to exclude load-dependent resource prioritization
that would calculate to 100% of capacity on an idle system and less capacity on a loaded system.
Additionally I also exclude "system load" since it would be silly to try to identify
other, perhaps higher priority, processes hogging some CPU cores that aren't explicitly excluded
by masks/quotas/whatever.
Document non-guarantees for Hash
Dependence on endianness and type sizes was reported for enum discriminants in #74215 but it is a more general
issue since for example the default implementation of `Hasher::write_usize` uses native endianness.
Additionally the implementations of library types are occasionally changed as their internal fields
change or hashing gets optimized.
## Question
Should this go on the module level documentation instead since it also concerns `Hasher` to some extent and not just `Hash`?
resolves#74215
Weaken guarantee around advancing underlying iterators in zip
The current guarantee (introduced in #52279) is too strong as it prevents adapters from exploiting knowledge about the iterator length and using counted loops for example because they would stop calling `next()` before it ever returned `None`. Additionally several nested zip iterators already fail to uphold this.
This does not yet remove any of the specialization code that tries (and sometimes fails) to uphold the guarantee for `next()`
because removing it would also affect `next_back()` in more surprising ways.
The intent is to be able to remove for example this branch
36bcf40697/library/core/src/iter/adapters/zip.rs (L234-L243)
or this test
36bcf40697/library/core/tests/iter/adapters/zip.rs (L177-L188)
Solves #82303 by declaring it a non-issue.
Refactor weak symbols in std::sys::unix
This makes a few changes to the weak symbol macros in `sys::unix`:
- `dlsym!` is added to keep the functionality for runtime `dlsym`
lookups, like for `__pthread_get_minstack@GLIBC_PRIVATE` that we don't
want to show up in ELF symbol tables.
- `weak!` now uses `#[linkage = "extern_weak"]` symbols, so its runtime
behavior is just a simple null check. This is also used by `syscall!`.
- On non-ELF targets (macos/ios) where that linkage is not known to
behave, `weak!` is just an alias to `dlsym!` for the old behavior.
- `raw_syscall!` is added to always call `libc::syscall` on linux and
android, for cases like `clone3` that have no known libc wrapper.
The new `weak!` linkage does mean that you'll get versioned symbols if
you build with a newer glibc, like `WEAK DEFAULT UND statx@GLIBC_2.28`.
This might seem problematic, but old non-weak symbols can tie the build
to new versions too, like `dlsym@GLIBC_2.34` from their recent library
unification. If you build with an old glibc like `dist-x86_64-linux`
does, you'll still get unversioned `WEAK DEFAULT UND statx`, which may
be resolved based on the runtime glibc.
I also found a few functions that don't need to be weak anymore:
- Android can directly use `ftruncate64`, `pread64`, and `pwrite64`, as
these were added in API 12, and our baseline is API 14.
- Linux can directly use `splice`, added way back in glibc 2.5 and
similarly old musl. Android only added it in API 21 though.
Saner formatting for UTF8_CHAR_WIDTH table
The way these lines were currently wrapped definitely does not look like someone's intentional formatting. It's likely they got disfigured by rustfmt at some point.
This commit rearranges it to a rustfmt-compatible formatting that I find easier to read.
Faster `Layout::array`
`Layout::array` is called (indirectly) by `Vec::push()`, which is typically instantiated many times, and so making it smaller can help with compile times because less LLVM IR is generated.
r? `@ghost`
If the thread does not get the lock in the short term, yield the CPU
Reduces on [RustyHermit](https://github.com/hermitcore/rusty-hermit) the amount of wasted processor cycles
The current implementation is much more conservative than it needs to
be, because it's dealing with the size and alignment of a given `T`,
which are more restricted than an arbitrary `Layout`.
For example, imagine a struct with a `u32` and a `u4`. You can safely
create a `Layout { size_: 5, align_: 4 }` by hand, but
`Layout:🆕:<T>` will give `Layout { size_: 8, align_: 4}`, where the
size already has padding that accounts for the alignment. (And the
existing `debug_assert_eq!` in `Layout::array` already demonstrates that
no additional padding is required.)
Using a macro to stamp out 7 identical copies of the nontrivial slicing
logic to exit this loop didn't seem like a necessary use of a macro. The
early return case can be handled by `break` without practically any
changes to the logic inside the loop.
All this code is from early 2014 (7.5 years old, pre-1.0) so it's
possible there were compiler limitations that forced the macro way at
the time.
Confirmed that `x.py bench library/alloc --stage 0 --test-args from_utf8_lossy`
is unaffected on my machine.
Utf8Lossy's Iterator implementation ensures that only the final chunk
has an empty slice for broken. Thus the only way the first chunk could
have an empty broken is if it is the final chunk, i.e. there is only one
chunk total. And the only way that there could be one chunk total is if
the whole input is valid utf8 and non-empty. That condition has already
been handled by an early return, so at the point that the first
REPLACEMENT is being pushed, it's impossible for first_broken to be
empty.
Print associated types on opaque `impl Trait` types
This PR generalizes #91021, printing associated types for all opaque `impl Trait` types instead of just special-casing for future.
before:
```
error[E0271]: type mismatch resolving `<impl Iterator as Iterator>::Item == u32`
```
after:
```
error[E0271]: type mismatch resolving `<impl Iterator<Item = usize> as Iterator>::Item == u32`
```
---
Questions:
1. I'm kinda lost in binders hell with this one. Is all of the `rebind`ing necessary?
2. Is there a map collection type that will give me a stable iteration order? Doesn't seem like TraitRef is Ord, so I can't just sort later..
3. I removed the logic that suppresses printing generator projection types. It creates outputs like this [gist](https://gist.github.com/compiler-errors/d6f12fb30079feb1ad1d5f1ab39a3a8d). Should I put that back?
4. I also added spaces between traits, `impl A+B` -> `impl A + B`. I quite like this change, but is there a good reason to keep it like that?
r? ````@estebank````
Partially stabilize `duration_consts_2`
Methods that were only blocked on `const_panic` have been stabilized.
The remaining methods of `duration_consts_2` are all related to floats,
and as such have been placed behind the `duration_consts_float` feature
gate.
kernel_copy: avoid panic on unexpected OS error
According to documentation, the listed errnos should only occur
if the `copy_file_range` call cannot be made at all, so the
assert be correct. However, since in practice file system
drivers (incl. FUSE etc.) can return any errno they want, we
should not panic here.
Fixes#91152
According to documentation, the listed errnos should only occur
if the `copy_file_range` call cannot be made at all, so the
assert be correct. However, since in practice file system
drivers (incl. FUSE etc.) can return any errno they want, we
should not panic here.
Fixes#91152
Methods that were only blocked on `const_panic` have been stabilized.
The remaining methods of `duration_consts_2` are all related to floats,
and as such have been placed behind the `duration_consts_float` feature
gate.
Mention std::io::Error::from(ErrorKind) in Error::new() docs
This conversion is not very discoverable for the cases
where an error is required without extra payload.
Simplify `for` loop desugar
Basically two intermediate bindings are inlined. I could have left one intermediate binding in place as this would simplify some diagnostic logic, but I think the difference in that regard would be negligible, so it is better to have a minimal HIR.
For checking that the pattern is irrefutable, I added a special case when the `match` is found to be non-exhaustive.
The reordering of the arms is purely stylistic. I don't *think* there are any perf implications.
```diff
match IntoIterator::into_iter($head) {
mut iter => {
$label: loop {
- let mut __next;
match Iterator::next(&mut iter) {
- Some(val) => __next = val,
None => break,
+ Some($pat) => $block,
}
- let $pat = __next;
- $block
}
}
}
```
The functions are now `unsafe` and they use `Option::unwrap_unchecked` instead of `unwrap_or_0`
`unwrap_or_0` was added in 42357d772b. I guess `unwrap_unchecked` was not available back then.
Given this example:
```rust
pub fn first_char(s: &str) -> Option<char> {
s.chars().next()
}
```
Previously, the following assembly was produced:
```asm
_ZN7example10first_char17ha056ddea6bafad1cE:
.cfi_startproc
test rsi, rsi
je .LBB0_1
movzx edx, byte ptr [rdi]
test dl, dl
js .LBB0_3
mov eax, edx
ret
.LBB0_1:
mov eax, 1114112
ret
.LBB0_3:
lea r8, [rdi + rsi]
xor eax, eax
mov r9, r8
cmp rsi, 1
je .LBB0_5
movzx eax, byte ptr [rdi + 1]
add rdi, 2
and eax, 63
mov r9, rdi
.LBB0_5:
mov ecx, edx
and ecx, 31
cmp dl, -33
jbe .LBB0_6
cmp r9, r8
je .LBB0_9
movzx esi, byte ptr [r9]
add r9, 1
and esi, 63
shl eax, 6
or eax, esi
cmp dl, -16
jb .LBB0_12
.LBB0_13:
cmp r9, r8
je .LBB0_14
movzx edx, byte ptr [r9]
and edx, 63
jmp .LBB0_16
.LBB0_6:
shl ecx, 6
or eax, ecx
ret
.LBB0_9:
xor esi, esi
mov r9, r8
shl eax, 6
or eax, esi
cmp dl, -16
jae .LBB0_13
.LBB0_12:
shl ecx, 12
or eax, ecx
ret
.LBB0_14:
xor edx, edx
.LBB0_16:
and ecx, 7
shl ecx, 18
shl eax, 6
or eax, ecx
or eax, edx
ret
```
After this change, the assembly is reduced to:
```asm
_ZN7example10first_char17h4318683472f884ccE:
.cfi_startproc
test rsi, rsi
je .LBB0_1
movzx ecx, byte ptr [rdi]
test cl, cl
js .LBB0_3
mov eax, ecx
ret
.LBB0_1:
mov eax, 1114112
ret
.LBB0_3:
mov eax, ecx
and eax, 31
movzx esi, byte ptr [rdi + 1]
and esi, 63
cmp cl, -33
jbe .LBB0_4
movzx edx, byte ptr [rdi + 2]
shl esi, 6
and edx, 63
or edx, esi
cmp cl, -16
jb .LBB0_7
movzx ecx, byte ptr [rdi + 3]
and eax, 7
shl eax, 18
shl edx, 6
and ecx, 63
or ecx, edx
or eax, ecx
ret
.LBB0_4:
shl eax, 6
or eax, esi
ret
.LBB0_7:
shl eax, 12
or eax, edx
ret
```
Adds IEEE 754-2019 minimun and maximum functions for f32/f64
IEEE 754-2019 removed the `minNum` (`min` in Rust) and `maxNum` (`max` in Rust) operations in favor of the newly created `minimum` and `maximum` operations due to their [non-associativity](https://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/background/minNum_maxNum_Removal_Demotion_v3.pdf) that cannot be fix in a backwards compatible manner. This PR adds `fN::{minimun,maximum}` functions following the new rules.
### IEEE 754-2019 Rules
> **minimum(x, y)** is x if x < y, y if y < x, and a quiet NaN if either operand is a NaN, according to 6.2.
For this operation, −0 compares less than +0. Otherwise (i.e., when x = y and signs are the same)
it is either x or y.
> **maximum(x, y)** is x if x > y, y if y > x, and a quiet NaN if either operand is a NaN, according to 6.2.
For this operation, +0 compares greater than −0. Otherwise (i.e., when x = y and signs are the
same) it is either x or y.
"IEEE Standard for Floating-Point Arithmetic," in IEEE Std 754-2019 (Revision of IEEE 754-2008) , vol., no., pp.1-84, 22 July 2019, doi: 10.1109/IEEESTD.2019.8766229.
### Implementation
This implementation is inspired by the one in [`glibc` ](90f0ac10a7/math/s_fminimum_template.c) (it self derived from the C2X draft) expect that:
- it doesn't use `copysign` because it's not available in `core` and also because `copysign` is unnecessary (we only want to check the sign, no need to create a new float)
- it also prefer `other > self` instead of `self < other` like IEEE 754-2019 does
I originally tried to implement them [using intrinsics](1d8aa13bc3) but LLVM [error out](https://godbolt.org/z/7sMrxW49a) when trying to lower them to machine intructions, GCC doesn't yet have built-ins for them, only cranelift support them nativelly (as it doesn't support the nativelly the old sementics).
Helps with https://github.com/rust-lang/rust/issues/83984
Rollup of 6 pull requests
Successful merges:
- #89741 (Mark `Arc::from_inner` / `Rc::from_inner` as unsafe)
- #90927 (Fix float ICE)
- #90994 (Fix ICE `#90993`: add missing call to cancel)
- #91018 (Adopt let_else in more places in rustc_mir_build)
- #91022 (Suggest `await` in more situations where infer types are involved)
- #91088 (Revert "require full validity when determining the discriminant of a value")
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Mark `Arc::from_inner` / `Rc::from_inner` as unsafe
While it's an internal function, it is easy to create invalid Arc/Rcs to
a dangling pointer with it.
Fixes https://github.com/rust-lang/rust/issues/89740
Windows: Resolve `process::Command` program without using the current directory
Currently `std::process::Command` searches many directories for the executable to run, including the current directory. This has lead to a [CVE for `ripgrep`](https://cve.circl.lu/cve/CVE-2021-3013) but presumably other command line utilities could be similarly vulnerable if they run commands. This was [discussed on the internals forum](https://internals.rust-lang.org/t/std-command-resolve-to-avoid-security-issues-on-windows/14800). Also discussed was [which directories should be searched](https://internals.rust-lang.org/t/windows-where-should-command-new-look-for-executables/15015).
EDIT: This PR originally removed all implicit paths. They've now been added back as laid out in the rest of this comment.
## Old Search Strategy
The old search strategy is [documented here][1]. Additionally Rust adds searching the child's paths (see also #37519). So the full list of paths that were searched was:
1. The directories that are listed in the child's `PATH` environment variable.
2. The directory from which the application loaded.
3. The current directory for the parent process.
4. The 32-bit Windows system directory.
5. The 16-bit Windows system directory.
6. The Windows directory.
7. The directories that are listed in the PATH environment variable.
## New Search Strategy
The new strategy removes the current directory from the searched paths.
1. The directories that are listed in the child's PATH environment variable.
2. The directory from which the application loaded.
3. The 32-bit Windows system directory.
4. The Windows directory.
5. The directories that are listed in the parent's PATH environment variable.
Note that it also removes the 16-bit system directory, mostly because there isn't a function to get it. I do not anticipate this being an issue in modern Windows.
## Impact
Removing the current directory should fix CVE's like the one linked above. However, it's possible some Windows users of affected Rust CLI applications have come to expect the old behaviour.
This change could also affect small Windows-only script-like programs that assumed the current directory would be used. The user would need to use `.\file.exe` instead of the bare application name.
This PR could break tests, especially those that test the exact output of error messages (e.g. Cargo) as this does change the error messages is some cases.
[1]: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#parameters
Makes docs for references a little less confusing
- Make clear that the `Pointer` trait is related to formatting
- Make clear that the `Pointer` trait is implemented for references (previously it was confusing to first see that it's implemented and then see it in "expect")
- Make clear that `&T` (shared reference) implements `Send` (if `T: Send + Sync`)
The "fixed" in "fixed steady state limits" means to exclude load-dependent resource prioritization
that would calculate to 100% of capacity on an idle system and less capacity on a loaded system.
Additionally I also exclude "system load" since it would be silly to try to identify
other, perhaps higher priority, processes hogging some CPU cores that aren't explicitly excluded
by masks/quotas/whatever.
The `advance_by(n)` docs state that in the error case `Err(k)` that k is always less than n.
It also states that `advance_by(0)` may return `Err(0)` to indicate an exhausted iterator.
These statements are inconsistent.
Since only one implementation (Skip) actually made use of that I changed it to return Ok(()) in that case too.
While adding some tests I also found a bug in `Take::advance_back_by`.
Make char conversion functions unstably const
The char conversion functions like `char::from_u32` do trivial computations and can easily be converted into const fns. Only smaller tricks are needed to avoid non-const standard library functions like `Result::ok` or `bool::then_some`.
Tracking issue: https://github.com/rust-lang/rust/issues/89259
std: Tweak expansion of thread-local const
This commit tweaks the expansion of `thread_local!` when combined with a
`const { ... }` value to help ensure that the rules which apply to
`const { ... }` blocks will be the same as when they're stabilized.
Previously with this invocation:
thread_local!(static NAME: Type = const { init_expr });
this would generate (on supporting platforms):
#[thread_local]
static NAME: Type = init_expr;
instead the macro now expands to:
const INIT_EXPR: Type = init_expr;
#[thread_local]
static NAME: Type = INIT_EXPR;
with the hope that because `init_expr` is defined as a `const` item then
it's not accidentally allowing more behavior than if it were put into a
`static`. For example on the stabilization issue [this example][ex] now
gives the same error both ways.
[ex]: https://github.com/rust-lang/rust/issues/84223#issuecomment-953384298
Rollup of 8 pull requests
Successful merges:
- #90386 (Add `-Zassert-incr-state` to assert state of incremental cache)
- #90438 (Clean up mess for --show-coverage documentation)
- #90480 (Mention `Vec::remove` in `Vec::swap_remove`'s docs)
- #90607 (Make slice->str conversion and related functions `const`)
- #90750 (rustdoc: Replace where-bounded Clean impl with simple function)
- #90895 (require full validity when determining the discriminant of a value)
- #90989 (Avoid suggesting literal formatting that turns into member access)
- #91002 (rustc: Remove `#[rustc_synthetic]`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
std: Get the standard library compiling for wasm64
This commit goes through and updates various `#[cfg]` as appropriate to
get the wasm64-unknown-unknown target behaving similarly to the
wasm32-unknown-unknown target. Most of this is just updating various
conditions for `target_arch = "wasm32"` to also account for `target_arch
= "wasm64"` where appropriate. This commit also lists `wasm64` as an
allow-listed architecture to not have the `restricted_std` feature
enabled, enabling experimentation with `-Z build-std` externally.
The main goal of this commit is to enable playing around with
`wasm64-unknown-unknown` externally via `-Z build-std` in a way that's
similar to the `wasm32-unknown-unknown` target. These targets are
effectively the same and only differ in their pointer size, but wasm64
is much newer and has much less ecosystem/library support so it'll still
take time to get wasm64 fully-fledged.
Dependence on endianness and type sizes was reported for enum discriminants in #74215 but it is a more general
issue since for example the default implementation of `Hasher::write_usize` uses native endianness.
Additionally the implementations of library types are occasionally changed as their internal fields
change or hashing gets optimized.
This commit makes the following functions from `core::str` `const fn`:
- `from_utf8[_mut]` (`feature(const_str_from_utf8)`)
- `from_utf8_unchecked_mut` (`feature(const_str_from_utf8_unchecked_mut)`)
- `Utf8Error::{valid_up_to,error_len}` (`feature(const_str_from_utf8)`)
Add Vec::retain_mut
This is to continue the discussion started in #83218.
Original comment was:
> Take 2 of #34265, since I needed this today.
The reason I think why we should add `retain_mut` is for coherency and for discoverability. For example we have `chunks` and `chunks_mut` or `get` and `get_mut` or `iter` and `iter_mut`, etc. When looking for mutable `retain`, I would expect `retain_mut` to exist. It took me a while to find out about `drain_filter`. So even if it provides an API close to `drain_filter`, just for the discoverability, I think it's worth it.
cc ``````@m-ou-se`````` ``````@jonas-schievink`````` ``````@Mark-Simulacrum``````
Permit const panics in stable const contexts in stdlib
Without this change, it is not possible to use `panic!` and similar (including `assert!`) in stable const contexts inside of stdlib. See #89542 for a real-world case that currently fails for this reason. This does _not_ affect any user code.
For example, this snippet currently fails to compile:
```rust
#[stable(feature = "foo", since = "1.0.0")]
#[rustc_const_stable(feature = "foo", since = "1.0.0")]
const fn foo() {
assert!(false);
assert!(false, "foo");
}
```
With the addition of `#[rustc_const_unstable]` to `core::panicking::panic`, the error no longer occurs. This snippet has been added verbatim in this PR as a UI test.
To avoid needing to add `#![feature(core_panic)]` to libcore, the two instances of direct calls to `core::panicking::panic` have been switched to use the `panic!` macro.
I am requesting prioritization because this is holding up other stabilizations such as #89542 (which is otherwise ready to merge and succeeds with this change)
Remove bigint_helper_methods for *signed* types
This PR inspired by `@cuviper's` comment @ https://github.com/rust-lang/rust/issues/90541#issuecomment-967309808
These are working well for *unsigned* types, so keep those, but for the the *signed* ones there are a bunch of questions about what the semantics and API should be. For the main "helpers for big integer implementations" use, there's no need for the signed versions anyway. There are plenty of other methods which exist for unsigned types but not signed ones, like `next_power_of_two`, so this isn't unusual.
Fixes#90541
Tracking issue #85532
Rename WASI's `is_character_device` to `is_char_device`.
Rename WASI's `FileTypeExt::is_character_device` to
`FileTypeExt::is_char_device`, for consistency with the Unix
`FileTypeExt::is_char_device`.
Also, add a `FileTypeExt::is_socket` function, for consistency with the
Unix `FileTypeExt::is_socket` function.
r? `@alexcrichton`
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)>
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.
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.
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 are working well for *unsigned* types, for the the signed ones there are a bunch of questions about what the semantics and API should be. And for the main "helpers for big integer implementations" use, there's no need for the signed versions anyway.
And there are plenty of other methods which exist for unsigned types but not signed ones, like `next_power_of_two`, so this isn't unusual.
Fixes 90541
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 makes a few changes to the weak symbol macros in `sys::unix`:
- `dlsym!` is added to keep the functionality for runtime `dlsym`
lookups, like for `__pthread_get_minstack@GLIBC_PRIVATE` that we don't
want to show up in ELF symbol tables.
- `weak!` now uses `#[linkage = "extern_weak"]` symbols, so its runtime
behavior is just a simple null check. This is also used by `syscall!`.
- On non-ELF targets (macos/ios) where that linkage is not known to
behave, `weak!` is just an alias to `dlsym!` for the old behavior.
- `raw_syscall!` is added to always call `libc::syscall` on linux and
android, for cases like `clone3` that have no known libc wrapper.
The new `weak!` linkage does mean that you'll get versioned symbols if
you build with a newer glibc, like `WEAK DEFAULT UND statx@GLIBC_2.28`.
This might seem problematic, but old non-weak symbols can tie the build
to new versions too, like `dlsym@GLIBC_2.34` from their recent library
unification. If you build with an old glibc like `dist-x86_64-linux`
does, you'll still get unversioned `WEAK DEFAULT UND statx`, which may
be resolved based on the runtime glibc.
I also found a few functions that don't need to be weak anymore:
- Android can directly use `ftruncate64`, `pread64`, and `pwrite64`, as
these were added in API 12, and our baseline is API 14.
- Linux can directly use `splice`, added way back in glibc 2.5 and
similarly old musl. Android only added it in API 21 though.
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
Rename WASI's `FileTypeExt::is_character_device` to
`FileTypeExt::is_char_device`, for consistency with the Unix
`FileTypeExt::is_char_device`.
Also, add a `FileTypeExt::is_socket` function, for consistency with the
Unix `FileTypeExt::is_socket` function.
For small types with padding, the current implementation is UB because it does integer operations on uninit values. But LLVM has gotten smarter since I wrote the previous implementation in 2017, so remove all the manual magic and just write it in such a way that LLVM will vectorize. This code is much simpler (albeit nuanced) and has very little `unsafe`, and is actually faster to boot!
As discussed here
https://github.com/rust-lang/rust/pull/88300#issuecomment-936097710
I felt this was the best place to put this (rather than next to
ExitStatusExt). After all, it's a property of the ExitStatus type on
Unix.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>