scoped threads: pass closure through MaybeUninit to avoid invalid dangling references
The `main` function defined here looks roughly like this, if it were written as a more explicit stand-alone function:
```rust
// Not showing all the `'lifetime` tracking, the point is that
// this closure might live shorter than `thread`.
fn thread(control: ..., closure: impl FnOnce() + 'lifetime) {
closure();
control.signal_done();
// A lot of time can pass here.
}
```
Note that `thread` continues to run even after `signal_done`! Now consider what happens if the `closure` captures a reference of lifetime `'lifetime`:
- The type of `closure` is a struct (the implicit unnameable closure type) with a `&'lifetime mut T` field. References passed to a function are marked with `dereferenceable`, which is LLVM speak for *this reference will remain live for the entire duration of this function*.
- The closure runs, `signal_done` runs. Then -- potentially -- this thread gets scheduled away and the main thread runs, seeing the signal and returning to the user. Now `'lifetime` ends and the memory the reference points to might be deallocated.
- Now we have UB! The reference that as passed to `thread` with the promise of remaining live for the entire duration of the function, actually got deallocated while the function still runs. Oops.
Long-term I think we should be able to use `ManuallyDrop` to fix this without `unsafe`, or maybe a new `MaybeDangling` type. I am working on an RFC for that. But in the mean time it'd be nice to fix this so that Miri with `-Zmiri-retag-fields` (which is needed for "full enforcement" of all the LLVM flags we generate) stops erroring on scoped threads.
Fixes https://github.com/rust-lang/rust/issues/101983
r? `@m-ou-se`
Copying the approach of the Unix target, this change uses the standard
`RwLock` to protect against concurrent access of libc's environment.
This locking is only enabled when WebAssembly's `atomics` feature is
also enabled.
The issue #102157 demonstrates how currently the `-Z build-std` option
will fail when re-compiling the standard library with `RUSTFLAGS` like
`RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C
link-args=--shared-memory"`. This change attempts to resolve those build
issues by depending on the the WebAssembly `futex` module and providing
an implementation for `env_lock`. Fixes#102157.
Make tests capture the error printed by a Result return
An error returned by tests previously would get written directly to stderr, instead of to the capture buffer set up by the test harness. This PR makes it write to the capture buffer so that it can be integrated as part of the test output by build tools such as `buck test`, since being able to read the error message returned by a test is pretty critical to debugging why the test failed.
<br>
**Before:**
```rust
// tests/test.rs
#[test]
fn test() -> Result<(), &'static str> {
println!("STDOUT");
eprintln!("STDERR");
Err("RESULT")
}
```
```console
$ cargo build --test test
$ target/debug/deps/test-???????????????? -Z unstable-options --format=json
{ "type": "suite", "event": "started", "test_count": 1 }
{ "type": "test", "event": "started", "name": "test" }
Error: "RESULT"
{ "type": "test", "name": "test", "event": "failed", "stdout": "STDOUT\nSTDERR\n" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "ignored": 0, "measured": 0, "filtered_out": 0, "exec_time": 0.00040313 }
```
**After:**
```console
$ target/debug/deps/test-???????????????? -Z unstable-options --format=json
{ "type": "suite", "event": "started", "test_count": 1 }
{ "type": "test", "event": "started", "name": "test" }
{ "type": "test", "name": "test", "event": "failed", "stdout": "STDOUT\nSTDERR\nError: \"RESULT\"" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "ignored": 0, "measured": 0, "filtered_out": 0, "exec_time": 0.000261894 }
```
Rollup of 8 pull requests
Successful merges:
- #101118 (fs::get_mode enable getting the data via fcntl/F_GETFL on major BSD)
- #102072 (Add `ptr::Alignment` type)
- #102799 (rustdoc: remove hover gap in file picker)
- #102820 (Show let-else suggestion on stable.)
- #102829 (rename `ImplItemKind::TyAlias` to `ImplItemKind::Type`)
- #102831 (Don't use unnormalized type in `Ty::fn_sig` call in rustdoc `clean_middle_ty`)
- #102834 (Remove unnecessary `lift`/`lift_to_tcx` calls from rustdoc)
- #102838 (remove cfg(bootstrap) from Miri)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
the kernel currently enforce that a stack is immutable. calling mmap(2) or
mprotect(2) to change it will result in EPERM, which generate a panic!().
so just do like for Linux, and trust the kernel to do the right thing.
Reduce CString allocations in std as much as possible
Currently, every operation involving paths in `fs` allocates memory to hold the path before sending it through the syscall. This PR instead uses a stack allocation (chosen size is somewhat arbitrary) when the path is short before falling back to heap allocations for long paths.
Benchmarks show that the stack allocation is ~2x faster for short paths:
```
test sys::unix::fd::tests::bench_heap_path_alloc ... bench: 34 ns/iter (+/- 2)
test sys::unix::fd::tests::bench_stack_path_alloc ... bench: 15 ns/iter (+/- 1)
```
For long paths, I couldn't find any measurable difference.
---
I'd be surprised if I was the first to think of this, so I didn't fully flush out the PR. If this change is desirable, I'll make use of `run_with_cstr` across all platforms in every fs method (currently just unix open for testing). I also added an `impl From<FromBytesWithNulError>` which is presumably a no-no (or at least needs to be done in another PR).
---
Also see https://github.com/nix-rust/nix/pull/1655 with a bunch of discussion where I'm doing something similar.
Remove empty core::lazy and std::lazy
PR #98165 with commits 7c360dc117 and c1a2db3372 has moved all of the components of these modules into different places, namely {std,core}::sync and {std,core}::cell. The empty modules remained. As they are unstable, we can simply remove them.
PR #98165 with commits 7c360dc117 and c1a2db3372
has moved all of the components of these modules into different places,
namely {std,core}::sync and {std,core}::cell. The empty
modules remained. As they are unstable, we can simply remove them.
std: use futex in `Once`
Now that we have efficient locks, let's optimize the rest of `sync` as well. This PR adds a futex-based implementation for `Once`, which drastically simplifies the implementation compared to the generic version, which is provided as fallback for platforms without futex (Windows only supports them on newer versions, so it uses the fallback for now).
Instead of storing a linked list of waiters, the new implementation adds another state (`QUEUED`), which is set when there are waiting threads. These now use `futex_wait` on that state and are woken by the running thread when it finishes and notices the `QUEUED` state, thereby avoiding unnecessary calls to `futex_wake_all`.
Avoid repeated re-initialization of the BufReader buffer
Fixes https://github.com/rust-lang/rust/issues/102727
We accidentally removed this in https://github.com/rust-lang/rust/pull/98748. It looks so redundant. But it isn't.
The default `Read::read_buf` will defensively initialize the whole buffer, if any of it is indicated to be uninitialized. In uses where reads from the wrapped `Read` impl completely fill the `BufReader`, `initialized` and `filled` are the same, and this extra member isn't required. But in the reported issue, the `BufReader` wraps a `Read` impl which will _never_ fill the whole buffer. So the default `Read::read_buf` implementation repeatedly re-initializes the extra space in the buffer.
This adds back the extra `initialized` member, which ensures that the default `Read::read_buf` only zero-initialized the buffer once, and I've tried to add a comment which explains this whole situation.
unsafe keyword: trait examples and unsafe_op_in_unsafe_fn update
Having a safe `fn` in an `unsafe trait` vs an `unsafe fn` in a safe `trait` are pretty different situations, but the distinction is subtle and can confuse even seasoned Rust developers. So let's have explicit examples of both. I also removed the existing `unsafe trait` example since it was rather strange.
Also the `unsafe_op_in_unsafe_fn` lint can help disentangle the two sides of `unsafe`, so update the docs to account for that.
After calling libc::fork, the child process tried to access
a TLS variable when processing a panic. This caused
a memory allocation which is UB in the child.
To prevent this from happening, the panic handler will
not access the TLS variable in case `panic::always_abort`
was called before.
The EH actions stored in the LSDA follows the format of GCC except table
(even for LLVM-generated code). An missing action in the table is the
encoding for `Terminate`, see [1].
The currently code interprets it as `None`, as a workaround for #35011,
an issue that seems to occur in LLVM 3.7 and not after 3.9. These are
very old versions of LLVM and we don't support them anymore, so remove
this workaround and interpret them properly.
Note that LLVM currently does not emit any `Terminate` actions, but GCC
does. Although GCC backend currently doesn't do unwinding, removing it
preemptively would prevent future developers from wasting time to figure
out what's wrong.
[1]: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/eh_personality.cc#L522-L526
Add `AsFd` implementations for stdio lock types on WASI.
This mirrors the implementations on Unix platforms, and also mirrors the existing `AsRawFd` impls.
This is similar to #100892, but is for the `*Lock` types.
Update docs so that deprecated method points to relevant method
The docs for the deprecated 'park_timeout_ms' method suggests that the user 'use park_timeout' method instead (at https://doc.rust-lang.org/std/thread/index.html).
Making a similar change so that the docs for the deprecated `sleep_ms` method suggest that the user `use sleep` method instead.
Add a niche to `Duration`, unix `SystemTime`, and non-apple `Instant`
As the nanoseconds fields is always between `0` and `(NANOS_PER_SEC - 1)` inclusive, use the `rustc_layout_scalar_valid_range` attributes to create a niche in the nanosecond field of `Duration` and `Timespec` (which is used to implement unix `SystemTime` and non-apple unix `Instant`; windows `Instant` is implemented with `Duration` and therefore will also benefit). This change has the benefit of making `Option<T>` the same size as `T` for the previously mentioned types. Also shrinks the nanoseconds field of `Timespec` to a `u32` as nanoseconds do not need the extra range of an `i64`, shrinking `Timespec` by 4 bytes on 32-bit platforms.
r? ```@joshtriplett```
Make `std::os::fd` public.
`std::os::fd` defines types like `OwnedFd` and `RawFd` and is common
between Unix and non-Unix platforms that share a basic file-descriptor
concept. Rust currently uses this internally to simplify its own code,
but it would be useful for external users in the same way, so make it
public.
This means that `OwnedFd` etc. will all appear in three places, for
example on unix platforms:
- `std::os::fd::OwnedFd`
- `std::os::unix::io::OwnedFd`
- `std::os::unix::prelude::OwnedFd`
r? `````@joshtriplett`````
Suggest unwrapping `???<T>` if a method cannot be found on it but is present on `T`.
This suggests various ways to get inside wrapper types if the method cannot be found on the wrapper type, but is present on the wrappee.
For this PR, those wrapper types include `Localkey`, `MaybeUninit`, `RefCell`, `RwLock` and `Mutex`.
Stabilize bench_black_box
This PR stabilize `feature(bench_black_box)`.
```rust
pub fn black_box<T>(dummy: T) -> T;
```
The FCP was completed in https://github.com/rust-lang/rust/issues/64102.
`@rustbot` label +T-libs-api -T-libs
Stabilize `#![feature(mixed_integer_ops)]`
Tracked and FCP completed in #87840.
````@rustbot```` label +T-libs-api +S-waiting-on-review +relnotes
r? rust-lang/t-libs-api
Recover error strings on Unix from_lossy_utf8
Some language settings can result in unreliable UTF-8 being produced.
This can result in failing to emit the error string, panicking instead.
from_lossy_utf8 allows us to assume these strings usually will be fine.
This fixes rust-lang#99535.
make Condvar, Mutex, RwLock const constructors work with the `unsupported` impl
applying this patch locally to the `rust-src` component fixes#98378
however, the solution seems wrong to me because PR #97791 didn't add any `rustc_const_stable` attribute to underlying implementations like `std::sys::unix::futex`, so I must be missing something about how const-stability is checked ... maybe the `restricted_std` feature (gate?) has an effect?
fixes#98378fixes#98293 (probably)
Refactor some `std` code that works with pointer offstes
This PR replaces `pointer::offset` in standard library with `pointer::add` and `pointer::sub`, [re]moving some casts and using `.addr()` while we are at it.
This is a more complicated refactor than all other sibling PRs, so take a closer look when reviewing, please 😃 (though I've checked this multiple times and it looks fine).
r? ````@scottmcm````
_split off from #100746, continuation of #100822_
Update doc after renaming `fn is_zero`
`fn is_zero` has been renamed to `fn count_is_zero` in 1b1bf24636.
This patch updates the documentation accordingly.
Remove `RtlGenRandom` (take two)
First try to use the system preferred RNG but if that fails (e.g. due to a broken system configuration) then fallback to manually opening an algorithm handle.
This mirrors the implementations on Unix platforms, and also mirrors the
existing `AsRawFd` impls.
This is similar to #100892, but is for the `*Lock` types.
Remove use of `io::ErrorKind::Other` in std
The documentation states that this `ErrorKind` is not used by the standard library. Instead, `io::ErrorKind::Uncategorized` should be used.
The two instances are in the unstable API [linux_pidfd](https://github.com/rust-lang/rust/issues/82971).
Clarify Path::extension() semantics in docs abstract
State up-front and center what shape the returned extension will have, without making the user read through the description and examples.
This is a doc-only change. There are no changes to the API contract and the clarification is in line with what was already stated/promised in the existing doc text - just clarified, summarized, and served bright and early.
Rationale: Various frameworks and libraries for different platforms have their different conventions as to whether an "extension" is ".ext" or just "ext" and anyone that's had to deal with this ambiguity in the past is always double- or triple-checking to make sure the function call returns an extension that matches the expected semantics. Offer the answer to this important question right off the bat instead of making them dig to find it.
```@rustbot``` label +A-docs
std: use `sync::RwLock` for internal statics
Since `sync::RwLock` is now `const`-constructible, it can be used for internal statics, removing the need for `sys_common::StaticRwLock`. This adds some extra allocations on platforms which need to box their locks (currently SGX and some UNIX), but these will become unnecessary with the lock improvements tracked in #93740.
First try to use the system preferred RNG but if that fails (e.g. due to a broken system configuration) then fallback to manually opening an algorithm handle.
State up-front and center what shape the returned extension will have, without
making the user read through the description and examples.
Rationale: Various frameworks and libraries for different platforms have their
different conventions as to whether an "extension" is ".ext" or just "ext" and
anyone that's had to deal with this ambiguity in the past is always double- or
triple-checking to make sure the function call returns an extension that matches
the expected semantics. Offer the answer to this important question right off
the bat instead of making them dig to find it.
Make `from_waker`, `waker` and `from_raw` unstably `const`
Make
- `Context::from_waker`
- `Context::waker`
- `Waker::from_raw`
`const`.
Also added a small test.
This documents the very surprising behaviour that `set_readonly(false)` will make a file *world writable* on Unix. I would go so far as to say that this function should be deprecated on Unix, or maybe even entirely. But documenting the bad behaviour is a good first step.
Update stdarch
This pulls in the following changes:
- [Use simd_bitmask intrinsic in a couple of places](9f0928782b)
- [Remove simd_shuffle<n> usage in favor of simd_shuffle](3fd17e4607)
- [Remove late specifiers in __cpuid_count](f1db941633)
- Helps with #101346
- [Use mov and xchg instead of movl(q) and xchgl(q)](3049a31937)
- [Bump cfg-if dependency to 1.0](f305cc83e7)
- [Fix documentation of __m256bh and __m512bh structs](699c093a42)
r? ``@Amanieu``
array docs - advertise how to get array from slice
On my first Rust project, I spent more time than I care to admit figuring out how to efficiently get an array from a slice. Update the array documentation to explain this a bit more clearly.
(As a side note, it's a bit unfortunate that get-array-from-slice is only available via trait since that means it can't be used from const functions yet.)
On later stages, the feature is already stable.
Result of running:
rg -l "feature.let_else" compiler/ src/librustdoc/ library/ | xargs sed -s -i "s#\\[feature.let_else#\\[cfg_attr\\(bootstrap, feature\\(let_else\\)#"
Check if TCS is a null pointer on SGX
The `EENTER` instruction only checks if the TCS is aligned, not if it zero. Saying the address returned is a `NonNull<u8>` (for which `Tcs` is a type alias) is unsound. As well-behaved runners will not put the TCS at address zero, so the definition of `Tcs` is correct. However, `std` should check the address before casting it to a `NonNull`.
ping `@jethrogb` `@raoulstrackx`
`@rustbot` label I-unsound
Optimize thread parking on NetBSD
As the futex syscall is not present in the latest stable release, NetBSD cannot use the efficient thread parker and locks Linux uses. Currently, it therefore relies on a pthread-based parker, consisting of a mutex and semaphore which protect a state variable. NetBSD however has more efficient syscalls available: [`_lwp_park`](https://man.netbsd.org/_lwp_park.2) and [`_lwp_unpark`](https://man.netbsd.org/_lwp_unpark.2). These already provide the exact semantics of `thread::park` and `Thread::unpark`, but work with thread ids. In `std`, this ID is here stored in an atomic state variable, which is also used to optimize cases were the parking token is already available at the time `thread::park` is called.
r? `@m-ou-se`
On my first Rust project, I spent more time than I care to admit
figuring out how to efficiently get an array from a slice. Update the
array documentation to explain this a bit more clearly.
(As a side note, it's a bit unfortunate that get-array-from-slice is
only available via trait since that means it can't be used from const
functions yet.)
Rollup of 5 pull requests
Successful merges:
- #101366 (Restore old behaviour on broken UNC paths)
- #101492 (Suggest adding array lengths to references to arrays if possible)
- #101529 (Fix the example code and doctest for Formatter::sign_plus)
- #101573 (update `ParamKindOrd`)
- #101612 (Fix code generation of `Rvalue::Repeat` with 128 bit values)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Restore old behaviour on broken UNC paths
This fixes#101358 by restoring the behaviour from previous stable Rust versions. I'm not convinced this is ultimately right but I think it's less wrong and maybe this should be backported to beta?
r? libs
Open a BCrypt algorithm handle
Fixes#101474, supplants #101456.
Replaces use of a pseduo handle with manually opening a algorithm handle.
Most interesting thing here is the atomics.
r? `@thomcc`
Printing to stdio/stderr that have been opened with non-blocking
(O_NONBLOCK in linux) can result in an error, which is not handled
by std::io module causing a panic.
Signed-off-by: Usama Arif <usama.arif@bytedance.com>
Don't duplicate file descriptors into stdio fds
Ensures that file descriptors are never duplicated into the stdio fds even if a stdio fd has been closed.
Make `ReentrantMutex` movable and `const`
As `MovableMutex` is now `const`, it can be used to simplify the implementation and interface of the internal reentrant mutex type. Consequently, the standard error stream does not need to be wrapped in `OnceLock` and `OnceLock::get_or_init_pin()` can be removed.
Forbid mixing `System` with direct sytem allocator calls
e.g. [on windows](dec689432f/library/std/src/sys/windows/alloc.rs (L129-L178)), trying to mix `System::alloc` and `HeapFree` will not work because of the extra work done to serve higher alignments.
Fix `std::collections::HashSet::drain` documentation
Hi!
`std::collections::HashSet::drain` contains small typo in the docstring.
I didn't read too much about the model of contributing to Rust, so merge this PR or close and fix the typo the right way :)
Thanks for Rust!
Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default
This only changes a small amount of actual code, the rest is documentation outlining the history of this module as I feel it will be relevant to any future issues that might crop up.
The code change is to use the `BCRYPT_RNG_ALG_HANDLE` [pseudo-handle](https://docs.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-pseudo-handles) by default, which simply uses the default RNG. Previously we used `BCRYPT_USE_SYSTEM_PREFERRED_RNG` which has to load the system configuration and then find and load that RNG. I suspect this was the cause of failures on some systems (e.g. due to corrupted config). However, this is admittedly speculation as I can't reproduce the issue myself (and it does seem quite rare even in the wild). Still, removing a possible point of failure is likely worthwhile in any case.
r? libs
Support `#[unix_sigpipe = "inherit|sig_dfl"]` on `fn main()` to prevent ignoring `SIGPIPE`
When enabled, programs don't have to explicitly handle `ErrorKind::BrokenPipe` any longer. Currently, the program
```rust
fn main() { loop { println!("hello world"); } }
```
will print an error if used with a short-lived pipe, e.g.
% ./main | head -n 1
hello world
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1016:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
by enabling `#[unix_sigpipe = "sig_dfl"]` like this
```rust
#![feature(unix_sigpipe)]
#[unix_sigpipe = "sig_dfl"]
fn main() { loop { println!("hello world"); } }
```
there is no error, because `SIGPIPE` will not be ignored and thus the program will be killed appropriately:
% ./main | head -n 1
hello world
The current libstd behaviour of ignoring `SIGPIPE` before `fn main()` can be explicitly requested by using `#[unix_sigpipe = "sig_ign"]`.
With `#[unix_sigpipe = "inherit"]`, no change at all is made to `SIGPIPE`, which typically means the behaviour will be the same as `#[unix_sigpipe = "sig_dfl"]`.
See https://github.com/rust-lang/rust/issues/62569 and referenced issues for discussions regarding the `SIGPIPE` problem itself
See the [this](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Proposal.3A.20First.20step.20towards.20solving.20the.20SIGPIPE.20problem) Zulip topic for more discussions, including about this PR.
Tracking issue: https://github.com/rust-lang/rust/issues/97889
Uplift the `let_underscore` lints from clippy into rustc.
This PR resolves#97241.
This PR adds three lints from clippy--`let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use`, which are meant to capture likely-incorrect uses of `let _ = ...` bindings (in particular, doing this on a type with a non-trivial `Drop` causes the `Drop` to occur immediately, instead of at the end of the scope. For a type like `MutexGuard`, this effectively releases the lock immediately, which is almost certainly the wrong behavior)
In porting the lints from clippy I had to copy over a bunch of utility functions from `clippy_util` that these lints also relied upon. Is that the right approach?
Note that I've set the `must_use` and `drop` lints to Allow by default and set `lock` to Deny by default (this matches the same settings that clippy has). In talking with `@estebank` he informed me to do a Crater run (I am not sure what type of Crater run to request here--I think it's just "check only"?)
On the linked issue, there's some discussion about using `must_use` and `Drop` together as a heuristic for when to warn--I did not implement this yet.
r? `@estebank`
Fix a bunch of typo
This PR will fix some typos detected by [typos].
I only picked the ones I was sure were spelling errors to fix, mostly in
the comments.
[typos]: https://github.com/crate-ci/typos
This PR will fix some typos detected by [typos].
I only picked the ones I was sure were spelling errors to fix, mostly in
the comments.
[typos]: https://github.com/crate-ci/typos
Fix UB from misalignment and provenance widening in `std::sys::windows`
This fixes two types of UB:
1. Reading past the end of a reference in types like `&c::REPARSE_DATA_BUFFER` (see https://github.com/rust-lang/unsafe-code-guidelines/issues/256). This is fixed by using `addr_of!`. I think there are probably a couple more cases where we do this for other structures, and will look into it in a bit.
2. Failing to ensure that a `[u8; N]` on the stack is sufficiently aligned to convert to a `REPARSE_DATA_BUFFER`. ~~This was done by introducing a new `AlignedAs` struct that allows aligning one type to the alignment of another type. I expect there are other places where we have this issue too, or I wouldn't introduce this type, but will get to them after this lands.~~
~~Worth noting, it *is* implemented in a way that can cause problems depending on how we fix#81996, but this would be caught by the test I added (and presumably if we decide to fix that in a way that would break this code, we'd also introduce a `#[repr(simple)]` or `#[repr(linear)]` as a replacement for this usage of `#[repr(C)]`).~~
Edit: None of that is still in the code, I just went with a `Align8` since that's all we'll need for almost everything we want to call.
These are more or less "potential UB" since it's likely at the moment everything works fine, although the alignment not causing issues might just be down to luck (and x86 being forgiving).
~~NB: I've only ensured this check builds, but will run tests soon.~~ All tests pass, including stage2 compiler tests.
r? ``@ChrisDenton``
Use getentropy when possible on all Apple platforms
As the current code comments say, `SecRandomCopyBytes` is very heavyweight (regardless of purpose) compared to just asking the kernel directly for bytes from its own CSPRNG. We were not previously making an attempt to use the more efficient `getentropy` call on other Apple targets, instead solely using it on macOS. As the function is available on newer versions of Apple's different OSes, this changes the random filling to always attempt it first everywhere, only falling back to the less ideal alternatives after. This also cleans up the multiple Apple `imp` blocks into one.
It also should give a perf improvement, even if its likely unnoticeably small.
Refed XCode header for `getentropy` in the SDK:
```h
int getentropy(void* buffer, size_t size) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
```
r? ``@thomcc``
Reinstate preloading of some dll imports
I've now come around to the conclusion that there is a justification for pre-loading the synchronization functions `WaitOnAddress` and `WakeByAddressSingle`. I've found this to have a particularly impact in testing frameworks that may have short lived processes which immediately spawn lots of threads.
Also, because pre-main initializers imply a single-threaded environment, we can switch back to using relaxed atomics which might be a minor perf improvement on some platforms (though I doubt it's particularly notable).
r? ``@Mark-Simulacrum`` and sorry for the churn here.
For convenience I'll summarise previous issues with preloading and the solutions that are included in this PR (if any):
**Issue:** User pre-main initializers may be run before std's
**Solution:** The std now uses initializers that are guaranteed to run earlier than the old initializers. A note is also added that users should not copy std's behaviour if they want to ensure they run their initializers after std.
**Issue:** Miri does not understand pre-main initializers.
**Solution:** For miri only, run the function loading lazily instead.
**Issue:** We should ideally use `LoadLibrary` to get "api-ms-win-core-synch-l1-2-0". Only "ntdll" and "kernel32" are guaranteed to always be loaded.
**Solution:** None. We can't use `LoadLibrary` pre-main. However, in the past `GetModuleHandle` has always worked in practice so this should hopefully not be a problem.
If/when Windows 7 support is dropped, we can finally remove all this for good and just use normal imports.
Avoid zeroing large stack buffers in stdio on Windows
Does what it says on the tin, using `[MaybeUninit<u16>; N]` instead of `[0u16; N]`. These buffers seem to be around 8kb, which is big enough that this is likely to be a very nice perf boost to stdio-heavy windows code.
r? ``@ChrisDenton``
*(Note: this PR also has a commit that adds windows to CI, but as it mentions I'll revert that after it comes out green -- I can only do a check build on the machine I'm typing this on)*
Revert let_chains stabilization
This is the revert against master, the beta revert was already done in #100538.
Bumps the stage0 compiler which already has it reverted.
Rollup of 7 pull requests
Successful merges:
- #100898 (Do not report too many expr field candidates)
- #101056 (Add the syntax of references to their documentation summary.)
- #101106 (Rustdoc-Json: Retain Stripped Modules when they are imported, not when they have items)
- #101131 (CTFE: exposing pointers and calling extern fn is just impossible)
- #101141 (Simplify `get_trait_ref` fn used for `virtual_function_elimination`)
- #101146 (Various changes to logging of borrowck-related code)
- #101156 (Remove `Sync` requirement from lint pass objects)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Add the syntax of references to their documentation summary.
Without this change, in <https://doc.rust-lang.org/1.63.0/std/#primitives>, `reference` is the only entry in that list which does not contain the syntax by which the type is named in source code. With this change, it contains them, in roughly the same way as the `pointer` entry does.
`std::os::fd` defines types like `OwnedFd` and `RawFd` and is common
between Unix and non-Unix platforms that share a basic file-descriptor
concept. Rust currently uses this internally to simplify its own code,
but it would be useful for external users in the same way, so make it
public.
This means that `OwnedFd` etc. will all appear in three places, for
example on unix platforms:
- `std::os::fd::OwnedFd`
- `std::os::unix::io::OwnedFd`
- `std::os::unix::prelude::OwnedFd`
Make use of `[wrapping_]byte_{add,sub}`
These new methods trivially replace old `.cast().wrapping_offset().cast()` & similar code.
Note that [`arith_offset`](https://doc.rust-lang.org/std/intrinsics/fn.arith_offset.html) and `wrapping_offset` are the same thing.
r? ``@scottmcm``
_split off from #100746_
Stabilize `std::io::read_to_string`
Closes#80218. 🎉
This PR stabilizes the `std::io::read_to_string` function, with the following public API:
```rust
pub fn read_to_string<R: Read>(reader: R) -> Result<String>;
```
It's analogous to `std::fs::read_to_string` for files, but it works on anything that implements `io::Read`, including `io::stdin()`.
See the tracking issue (#80218) or documentation for details.
Add a `File::create_new` constructor
We have `File::create` for creating a file or opening an existing file,
but the secure way to guarantee creating a new file requires a longhand
invocation via `OpenOptions`.
Add `File::create_new` to handle this case, to make it easier for people
to do secure file creation.
Use posix_spawn for absolute paths on macOS
Currently, on macOS, Rust never uses the fast posix_spawn path if a
directory change is requested, due to a bug in Apple's libc. However, the
bug is only triggered if the program is a relative path.
This PR makes it so that the fast path continues to work if the program
is an absolute path or a lone filename.
This was an alternative proposed in https://github.com/rust-lang/rust/pull/80537#issue-776674009, and it makes a measurable performance difference in some of my code that spawns thousands of processes.
Support parsing IP addresses from a byte string
Fixes#94821
The goal is to be able to parse addresses from a byte string without requiring to do any utf8 validation. Since internally the parser already works on byte strings, this should be possible and I personally already needed this in the past too.
~~I used the proposed approach from the issue by implementing `TryFrom<&'a [u8]>` for all 6 address types (3 ip address types and 3 socket address types). I believe implementing stable traits for stable types is insta-stable so this will probably need an FCP?~~
Switched to an unstable inherent method approach called `parse_ascii` as requested.
cc ``````@jyn514``````
Currently, on macOS, Rust never uses the fast posix_spawn path if a
directory change is requested due to a bug in Apple's libc. However, the
bug is only triggered if the program is a relative path.
This PR makes it so that the fast path continues to work if the program
is an absolute path or a lone filename.
This was an alternative proposed in
https://github.com/rust-lang/rust/pull/80537#issue-776674009, and it
makes a measurable performance difference in some of my code that spawns
thousands of processes.
Add next_up and next_down for f32/f64 - take 2
This is a revival of https://github.com/rust-lang/rust/pull/88728 which staled due to inactivity of the original author. I've address the last review comment.
---
This is a pull request implementing the features described at https://github.com/rust-lang/rfcs/pull/3173.
`@rustbot` label +T-libs-api -T-libs
r? `@scottmcm`
cc `@orlp`
This makes it possible to instruct libstd to never touch the signal
handler for `SIGPIPE`, which makes programs pipeable by default (e.g.
with `./your-program | head -n 1`) without `ErrorKind::BrokenPipe`
errors.
std: use realstd fast key when building tests
Under `cfg(test)`, the `std` crate is not the actual standard library, just any old crate we are testing. It imports the real standard library as `realstd`, and then does some careful `cfg` magic so that the crate built for testing uses the `realstd` global state rather than having its own copy of that.
However, this was not done for all global state hidden in std: the 'fast' version of thread-local keys, at least on some platforms, also involves some global state. Specifically its macOS version has this [`static REGISTERED`](bc63d5a26a/library/std/src/sys/unix/thread_local_dtor.rs (L62)) that would get duplicated. So this PR imports the 'fast' key type from `realstd` rather than using the local copy, to ensure its internal state (and that of the functions it calls) does not get duplicated.
I also noticed that the `__OsLocalKeyInner` is unused under `cfg(target_thread_local)`, so I removed it for that configuration. There was a comment saying macOS picks between `__OsLocalKeyInner` and `__FastLocalKeyInner` at runtime, but I think that comment is outdated -- I found no trace of such a runtime switching mechanism, and the library still check-builds on apple targets with this PR. (I don't have a Mac so I cannot actually run it.)
Some papercuts on error::Error
Renames the chain method, since I chain could mean anything and doesn't refer to a chain of sources (cc #58520) (and adds a comment explaining why sources is not a provided method on Error). Renames arguments to the request method from `req` to `demand` since the type is `Demand` rather than Request or Requisition.
r? ``@yaahc``
Add mention of `BufReader` in `Read::bytes` docs
There is a general paragraph about `BufRead` in the `Read` trait's docs, however using `bytes` without `BufRead` *always* has a large impact, due to reads of size 1.
`@rustbot` label +A-docs
Add standard C error function aliases to last_os_error
This aids the discoverability of `io::Error::last_os_error()` by linking to commonly used error number functions from C/C++.
I've seen a few people not realize this exists, so hopefully this helps draw attention to the API to encourage using it over integer error codes.
std::io: migrate ReadBuf to BorrowBuf/BorrowCursor
This PR replaces `ReadBuf` (used by the `Read::read_buf` family of methods) with `BorrowBuf` and `BorrowCursor`.
The general idea is to split `ReadBuf` because its API is large and confusing. `BorrowBuf` represents a borrowed buffer which is mostly read-only and (other than for construction) deals only with filled vs unfilled segments. a `BorrowCursor` is a mostly write-only view of the unfilled part of a `BorrowBuf` which distinguishes between initialized and uninitialized segments. For `Read::read_buf`, the caller would create a `BorrowBuf`, then pass a `BorrowCursor` to `read_buf`.
In addition to the major API split, I've made the following smaller changes:
* Removed some methods entirely from the API (mostly the functionality can be replicated with two calls rather than a single one)
* Unified naming, e.g., by replacing initialized with init and assume_init with set_init
* Added an easy way to get the number of bytes written to a cursor (`written` method)
As well as simplifying the API (IMO), this approach has the following advantages:
* Since we pass the cursor by value, we remove the 'unsoundness footgun' where a malicious `read_buf` could swap out the `ReadBuf`.
* Since `read_buf` cannot write into the filled part of the buffer, we prevent the filled part shrinking or changing which could cause underflow for the caller or unexpected behaviour.
## Outline
```rust
pub struct BorrowBuf<'a>
impl Debug for BorrowBuf<'_>
impl<'a> From<&'a mut [u8]> for BorrowBuf<'a>
impl<'a> From<&'a mut [MaybeUninit<u8>]> for BorrowBuf<'a>
impl<'a> BorrowBuf<'a> {
pub fn capacity(&self) -> usize
pub fn len(&self) -> usize
pub fn init_len(&self) -> usize
pub fn filled(&self) -> &[u8]
pub fn unfilled<'this>(&'this mut self) -> BorrowCursor<'this, 'a>
pub fn clear(&mut self) -> &mut Self
pub unsafe fn set_init(&mut self, n: usize) -> &mut Self
}
pub struct BorrowCursor<'buf, 'data>
impl<'buf, 'data> BorrowCursor<'buf, 'data> {
pub fn clone<'this>(&'this mut self) -> BorrowCursor<'this, 'data>
pub fn capacity(&self) -> usize
pub fn written(&self) -> usize
pub fn init_ref(&self) -> &[u8]
pub fn init_mut(&mut self) -> &mut [u8]
pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>]
pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit<u8>]
pub unsafe fn advance(&mut self, n: usize) -> &mut Self
pub fn ensure_init(&mut self) -> &mut Self
pub unsafe fn set_init(&mut self, n: usize) -> &mut Self
pub fn append(&mut self, buf: &[u8])
}
```
## TODO
* ~~Migrate non-unix libs and tests~~
* ~~Naming~~
* ~~`BorrowBuf` or `BorrowedBuf` or `SliceBuf`? (We might want an owned equivalent for the async IO traits)~~
* ~~Should we rename the `readbuf` module? We might keep the name indicate it includes both the buf and cursor variations and someday the owned version too. Or we could change it. It is not publicly exposed, so it is not that important~~.
* ~~`read_buf` method: we read into the cursor now, so the `_buf` suffix is a bit weird.~~
* ~~Documentation~~
* Tests are incomplete (I adjusted existing tests, but did not add new ones).
cc https://github.com/rust-lang/rust/issues/78485, https://github.com/rust-lang/rust/issues/94741
supersedes: https://github.com/rust-lang/rust/pull/95770, https://github.com/rust-lang/rust/pull/93359fixes#93305
Move EH personality functions to std
These were previously in the panic_unwind crate with dummy stubs in the
panic_abort crate. However it turns out that this is insufficient: we
still need a proper personality function even with -C panic=abort to
handle the following cases:
1) `extern "C-unwind"` still needs to catch foreign exceptions with -C
panic=abort to turn them into aborts. This requires landing pads and a
personality function.
2) ARM EHABI uses the personality function when creating backtraces.
The dummy personality function in panic_abort was causing backtrace
generation to get stuck in a loop since the personality function is
responsible for advancing the unwind state to the next frame.
Fixes#41004
Without this change, in <https://doc.rust-lang.org/1.63.0/std/#primitives>,
`reference` is the only entry in that list which does not contain the
syntax by which the type is named in source code. With this change, it
contains them, in roughly the same way as the `pointer` entry does.