`UniqueRc` trait impls
UniqueRc tracking Issue: #112566
Stable traits: (i.e. impls behind only the `unique_rc_arc` feature gate)
* Support the same formatting as `Rc`:
* `fmt::Debug` and `fmt::Display` delegate to the pointee.
* `fmt::Pointer` prints the address of the pointee.
* Add explicit `!Send` and `!Sync` impls, to mirror `Rc`.
* Borrowing traits: `Borrow`, `BorrowMut`, `AsRef`, `AsMut`
* `Rc` does not implement `BorrowMut` and `AsMut`, but `UniqueRc` can.
* Unconditional `Unpin`, like other heap-allocated types.
* Comparison traits `(Partial)Ord` and `(Partial)Eq` delegate to the pointees.
* `PartialEq for UniqueRc` does not do `Rc`'s specialization shortcut for pointer equality when `T: Eq`, since by definition two `UniqueRc`s cannot share an allocation.
* `Hash` delegates to the pointee.
* `AsRawFd`, `AsFd`, `AsHandle`, `AsSocket` delegate to the pointee like `Rc`.
* Sidenote: The bounds on `T` for the existing `Pointer<T>` impls for specifically `AsRawFd` and `AsSocket` do not allow `T: ?Sized`. For the added `UniqueRc` impls I allowed `T: ?Sized` for all four traits, but I did not change the existing (stable) impls.
Unstable traits:
* `DispatchFromDyn`, allows using `UniqueRc<Self>` as a method receiver under `feature(arbitrary_self_types)`.
* Existing `PinCoerceUnsized for UniqueRc` is generalized to allow non-`Global` allocators, like `Rc`.
* `DerefPure`, allows using `UniqueRc` in deref-patterns under `feature(deref_patterns)`, like `Rc`.
For documentation, `Rc` only has documentation on the comparison traits' methods, so I copied/adapted the documentation for those, and left the rest without impl-specific docs.
~~Edit: Marked as draft while I figure out `UnwindSafe`.~~
Edit: Ignoring `UnwindSafe` for this PR
Add AST support for unsafe binders
I'm splitting up #130514 into pieces. It's impossible for me to keep up with a huge PR like that. I'll land type system support for this next, probably w/o MIR lowering, which will come later.
r? `@oli-obk`
cc `@BoxyUwU` and `@lcnr` who also may want to look at this, though this PR doesn't do too much yet
Stabilize the Rust 2024 prelude
This stabilizes the `core::prelude::rust_2024` and `std::prelude::rust_2024` modules. I missed these in the #133349 stabilization.
Run TLS destructors for wasm32-wasip1-threads
The target wasm32-wasip1-threads has support for pthreads and allows registration of TLS destructors.
For spawned threads, this registers Rust TLS destructors by creating a pthreads key with an attached destructor function.
For the main thread, this registers an `atexit` handler to run the TLS destructors.
try-job: test-various
wasi/fs: Improve stopping condition for <ReadDir as Iterator>::next
When upgrading [Zed](https://github.com/zed-industries/zed/pull/19349) to Rust 1.82 I've encountered a test failure in our test suite. Specifically, one of our extension tests started hanging. I've tracked it down to a call to std::fs::remove_dir_all not returning when an extension is compiled with Rust 1.82 Our extension system uses WASM components, thus I've looked at the diff between 1.81 and 1.82 with respect to WASI and found 736f773844
As it turned out, calling remove_dir_all from extension returned io::ErrorKind::NotFound in 1.81; the underlying issue is that the ReadDir iterator never actually terminates iteration, however since it loops around, with 1.81 we'd come across an entry second time and fail to remove it, since it would've been removed previously. With 1.82 and 736f773844 it is no longer the case, thus we're seeing the hang. The tests do pass when everything but the extensions is compiled with 1.82.
This commit makes ReadDir::next adhere to readdir contract, namely it will no longer call readdir once the returned # of bytes is smaller than the size of a passed-in buffer. Previously we'd only terminate the loop if readdir returned 0.
Define acronym for thread local storage
There are multiple references in this module's documentation to the acronym "TLS" (meaning "thread local storage"), without defining it. This is confusing for the reader.
I propose that this acronym be defined during the first use of the term.
There are multiple references in this module's documentation to the acronym "TLS", without defining it. This is confusing for the reader.
I propose that this acronym be defined during the first use of the term.
Implementation of `fmt::FormattingOptions`
Tracking issue: #118117
Public API:
```rust
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct FormattingOptions { … }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Sign {
Plus,
Minus
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DebugAsHex {
Lower,
Upper
}
impl FormattingOptions {
pub fn new() -> Self;
pub fn sign(&mut self, sign: Option<Sign>) -> &mut Self;
pub fn sign_aware_zero_pad(&mut self, sign_aware_zero_pad: bool) -> &mut Self;
pub fn alternate(&mut self, alternate: bool) -> &mut Self;
pub fn fill(&mut self, fill: char) -> &mut Self;
pub fn align(&mut self, alignment: Option<Alignment>) -> &mut Self;
pub fn width(&mut self, width: Option<usize>) -> &mut Self;
pub fn precision(&mut self, precision: Option<usize>) -> &mut Self;
pub fn debug_as_hex(&mut self, debug_as_hex: Option<DebugAsHex>) -> &mut Self;
pub fn get_sign(&self) -> Option<Sign>;
pub fn get_sign_aware_zero_pad(&self) -> bool;
pub fn get_alternate(&self) -> bool;
pub fn get_fill(&self) -> char;
pub fn get_align(&self) -> Option<Alignment>;
pub fn get_width(&self) -> Option<usize>;
pub fn get_precision(&self) -> Option<usize>;
pub fn get_debug_as_hex(&self) -> Option<DebugAsHex>;
pub fn create_formatter<'a>(self, write: &'a mut (dyn Write + 'a)) -> Formatter<'a>;
}
impl<'a> Formatter<'a> {
pub fn new(write: &'a mut (dyn Write + 'a), options: FormattingOptions) -> Self;
pub fn with_options<'b>(&'b mut self, options: FormattingOptions) -> Formatter<'b>;
pub fn sign(&self) -> Option<Sign>;
pub fn options(&self) -> FormattingOptions;
}
```
Relevant changes from the public API in the tracking issue (I'm leaving out some stuff I consider obvious mistakes, like missing `#[derive(..)]`s and `pub` specifiers):
- `enum DebugAsHex`/`FormattingOptions::debug_as_hex`/`FormattingOptions::get_debug_as_hex`: To support `{:x?}` as well as `{:X?}`. I had completely missed these options in the ACP. I'm open for any and all bikeshedding, not married to the name.
- `fill`/`get_fill` now takes/returns `char` instead of `Option<char>`. This simply mirrors what `Formatter::fill` returns (with default being `' '`).
- Changed `zero_pad`/`get_zero_pad` to `sign_aware_zero_pad`/`get_sign_aware_zero_pad`. This also mirrors `Formatter::sign_aware_zero_pad`. While I'm not a fan of this quite verbose name, I do believe that having the interface of `Formatter` and `FormattingOptions` be compatible is more important.
- For the same reason, renamed `alignment`/`get_alignment` to `aling`/`get_align`.
- Deviating from my initial idea, `Formatter::with_options` returns a `Formatter` which has the lifetime of the `self` reference as its generic lifetime parameter (in the original API spec, the generic lifetime of the returned `Formatter` was the generic lifetime used by `self` instead). Otherwise, one could construct two `Formatter`s that both mutably borrow the same underlying buffer, which would be unsound. This solution still has performance benefits over simply using `Formatter::new`, so I believe it is worthwhile to keep this method.
Stabilize `std::io::ErrorKind::CrossesDevices`
FCP in #130191
cc #86442
See #130191 for more info and a recap of what has happened up until now.
TLDR: This had been FCP'd in December 2022 with some other `ErrorKind`s, but the stabilization got postponed due to some concerns voiced about several of the variants. However, the only concern ever voiced for this variant in particular was a wish to rename this to `NotSameDevice` analogous to Windows's `ERROR_NOT_SAME_DEVICE` (as opposed to Unix's `EXDEV`). This suggestion did not receive any support. So let's try to FCP this as is.
r? libs-api
Improve comments for the default backtrace printer
The existing comments were misleading, confusing, and outdated.
Take this comment for example:
```
// Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace`
// are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be
// called before the panic hook, so we won't ignore any frames if there is no
// invoke of `__rust_begin_short_backtrace`.
```
this is just wrong. here is an example (full) backtrace:
<details>
```
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `/home/jyn/.local/lib/cargo/target/debug/example`
called `Option::unwrap()` on a `None` value
stack backtrace:
0: 0x56499698c595 - std::backtrace_rs::backtrace::libunwind::trace::h5ef2cc16e9a7415a
1: 0x56499698c595 - std::backtrace_rs::backtrace::trace_unsynchronized::h9b5e016e9075f714
2: 0x56499698c595 - std::sys_common::backtrace::_print_fmt::h2f62c7f9ff224e93
3: 0x56499698c595 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hbe51682735731910
4: 0x5649969aa26b - core::fmt::rt::Argument::fmt::h1994ab2b310d665e
5: 0x5649969aa26b - core::fmt::write::hade58a36d63468d7
6: 0x56499698a43f - std::io::Write::write_fmt::h16145587d801a9ab
7: 0x56499698c36e - std::sys_common::backtrace::_print::ha8082e56201dadb4
8: 0x56499698c36e - std::sys_common::backtrace::print::he30f96b4e7f6cbfd
9: 0x56499698d709 - std::panicking::default_hook::{{closure}}::hf0801f6b18a968d3
10: 0x56499698d4ac - std::panicking::default_hook::hd2defec7eda5aeb0
11: 0x56499698dc31 - std::panicking::rust_panic_with_hook::hde93283600065c53
12: 0x56499698daf3 - std::panicking::begin_panic_handler::{{closure}}::h5e151adbdb7ec0c1
13: 0x56499698ca59 - std::sys_common::backtrace::__rust_end_short_backtrace::he36a1407e0f77700
14: 0x56499698d7d4 - rust_begin_unwind
15: 0x5649969a9503 - core::panicking::panic_fmt::h2380d41365f95412
16: 0x5649969a958c - core::panicking::panic::h38cf8db80e8c6e67
17: 0x5649969a93e9 - core::option::unwrap_failed::he72696e53ff29a05
18: 0x5649969722b6 - core::option::Option<T>::unwrap::hb574dc0dc1703062
19: 0x5649969722b6 - example::main::h7a867aafacd93d75
20: 0x5649969721db - core::ops::function::FnOnce::call_once::h734f99a5e57291b7
21: 0x56499697226e - std::sys_common::backtrace::__rust_begin_short_backtrace::h02f5d58c351c4756
22: 0x564996972241 - std::rt::lang_start::{{closure}}::h8b134fe2c31a4355
23: 0x564996988662 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h88d7bb571ee2aaf4
24: 0x564996988662 - std::panicking::try::do_call::hfb78dfb6599c871d
25: 0x564996988662 - std::panicking::try::habd041c8c4c8e50c
27: 0x564996988662 - std::rt::lang_start_internal::{{closure}}::h227591a6f9c0879e
28: 0x564996988662 - std::panicking::try::do_call::h3c5878333c38916a
29: 0x564996988662 - std::panicking::try::h5af7b3a127cdae70
31: 0x564996988662 - std::rt::lang_start_internal::hbc85e809eeace0dd
32: 0x56499697221a - std::rt::lang_start::ha1eb16922c9cb224
33: 0x5649969722ee - main
34: 0x7f031962a1ca - __libc_start_call_main
35: 0x7f031962a28b - __libc_start_main_impl
36: 0x5649969720a5 - _start
37: 0x0 - <unknown>
```
</details>
note particularly frames 13-21, from start_backtrace to end_backtrace. with PrintFmt::Short, these are the *only* frames that are printed; i.e. we are doing the exact opposite of the comment.
r? ``@saethlin``
The existing comments were misleading, confusing, and wrong.
Take this comment for example:
```
// Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace`
// are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be
// called before the panic hook, so we won't ignore any frames if there is no
// invoke of `__rust_begin_short_backtrace`.
```
this is just wrong. here is an example (full) backtrace:
```
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `/home/jyn/.local/lib/cargo/target/debug/example`
called `Option::unwrap()` on a `None` value
stack backtrace:
0: 0x56499698c595 - std::backtrace_rs::backtrace::libunwind::trace::h5ef2cc16e9a7415a
1: 0x56499698c595 - std::backtrace_rs::backtrace::trace_unsynchronized::h9b5e016e9075f714
2: 0x56499698c595 - std::sys_common::backtrace::_print_fmt::h2f62c7f9ff224e93
3: 0x56499698c595 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hbe51682735731910
4: 0x5649969aa26b - core::fmt::rt::Argument::fmt::h1994ab2b310d665e
5: 0x5649969aa26b - core::fmt::write::hade58a36d63468d7
6: 0x56499698a43f - std::io::Write::write_fmt::h16145587d801a9ab
7: 0x56499698c36e - std::sys_common::backtrace::_print::ha8082e56201dadb4
8: 0x56499698c36e - std::sys_common::backtrace::print::he30f96b4e7f6cbfd
9: 0x56499698d709 - std::panicking::default_hook::{{closure}}::hf0801f6b18a968d3
10: 0x56499698d4ac - std::panicking::default_hook::hd2defec7eda5aeb0
11: 0x56499698dc31 - std::panicking::rust_panic_with_hook::hde93283600065c53
12: 0x56499698daf3 - std::panicking::begin_panic_handler::{{closure}}::h5e151adbdb7ec0c1
13: 0x56499698ca59 - std::sys_common::backtrace::__rust_end_short_backtrace::he36a1407e0f77700
14: 0x56499698d7d4 - rust_begin_unwind
15: 0x5649969a9503 - core::panicking::panic_fmt::h2380d41365f95412
16: 0x5649969a958c - core::panicking::panic::h38cf8db80e8c6e67
17: 0x5649969a93e9 - core::option::unwrap_failed::he72696e53ff29a05
18: 0x5649969722b6 - core::option::Option<T>::unwrap::hb574dc0dc1703062
19: 0x5649969722b6 - example::main::h7a867aafacd93d75
20: 0x5649969721db - core::ops::function::FnOnce::call_once::h734f99a5e57291b7
21: 0x56499697226e - std::sys_common::backtrace::__rust_begin_short_backtrace::h02f5d58c351c4756
22: 0x564996972241 - std::rt::lang_start::{{closure}}::h8b134fe2c31a4355
23: 0x564996988662 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h88d7bb571ee2aaf4
24: 0x564996988662 - std::panicking::try::do_call::hfb78dfb6599c871d
25: 0x564996988662 - std::panicking::try::habd041c8c4c8e50c
27: 0x564996988662 - std::rt::lang_start_internal::{{closure}}::h227591a6f9c0879e
28: 0x564996988662 - std::panicking::try::do_call::h3c5878333c38916a
29: 0x564996988662 - std::panicking::try::h5af7b3a127cdae70
31: 0x564996988662 - std::rt::lang_start_internal::hbc85e809eeace0dd
32: 0x56499697221a - std::rt::lang_start::ha1eb16922c9cb224
33: 0x5649969722ee - main
34: 0x7f031962a1ca - __libc_start_call_main
35: 0x7f031962a28b - __libc_start_main_impl
36: 0x5649969720a5 - _start
37: 0x0 - <unknown>
```
note particularly frames 13-21, from start_backtrace to end_backtrace. with PrintFmt::Short, these are the *only* frames that are printed; i.e. we are doing the exact opposite of the comment.
a release operation synchronizes with an acquire operation
Change:
1. `Calls to park _synchronize-with_ calls to unpark` to `Calls to unpark _synchronize-with_ calls to park`
2. `park synchronizes-with _all_ prior unpark operations` to `_all_ prior unpark operations synchronize-with park`
fix: hurd build, stat64.st_fsid was renamed to st_dev
On hurd, `stat64.st_fsid` was renamed to `st_dev` in https://github.com/rust-lang/libc/pull/3785, so if you have a new libc with this patch included, and you build std from source, you get this error:
```sh
error[E0609]: no field `st_fsid` on type `&stat64`
--> /home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/os/hurd/fs.rs:301:36
|
301 | self.as_inner().as_inner().st_fsid as u64
| ^^^^^^^ unknown field
|
help: a field with a similar name exists
|
301 | self.as_inner().as_inner().st_uid as u64
| ~~~~~~
```
Full CI log: https://github.com/nix-rust/nix/actions/runs/12033180710/job/33546728266?pr=2544
std: refactor `pthread`-based synchronization
The non-trivial code for `pthread_condvar` is duplicated across the thread parking and the `Mutex`/`Condvar` implementations. This PR moves that code into `sys::pal`, which now exposes an `unsafe` wrapper type for `pthread_mutex_t` and `pthread_condvar_t`.
thread::available_parallelism for wasm32-wasip1-threads
The target has limited POSIX support and provides the `libc::sysconf` function which allows querying the number of available CPUs.
Fix and undeprecate home_dir()
`home_dir()` has been deprecated for 6 years due to using `HOME` env var on Windows.
It's been a long time, and having a perpetually buggy and deprecated function in the standard library is not useful. I propose fixing and undeprecating it.
6 years seems more than long enough to warn users against relying on this function. The change in behavior is minor, and it's more of a bug fix than breakage. The old behavior is unlikely to be useful, and even if anybody actually needed to specifically use the non-standard `HOME` on Windows, they can trivially mitigate this change by reading the env var themselves.
----
Use of `USERPROFILE` is in line with the `home` crate: 37bc5f0232/crates/home/src/windows.rs (L12)
The `home` crate uses `SHGetKnownFolderPath` instead of `GetUserProfileDirectoryW`. AFAIK it doesn't make any difference in practice, because `SHGetKnownFolderPath` merely adds support for more kinds of folders, including virtual (non-filesystem) folders identified by a GUID, but the specific case of [`FOLDERID_Profile`](https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#FOLDERID_Profile) is documented as a FIXED folder (a regular filesystem path). Just in case, I've added a note to documentation that the use of `GetUserProfileDirectoryW` can change.
I've used `CURRENT_RUSTC_VERSION` in a doccomment. `replace-version-placeholder` tool seems to perform a simple string replacement, so hopefully it'll get updated.
Stabilize `extended_varargs_abi_support`
I think that is everything? If there is any documentation regarding `extern` and/or varargs to correct, let me know, some quick greps suggest that there might be none.
Tracking issue: https://github.com/rust-lang/rust/issues/100189
Bump boostrap compiler to new beta
Currently failing due to something about the const stability checks and `panic!`. I'm not sure why though since I wasn't able to see any PRs merged in the past few days that would result in a `cfg(bootstrap)` that shouldn't be removed. cc `@RalfJung` #131349
Use consistent wording in docs, use is zero instead of is 0
In documentation, wording of _"`rhs` is zero"_ and _"`rhs` is 0"_ is intermixed. This is especially visible [here](https://doc.rust-lang.org/std/primitive.usize.html#method.div_ceil).
This changes all occurrences to _"`rhs` is zero"_ for better readability.
Enable -Zshare-generics for inline(never) functions
This avoids inlining cross-crate generic items when possible that are
already marked inline(never), implying that the author is not intending
for the function to be inlined by callers. As such, having a local copy
may make it easier for LLVM to optimize but mostly just adds to binary
bloat and codegen time. In practice our benchmarks indicate this is
indeed a win for larger compilations, where the extra cost in dynamic
linking to these symbols is diminished compared to the advantages in
fewer copies that need optimizing in each binary.
It might also make sense it expand this with other heuristics (e.g.,
`#[cold]`) in the future, but this seems like a good starting point.
FWIW, I expect that doing cleanup in where we make the decision
what should/shouldn't be shared is also a good idea. Way too
much code needed to be tweaked to check this. But I'm hoping
to leave that for a follow-up PR rather than blocking this on it.
This reduces code sizes and better respects programmer intent when
marking inline(never). Previously such a marking was essentially ignored
for generic functions, as we'd still inline them in remote crates.
Rollup of 12 pull requests
Successful merges:
- #129409 (Expand std::os::unix::fs::chown() doc with a warning)
- #133320 (Add release notes for Rust 1.83.0)
- #133368 (Delay a bug when encountering an impl with unconstrained generics in `codegen_select`)
- #133428 (Actually use placeholder regions for trait method late bound regions in `collect_return_position_impl_trait_in_trait_tys`)
- #133512 (Add `as_array` and `as_mut_array` conversion methods to slices.)
- #133519 (Check `xform_ret_ty` for WF in the new solver to improve method winnowing)
- #133520 (Structurally resolve before applying projection in borrowck)
- #133534 (extend group-forbid-always-trumps-cli test)
- #133537 ([rustdoc] Fix new clippy lints)
- #133543 ([AIX] create shim for lgammaf_r)
- #133547 (rustc_span: Replace a `HashMap<_, ()>` with `HashSet`)
- #133550 (print generated doc paths)
r? `@ghost`
`@rustbot` modify labels: rollup
[AIX] create shim for lgammaf_r
On AIX, we don't have 32bit floating point for re-entrant `lgammaf_r` but we do have the 64bit floating point re-entrant `lgamma_r` so we can use the 64bit version instead and truncate back to a 32bit float.
This solves the linker missing symbol for `.lgammaf_r` when testing and using these parts of the `std`.
Expand std::os::unix::fs::chown() doc with a warning
Include warning about losing setuid/gid when chowning, per POSIX.
It is about the underlying system call but it is rather useful to mention it in the help in case someone accidentally forgets (don't look at me :)).
std:🧵 avoid leading whitespace in some panic messages
This:
```
panic!(
"use of std:🧵:current() is not possible after the thread's
local data has been destroyed"
)
```
will print a newline followed by a bunch of spaces, since the entire string literal is interpreted literally.
I think the intention was to print the message without the newline and the spaces, so let's add some `\` to make that happen.
r? ``@joboet``
Added a doc test for std::path::strip_prefix
I was about 90% sure `Path::new("/test/haha/foo.txt").strip_prefix("/te")` would return an Err, but I couldn't find an example to confirm this behaviour.
This should be an easy merge :)
Mention that std::fs::remove_dir_all fails on files
This is explicitly mentioned for std::fs::remove_file.
It is more likely for a slightly lazy programmer to believe that removing a file would work and that they do not have to distinguish between directories (with contents) and files themself, because of the function's recursive nature and how it distinguishes between files and directories when removing them.
Follow-up for #133183.
std: allow after-main use of synchronization primitives
By creating an unnamed thread handle when the actual one has already been destroyed, synchronization primitives using thread parking can be used even outside the Rust runtime.
This also fixes an inefficiency in the queue-based `RwLock`: if `thread::current` was not initialized yet, it will create a new handle on every parking attempt without initializing `thread::current`. The private `current_or_unnamed` function introduced here fixes this.
Add `AsyncFn*` to the prelude in all editions
The general vibe is that we will most likely stabilize the `feature(async_closure)` *without* the `async Fn()` trait bound modifier.
Without `async Fn()` bound syntax, this necessitates users to spell the bound like `AsyncFn()`. Since `core::ops::AsyncFn` is not in the prelude, users will need to import these any time they actually want to use the trait. This seems annoying, so let's add these traits to the prelude unstably.
We're trying to work on the general vision of `async` trait bound modifier in general in: https://github.com/rust-lang/rfcs/pull/3710, however that RFC still needs more time for consensus to converge, and we've decided that the value that users get from calling the bound `async Fn()` is *not really* worth blocking landing async closures in general.