update zulip link in `std` documentation
#docs doesn't seem to exist anymore, so point people to `t-libs`. Also include direct link to topic since Zulip is world-viewable now.
Add `IoSplit` diagnostic item for `std::io::Split`
Similar to the existing `IoLines` item. It will be used in Clippy to detect uses of `Split` leading to infinite loops similar to the existing lint for `Lines`.
feat: reimplement `hash_map!` macro
originally implemented in rust-lang/rust#144070, this had to be reverted in rust-lang/rust#148049 due to name ambiguity, as the macro was automatically put into the prelude. now, that rust-lang/rust#139493 has landed, it is possible to have a top-level macro, that is not exported by default, which should make it possible to reland this again.
implements rust-lang/rust#144032
implementation from rust-lang/rust#144070, original author has been added as co-author
effectively reverts rust-lang/rust#148049
Prevent no_threads RwLock's write() impl from setting mode to -1 when it is locked for reading
In my time updating the docs to `std::sync::RwLock` and adding a test verifying that max reader count is reachable in rust-lang/rust#153555, I noticed that the no_threads RwLock's `write()` implementation always sets the `mode` to `-1` (denoting writer locked) even though it could be reader locked. I feel like that's logically incorrect and that it should only be setting the `mode` to `-1` when we know that the mode is unlocked (`0`); `write()` should mirror the code that `read()` and `try_read()` has with `try_write()`.
For reference on read/try_read and write/try_write current implementations:
```rust
#[inline]
pub fn read(&self) {
let m = self.mode.get();
if m >= 0 {
self.mode.set(m + 1);
} else {
rtabort!("rwlock locked for writing");
}
}
#[inline]
pub fn try_read(&self) -> bool {
let m = self.mode.get();
if m >= 0 {
self.mode.set(m + 1);
true
} else {
false
}
}
#[inline]
pub fn write(&self) {
if self.mode.replace(-1) != 0 { // <-- This behavior logically does something different than what `try_write` does
rtabort!("rwlock locked for reading")
}
}
#[inline]
pub fn try_write(&self) -> bool {
if self.mode.get() == 0 {
self.mode.set(-1);
true
} else {
false
}
}
```
r? @jhpratt
Use common Timestamp impl in Hermit (attempt 2)
The goal is to have less code to maintain, so to be able to make changes easier.
Previous attempt https://github.com/rust-lang/rust/pull/148847 was asked to postpone because there was restructure of code, which is complete now.
r? joboet
Similar to the existing `IoLines` item. It will be used in Clippy to
detect uses of `Split` leading to infinite loops similar to the existing
lint for `Lines`.
Also, delete impls on non-Deref types.
Pin doesn't do anything useful for non-Deref types, so PinCoerceUnsized
on such types makes no sense.
This is a breaking change, since stable code can observe the deleted
`PinCoerceUnsized` impls by uselessly coercing between such types
inside a `Pin`.
There is still some strange behavior, such as `Pin<&mut i32>` being
able to coerce to `Pin<&dyn Send>`, but not being able to coerce to
`Pin<&i32>`. However, I don't think it's possible to fix this.
Fixes https://github.com/rust-lang/rust/issues/145081
Skip stack_start_aligned for immediate-abort
This improves startup performance by 16%, shown by an optimized hello-world program. glibc's `pthread_getattr_np` performs expensive syscalls when reading `/proc/self/maps`. That is all wasted with `panic = immediate-abort` active because `init()` immediately discards the return value from `install_main_guard()`. A similar improvement can be seen in environments that don't have `/proc`. This change is safe because the immediately succeeding comment says that we rely on Linux's "own stack-guard mechanism".
Tracking issue: https://github.com/rust-lang/rust/issues/147286
# Benchmark
Set it up with `cargo new hello-world2`, and replace these files:
```toml
# Cargo.toml
cargo-features = ["panic-immediate-abort"]
[package]
name = "hello-world"
version = "0.1.0"
edition = "2024"
[profile.release]
lto = true
panic = "immediate-abort"
codegen-units = 1
opt-level = "z"
strip = true
# .cargo/config.toml
[unstable]
build-std = ["std"]
```
## Before
```console
home@daniel-desktop3:~/CLionProjects/hello-world2$ hyperfine -N target/release/hello-world2
Benchmark 1: target/release/hello-world2
Time (mean ± σ): 524.8 µs ± 65.1 µs [User: 276.1 µs, System: 187.0 µs]
Range (min … max): 446.4 µs … 975.5 µs 3996 runs
home@daniel-desktop3:~/CLionProjects/hello-world2$ hyperfine -N target/release/hello-world2
Benchmark 1: target/release/hello-world2
Time (mean ± σ): 519.4 µs ± 65.8 µs [User: 282.1 µs, System: 177.7 µs]
Range (min … max): 443.2 µs … 830.5 µs 3612 runs
home@daniel-desktop3:~/CLionProjects/hello-world2$ hyperfine -N target/release/hello-world2
Benchmark 1: target/release/hello-world2
Time (mean ± σ): 520.0 µs ± 64.3 µs [User: 277.1 µs, System: 182.1 µs]
Range (min … max): 447.1 µs … 1001.3 µs 3804 runs
```
For a visualization of the problem, run `cargo +stage1 build --release && perf record --call-graph dwarf -F max ./target/release/hello-world2 && perf script | inferno-collapse-perf | inferno-flamegraph > flamegraph.svg`:
<img width="3832" height="1216" alt="flamegraph with 17.41% __pthread_getattr_np" src="https://github.com/user-attachments/assets/acc2286e-1582-4772-9e3b-68b5c35e3e70" />
## After
```console
home@daniel-desktop3:~/CLionProjects/hello-world2$ hyperfine -N target/release/hello-world2Benchmark 1: target/release/hello-world2
Time (mean ± σ): 444.7 µs ± 57.3 µs [User: 257.4 µs, System: 130.2 µs]
Range (min … max): 379.4 µs … 1289.3 µs 3893 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
home@daniel-desktop3:~/CLionProjects/hello-world2$ hyperfine -N target/release/hello-world2
Benchmark 1: target/release/hello-world2
Time (mean ± σ): 452.3 µs ± 60.7 µs [User: 261.5 µs, System: 133.5 µs]
Range (min … max): 374.9 µs … 1512.4 µs 4177 runs
Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
home@daniel-desktop3:~/CLionProjects/hello-world2$ hyperfine -N target/release/hello-world2
Benchmark 1: target/release/hello-world2
Time (mean ± σ): 441.2 µs ± 56.1 µs [User: 256.2 µs, System: 128.8 µs]
Range (min … max): 375.0 µs … 760.4 µs 4032 runs
```
docs(fs): Clarify That File::lock Coordinates Across Processes
### Summary:
The documentation for `lock`, `lock_shared`, `try_lock`, and `try_lock_shared` did not make it clear that these are OS level file locks that coordinate access across processes, not just between handles within the current process.
Add "in this or any other process" to each method's existing description to clarify this.
Fixesrust-lang/rust#153618
r? @Mark-Simulacrum
std: move `sys::pal::os` to `sys::paths`
Part of rust-lang/rust#117276.
After rust-lang/rust#150723, rust-lang/rust#153130, rust-lang/rust#153341 and rust-lang/rust#153413, `sys::pal::os` only contains default-path related functions (like `getcwd` and the `PATH`-splitting logic). In line with rust-lang/rust#117276, this PR thus moves all these implementations into a new module in `sys`: `sys::paths`.
~There is one functional change here: The `chdir` implementation on SGX used to use `sgx_ineffective` which silently fails, but now returns an error unconditionally – I think that's much more reasonable given that SGX doesn't support filesystem stuff at all.~
I've corrected the misleading panic messages in `temp_dir` for UEFI and WASI, aside from that, this PR only consists of code moves.
CC @jethrogb @raoulstrackx @aditijannu for the SGX change (resolved)
Move `freeze_*` methods to `OpenOptionsExt2`
Move the unstable `freeze_last_access_time` and `freeze_last_write_time` from `OpenOptionsExt` to a new `OpenOptionsExt2` trait. This should fixrust-lang/rust#153486.
Fix environ on FreeBSD with cdylib targets that use -Wl,--no-undefined .
Instead of relying on the linker to find the 'environ' symbol, use dlsym. This fixes using `environ` from cdylibs that link with `-Wl,--no-undefined` .
Fixesrust-lang/rust#153451
Sponsored by: ConnectWise
`std`: include `dlmalloc` for all non-wasi Wasm targets
Currently, building std for a custom Wasm target with an OS other than `unknown` will fail, because `sys/alloc/mod.rs` will attempt to use `sys/alloc/wasm.rs`, the dlmalloc-based allocator used on `wasm32-unknown-unknown`. However, currently dlmalloc is only pulled in when `target_os = "unknown"`.
Instead, we should make `Cargo.toml` and `alloc/mod.rs` match: either
- disable `wasm.rs` in `alloc/mod.rs` where `not(target_os = "unknown")`, or
- pull in `dlmalloc` for all Wasm targets with `target_family = "wasm32"` that aren't covered by the [upper branches of `alloc/mod.rs`](https://github.com/rust-lang/rust/blob/main/library/std/src/sys/alloc/mod.rs#L72-L100).
This PR takes the latter approach, because it allows more code to compile without a custom allocator.
Allow passing `expr` metavariable as `cfg` predicate
This PR allows expanding `expr` metavariables inside the configuration predicates of `cfg` and `cfg_attr` invocations.
For example, the following code will now compile:
```rust
macro_rules! mac {
($e:expr) => {
#[cfg_attr($e, inline)]
#[cfg($e)]
fn func() {}
#[cfg(not($e))]
fn func() {
panic!()
}
}
}
mac!(any(unix, feature = "foo"));
```
There is currently no `macro_rules` fragment specifier that can represent all valid `cfg` predicates. `meta` comes closest, but excludes `true` and `false`. By fixing that, this change makes it easier to write declarative macros that parse `cfg` or `cfg_attr` invocations, for example https://github.com/rust-lang/rust/pull/146281/.
@rustbot label T-lang needs-fcp A-attributes A-cfg A-macros
This improves startup performance by 16%, shown by an optimized
hello-world program. glibc's `pthread_getattr_np` performs expensive
syscalls when reading `/proc/self/maps`. That is all wasted with
`panic = immediate-abort` active because `init()` immediately discards
the return value from `install_main_guard()`. A similar improvement can
be seen in environments that don't have `/proc`. This change is safe
because the immediately succeeding comment says that we rely on Linux's
"own stack-guard mechanism".
two smaller feature cleanups
Remove an unneeded feature gate for a private macro and sort the used features correctly by whether they are language or library features.
Add is_disconnected functions to mpsc and mpmc channels
Add `is_disconnected()` functions to the `Sender` and `Receiver` of both `mpmc` an `mpsc` channels.
```rust
std::sync::mpmc::Sender<T>::is_disconnected(&self) -> bool
std::sync::mpmc::Receiver<T>::is_disconnected(&self) -> bool
std::sync::mpsc::Sender<T>::is_disconnected(&self) -> bool
std::sync::mpsc::Receiver<T>::is_disconnected(&self) -> bool
```
The `mpsc` methods are locked behind the `mpsc_is_disconnected` feature gate, which has no tracking issue yet.
ACP: https://github.com/rust-lang/libs-team/issues/748
Tracking issue: https://github.com/rust-lang/rust/issues/153668
Fix bootstrap rust build failure for vxworks
Fixesrust-lang/rust#153332
Starting with VxWorks 25.09, struct stat was updated to use struct timespec instead of time_t for timestamp fields.
The following changes were made in libc in the commit [libc](https://github.com/rust-lang/libc/pull/4781).
As a result, when performing a bootstrap build with VxWorks ≥ 25.09, libc no longer exposes the fields st_mtime, st_atime, and st_ctime, as they are conditionally compiled in src/vxworks/mod.rs here [libc](https://github.com/rust-lang/libc/blob/56caa81b6b433c49c5704bf0400a02d428cfacda/src/vxworks/mod.rs#L229). This causes the build to fail.
For VxWorks versions earlier than 25.09, the build completes successfully without errors.
This PR resolves the issue by detecting the WIND_RELEASE_ID environment variable (which is set in the VxWorks build environment) and conditionally guarding the affected functions in the two additional files where the errors originate.
std: make `OsString::truncate` a no-op when `len > current_len`
Align `OsString::truncate` (and the underlying WTF-8 implementation) with `String::truncate` by making it a no-op when `len > self.len()`.
Previously, `OsString::truncate` would panic if `len > self.len()`, while `String::truncate` treats such cases as a no-op.
Tracking (`os_string_truncate`): https://github.com/rust-lang/rust/issues/133262
See also: https://github.com/rust-lang/rust/pull/32977
cc: @alexcrichton, @lolbinarycat
- `From<T> for ThinBox<T>`
- `From<T> for UniqueRc<T>`
- `From<T> for UniqueArc<T>`
- `From<T: UnwindSafe> for AssertUnwindSafe<T>`
- `From<T> for LazyCell<T, F>`
- `From<T> for LazyLock<T, F>`
Currently, building std for a custom Wasm target with an OS other than `unknown` will fail, because `sys/alloc/mod.rs` will attempt to use `sys/alloc/wasm.rs`, the dlmalloc-based allocator used on `wasm32-unknown-unknown`. However, currently dlmalloc is only pulled in when `target_os = "unknown"`.
Instead, we should make `Cargo.toml` and `alloc/mod.rs` match: either
- disable `wasm.rs` in `alloc/mod.rs` where `not(target_os = "unknown")`, or
- pull in `dlmalloc` for all Wasm targets with `target_family = "wasm32"` that aren't covered by the [upper branches of `alloc/mod.rs`](https://github.com/rust-lang/rust/blob/main/library/std/src/sys/alloc/mod.rs#L72-L100).
This PR takes the latter approach, because it allows more code to compile without a custom allocator.