When CStr moves to core with an alias in std, this can link to
`crate::ffi::CStr`. However, linking in the reverse direction (from core
to std) requires a relative path, and that path can't work from both
core::ffi and std::os::raw (different number of `../` traversals
required).
The ability to interoperate with C code via FFI is not limited to crates
using std; this allows using these types without std.
The existing types in `std::os::raw` become type aliases for the ones in
`core::ffi`. This uses type aliases rather than re-exports, to allow the
std types to remain stable while the core types are unstable.
This also moves the currently unstable `NonZero_` variants and
`c_size_t`/`c_ssize_t`/`c_ptrdiff_t` types to `core::ffi`, while leaving
them unstable.
core can't depend on external crates the way std can. Rather than revert
usage of cfg_if, add a copy of it to core. This does not export our
copy, even unstably; such a change could occur in a later commit.
Sync portable-simd for bitmasks &c.
In the ideal case, where everything works easily and nothing has to be rearranged, it is as simple as:
- `git subtree pull -P library/portable-simd https://github.com/rust-lang/portable-simd - ${branch}`
- write the commit message
- `python x.py test --stage 1` to make sure it runs
- `git push` to your PR-to-rustc branch
If anything borks up this flow, you can fix it with sufficient git wizardry but you are usually better off going back to the source, fixing it, and starting over, before you open the PR.
r? `@calebzulawski`
Add Atomic*::from_mut_slice
Tracking issue #76314 for `from_mut` has a question about the possibility of `from_mut_slice`, and I found a real case for it. A user in the forum had a parallelism problem that could be solved by open-indexing updates to a vector of atomics, but they didn't want to affect the other code using that vector. Using `from_mut_slice`, they could borrow that data as atomics just long enough for their parallel loop.
ref: https://users.rust-lang.org/t/sharing-vector-with-rayon-par-iter-correctly/72022
use BOOL for TCP_NODELAY setsockopt value on Windows
This issue was found by the Wine project and mitigated there [^1].
Windows' setsockopt expects a BOOL (a typedef for int) for TCP_NODELAY
[^2]. Windows itself is forgiving and will accept any positive optlen and
interpret the first byte of *optval as the value, so this bug does not
affect Windows itself, but does affect systems implementing Windows'
interface more strictly, such as Wine. Wine was previously passing this
through to the host's setsockopt, where, e.g., Linux requires that
optlen be correct for the chosen option, and TCP_NODELAY expects an int.
[^1]: d6ea38f32d
[^2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-setsockopt
fix typo in btree/vec doc: Self -> self
this pr fixes#92345
the documentation refers to the object the method is called for, not the type, so it should be using the lower case self.
For MIRI, cfg out the swap vectorization logic from 94212
Because of #69488 the swap logic from #94212 doesn't currently work in MIRI.
Copying in smaller pieces is probably much worse for its performance anyway, so it'd probably rather just use the simple path regardless.
Part of #94371, though another PR will be needed for the CTFE aspect.
r? `@oli-obk`
cc `@RalfJung`
Rollup of 5 pull requests
Successful merges:
- #93603 (Populate liveness facts when calling `get_body_with_borrowck_facts` without `-Z polonius`)
- #93870 (Fix switch on discriminant detection in a presence of coverage counters)
- #94355 (Add one more case to avoid ICE)
- #94363 (Remove needless borrows from core::fmt)
- #94377 (`check_used` should only look at actual `used` attributes)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
This function was updated in a recent PR (92911) to be called without the caller
information passed in, but the function signature itself was not altered with
cfg_attr at the time.
As an example:
#[test]
#[ignore = "not yet implemented"]
fn test_ignored() {
...
}
Will now render as:
running 2 tests
test tests::test_ignored ... ignored, not yet implemented
test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
Stop manually SIMDing in `swap_nonoverlapping`
Like I previously did for `reverse` (#90821), this leaves it to LLVM to pick how to vectorize it, since it can know better the chunk size to use, compared to the "32 bytes always" approach we currently have.
A variety of codegen tests are included to confirm that the various cases are still being vectorized.
It does still need logic to type-erase in some cases, though, as while LLVM is now smart enough to vectorize over slices of things like `[u8; 4]`, it fails to do so over slices of `[u8; 3]`.
As a bonus, this change also means one no longer gets the spurious `memcpy`(s?) at the end up swapping a slice of `__m256`s: <https://rust.godbolt.org/z/joofr4v8Y>
<details>
<summary>ASM for this example</summary>
## Before (from godbolt)
note the `push`/`pop`s and `memcpy`
```x86
swap_m256_slice:
push r15
push r14
push r13
push r12
push rbx
sub rsp, 32
cmp rsi, rcx
jne .LBB0_6
mov r14, rsi
shl r14, 5
je .LBB0_6
mov r15, rdx
mov rbx, rdi
xor eax, eax
.LBB0_3:
mov rcx, rax
vmovaps ymm0, ymmword ptr [rbx + rax]
vmovaps ymm1, ymmword ptr [r15 + rax]
vmovaps ymmword ptr [rbx + rax], ymm1
vmovaps ymmword ptr [r15 + rax], ymm0
add rax, 32
add rcx, 64
cmp rcx, r14
jbe .LBB0_3
sub r14, rax
jbe .LBB0_6
add rbx, rax
add r15, rax
mov r12, rsp
mov r13, qword ptr [rip + memcpy@GOTPCREL]
mov rdi, r12
mov rsi, rbx
mov rdx, r14
vzeroupper
call r13
mov rdi, rbx
mov rsi, r15
mov rdx, r14
call r13
mov rdi, r15
mov rsi, r12
mov rdx, r14
call r13
.LBB0_6:
add rsp, 32
pop rbx
pop r12
pop r13
pop r14
pop r15
vzeroupper
ret
```
## After (from my machine)
Note no `rsp` manipulation, sorry for different ASM syntax
```x86
swap_m256_slice:
cmpq %r9, %rdx
jne .LBB1_6
testq %rdx, %rdx
je .LBB1_6
cmpq $1, %rdx
jne .LBB1_7
xorl %r10d, %r10d
jmp .LBB1_4
.LBB1_7:
movq %rdx, %r9
andq $-2, %r9
movl $32, %eax
xorl %r10d, %r10d
.p2align 4, 0x90
.LBB1_8:
vmovaps -32(%rcx,%rax), %ymm0
vmovaps -32(%r8,%rax), %ymm1
vmovaps %ymm1, -32(%rcx,%rax)
vmovaps %ymm0, -32(%r8,%rax)
vmovaps (%rcx,%rax), %ymm0
vmovaps (%r8,%rax), %ymm1
vmovaps %ymm1, (%rcx,%rax)
vmovaps %ymm0, (%r8,%rax)
addq $2, %r10
addq $64, %rax
cmpq %r10, %r9
jne .LBB1_8
.LBB1_4:
testb $1, %dl
je .LBB1_6
shlq $5, %r10
vmovaps (%rcx,%r10), %ymm0
vmovaps (%r8,%r10), %ymm1
vmovaps %ymm1, (%rcx,%r10)
vmovaps %ymm0, (%r8,%r10)
.LBB1_6:
vzeroupper
retq
```
</details>
This does all its copying operations as either the original type or as `MaybeUninit`s, so as far as I know there should be no potential abstract machine issues with reading padding bytes as integers.
<details>
<summary>Perf is essentially unchanged</summary>
Though perhaps with more target features this would help more, if it could pick bigger chunks
## Before
```
running 10 tests
test slice::swap_with_slice_4x_usize_30 ... bench: 894 ns/iter (+/- 11)
test slice::swap_with_slice_4x_usize_3000 ... bench: 99,476 ns/iter (+/- 2,784)
test slice::swap_with_slice_5x_usize_30 ... bench: 1,257 ns/iter (+/- 7)
test slice::swap_with_slice_5x_usize_3000 ... bench: 139,922 ns/iter (+/- 959)
test slice::swap_with_slice_rgb_30 ... bench: 328 ns/iter (+/- 27)
test slice::swap_with_slice_rgb_3000 ... bench: 16,215 ns/iter (+/- 176)
test slice::swap_with_slice_u8_30 ... bench: 312 ns/iter (+/- 9)
test slice::swap_with_slice_u8_3000 ... bench: 5,401 ns/iter (+/- 123)
test slice::swap_with_slice_usize_30 ... bench: 368 ns/iter (+/- 3)
test slice::swap_with_slice_usize_3000 ... bench: 28,472 ns/iter (+/- 3,913)
```
## After
```
running 10 tests
test slice::swap_with_slice_4x_usize_30 ... bench: 868 ns/iter (+/- 36)
test slice::swap_with_slice_4x_usize_3000 ... bench: 99,642 ns/iter (+/- 1,507)
test slice::swap_with_slice_5x_usize_30 ... bench: 1,194 ns/iter (+/- 11)
test slice::swap_with_slice_5x_usize_3000 ... bench: 139,761 ns/iter (+/- 5,018)
test slice::swap_with_slice_rgb_30 ... bench: 324 ns/iter (+/- 6)
test slice::swap_with_slice_rgb_3000 ... bench: 15,962 ns/iter (+/- 287)
test slice::swap_with_slice_u8_30 ... bench: 281 ns/iter (+/- 5)
test slice::swap_with_slice_u8_3000 ... bench: 5,324 ns/iter (+/- 40)
test slice::swap_with_slice_usize_30 ... bench: 275 ns/iter (+/- 5)
test slice::swap_with_slice_usize_3000 ... bench: 28,277 ns/iter (+/- 277)
```
</detail>
remove feature gate in control_flow examples
Stabilization was done in https://github.com/rust-lang/rust/pull/91091, but the two examples weren't updated accordingly.
Probably too late to put it into stable, but it should be in the next release :)
Fix a layout possible miscalculation in `alloc::RawVec`
A layout miscalculation could happen in `RawVec` when used with a type whose size isn't a multiple of its alignment. I don't know if such type can exist in Rust, but the Layout API provides ways to manipulate such types. Anyway, it is better to calculate memory size in a consistent way.
Some improvements to the async docs
The goal here is to make the docs overall a little bit more comprehensive and add more links between the things.
One thing that's not working yet is the links to the keywords. Somehow I couldn't get them to work.
r? ````@GuillaumeGomez```` do you know how I could get the keyword links to work?
Like I previously did for `reverse`, this leaves it to LLVM to pick how to vectorize it, since it can know better the chunk size to use, compared to the "32 bytes always" approach we currently have.
It does still need logic to type-erase where appropriate, though, as while LLVM is now smart enough to vectorize over slices of things like `[u8; 4]`, it fails to do so over slices of `[u8; 3]`.
As a bonus, this also means one no longer gets the spurious `memcpy`(s?) at the end up swapping a slice of `__m256`s: <https://rust.godbolt.org/z/joofr4v8Y>
This issue was found by the Wine project and mitigated there [1].
Windows' documented interface for `setsockopt` expects a `BOOL` (a
`typedef` for `int`) for `TCP_NODELAY` [2]. Windows is forgiving and
will accept any positive length and interpret the first byte of
`*option_value` as the value, so this bug does not affect Windows
itself, but does affect systems implementing Windows' interface more
strictly, such as Wine. Wine was previously passing this through to the
host's `setsockopt`, where, e.g., Linux requires that `option_len` be
correct for the chosen option, and `TCP_NODELAY` expects an `int`.
[1]: d6ea38f32d
[2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-setsockopt
POSIX allows `getsockopt` to set `*option_len` to a smaller value if
necessary. Windows will set `*option_len` to 1 for boolean options even
when the caller passes a `BOOL` (`int`) with `*option_len` as 4.
Previously `level` was named `opt` and `option_name` was named `val`,
then extra names of `payload` or `slot` were used for the option value.
This change aligns the wrapper parameters with their names in POSIX.
Winsock uses similar but more abbreviated names: `level`, `optname`,
`optval`, `optlen`.
Fix miniz_oxide types showing up in std docs
Fixes#90526.
Thanks to ```````@camelid,``````` I rediscovered `doc(masked)`, allowing us to prevent `miniz_oxide` type to show up in std docs.
r? ```````@notriddle```````
removing architecture requirements for RustyHermit
RustHermit and HermitCore is able to run on aarch64 and x86_64. In the future these operating systems will also support RISC-V. Consequently, the dependency to a specific target should be removed.
The build process of `hermit-abi` fails if the architecture isn't supported.
core: Implement ASCII trim functions on byte slices
Hi ````````@rust-lang/libs!```````` This is a feature that I wished for when implementing serial protocols with microcontrollers. Often these protocols may contain leading or trailing whitespace, which needs to be removed. Because oftentimes drivers will operate on the byte level, decoding to unicode and checking for unicode whitespace is unnecessary overhead.
This PR adds three new methods to byte slices:
- `trim_ascii_start`
- `trim_ascii_end`
- `trim_ascii`
I did not find any pre-existing discussions about this, which surprises me a bit. Maybe I'm missing something, and this functionality is already possible through other means? There's https://github.com/rust-lang/rfcs/issues/2547 ("Trim methods on slices"), but that has a different purpose.
As per the [std dev guide](https://std-dev-guide.rust-lang.org/feature-lifecycle/new-unstable-features.html), this is a proposed implementation without any issue / RFC. If this is the wrong process, please let me know. However, I thought discussing code is easier than discussing a mere idea, and hacking on the stdlib was fun.
Tracking issue: https://github.com/rust-lang/rust/issues/94035
Guard against unwinding in cleanup code
Currently the only safe guard we have against double unwind is the panic count (which is local to Rust). When double unwinds indeed happen (e.g. C++ exception + Rust panic, or two C++ exceptions), then the second unwind actually goes through and the first unwind is leaked. This can cause UB. cc rust-lang/project-ffi-unwind#6
E.g. given the following C++ code:
```c++
extern "C" void foo() {
throw "A";
}
extern "C" void execute(void (*fn)()) {
try {
fn();
} catch(...) {
}
}
```
This program is well-defined to terminate:
```c++
struct dtor {
~dtor() noexcept(false) {
foo();
}
};
void a() {
dtor a;
dtor b;
}
int main() {
execute(a);
return 0;
}
```
But this Rust code doesn't catch the double unwind:
```rust
extern "C-unwind" {
fn foo();
fn execute(f: unsafe extern "C-unwind" fn());
}
struct Dtor;
impl Drop for Dtor {
fn drop(&mut self) {
unsafe { foo(); }
}
}
extern "C-unwind" fn a() {
let _a = Dtor;
let _b = Dtor;
}
fn main() {
unsafe { execute(a) };
}
```
To address this issue, this PR adds an unwind edge to an abort block, so that the Rust example aborts. This is similar to how clang guards against double unwind (except clang calls terminate per C++ spec and we abort).
The cost should be very small; it's an additional trap instruction (well, two for now, since we use TrapUnreachable, but that's a different issue) for each function with landing pads; if LLVM gains support to encode "abort/terminate" info directly in LSDA like GCC does, then it'll be free. It's an additional basic block though so compile time may be worse, so I'd like a perf run.
r? `@ghost`
`@rustbot` label: F-c_unwind
Add debug assertions to validate NUL terminator in c strings
The `unchecked` variants from the stdlib usually perform the check anyway if debug assertions are on (for example, `unwrap_unchecked`). This PR does the same thing for `CStr` and `CString`, validating the correctness for the NUL byte in debug mode.
Destabilise entry_insert
See: https://github.com/rust-lang/rust/pull/90345
I didn't revert the rename that was done in that PR, I left it as `entry_insert`.
Additionally, before that PR, `VacantEntry::insert_entry` seemingly had no stability attribute on it? I kept the attribute, just made it an unstable one, same as the one on `Entry`.
There didn't seem to be any mention of this in the RELEASES.md, so I don't think there's anything for me to do other than this?
kmc-solid: Use the filesystem thread-safety wrapper
Fixes the thread unsafety of the `std::fs` implementation used by the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets.
Neither the SOLID filesystem API nor built-in filesystem drivers guarantee thread safety by default. Although this may suffice in general embedded-system use cases, and in fact the API can be used from multiple threads without any problems in many cases, this has been a source of unsoundness in `std::sys::solid::fs`.
This commit updates the implementation to leverage the filesystem thread-safety wrapper (which uses a pluggable synchronization mechanism) to enforce thread safety. This is done by prefixing all paths passed to the filesystem API with `\TS`. (Note that relative paths aren't supported in this platform.)
Fix documentation for is_X_feature_detected!
These are now properly documented for all architectures and the
stability attributes in the docs are now correctly displayed.
This addresses this comment by `@ehuss:` https://github.com/rust-lang/rust/pull/90271#issuecomment-1038400916
cc `@adamgemmell`
Add a `try_collect()` helper method to `Iterator`
Implement `Iterator::try_collect()` as a helper around `Iterator::collect()` as discussed [here](https://internals.rust-lang.org/t/idea-fallible-iterator-mapping-with-try-map/15715/5?u=a.lafrance).
First time contributor so definitely open to any feedback about my implementation! Specifically wondering if I should open a tracking issue for the unstable feature I introduced.
As the main participant in the internals discussion: r? `@scottmcm`
Add MAIN_SEPARATOR_STR
Currently, if someone needs access to the path separator as a str, they need to go through this mess:
```rust
unsafe {
std::str::from_utf8_unchecked(slice::from_ref(&(MAIN_SEPARATOR as u8)))
}
```
This PR just re-exports an existing path separator str API.
Use `optflag` for `--report-time`
Essentially, what is described here:
https://github.com/rust-lang/rust/issues/64888#issuecomment-1008047228
There is one difference. The comment proposes to add a
`--report-time-color` option. This change instead uses libtest's
existing `--color` option for that purpose.
Add documentation to more `From::from` implementations.
For users looking at documentation through IDE popups, this gives them relevant information rather than the generic trait documentation wording “Performs the conversion”. For users reading the documentation for a specific type for any reason, this informs them when the conversion may allocate or copy significant memory versus when it is always a move or cheap copy.
Notes on specific cases:
* The new documentation for `From<T> for T` explains that it is not a conversion at all.
* Also documented `impl<T, U> Into<U> for T where U: From<T>`, the other central blanket implementation of conversion.
* The new documentation for construction of maps and sets from arrays of keys mentions the handling of duplicates. Future work could be to do this for *all* code paths that convert an iterable to a map or set.
* I did not add documentation to conversions of a specific error type to a more general error type.
* I did not add documentation to unstable code.
This change was prepared by searching for the text "From<... for" and so may have missed some cases that for whatever reason did not match. I also looked for `Into` impls but did not find any worth documenting by the above criteria.
Destabilize cfg(target_has_atomic_load_store = ...)
This was not intended to be stabilized yet.
This keeps the cfg_target_has_atomic feature gate name since compiler-builtins otherwise depends on it and I'd rather not try to manage a bump across a crates.io published repository given the time-sensitivity here (we need to land this quickly to avoid a beta backport).
Closes https://github.com/rust-lang/rust/issues/32976
r? `@Amanieu`
Maintain broken symlink behaviour for the Windows exe resolver
When the resolver was updated to remove the current directory from the search path (see #87704), care was take to avoid unintentional changes that hadn't been discussed. However, I missed the broken symlink behaviour. This PR fixes that.
**Edit** This turned out to be more important than I first realised. There are some types of application stubs that will redirect to the actual process when run using `CreateProcessW`, but due to the way they're implemented they cannot be opened normally using a `File::open` that follows reparse points. So this doesn't work with our current `exists` and `try_exists` methods.
Fixes#91177
Make [u8]::cmp implementation branchless
The current implementation generates rather ugly assembly code, branching when the common parts are equal. By performing the comparison of the lengths upfront using a subtraction, the assembly gets much prettier: https://godbolt.org/z/4e5fnEKGd.
This will probably not impact speed too much, as the expensive part is in most cases the `memcmp`, but it sure looks better (I'm porting a sorting algorithm currently, and that branch just bothered me).
Add basic platform support to library/{panic_}unwind for m68k
This PR adds basic platform support for m68k for library/{panic_}unwind for m68k.
Register information for UNWIND_DATA_REG has been extracted from LLVM.
Describe VecDeque with more consistent names
The public documentation of VecDeque starts describing itself as a "queue". In method descriptions, it's ~~never~~ sometimes named queue again, or `VecDeque` (IMO a sometimes useful and often noisy notation) or "deque" or "vector". In examples, `deque`, `v` (hidden in `range_mut`) or `vector`. Here is a subjective attempt at more consistency.
RustHermit and HermitCore is able to run on aarch64 and x86_64.
In the future these operating systems will also support RISC-V.
Consequently, the dependency to a specific target should be removed.
Building hermit-abi fails if the architecture isn't supported.
Since `decl_macro`s and/or `Span::def_site()` is deemed quite unstable,
no public-facing macro that relies on it can hope to be, itself, stabilized.
We circumvent the issue by no longer relying on field privacy for safety and,
instead, relying on an unstable feature-gate to act as the gate keeper for
non users of the macro (thanks to `allow_internal_unstable`).
This is technically not correct (since a `nightly` user could technically enable
the feature and cause unsoundness with it); or, in other words, this makes the
feature-gate used to gate the access to the field be (technically unsound, and
in practice) `unsafe`. Hence it having `unsafe` in its name.
Back to the macro, we go back to `macro_rules!` / `mixed_site()`-span rules thanks
to declaring the `decl_macro` as `semitransparent`, which is a hack to basically have
`pub macro_rules!`
Co-Authored-By: Mara Bos <m-ou.se@m-ou.se>
Stabilise inherent_ascii_escape (FCP in #77174)
Implements #77174, which completed its FCP.
This does *not* deprecate any existing methods or structs, as that is tracked in #93887. That stated, people should prefer using `u8::escape_ascii` to `std::ascii::escape_default`.
More practical examples for `Option::and_then` & `Result::and_then`
To be blatantly honest, I think the current example given for `Option::and_then` is objectively terrible. (No offence to whoever wrote them initially.)
```rust
fn sq(x: u32) -> Option<u32> { Some(x * x) }
fn nope(_: u32) -> Option<u32> { None }
assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16));
assert_eq!(Some(2).and_then(sq).and_then(nope), None);
assert_eq!(Some(2).and_then(nope).and_then(sq), None);
assert_eq!(None.and_then(sq).and_then(sq), None);
```
Current example:
- does not demonstrate that `and_then` converts `Option<T>` to `Option<U>`
- is far removed from any realistic code
- generally just causes more confusion than it helps
So I replaced them with two blocks:
- the first one shows basic usage (including the type conversion)
- the second one shows an example of typical usage
Same thing with `Result::and_then`.
Hopefully this helps with clarity.
make `Instant::{duration_since, elapsed, sub}` saturating and remove workarounds
This removes all mutex/atomic-based workarounds for non-monotonic clocks and makes the previously panicking methods saturating instead. Additionally `saturating_duration_since` becomes deprecated since `duration_since` now fills that role.
Effectively this moves the fixup from `Instant` construction to the comparisons.
This has some observable effects, especially on platforms without monotonic clocks:
* Incorrectly ordered Instant comparisons no longer panic in release mode. This could hide some programming errors, but since debug mode still panics tests can still catch them.
* `checked_duration_since` will now return `None` in more cases. Previously it only happened when one compared instants obtained in the wrong order or manually created ones. Now it also does on backslides.
* non-monotonic intervals will not be transitive, i.e. `b.duration_since(a) + c.duration_since(b) != c.duration_since(a)`
The upsides are reduced complexity and lower overhead of `Instant::now`.
## Motivation
Currently we must choose between two poisons. One is high worst-case latency and jitter of `Instant::now()` due to explicit synchronization; see #83093 for benchmarks, the worst-case overhead is > 100x. The other is sporadic panics on specific, rare combinations of CPU/hypervisor/operating system due to platform bugs.
Use-cases where low-overhead, fine-grained timestamps are needed - such as syscall tracing, performance profiles or sensor data acquisition (drone flight controllers were mentioned in a libs meeting) in multi-threaded programs - are negatively impacted by the synchronization.
The panics are user-visible (program crashes), hard to reproduce and can be triggered by any dependency that might be using Instants for any reason.
A solution that is fast _and_ doesn't panic is desirable.
----
closes#84448closes#86470
This removes all mutex/atomics based workarounds for non-monotonic clocks and makes the previously panicking methods saturating instead.
Effectively this moves the monotonization from `Instant` construction to the comparisons.
This has some observable effects, especially on platforms without monotonic clocks:
* Incorrectly ordered Instant comparisons no longer panic. This may hide some programming errors until someone actually looks at the resulting `Duration`
* `checked_duration_since` will now return `None` in more cases. Previously it only happened when one compared instants obtained in the wrong order or
manually created ones. Now it also does on backslides.
The upside is reduced complexity and lower overhead of `Instant::now`.
Fix hashing for windows paths containing a CurDir component
* the logic only checked for / but not for \
* verbatim paths shouldn't skip items at all since they don't get normalized
* the extra branches get optimized out on unix since is_sep_byte is a trivial comparison and is_verbatim is always-false
* tests lacked windows coverage for these cases
That lead to equal paths not having equal hashes and to unnecessary collisions.
Rollup of 10 pull requests
Successful merges:
- #90955 (Rename `FilenameTooLong` to `InvalidFilename` and also use it for Windows' `ERROR_INVALID_NAME`)
- #91607 (Make `span_extend_to_prev_str()` more robust)
- #92895 (Remove some unused functionality)
- #93635 (Add missing platform-specific information on current_dir and set_current_dir)
- #93660 (rustdoc-json: Add some tests for typealias item)
- #93782 (Split `pauth` target feature)
- #93868 (Fix incorrect register conflict detection in asm!)
- #93888 (Implement `AsFd` for `&T` and `&mut T`.)
- #93909 (Fix typo: explicitely -> explicitly)
- #93910 (fix mention of moved function in `rustc_hir` docs)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Implement `AsFd` for `&T` and `&mut T`.
Add implementations of `AsFd` for `&T` and `&mut T`, so that users can
write code like this:
```rust
pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
```
with `fd: F` rather than `fd: &F`.
And similar for `AsHandle` and `AsSocket` on Windows.
Also, adjust the `fchown` example to pass the file by reference. The
code can work either way now, but passing by reference is more likely
to be what users will want to do.
This is an alternative to #93869, and is a simpler way to achieve the
same goals: users don't need to pass borrowed-`BorrowedFd` arguments,
and it prevents a pitfall in the case where users write `fd: F` instead
of `fd: &F`.
r? ```@joshtriplett```
Rename `FilenameTooLong` to `InvalidFilename` and also use it for Windows' `ERROR_INVALID_NAME`
Address https://github.com/rust-lang/rust/issues/90940#issuecomment-970157931
`ERROR_INVALID_NAME` (i.e. "The filename, directory name, or volume label syntax is incorrect") happens if we pass an invalid filename, directory name, or label syntax, so mapping as `InvalidInput` is reasonable to me.
Stabilise `is_aarch64_feature_detected!` under `simd_aarch64` feature
Initial implementation, looking for feedback on the approach here. https://github.com/rust-lang/rust/issues/86941
One point I noticed was that I haven't seen different "since" versions for the same feature - does this mean that other features can't be added to to the `simd_aarch64` feature once this is in stable? If so it might need a more specific name.
r? `@Amanieu`
Add implementations of `AsFd` for `&T` and `&mut T`, so that users can
write code like this:
```rust
pub fn fchown<F: AsFd>(fd: F, uid: Option<u32>, gid: Option<u32>) -> io::Result<()> {
```
with `fd: F` rather than `fd: &F`.
And similar for `AsHandle` and `AsSocket` on Windows.
Also, adjust the `fchown` example to pass the file by reference. The
code can work either way now, but passing by reference is more likely
to be what users will want to do.
This is an alternative to #93869, and is a simpler way to achieve the
same goals: users don't need to pass borrowed-`BorrowedFd` arguments,
and it prevents a pitfall in the case where users write `fd: F` instead
of `fd: &F`.
kmc-solid: Fix wait queue manipulation errors in the `Condvar` implementation
This PR fixes a number of bugs in the `Condvar` wait queue implementation used by the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets. These bugs can occur when there are multiple threads waiting on the same `Condvar` and sometimes manifest as an `unwrap` failure.
Neither the SOLID filesystem API nor built-in filesystems guarantee
thread safety by default. Although this may suffice in general embedded-
system use cases, and in fact the API can be used from multiple threads
without any problems in many cases, this has been a source of
unsoundness in `std::sys::solid::fs`.
This commit updates the `std` code to leverage the filesystem thread-
safety wrapper to enforce thread safety. This is done by prefixing all
paths passed to the filesystem API with `\TS`. (Note that relative paths
aren't supported in this platform.)
Fix typo in `std::fmt` docs
Hey!
Reading the docs (https://doc.rust-lang.org/std/fmt/#named-parameters), this seems like a typo?
The docs here also seem to mix “named argument” and “named parameter”? Intentional? Mistake?
Rollup of 7 pull requests
Successful merges:
- #91950 (Point at type when a `static` `#[global_allocator]` doesn't `impl` `GlobalAlloc`)
- #92715 (Do not suggest char literal for zero-length strings)
- #92917 (Don't constrain projection predicates with inference vars in GAT substs)
- #93206 (Use `NtCreateFile` instead of `NtOpenFile` to open a file)
- #93732 (add fut/back compat tests for implied trait bounds)
- #93764 (⬆️ rust-analyzer)
- #93767 (deduplicate `lcnr` in mailmap)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Use `NtCreateFile` instead of `NtOpenFile` to open a file
Generally the internal `Nt*` functions should be avoided but when we do need to use one we should stick to the most commonly used for the job. To that end, this PR replaces `NtOpenFile` with `NtCreateFile`.
NOTE: The initial version of this comment hypothesised that this may help with some recent false positives from malware scanners. This hypothesis proved wrong. Sorry for the distraction.
Change `ResultShunt` to be generic over `Try`
Just a refactor (and rename) for now, so it's not `Result`-specific.
This could be used for a future `Iterator::try_collect`, or similar, but anything like that is left for a future PR.
Add {floor,ceil}_char_boundary methods to str
This is technically already used internally by the standard library in the form of `truncate_to_char_boundary`.
Essentially these are two building blocks to allow for approximate string truncation, where you want to cut off the string at "approximately" a given length in bytes but don't know exactly where the character boundaries lie. It's also a good candidate for the standard library as it can easily be done naively, but would be difficult to properly optimise. Although the existing code that's done in error messages is done naively, this code will explicitly only check a window of 4 bytes since we know that a boundary must lie in that range, and because it will make it possible to vectorise.
Although this method doesn't take into account graphemes or other properties, this would still be a required building block for splitting that takes those into account. For example, if you wanted to split at a grapheme boundary, you could take your approximate splitting point and then determine the graphemes immediately following and preceeding the split. If you then notice that these two graphemes could be merged, you can decide to either include the whole grapheme or exclude it depending on whether you decide splitting should shrink or expand the string.
This takes the most conservative approach and just offers the raw indices to the user, and they can decide how to use them. That way, the methods are as useful as possible despite having as few methods as possible.
(Note: I'll add some tests and a tracking issue if it's decided that this is worth including.)
Just a refactor (and rename) for now, so it's not `Result`-specific.
This could be used for a future `Iterator::try_collect`, or similar, but anything like that is left for a future PR.
Make io::Error use 64 bits on targets with 64 bit pointers.
I've wanted this for a long time, but didn't see a good way to do it without having extra allocation. When looking at it yesterday, it was more clear what to do for some reason.
This approach avoids any additional allocations, and reduces the size by half (8 bytes, down from 16). AFAICT it doesn't come additional runtime cost, and the compiler seems to do a better job with code using it.
Additionally, this `io::Error` has a niche (still), so `io::Result<()>` is *also* 64 bits (8 bytes, down from 16), and `io::Result<usize>` (used for lots of io trait functions) is 2x64 bits (16 bytes, down from 24 — this means on x86_64 it can use the nice rax/rdx 2-reg struct return). More generally, it shaves a whole 64 bit integer register off of the size of basically any `io::Result<()>`.
(For clarity: Improving `io::Result` (rather than io::Error) was most of the motivation for this)
On 32 bit (or other non-64bit) targets we still use something equivalent the old repr — I don't think think there's improving it, since one of the fields it stores is a `i32`, so we can't get below that, and it's already about as close as we can get to it.
---
### Isn't Pointer Tagging Dodgy?
The details of the layout, and why its implemented the way it is, are explained in the header comment of library/std/src/io/error/repr_bitpacked.rs. There's probably more details than there need to be, but I didn't trim it down that much, since there's a lot of stuff I did deliberately, that might have not seemed that way.
There's actually only one variant holding a pointer which gets tagged. This one is the (holder for the) user-provided error.
I believe the scheme used to tag it is not UB, and that it preserves pointer provenance (even though often pointer tagging does not) because the tagging operation is just `core::ptr::add`, and untagging is `core::ptr::sub`. The result of both operations lands inside the original allocation, so it would follow the safety contract of `core::ptr::{add,sub}`.
The other pointer this had to encode is not tagged — or rather, the tagged repr is equivalent to untagged (it's tagged with 0b00, and has >=4b alignment, so we can reuse the bottom bits). And the other variants we encode are just integers, which (which can be untagged using bitwise operations without worry — they're integers).
CC `@RalfJung` for the stuff in repr_bitpacked.rs, as my comments are informed by a lot of the UCG work, but it's possible I missed something or got it wrong (even if the implementation is okay, there are parts of the header comment that says things like "We can't do $x" which could be false).
---
### Why So Many Changes?
The repr change was mostly internal, but changed one widely used API: I had to switch how `io::Error::new_const` works.
This required switching `io::Error::new_const` to take the full message data (including the kind) as a `&'static`, rather than just the string. This would have been really tedious, but I made a macro that made it much simpler, but it was a wide change since `io::Error::new_const` is used everywhere.
This included changing files for a lot of targets I don't have easy access to (SGX? Haiku? Windows? Who has heard of these things), so I expect there to be spottiness in CI initially, unless luck is on my side.
Anyway this large only tangentially-related change is all in the first commit (although that commit also pulls the previous repr out into its own file), whereas the packing stuff is all in commit 2.
---
P.S. I haven't looked at all of this since writing it, and will do a pass over it again later, sorry for any obvious typos or w/e. I also definitely repeat myself in comments and such.
(It probably could use more tests too. I did some basic testing, and made it so we `debug_assert!` in cases the decode isn't what we encoded, but I don't know the degree which I can assume libstd's testing of IO would exercise this. That is: it wouldn't be surprising to me if libstds IO testing were minimal, especially around error cases, although I have no idea).
Impl {Add,Sub,Mul,Div,Rem,BitXor,BitOr,BitAnd}Assign<$t> for Wrapping<$t> for rust 1.60.0
Tracking issue #93204
This is about adding basic integer operations to the `Wrapping` type:
```rust
let mut value = Wrapping(2u8);
value += 3u8;
value -= 1u8;
value *= 2u8;
value /= 2u8;
value %= 2u8;
value ^= 255u8;
value |= 123u8;
value &= 2u8;
```
Because this adds stable impls on a stable type, it runs into the following issue if an `#[unstable(...)]` attribute is used:
```
an `#[unstable]` annotation here has no effect
note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
```
This means - if I understood this correctly - the new impls have to be stabilized instantly.
Which in turn means, this PR has to kick of an FCP on the tracking issue as well?
This impl is analog to 1c0dc1810d#92356 for the `Saturating` type ``@dtolnay`` ``@Mark-Simulacrum``
Fix invalid special casing of the unreachable! macro
This pull-request fix an invalid special casing of the `unreachable!` macro in the same way the `panic!` macro was solved, by adding two new internal only macros `unreachable_2015` and `unreachable_2021` edition dependent and turn `unreachable!` into a built-in macro that do dispatching. This logic is stolen from the `panic!` macro.
~~This pull-request also adds an internal feature `format_args_capture_non_literal` that allows capturing arguments from formatted string that expanded from macros. The original RFC #2795 mentioned this as a future possibility. This feature is [required](https://github.com/rust-lang/rust/issues/92137#issuecomment-1018630522) because of concatenation that needs to be done inside the macro:~~
```rust
$crate::concat!("internal error: entered unreachable code: ", $fmt)
```
**In summary** the new behavior for the `unreachable!` macro with this pr is:
Edition 2021:
```rust
let x = 5;
unreachable!("x is {x}");
```
```
internal error: entered unreachable code: x is 5
```
Edition <= 2018:
```rust
let x = 5;
unreachable!("x is {x}");
```
```
internal error: entered unreachable code: x is {x}
```
Also note that the change in this PR are **insta-stable** and **breaking changes** but this a considered as being a [bug](https://github.com/rust-lang/rust/issues/92137#issuecomment-998441613).
If someone could start a perf run and then a crater run this would be appreciated.
Fixes https://github.com/rust-lang/rust/issues/92137
Rollup of 2 pull requests
Successful merges:
- #90998 (Require const stability attribute on all stable functions that are `const`)
- #93489 (Mark the panic_no_unwind lang item as nounwind)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
* the logic only checked for / but not for \
* verbatim paths shouldn't skip items at all since they don't get normalized
* the extra branches get optimized out on unix since is_sep_byte is a trivial comparison and is_verbatim is always-false
* tests lacked windows coverage for these cases
That lead to equal paths not having equal hashes and to unnecessary collisions.
Mark the panic_no_unwind lang item as nounwind
This has 2 effects:
- It helps LLVM when inlining since it doesn't need to generate landing pads for `panic_no_unwind`.
- It makes it sound for a panic handler to unwind even if `PanicInfo::can_unwind` returns true. This will simply cause another panic once the unwind tries to go past the `panic_no_unwind` lang item. Eventually this will cause a stack overflow, which is safe.
Require const stability attribute on all stable functions that are `const`
This PR requires all stable functions (of all kinds) that are `const fn` to have a `#[rustc_const_stable]` or `#[rustc_const_unstable]` attribute. Stability was previously implied if omitted; a follow-up PR is planned to change the fallback to be unstable.
Optimize `core::str::Chars::count`
I wrote this a while ago after seeing this function as a bottleneck in a profile, but never got around to contributing it. I saw it again, and so here it is. The implementation is fairly complex, but I tried to explain what's happening at both a high level (in the header comment for the file), and in line comments in the impl. Hopefully it's clear enough.
This implementation (`case00_cur_libcore` in the benchmarks below) is somewhat consistently around 4x to 5x faster than the old implementation (`case01_old_libcore` in the benchmarks below), for a wide variety of workloads, without regressing performance on any of the workload sizes I've tried.
I also improved the benchmarks for this code, so that they explicitly check text in different languages and of different sizes (err, the cross product of language x size). The results of the benchmarks are here:
<details>
<summary>Benchmark results</summary>
<pre>
test str::char_count::emoji_huge::case00_cur_libcore ... bench: 20,216 ns/iter (+/- 3,673) = 17931 MB/s
test str::char_count::emoji_huge::case01_old_libcore ... bench: 108,851 ns/iter (+/- 12,777) = 3330 MB/s
test str::char_count::emoji_huge::case02_iter_increment ... bench: 329,502 ns/iter (+/- 4,163) = 1100 MB/s
test str::char_count::emoji_huge::case03_manual_char_len ... bench: 223,333 ns/iter (+/- 14,167) = 1623 MB/s
test str::char_count::emoji_large::case00_cur_libcore ... bench: 293 ns/iter (+/- 6) = 19331 MB/s
test str::char_count::emoji_large::case01_old_libcore ... bench: 1,681 ns/iter (+/- 28) = 3369 MB/s
test str::char_count::emoji_large::case02_iter_increment ... bench: 5,166 ns/iter (+/- 85) = 1096 MB/s
test str::char_count::emoji_large::case03_manual_char_len ... bench: 3,476 ns/iter (+/- 62) = 1629 MB/s
test str::char_count::emoji_medium::case00_cur_libcore ... bench: 48 ns/iter (+/- 0) = 14750 MB/s
test str::char_count::emoji_medium::case01_old_libcore ... bench: 217 ns/iter (+/- 4) = 3262 MB/s
test str::char_count::emoji_medium::case02_iter_increment ... bench: 642 ns/iter (+/- 7) = 1102 MB/s
test str::char_count::emoji_medium::case03_manual_char_len ... bench: 445 ns/iter (+/- 3) = 1591 MB/s
test str::char_count::emoji_small::case00_cur_libcore ... bench: 18 ns/iter (+/- 0) = 3777 MB/s
test str::char_count::emoji_small::case01_old_libcore ... bench: 23 ns/iter (+/- 0) = 2956 MB/s
test str::char_count::emoji_small::case02_iter_increment ... bench: 66 ns/iter (+/- 2) = 1030 MB/s
test str::char_count::emoji_small::case03_manual_char_len ... bench: 29 ns/iter (+/- 1) = 2344 MB/s
test str::char_count::en_huge::case00_cur_libcore ... bench: 25,909 ns/iter (+/- 39,260) = 13299 MB/s
test str::char_count::en_huge::case01_old_libcore ... bench: 102,887 ns/iter (+/- 3,257) = 3349 MB/s
test str::char_count::en_huge::case02_iter_increment ... bench: 166,370 ns/iter (+/- 12,439) = 2071 MB/s
test str::char_count::en_huge::case03_manual_char_len ... bench: 166,332 ns/iter (+/- 4,262) = 2071 MB/s
test str::char_count::en_large::case00_cur_libcore ... bench: 281 ns/iter (+/- 6) = 19160 MB/s
test str::char_count::en_large::case01_old_libcore ... bench: 1,598 ns/iter (+/- 19) = 3369 MB/s
test str::char_count::en_large::case02_iter_increment ... bench: 2,598 ns/iter (+/- 167) = 2072 MB/s
test str::char_count::en_large::case03_manual_char_len ... bench: 2,578 ns/iter (+/- 55) = 2088 MB/s
test str::char_count::en_medium::case00_cur_libcore ... bench: 44 ns/iter (+/- 1) = 15295 MB/s
test str::char_count::en_medium::case01_old_libcore ... bench: 201 ns/iter (+/- 51) = 3348 MB/s
test str::char_count::en_medium::case02_iter_increment ... bench: 322 ns/iter (+/- 40) = 2090 MB/s
test str::char_count::en_medium::case03_manual_char_len ... bench: 319 ns/iter (+/- 5) = 2109 MB/s
test str::char_count::en_small::case00_cur_libcore ... bench: 15 ns/iter (+/- 0) = 2333 MB/s
test str::char_count::en_small::case01_old_libcore ... bench: 14 ns/iter (+/- 0) = 2500 MB/s
test str::char_count::en_small::case02_iter_increment ... bench: 30 ns/iter (+/- 1) = 1166 MB/s
test str::char_count::en_small::case03_manual_char_len ... bench: 30 ns/iter (+/- 1) = 1166 MB/s
test str::char_count::ru_huge::case00_cur_libcore ... bench: 16,439 ns/iter (+/- 3,105) = 19777 MB/s
test str::char_count::ru_huge::case01_old_libcore ... bench: 89,480 ns/iter (+/- 2,555) = 3633 MB/s
test str::char_count::ru_huge::case02_iter_increment ... bench: 217,703 ns/iter (+/- 22,185) = 1493 MB/s
test str::char_count::ru_huge::case03_manual_char_len ... bench: 157,330 ns/iter (+/- 19,188) = 2066 MB/s
test str::char_count::ru_large::case00_cur_libcore ... bench: 243 ns/iter (+/- 6) = 20905 MB/s
test str::char_count::ru_large::case01_old_libcore ... bench: 1,384 ns/iter (+/- 51) = 3670 MB/s
test str::char_count::ru_large::case02_iter_increment ... bench: 3,381 ns/iter (+/- 543) = 1502 MB/s
test str::char_count::ru_large::case03_manual_char_len ... bench: 2,423 ns/iter (+/- 429) = 2096 MB/s
test str::char_count::ru_medium::case00_cur_libcore ... bench: 42 ns/iter (+/- 1) = 15119 MB/s
test str::char_count::ru_medium::case01_old_libcore ... bench: 180 ns/iter (+/- 4) = 3527 MB/s
test str::char_count::ru_medium::case02_iter_increment ... bench: 402 ns/iter (+/- 45) = 1579 MB/s
test str::char_count::ru_medium::case03_manual_char_len ... bench: 280 ns/iter (+/- 29) = 2267 MB/s
test str::char_count::ru_small::case00_cur_libcore ... bench: 12 ns/iter (+/- 0) = 2666 MB/s
test str::char_count::ru_small::case01_old_libcore ... bench: 12 ns/iter (+/- 0) = 2666 MB/s
test str::char_count::ru_small::case02_iter_increment ... bench: 19 ns/iter (+/- 0) = 1684 MB/s
test str::char_count::ru_small::case03_manual_char_len ... bench: 14 ns/iter (+/- 1) = 2285 MB/s
test str::char_count::zh_huge::case00_cur_libcore ... bench: 15,053 ns/iter (+/- 2,640) = 20067 MB/s
test str::char_count::zh_huge::case01_old_libcore ... bench: 82,622 ns/iter (+/- 3,602) = 3656 MB/s
test str::char_count::zh_huge::case02_iter_increment ... bench: 230,456 ns/iter (+/- 7,246) = 1310 MB/s
test str::char_count::zh_huge::case03_manual_char_len ... bench: 220,595 ns/iter (+/- 11,624) = 1369 MB/s
test str::char_count::zh_large::case00_cur_libcore ... bench: 227 ns/iter (+/- 65) = 20792 MB/s
test str::char_count::zh_large::case01_old_libcore ... bench: 1,136 ns/iter (+/- 144) = 4154 MB/s
test str::char_count::zh_large::case02_iter_increment ... bench: 3,147 ns/iter (+/- 253) = 1499 MB/s
test str::char_count::zh_large::case03_manual_char_len ... bench: 2,993 ns/iter (+/- 400) = 1577 MB/s
test str::char_count::zh_medium::case00_cur_libcore ... bench: 36 ns/iter (+/- 5) = 16388 MB/s
test str::char_count::zh_medium::case01_old_libcore ... bench: 142 ns/iter (+/- 18) = 4154 MB/s
test str::char_count::zh_medium::case02_iter_increment ... bench: 379 ns/iter (+/- 37) = 1556 MB/s
test str::char_count::zh_medium::case03_manual_char_len ... bench: 364 ns/iter (+/- 51) = 1620 MB/s
test str::char_count::zh_small::case00_cur_libcore ... bench: 11 ns/iter (+/- 1) = 3000 MB/s
test str::char_count::zh_small::case01_old_libcore ... bench: 11 ns/iter (+/- 1) = 3000 MB/s
test str::char_count::zh_small::case02_iter_increment ... bench: 20 ns/iter (+/- 3) = 1650 MB/s
</pre>
</details>
I also added fairly thorough tests for different sizes and alignments. This completes on my machine in 0.02s, which is surprising given how thorough they are, but it seems to detect bugs in the implementation. (I haven't run the tests on a 32 bit machine yet since before I reworked the code a little though, so... hopefully I'm not about to embarrass myself).
This uses similar SWAR-style techniques to the `is_ascii` impl I contributed in https://github.com/rust-lang/rust/pull/74066, so I'm going to request review from the same person who reviewed that one. That said am not particularly picky, and might not have the correct syntax for requesting a review from someone (so it goes).
r? `@nagisa`
Also, rename `BorrowedHandle::borrow_raw_handle` and
`BorrowedSocket::borrow_raw_socket` to `BorrowedHandle::borrow_raw` and
`BorrowedSocket::borrow_raw`.
This is just a minor rename to reduce redundancy in the user code calling
these functions, and to eliminate an inessential difference between
`BorrowedFd` code and `BorrowedHandle`/`BorrowedSocket` code.
While here, add a simple test exercising `BorrowedFd::borrow_raw_fd`.
kmc-solid: Fix off-by-one error in `SystemTime::now`
Fixes a miscalculation of `SystemTime` on the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets.
Unlike the identically-named libc counterpart `tm::tm_mon`, `SOLID_RTC_TIME::tm_mon` contains a 1-based month number.
impl `Arc::unwrap_or_clone`
The function gets the inner value, cloning only if necessary. The conversation started on [`irlo`](https://internals.rust-lang.org/t/arc-into-inner/15707). If the reviewer think the PR has potential to be merged, and does not need an RFC, then I will create the corresponding tracking issues and update the PR.
## Alternative names
- `into_inner`
- `make_owned`
- `make_unique`
- `take_*` (`take_inner`?)
Link `try_exists` docs to `Path::exists`
Links to the existing `Path::exists` method from both `std::Path::try_exists` and `std::fs:try_exists`.
Tracking issue for `path_try_exists`: #83186
pub use std::simd::StdFloat;
Syncs portable-simd up to commit rust-lang/portable-simd@03f6fbb21e,
Diff: 533f0fc81a...03f6fbb21e
This sync requires a little bit more legwork because it also introduces a trait into `std::simd`, so that it is no longer simply a reexport of `core::simd`. Out of simple-minded consistency and to allow more options, I replicated the pattern for the way `core::simd` is integrated in the first place, however this is not necessary if it doesn't acquire any interdependencies inside `std`: it could be a simple crate reexport. I just don't know yet if that will happen or not.
To summarize other misc changes:
- Shifts no longer panic, now wrap on too-large shifts (like `Simd` integers usually do!)
- mask16x32 will now be many i16s, not many i32s... 🙃
- `#[must_use]` is spread around generously
- Adjusts division, float min/max, and `Mask::{from,to}_array` internally to be faster
- Adds the much-requested `Simd::cast::<U>` function (equivalent to `simd.to_array().map(|lane| lane as U)`)
Support configuring whether to capture backtraces at runtime
Tracking issue: https://github.com/rust-lang/rust/issues/93346
This adds a new API to the `std::panic` module which configures whether and how the default panic hook will emit a backtrace when a panic occurs.
After discussion with `@yaahc` on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/backtrace.20lib.20vs.2E.20panic), this PR chooses to avoid adjusting or seeking to provide a similar API for the (currently unstable) std::backtrace API. It seems likely that the users of that API may wish to expose more specific settings rather than just a global one (e.g., emulating the `env_logger`, `tracing` per-module configuration) to avoid the cost of capture in hot code. The API added here could plausibly be copied and/or re-exported directly from std::backtrace relatively easily, but I don't think that's the right call as of now.
```rust
mod panic {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum BacktraceStyle {
Short,
Full,
Off,
}
fn set_backtrace_style(BacktraceStyle);
fn get_backtrace_style() -> Option<BacktraceStyle>;
}
```
Several unresolved questions:
* Do we need to move to a thread-local or otherwise more customizable strategy for whether to capture backtraces? See [this comment](https://github.com/rust-lang/rust/pull/79085#issuecomment-727845826) for some potential use cases for this.
* Proposed answer: no, leave this for third-party hooks.
* Bikeshed on naming of all the options, as usual.
* Should BacktraceStyle be moved into `std::backtrace`?
* It's already somewhat annoying to import and/or re-type the `std::panic::` prefix necessary to use these APIs, probably adding a second module to the mix isn't worth it.
Note that PR #79085 proposed a much simpler API, but particularly in light of the desire to fully replace setting environment variables via `env::set_var` to control the backtrace API, a more complete API seems preferable. This PR likely subsumes that one.
Fix incorrect panic message in example
The panic message when calling the `connect()` should probably be a message about connection failure, not a message about binding address failure.
Document valid values of the char type
As discussed at #93392, the current documentation on what constitutes a valid char isn't very detailed and is partly on the MAX constant rather than the type itself.
This PR expands on that information, stating the actual numerical range, giving examples of what won't work, and also mentions how a `char` might be a valid USV but still not be a defined character (terminology checked against [Unicode 14.0, table 2-3](https://www.unicode.org/versions/Unicode14.0.0/ch02.pdf#M9.61673.TableTitle.Table.22.Types.of.Code.Points)).
This change weakens the descriptions of the
`{as,into,from}_raw_{fd,handle,socket}` descriptions from saying that
they *do* express ownership relations to say that they are *typically used*
in ways that express ownership relations. This needed needed since, for
example, std's own [`RawFd`] implements `{As,From,Into}Fd` without any of
the ownership relationships.
This adds proper `# Safety` comments to `from_raw_{fd,handle,socket}`,
adds the requirement that raw handles be not opened with the
`FILE_FLAG_OVERLAPPED` flag, and merges the `OwnedHandle::from_raw_handle`
comment into the main `FromRawHandle::from_raw_handle` comment.
And, this changes `HandleOrNull` and `HandleOrInvalid` to not implement
`FromRawHandle`, since they are intended for limited use in FFI situations,
and not for generic use, and they have constraints that are stronger than
the those of `FromRawHandle`.
[`RawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/type.RawFd.html
Change Termination::report return type to ExitCode
Related to https://github.com/rust-lang/rust/issues/43301
The goal of this change is to minimize the forward compatibility risks in stabilizing Termination. By using the opaque type `ExitCode` instead of an `i32` we leave room for us to evolve the API over time to provide what cross-platform consistency we can / minimize footguns when working with exit codes, where as stabilizing on `i32` would limit what changes we could make in the future in how we represent and construct exit codes.
Implement `RawWaker` and `Waker` getters for underlying pointers
implement #87021
New APIs:
- `RawWaker::data(&self) -> *const ()`
- `RawWaker::vtable(&self) -> &'static RawWakerVTable`
- ~`Waker::as_raw_waker(&self) -> &RawWaker`~ `Waker::as_raw(&self) -> &RawWaker`
This third one is an auxiliary function to make the two APIs above more useful. Since we can only get `&Waker` in `Future::poll`, without this, we need to `transmute` it into `&RawWaker` (relying on `repr(transparent)`) in order to access its data/vtable pointers.
~Not sure if it should be named `as_raw` or `as_raw_waker`. Seems we always use `as_<something-raw>` instead of just `as_raw`. But `as_raw_waker` seems not quite consistent with `Waker::from_raw`.~ As suggested in https://github.com/rust-lang/rust/pull/91828#discussion_r770729837, use `as_raw`.
Carefully remove bounds checks from some chunk iterator functions
So, I was writing code that requires the equivalent of `rchunks(N).rev()` (which isn't the same as forward `chunks(N)` — in particular, if the buffer length is not a multiple of `N`, I must handle the "remainder" first).
I happened to look at the codegen output of the function (I was actually interested in whether or not a nested loop was being unrolled — it was), and noticed that in the outer `rchunks(n).rev()` loop, LLVM seemed to be unable to remove the bounds checks from the iteration: https://rust.godbolt.org/z/Tnz4MYY8f (this panic was from the split_at in `RChunks::next_back`).
After doing some experimentation, it seems all of the `next_back` in the non-exact chunk iterators have the issue: (`Chunks::next_back`, `RChunks::next_back`, `ChunksMut::next_back`, and `RChunksMut::next_back`)...
Even worse, the forward `rchunks` iterators sometimes have the issue as well (... but only sometimes). For example https://rust.godbolt.org/z/oGhbqv53r has bounds checks, but if I uncomment the loop body, it manages to remove the check (which is bizarre, since I'd expect the opposite...). I suspect it's highly dependent on the surrounding code, so I decided to remove the bounds checks from them anyway. Overall, this change includes:
- All `next_back` functions on the non-`Exact` iterators (e.g. `R?Chunks(Mut)?`).
- All `next` functions on the non-exact rchunks iterators (e.g. `RChunks(Mut)?`).
I wasn't able to catch any of the other chunk iterators failing to remove the bounds checks (I checked iterations over `r?chunks(_exact)?(_mut)?` with constant chunk sizes under `-O3`, `-Os`, and `-Oz`), which makes sense, since these were the cases where it was harder to prove the bounds check correct to remove...
In fact, it took quite a bit of thinking to convince myself that using unchecked_ here was valid — so I'm not really surprised that LLVM had trouble (although compilers are slightly better at this sort of reasoning than humans). A consequence of that is the fact that the `// SAFETY` comment for these are... kinda long...
---
I didn't do this for, or even think about it for, any of the other iteration methods; just `next` and `next_back` (where it mattered). If this PR is accepted, I'll file a follow up for someone (possibly me) to look at the others later (in particular, `nth`/`nth_back` looked like they had similar logic), but I wanted to do this now, as IMO `next`/`next_back` are the most important here, since they're what gets used by the iteration protocol.
---
Note: While I don't expect this to impact performance directly, the panic is a side effect, which would otherwise not exist in these loops. That is, this could prevent the compiler from being able to move/remove/otherwise rework a loop over these iterators (as an example, it could not delete the code for a loop whose body computes a value which doesn't get used).
Also, some like to be able to have confidence this code has no panicking branches in the optimized code, and "no bounds checks" is kinda part of the selling point of Rust's iterators anyway.
kmc-solid: Increase the default stack size
This PR increases the default minimum stack size on the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets to 64KiB (Arm) and 128KiB (AArch64).
This value was chosen as a middle ground between supporting a relatively complex program (e.g., an application using a full-fledged off-the-shelf web server framework) with no additional configuration and minimizing resource consumption for the embedded platform that doesn't support lazily-allocated pages nor over-commitment (i.e., wasted stack spaces are wasted physical memory). If the need arises, the users can always set the `RUST_MIN_STACK` environmental variable to override the default stack size or use the platform API directly.
kmc-solid: Inherit the calling task's base priority in `Thread::new`
This PR fixes the initial priority calculation of spawned threads on the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets.
Fixes a spawned task (an RTOS object on top of which threads are implemented for this target; unrelated to async tasks) getting an unexpectedly higher priority if it's spawned by a task whose priority is temporarily boosted by a priority-protection mutex.
Remove deprecated and unstable slice_partition_at_index functions
They have been deprecated since commit 01ac5a97c9
which was part of the 1.49.0 release, so from the point of nightly,
11 releases ago.
unix: Use metadata for `DirEntry::file_type` fallback
When `DirEntry::file_type` fails to match a known `d_type`, we should
fall back to `DirEntry::metadata` instead of a bare `lstat`, because
this is faster and more reliable on targets with `fstatat`.
review the total_cmp documentation
The documentation has been restructured to split out a brief summary
paragraph out from the following elaborating paragraphs.
I also attempted my hand at wording improvements and adding articles
where I felt them missing, but being non-native english speaker these
may need more thorough review.
cc https://github.com/rust-lang/rust/issues/72599
Clarify documentation on char::MAX
As mentioned in https://github.com/rust-lang/rust/issues/91836#issuecomment-994106874, the documentation on `char::MAX` is not quite correct – USVs are not "only ones within a certain range", they are code points _outside_ a certain range. I have corrected this and given the actual numbers as there is no reason to hide them.
Make `char::DecodeUtf16::size_hist` more precise
New implementation takes into account contents of `self.buf` and rounds lower bound up instead of down.
Fixes#88762
Revival of #88763
Fixes a spawned task getting an unexpectedly higher priority if it's
spawned by a task whose priority is temporarily boosted by a priority-
protection mutex.
Create `core::fmt::ArgumentV1` with generics instead of fn pointer
Split from (and prerequisite of) #90488, as this seems to have perf implication.
`@rustbot` label: +T-libs
The documentation has been restructured to split out a brief summary
paragraph out from the following elaborating paragraphs.
I also attempted my hand at wording improvements and adding articles
where I felt them missing, but being non-native english speaker these
may need more thorough review.
When `DirEntry::file_type` fails to match a known `d_type`, we should
fall back to `DirEntry::metadata` instead of a bare `lstat`, because
this is faster and more reliable on targets with `fstatat`.
fs: Don't copy d_name from struct dirent
The dirent returned from readdir() is only guaranteed to be valid for
d_reclen bytes on common platforms. Since we copy the name separately
anyway, we can copy everything except d_name into DirEntry::entry.
Fixes#93384.
Move unstable is_{arch}_feature_detected! macros to std::arch
These macros are unstable, except for `is_x86_feature_detected` which is still exported from the crate root for backwards-compatibility.
This should unblock the stabilization of `is_aarch64_feature_detected`.
r? ```@m-ou-se```
The dirent returned from readdir() is only guaranteed to be valid for
d_reclen bytes on common platforms. Since we copy the name separately
anyway, we can copy everything except d_name into DirEntry::entry.
Fixes#93384.
kmc-solid: Implement `net::FileDesc::duplicate`
This PR implements `std::sys::solid::net::FileDesc::duplicate`, which was accidentally left out when this target was added by #86191.