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
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>`
std: organise `sys::pal::os`
Continuing rust-lang/rust#153341, this moves around some functions in `sys::pal`, so that `pal::os` only contains standard-path-related code (which I'll move later as part of rust-lang/rust#117276).
Best reviewed commit-by-commit.
std: add wasm64 to sync::Once and thread_parking atomics cfg guards
When targeting `wasm64-unknown-unknown` with atomics enabled, `std::sync::Once` and `thread_parking` fall through to the `no_threads`/`unsupported` implementations because the cfg guards only check for `wasm32`. This causes worker threads to panic with `unreachable` at runtime. The underlying futex implementations already handle both wasm32 and wasm64 correctly, only the cfg guards were missing wasm64.
I tested this manually with a multithreaded wasm64 application ([o1js](https://github.com/o1-labs/o1js/)) compiled with `-Z build-std=panic_abort,std` and `-C target-feature=+atomics,+bulk-memory,+mutable-globals`
Related: rust-lang/rust#83879rust-lang/rust#77839
Happy to adjust anything based on feedback
Update path separators to be available in const context
Tracking issue: rust-lang/rust#153106
This makes platform-dependent secondary path separators available in const context (ie. at compile time). The platform definitions have also been consolidated behind a common macro to prevent transcription errors, whereas previously they were defined 3-4 times per platform.
### Questions
I've manually verified that this compiles against each platform. It seems like no unit tests should be required for this change; is that correct?
* consolidate various representations of separators in std::sys::path
into a single macro_rules invocation per platform to save
transcription errors
* make `std::path::is_separator()` const
* new constants `std::path::{SEPARATORS, SEPARATORS_STR}`
std: refactor Xous startup code
To facilitate rust-lang/rust#117276 I'm moving all non-path-related code out of `sys::pal::os` (see also rust-lang/rust#153130). This is particularly involved for Xous as `pal::os` also contains the `_start` entry function and the parameter block handling. This PR moves both out into the main `sys::pal` module and also simplifies the parameter block initialisation code slightly.
CC @xobs
update panicking() docs for panic=abort
fixesrust-lang/rust#151458
The documentation for `std::thread::panicking()` has not been changed since v1.0, even though panic hooks were added in v1.10.
Current documentation is misleading for `panic=abort`
`panicking()` can return `true` in 2 different cases:
1. Thread unwinds due to panic
2. Panic hook is executing with `panic=abort`
r? @SpriteOvO
Add a convenience method Path::absolute() that delegates to the
existing free function std::path::absolute(), mirroring the pattern of
Path::canonicalize() delegating to fs::canonicalize().
Tracking issue: https://github.com/rust-lang/rust/issues/153328
Update the name of the Hermit operating system
The HermitCore name was dropped a while ago, the project is now simply called "Hermit". See for example [the website](https://hermit-os.org/).
cc @stlankes @mkroening
Fix compile error in std::fs impl on VEXos target
This PR fixes a compile error in the standard library on the `armv7a-vex-v5` target that was caused by there not being a version of the `Dir` struct exported from `std::sys::fs::vexos`. Reading from directories isn't supported on this platform, so the module now re-exports the unsupported version of `Dir`.
std: move `getpid` to `sys::process`
Part of rust-lang/rust#117276.
Availability of process IDs is highly correlated with availability of processes, so moving the `getpid` implementations to `sys::process` makes a lot of sense (and removes quite some code duplication). The only notable change here is on Hermit, which doesn't have processes but does have `getpid`. But that [always returns 0](https://github.com/hermit-os/kernel/blob/ef27b798856b50d562a42c4ffd2edcb7493c5b5f/src/syscalls/tasks.rs#L21), so I doubt it is useful. If the change to a panic is problematic we could always copy the stub implementation and return zero ourselves (this also applies to the other single-process platforms).
CC @stlankes @mkroening
docs: note env var influence on `temp_dir` and `env_clear` on Windows
On Windows, `env::temp_dir()` internally calls `GetTempPath2`/`GetTempPath`,
which checks the `TMP`, `TEMP`, and `USERPROFILE` environment variables in
order before falling back to the Windows directory. This lookup order was
previously only discoverable by following links to Microsoft documentation.
This PR documents the env var lookup order directly in `env::temp_dir` docs
and notes `GetTempPath2`'s SYSTEM-identity behavior (`C:\Windows\SystemTemp`).
Addresses rust-lang/rust#125439.
* docs: explicitly list env vars checked by temp_dir on Windows
On Windows, temp_dir() internally calls GetTempPath2/GetTempPath which
checks TMP, TEMP, USERPROFILE environment variables in order. This
information was previously only available by following links to Microsoft
docs. Making it explicit in Rust's own documentation improves
discoverability.
Addresses #125439.
* docs: note env var influence on temp_dir and env_clear on Windows
On Windows, nv::temp_dir() internally calls GetTempPath2/GetTempPath,
which checks TMP, TEMP, and USERPROFILE in order. Document this
lookup order directly in the emp_dir docs rather than requiring users
to follow the link to Microsoft documentation.
Also add a note on Command::env_clear explaining that clearing the
environment affects the child process's emp_dir(), not the parent's.
Closes#125439.
* docs: drop Windows env_clear temp_dir note
add field representing types
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/152730)*
> [!NOTE]
> This is a rewrite of #146307 by using a lang item instead of a custom `TyKind`. We still need a `hir::TyKind::FieldOf` variant, because resolving the field name cannot be done before HIR construction. The advantage of doing it this way is that we don't need to make any changes to types after HIR (including symbol mangling). At the very beginning of this feature implementation, I tried to do it using a lang item, but then quickly abandoned the approach, because at that time I was still intending to support nested fields.
Here is a [range-diff](https://triagebot.infra.rust-lang.org/gh-range-diff/rust-lang/rust/605f49b27444a738ea4032cb77e3bdc4eb811bab..d15f5052095b3549111854a2555dd7026b0a729e/605f49b27444a738ea4032cb77e3bdc4eb811bab..f5f42d1e03495dbaa23671c46b15fccddeb3492f) between the two PRs
---
# Add Field Representing Types (FRTs)
This PR implements the first step of the field projection lang experiment (Tracking Issue: rust-lang/rust#145383). Field representing types (FRTs) are a new kind of type. They can be named through the use of the `field_of!` macro with the first argument being the type and the second the name of the field (or variant and field in the case of an enum). No nested fields are supported.
FRTs natively implement the `Field` trait that's also added in this PR. It exposes information about the field such as the type of the field, the type of the base (i.e. the type that contains the field) and the offset within that base type. Only fields of non-packed structs are supported, fields of enums an unions have unique types for each field, but those do not implement the `Field` trait.
This PR was created in collaboration with @dingxiangfei2009, it wouldn't have been possible without him, so huge thanks for mentoring me!
I updated my library solution for field projections to use the FRTs from `core` instead of creating my own using the hash of the name of the field. See the [Rust-for-Linux/field-projection `lang-experiment` branch](https://github.com/Rust-for-Linux/field-projection/tree/lang-experiment).
## API added to `core::field`
```rust
pub unsafe trait Field {
type Base;
type Type;
const OFFSET: usize;
}
pub macro field_of($Container:ty, $($fields:expr)+ $(,)?);
```
Along with a perma-unstable type that the compiler uses in the expansion of the macro:
```rust
#[unstable(feature = "field_representing_type_raw", issue = "none")]
pub struct FieldRepresentingType<T: ?Sized, const VARIANT: u32, const FIELD: u32> {
_phantom: PhantomData<T>,
}
```
## Explanation of Field Representing Types (FRTs)
FRTs are used for compile-time & trait-level reflection for fields of structs & tuples. Each struct & tuple has a unique compiler-generated type nameable through the `field_of!` macro. This type natively contains information about the field such as the outermost container, type of the field and its offset. Users may implement additional traits on these types in order to record custom information (for example a crate may define a [`PinnableField` trait](https://github.com/Rust-for-Linux/field-projection/blob/lang-experiment/src/marker.rs#L9-L23) that records whether the field is structurally pinned).
They are the foundation of field projections, a general operation that's generic over the fields of a struct. This genericism needs to be expressible in the trait system. FRTs make this possible, since an operation generic over fields can just be a function with a generic parameter `F: Field`.
> [!NOTE]
> The approach of field projections has changed considerably since this PR was opened. In the end we might not need FRTs, so this API is highly experimental.
FRTs should act as though they were defined as `struct MyStruct_my_field<StructGenerics>;` next to the struct. So it should be local to the crate defining the struct so that one can implement any trait for the FRT from that crate. The `Field` traits should be implemented by the compiler & populated with correct information (`unsafe` code needs to be able to rely on them being correct).
## TODOs
There are some `FIXME(FRTs)` scattered around the code:
- Diagnostics for `field_of!` can be improved
- `tests/ui/field_representing_types/nonexistent.rs`
- `tests/ui/field_representing_types/non-struct.rs`
- `tests/ui/field_representing_types/offset.rs`
- `tests/ui/field_representing_types/not-field-if-packed.rs`
- `tests/ui/field_representing_types/invalid.rs`
- Simple type alias already seem to work, but might need some extra work in `compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs`
r? @oli-obk
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.