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.
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
[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`.
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.
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.
Rwlock downgrade
Tracking Issue: #128203
This PR adds a `downgrade` method for `RwLock` / `RwLockWriteGuard` on all currently supported platforms.
Outstanding questions:
- [x] ~~Does the `futex.rs` change affect performance at all? It doesn't seem like it will but we can't be certain until we bench it...~~
- [x] ~~Should the SOLID platform implementation [be ported over](https://github.com/rust-lang/rust/pull/128219#discussion_r1693470090) to the `queue.rs` implementation to allow it to support downgrades?~~
This commit fixes a memory ordering bug in the futex implementation
(`Relaxed` -> `Release` on `downgrade`).
This commit also removes a badly written test that deadlocked and
replaces it with a more reasonable test based on an already-tested
`downgrade` test from the parking-lot crate.
This commit adds the `downgrade` method onto the inner `RwLock` queue
implementation.
There are also a few other style patches included in this commit.
Co-authored-by: Jonas Böttiger <jonasboettiger@icloud.com>
This commit only has documentation changes and a few things moved around
the file. The very few code changes are cosmetic: changes like turning a
`match` statement into an `if let` statement or reducing indentation for
long if statements.
This commit also adds several safety comments on top of `unsafe` blocks
that might not be immediately obvious to a first-time reader.
Code "changes" are in:
- `add_backlinks_and_find_tail`
- `lock_contended`
A majority of the changes are just expanding the comments from 80
columns to 100 columns.
[illumos] use pipe2 to create anonymous pipes
pipe2 allows the newly-created pipe to atomically be CLOEXEC.
pipe2 was added to illumos a long time ago:
5dbfd19ad5. I've verified that this change passes all of std's tests on illumos.
Fix compilation error on Solaris due to flock usage
PR 130999 added the file_lock feature, but libc does not define flock() for the Solaris platform leading to a compilation error.
Additionally, I went through all the Tier 2 platforms and read through their documentation to see whether flock was implemented. This turned up 5 more Unix platforms where flock is not supported, even though it may exist in the libc crate.
Fixes https://github.com/rust-lang/rust/issues/132921
Related to #130999
PR 130999 added the file_lock feature, but libc does not define
flock() for the Solaris platform leading to a compilation error.
Additionally, I went through all the Tier 2 platforms and read through
their documentation to see whether flock was implemented. This turned up
5 more Unix platforms where flock is not supported, even though it may
exist in the libc crate.
pipe2 allows the newly-created pipe to atomically be CLOEXEC.
pipe2 was added to illumos a long time ago:
5dbfd19ad5.
I've verified that this change passes all tests.
Implement file_lock feature
This adds lock(), lock_shared(), try_lock(), try_lock_shared(), and unlock() to File gated behind the file_lock feature flag
This is the initial implementation of https://github.com/rust-lang/rust/issues/130994 for Unix and Windows platforms. I will follow it up with an implementation for WASI preview 2
Revert using `HEAP` static in Windows alloc
Fixes#131468
This does the minimum to remove the `HEAP` static that was causing chromium issues. It would be worth having a more substantial look at this module but for now I think this addresses the immediate issue.
cc `@danakj`
Remove unintended link
Since `#[link_section]` is enclosed in braces, it was being confused with a link during docs compilation.
This caused compilation to fail when running `x dist` since it emitted a warning regarding broken links.
These functions had `#[rustc_const_stable(feature = "const_locks", since
= "1.63.0")]` on them because they were originally taken from
`no_threads`. with d066dfd these no longer compile. Since other
platforms do not have this attribute, remove it. This fixes the build
for Xous.
Signed-off-by: Sean Cross <sean@xobs.io>
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 a non-movable wrapper type for `pthread_mutex_t` and `pthread_condvar_t`.
Const stability checks v2
The const stability system has served us well ever since `const fn` were first stabilized. It's main feature is that it enforces *recursive* validity -- a stable const fn cannot internally make use of unstable const features without an explicit marker in the form of `#[rustc_allow_const_fn_unstable]`. This is done to make sure that we don't accidentally expose unstable const features on stable in a way that would be hard to take back. As part of this, it is enforced that a `#[rustc_const_stable]` can only call `#[rustc_const_stable]` functions. However, some problems have been coming up with increased usage:
- It is baffling that we have to mark private or even unstable functions as `#[rustc_const_stable]` when they are used as helpers in regular stable `const fn`, and often people will rather add `#[rustc_allow_const_fn_unstable]` instead which was not our intention.
- The system has several gaping holes: a private `const fn` without stability attributes whose inherited stability (walking up parent modules) is `#[stable]` is allowed to call *arbitrary* unstable const operations, but can itself be called from stable `const fn`. Similarly, `#[allow_internal_unstable]` on a macro completely bypasses the recursive nature of the check.
Fundamentally, the problem is that we have *three* disjoint categories of functions, and not enough attributes to distinguish them:
1. const-stable functions
2. private/unstable functions that are meant to be callable from const-stable functions
3. functions that can make use of unstable const features
Functions in the first two categories cannot use unstable const features and they can only call functions from the first two categories.
This PR implements the following system:
- `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions.
- `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category.
- `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls.
Also, all the holes mentioned above have been closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to be manually marked `#[rustc_const_stable_indirect]` to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine.
The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability.
Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
Also see the updated dev-guide at https://github.com/rust-lang/rustc-dev-guide/pull/2098.
I think in the future we may want to tweak this further, so that in the hopefully common case where a public function's const-stability just exactly mirrors its regular stability, we never have to add any attribute. But right now, once the function is stable this requires `#[rustc_const_stable]`.
### Open question
There is one point I could see we might want to do differently, and that is putting `#[rustc_const_unstable]` functions (but not intrinsics) in category 2 by default, and requiring an extra attribute for `#[rustc_const_not_exposed_on_stable]` or so. This would require a bunch of extra annotations, but would have the advantage that turning a `#[rustc_const_unstable]` into `#[rustc_const_stable]` will never change the way the function is const-checked. Currently, we often discover in the const stabilization PR that a function needs some other unstable const things, and then we rush to quickly deal with that. In this alternative universe, we'd work towards getting rid of the `rustc_const_not_exposed_on_stable` before stabilization, and once that is done stabilization becomes a trivial matter. `#[rustc_const_stable_indirect]` would then only be used for intrinsics.
I think I like this idea, but might want to do it in a follow-up PR, as it will need a whole bunch of annotations in the standard library. Also, we probably want to convert all const intrinsics to the "new" form (`#[rustc_intrinsic]` instead of an `extern` block) before doing this to avoid having to deal with two different ways of declaring intrinsics.
Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
Part of https://github.com/rust-lang/rust/issues/129815 (but not finished since this is not yet sufficient to safely let us expose `const fn` from hashbrown)
Fixes https://github.com/rust-lang/rust/issues/131073 by making it so that const-stable functions are always stable
try-job: test-various