From be01d87ba2c3ae88ed8a5f73c7440b02dbf9d80b Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 19 Sep 2025 10:52:53 +0200 Subject: [PATCH 1/9] Allow running remote-test-server on Apple simulators --- src/tools/remote-test-server/src/main.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index 67a7ad6f3b454..5ec5e6e28982d 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -53,6 +53,10 @@ impl Config { batch: false, bind: if cfg!(target_os = "android") || cfg!(windows) { ([0, 0, 0, 0], 12345).into() + } else if cfg!(target_env = "sim") { + // iOS/tvOS/watchOS/visionOS simulators share network device + // with the host machine. + ([127, 0, 0, 1], 12345).into() } else { ([10, 0, 2, 15], 12345).into() }, @@ -262,10 +266,17 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf cmd.args(args); cmd.envs(env); - // On windows, libraries are just searched in the executable directory, - // system directories, PWD, and PATH, in that order. PATH is the only one - // we can change for this. - let library_path = if cfg!(windows) { "PATH" } else { "LD_LIBRARY_PATH" }; + let library_path = if cfg!(windows) { + // On windows, libraries are just searched in the executable directory, + // system directories, PWD, and PATH, in that order. PATH is the only + // one we can change for this. + "PATH" + } else if cfg!(target_vendor = "apple") { + // On Apple platforms, the environment variable is named differently. + "DYLD_LIBRARY_PATH" + } else { + "LD_LIBRARY_PATH" + }; // Support libraries were uploaded to `work` earlier, so make sure that's // in `LD_LIBRARY_PATH`. Also include our own current dir which may have From b30c1b53f3fbd79b94f40b1d000067e1c49ea1d2 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 19 Sep 2025 13:55:02 +0200 Subject: [PATCH 2/9] Document how to test with iOS/tvOS/watchOS/visionOS simulator --- src/doc/rustc-dev-guide/src/tests/running.md | 31 +++++++++++++++++-- .../rustc/src/platform-support/apple-ios.md | 22 ++++++++++--- .../rustc/src/platform-support/apple-tvos.md | 13 ++------ .../src/platform-support/apple-visionos.md | 13 ++------ .../src/platform-support/apple-watchos.md | 13 ++------ 5 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md index 317b65f98cd3c..482f3c42578ae 100644 --- a/src/doc/rustc-dev-guide/src/tests/running.md +++ b/src/doc/rustc-dev-guide/src/tests/running.md @@ -339,9 +339,34 @@ results. The Docker image is set up to launch `remote-test-server` and the build tools use `remote-test-client` to communicate with the server to coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]). -> **TODO** -> -> - Is there any support for using an iOS emulator? +To run on the iOS/tvOS/watchOS/visionOS simulator, we can similarly treat it as +a "remote" machine. A curious detail here is that the network is shared between +the simulator instance and the host macOS, so we can use the local loopback +address `127.0.0.1`. Something like the following should work: + +```sh +# Build the test server for the iOS simulator: +./x build src/tools/remote-test-server --target aarch64-apple-ios-sim + +# If you already have a simulator instance open, copy the device UUID from: +xcrun simctl list devices booted +UDID=01234567-89AB-CDEF-0123-456789ABCDEF + +# Alternatively, create and boot a new simulator instance: +xcrun simctl list runtimes +xcrun simctl list devicetypes +UDID=$(xcrun simctl create $CHOSEN_DEVICE_TYPE $CHOSEN_RUNTIME) +xcrun simctl boot $UDID +# See https://nshipster.com/simctl/ for details. + +# Spawn the runner on port 12345: +xcrun simctl spawn $UDID ./build/host/stage2-tools/aarch64-apple-ios-sim/release/remote-test-server -v --bind 127.0.0.1:12345 + +# In a new terminal, run tests via the runner: +export TEST_DEVICE_ADDR="127.0.0.1:12345" +./x test --host='' --target aarch64-apple-ios-sim --skip tests/debuginfo +# FIXME(madsmtm): Allow debuginfo tests to work (maybe needs `.dSYM` folder to be copied to the target?). +``` [armhf-gnu]: https://github.com/rust-lang/rust/tree/master/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile [QEMU]: https://www.qemu.org/ diff --git a/src/doc/rustc/src/platform-support/apple-ios.md b/src/doc/rustc/src/platform-support/apple-ios.md index 586afa652262b..3ac1470475468 100644 --- a/src/doc/rustc/src/platform-support/apple-ios.md +++ b/src/doc/rustc/src/platform-support/apple-ios.md @@ -66,6 +66,11 @@ Rust programs can be built for these targets by specifying `--target`, if $ rustc --target aarch64-apple-ios your-code.rs ``` +Or if using Cargo and `-Zbuild-std`: +```console +$ cargo +nightly build -Zbuild-std --target armv7s-apple-ios +``` + The simulator variants can be differentiated from the variants running on-device with the `target_env = "sim"` cfg (or `target_abi = "sim"` before Rust CURRENT_RUSTC_VERSION). @@ -73,7 +78,7 @@ Rust CURRENT_RUSTC_VERSION). ```rust if cfg!(all(target_vendor = "apple", target_env = "sim")) { // Do something on the iOS/tvOS/visionOS/watchOS Simulator. -} { +} else { // Everything else, like Windows and non-Simulator iOS. } ``` @@ -82,8 +87,15 @@ This is similar to the `TARGET_OS_SIMULATOR` define in C code. ## Testing -There is no support for running the Rust or standard library testsuite at the -moment. Testing has mostly been done manually with builds of static libraries -embedded into applications called from Xcode or a simulator. +Running and testing your code naturally requires either an actual device +running iOS, or the equivalent Xcode simulator environment. There exists +several tools in the ecosystem for running a Cargo project on one of these. +One of these tools is [`cargo-dinghy`]. [madsmtm/objc2#459] contains a more +exhaustive list. + +See also [testing on emulators in the `rustc-dev-guide`][test-sim] for +instructions on running the standard library's test suite. -It hopefully will be possible to improve this in the future. +[`cargo-dinghy`]: https://github.com/sonos/dinghy +[madsmtm/objc2#459]: https://github.com/madsmtm/objc2/issues/459 +[test-sim]: https://rustc-dev-guide.rust-lang.org/tests/running.html#testing-on-emulators diff --git a/src/doc/rustc/src/platform-support/apple-tvos.md b/src/doc/rustc/src/platform-support/apple-tvos.md index 193d64666121e..a952d8e230d44 100644 --- a/src/doc/rustc/src/platform-support/apple-tvos.md +++ b/src/doc/rustc/src/platform-support/apple-tvos.md @@ -65,17 +65,8 @@ Using the unstable `-Zbuild-std` with a nightly Cargo may also work. ## Building Rust programs -Rust programs can be built for these targets by specifying `--target`, if -`rustc` has been built with support for them. For example: - -```console -$ rustc --target aarch64-apple-tvos your-code.rs -``` +See [the instructions for iOS](./apple-ios.md#building-rust-programs). ## Testing -There is no support for running the Rust or standard library testsuite at the -moment. Testing has mostly been done manually with builds of static libraries -embedded into applications called from Xcode or a simulator. - -It hopefully will be possible to improve this in the future. +See [the instructions for iOS](./apple-ios.md#testing). diff --git a/src/doc/rustc/src/platform-support/apple-visionos.md b/src/doc/rustc/src/platform-support/apple-visionos.md index ed96912da7a48..2ac069248ee91 100644 --- a/src/doc/rustc/src/platform-support/apple-visionos.md +++ b/src/doc/rustc/src/platform-support/apple-visionos.md @@ -46,20 +46,11 @@ be fixed in [#124560](https://github.com/rust-lang/rust/pull/124560). ## Building Rust programs -Rust programs can be built for these targets by specifying `--target`, if -`rustc` has been built with support for them. For example: - -```console -$ rustc --target aarch64-apple-visionos-sim your-code.rs -``` +See [the instructions for iOS](./apple-ios.md#building-rust-programs). ## Testing -There is no support for running the Rust or standard library testsuite at the -moment. Testing has mostly been done manually with builds of static libraries -embedded into applications called from Xcode or a simulator. - -It hopefully will be possible to improve this in the future. +See [the instructions for iOS](./apple-ios.md#testing). ## Cross-compilation toolchains and C code diff --git a/src/doc/rustc/src/platform-support/apple-watchos.md b/src/doc/rustc/src/platform-support/apple-watchos.md index 6ac09d0d1e538..c1a009614250a 100644 --- a/src/doc/rustc/src/platform-support/apple-watchos.md +++ b/src/doc/rustc/src/platform-support/apple-watchos.md @@ -50,17 +50,8 @@ Using the unstable `-Zbuild-std` with a nightly Cargo may also work. ## Building Rust programs -Rust programs can be built for these targets by specifying `--target`, if -`rustc` has been built with support for them. For example: - -```console -$ rustc --target aarch64-apple-watchos-sim your-code.rs -``` +See [the instructions for iOS](./apple-ios.md#building-rust-programs). ## Testing -There is no support for running the Rust or standard library testsuite at the -moment. Testing has mostly been done manually with builds of static libraries -embedded into applications called from Xcode or a simulator. - -It hopefully will be possible to improve this in the future. +See [the instructions for iOS](./apple-ios.md#testing). From 37be93497e5318fee712dabb70631f9676f07701 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 19 Sep 2025 09:17:20 +0200 Subject: [PATCH 3/9] Fix test suite in iOS/tvOS/watchOS/visionOS simulator --- library/std/src/os/unix/process.rs | 2 + library/std/src/process.rs | 16 +-- library/std/src/process/tests.rs | 102 ++++++++++++++---- .../std/src/sys/process/unix/unix/tests.rs | 1 + library/std/tests/process_spawning.rs | 1 + tests/ui/backtrace/apple-no-dsymutil.rs | 1 + tests/ui/backtrace/dylib-dep.rs | 4 + tests/ui/backtrace/line-tables-only.rs | 4 + tests/ui/command/command-current-dir.rs | 2 + tests/ui/command/command-exec.rs | 2 + tests/ui/command/command-pre-exec.rs | 2 + tests/ui/command/command-uid-gid.rs | 2 + .../ui/compiletest-self-test/test-aux-bin.rs | 1 + ...xporting-impl-from-root-causes-ice-2472.rs | 5 +- tests/ui/issues/issue-45731.rs | 4 + tests/ui/process/core-run-destroy.rs | 4 + tests/ui/process/env-funky-keys.rs | 19 +++- tests/ui/process/fds-are-cloexec.rs | 11 +- tests/ui/process/println-with-broken-pipe.rs | 4 + tests/ui/process/process-envs.rs | 4 + tests/ui/process/process-panic-after-fork.rs | 2 + tests/ui/process/process-remove-from-env.rs | 4 + tests/ui/process/process-sigpipe.rs | 4 + tests/ui/process/process-spawn-failure.rs | 4 + tests/ui/runtime/backtrace-debuginfo.rs | 4 + .../runtime/on-broken-pipe/child-processes.rs | 1 + tests/ui/runtime/on-broken-pipe/inherit.rs | 1 + 27 files changed, 179 insertions(+), 32 deletions(-) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 09429af06e386..5b7b5a8ea803d 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -406,8 +406,10 @@ pub trait ChildExt: Sealed { /// use libc::SIGTERM; /// /// fn main() -> io::Result<()> { + /// # if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) { /// let child = Command::new("cat").stdin(Stdio::piped()).spawn()?; /// child.send_signal(SIGTERM)?; + /// # } /// Ok(()) /// } /// ``` diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 48265de90c4d6..0883e56342c8f 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -532,6 +532,7 @@ impl fmt::Debug for ChildStderr { /// to be changed (for example, by adding arguments) prior to spawning: /// /// ``` +/// # if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) { /// use std::process::Command; /// /// let output = if cfg!(target_os = "windows") { @@ -548,6 +549,7 @@ impl fmt::Debug for ChildStderr { /// }; /// /// let hello = output.stdout; +/// # } /// ``` /// /// `Command` can be reused to spawn multiple processes. The builder methods @@ -1348,7 +1350,7 @@ impl Output { /// /// ``` /// #![feature(exit_status_error)] - /// # #[cfg(all(unix, not(target_os = "android")))] { + /// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] { /// use std::process::Command; /// assert!(Command::new("false").output().unwrap().exit_ok().is_err()); /// # } @@ -1695,7 +1697,7 @@ impl From for Stdio { /// # Ok(()) /// # } /// # - /// # if cfg!(all(unix, not(target_os = "android"))) { + /// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) { /// # test().unwrap(); /// # } /// ``` @@ -1724,7 +1726,7 @@ impl From for Stdio { /// # Ok(()) /// # } /// # - /// # if cfg!(all(unix, not(target_os = "android"))) { + /// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) { /// # test().unwrap(); /// # } /// ``` @@ -1800,7 +1802,7 @@ impl ExitStatus { /// /// ``` /// #![feature(exit_status_error)] - /// # if cfg!(unix) { + /// # if cfg!(all(unix, not(all(target_vendor = "apple", not(target_os = "macos"))))) { /// use std::process::Command; /// /// let status = Command::new("ls") @@ -1907,7 +1909,7 @@ impl crate::sealed::Sealed for ExitStatusError {} /// /// ``` /// #![feature(exit_status_error)] -/// # if cfg!(all(unix, not(target_os = "android"))) { +/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) { /// use std::process::{Command, ExitStatusError}; /// /// fn run(cmd: &str) -> Result<(), ExitStatusError> { @@ -1950,7 +1952,7 @@ impl ExitStatusError { /// /// ``` /// #![feature(exit_status_error)] - /// # #[cfg(all(unix, not(target_os = "android")))] { + /// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] { /// use std::process::Command; /// /// let bad = Command::new("false").status().unwrap().exit_ok().unwrap_err(); @@ -1975,7 +1977,7 @@ impl ExitStatusError { /// ``` /// #![feature(exit_status_error)] /// - /// # if cfg!(all(unix, not(target_os = "android"))) { + /// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) { /// use std::num::NonZero; /// use std::process::Command; /// diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index 5879914ca206a..12c5130defe5a 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -5,7 +5,15 @@ use crate::mem::MaybeUninit; use crate::str; fn known_command() -> Command { - if cfg!(windows) { Command::new("help") } else { Command::new("echo") } + if cfg!(windows) { + Command::new("help") + } else if cfg!(all(target_vendor = "apple", not(target_os = "macos"))) { + // iOS/tvOS/watchOS/visionOS have a very limited set of commandline + // binaries available. + Command::new("log") + } else { + Command::new("echo") + } } #[cfg(target_os = "android")] @@ -19,7 +27,10 @@ fn shell_cmd() -> Command { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn smoke() { let p = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "exit 0"]).spawn() @@ -41,7 +52,10 @@ fn smoke_failure() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn exit_reported_right() { let p = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "exit 1"]).spawn() @@ -56,7 +70,10 @@ fn exit_reported_right() { #[test] #[cfg(unix)] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn signal_reported_right() { use crate::os::unix::process::ExitStatusExt; @@ -80,7 +97,10 @@ pub fn run_output(mut cmd: Command) -> String { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn stdout_works() { if cfg!(target_os = "windows") { let mut cmd = Command::new("cmd"); @@ -94,7 +114,11 @@ fn stdout_works() { } #[test] -#[cfg_attr(any(windows, target_os = "vxworks"), ignore)] +#[cfg_attr(windows, ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn set_current_dir_works() { // On many Unix platforms this will use the posix_spawn path. let mut cmd = shell_cmd(); @@ -116,7 +140,11 @@ fn set_current_dir_works() { } #[test] -#[cfg_attr(any(windows, target_os = "vxworks"), ignore)] +#[cfg_attr(windows, ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn stdin_works() { let mut p = shell_cmd() .arg("-c") @@ -134,7 +162,10 @@ fn stdin_works() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn child_stdout_read_buf() { let mut cmd = if cfg!(target_os = "windows") { let mut cmd = Command::new("cmd"); @@ -165,7 +196,10 @@ fn child_stdout_read_buf() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_process_status() { let mut status = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap() @@ -191,7 +225,10 @@ fn test_process_output_fail_to_start() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_process_output_output() { let Output { status, stdout, stderr } = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap() @@ -206,7 +243,10 @@ fn test_process_output_output() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_process_output_error() { let Output { status, stdout, stderr } = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap() @@ -221,7 +261,10 @@ fn test_process_output_error() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_finish_once() { let mut prog = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap() @@ -232,7 +275,10 @@ fn test_finish_once() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_finish_twice() { let mut prog = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap() @@ -244,7 +290,10 @@ fn test_finish_twice() { } #[test] -#[cfg_attr(any(target_os = "vxworks"), ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_wait_with_output_once() { let prog = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap() @@ -279,7 +328,10 @@ pub fn env_cmd() -> Command { } #[test] -#[cfg_attr(target_os = "vxworks", ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_override_env() { use crate::env; @@ -302,7 +354,10 @@ fn test_override_env() { } #[test] -#[cfg_attr(target_os = "vxworks", ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_add_to_env() { let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap(); let output = String::from_utf8_lossy(&result.stdout).to_string(); @@ -314,7 +369,10 @@ fn test_add_to_env() { } #[test] -#[cfg_attr(target_os = "vxworks", ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no shell available" +)] fn test_capture_env_at_spawn() { use crate::env; @@ -378,7 +436,10 @@ fn test_interior_nul_in_current_dir_is_error() { // Regression tests for #30862. #[test] -#[cfg_attr(target_os = "vxworks", ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no `env` cmd available" +)] fn test_interior_nul_in_env_key_is_error() { match env_cmd().env("has-some-\0\0s-inside", "value").spawn() { Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), @@ -387,7 +448,10 @@ fn test_interior_nul_in_env_key_is_error() { } #[test] -#[cfg_attr(target_os = "vxworks", ignore)] +#[cfg_attr( + any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))), + ignore = "no `env` cmd available" +)] fn test_interior_nul_in_env_value_is_error() { match env_cmd().env("key", "has-some-\0\0s-inside").spawn() { Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput), diff --git a/library/std/src/sys/process/unix/unix/tests.rs b/library/std/src/sys/process/unix/unix/tests.rs index f4d6ac6b4e340..663ba61f966c9 100644 --- a/library/std/src/sys/process/unix/unix/tests.rs +++ b/library/std/src/sys/process/unix/unix/tests.rs @@ -51,6 +51,7 @@ fn exitstatus_display_tests() { #[test] #[cfg_attr(target_os = "emscripten", ignore)] +#[cfg_attr(any(target_os = "tvos", target_os = "watchos"), ignore = "fork is prohibited")] fn test_command_fork_no_unwind() { let got = catch_unwind(|| { let mut c = Command::new("echo"); diff --git a/library/std/tests/process_spawning.rs b/library/std/tests/process_spawning.rs index 43b45cb2d2b5c..93f73ccad3ea4 100644 --- a/library/std/tests/process_spawning.rs +++ b/library/std/tests/process_spawning.rs @@ -7,6 +7,7 @@ mod common; #[test] // Process spawning not supported by Miri, Emscripten and wasi #[cfg_attr(any(miri, target_os = "emscripten", target_os = "wasi"), ignore)] +#[cfg_attr(any(target_os = "tvos", target_os = "watchos"), ignore = "fork is prohibited")] fn issue_15149() { // If we're the parent, copy our own binary to a new directory. let my_path = env::current_exe().unwrap(); diff --git a/tests/ui/backtrace/apple-no-dsymutil.rs b/tests/ui/backtrace/apple-no-dsymutil.rs index e5aeced25ca35..00c8349d1293e 100644 --- a/tests/ui/backtrace/apple-no-dsymutil.rs +++ b/tests/ui/backtrace/apple-no-dsymutil.rs @@ -3,6 +3,7 @@ //@ compile-flags:-Cstrip=none //@ compile-flags:-g -Csplit-debuginfo=unpacked //@ only-apple +//@ ignore-remote needs the compiler-produced `.o` file to be copied to the device use std::process::Command; use std::str; diff --git a/tests/ui/backtrace/dylib-dep.rs b/tests/ui/backtrace/dylib-dep.rs index 05fdb9afef80d..cf420ec8d0697 100644 --- a/tests/ui/backtrace/dylib-dep.rs +++ b/tests/ui/backtrace/dylib-dep.rs @@ -7,6 +7,10 @@ //@ ignore-android FIXME #17520 //@ ignore-fuchsia Backtraces not symbolized //@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written). +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device //@ needs-unwind //@ ignore-backends: gcc //@ compile-flags: -g -Copt-level=0 -Cstrip=none -Cforce-frame-pointers=yes diff --git a/tests/ui/backtrace/line-tables-only.rs b/tests/ui/backtrace/line-tables-only.rs index 6624c71e184b0..5863cc1d17d46 100644 --- a/tests/ui/backtrace/line-tables-only.rs +++ b/tests/ui/backtrace/line-tables-only.rs @@ -11,6 +11,10 @@ //@ ignore-android FIXME #17520 //@ ignore-fuchsia Backtraces not symbolized //@ ignore-emscripten Requires custom symbolization code +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device //@ needs-unwind //@ aux-build: line-tables-only-helper.rs diff --git a/tests/ui/command/command-current-dir.rs b/tests/ui/command/command-current-dir.rs index e264cbe4d7045..a6b51df5f176c 100644 --- a/tests/ui/command/command-current-dir.rs +++ b/tests/ui/command/command-current-dir.rs @@ -2,6 +2,8 @@ //@ no-prefer-dynamic We move the binary around, so do not depend dynamically on libstd //@ needs-subprocess //@ ignore-fuchsia Needs directory creation privilege +//@ ignore-tvos `Command::current_dir` requires fork, which is prohibited +//@ ignore-watchos `Command::current_dir` requires fork, which is prohibited use std::env; use std::fs; diff --git a/tests/ui/command/command-exec.rs b/tests/ui/command/command-exec.rs index 77336377e8899..870f8b047b9a2 100644 --- a/tests/ui/command/command-exec.rs +++ b/tests/ui/command/command-exec.rs @@ -3,6 +3,8 @@ //@ only-unix (this is a unix-specific test) //@ needs-subprocess //@ ignore-fuchsia no execvp syscall provided +//@ ignore-tvos execvp is prohibited +//@ ignore-watchos execvp is prohibited use std::env; use std::os::unix::process::CommandExt; diff --git a/tests/ui/command/command-pre-exec.rs b/tests/ui/command/command-pre-exec.rs index 7299f357bd078..a62ab0b5ed6a7 100644 --- a/tests/ui/command/command-pre-exec.rs +++ b/tests/ui/command/command-pre-exec.rs @@ -2,6 +2,8 @@ //@ only-unix (this is a unix-specific test) //@ needs-subprocess //@ ignore-fuchsia no execvp syscall +//@ ignore-tvos execvp is prohibited +//@ ignore-watchos execvp is prohibited #![feature(rustc_private)] diff --git a/tests/ui/command/command-uid-gid.rs b/tests/ui/command/command-uid-gid.rs index f54a0f50708ba..ef0653eb2cb4e 100644 --- a/tests/ui/command/command-uid-gid.rs +++ b/tests/ui/command/command-uid-gid.rs @@ -1,6 +1,8 @@ //@ run-pass //@ ignore-android //@ ignore-fuchsia no '/bin/sh', '/bin/ls' +//@ ignore-tvos `Command::uid/gid` requires fork, which is prohibited +//@ ignore-watchos `Command::uid/gid` requires fork, which is prohibited //@ needs-subprocess #![feature(rustc_private)] diff --git a/tests/ui/compiletest-self-test/test-aux-bin.rs b/tests/ui/compiletest-self-test/test-aux-bin.rs index c1c28e12b3b5a..9ac17e6e14619 100644 --- a/tests/ui/compiletest-self-test/test-aux-bin.rs +++ b/tests/ui/compiletest-self-test/test-aux-bin.rs @@ -1,4 +1,5 @@ //@ ignore-cross-compile because aux-bin does not yet support it +//@ ignore-remote because aux-bin does not yet support it //@ aux-bin: print-it-works.rs //@ run-pass diff --git a/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs b/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs index 86d637b579dc6..c6cfae1e5452c 100644 --- a/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs +++ b/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs @@ -1,6 +1,9 @@ //@ run-pass //@ aux-build:exporting-impl-from-root-causes-ice-2472-b.rs - +//@ ignore-ios FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? +//@ ignore-tvos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? +//@ ignore-watchos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? +//@ ignore-visionos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? extern crate exporting_impl_from_root_causes_ice_2472_b as lib; diff --git a/tests/ui/issues/issue-45731.rs b/tests/ui/issues/issue-45731.rs index 49335362dd0f7..db11d1dbef1c7 100644 --- a/tests/ui/issues/issue-45731.rs +++ b/tests/ui/issues/issue-45731.rs @@ -1,6 +1,10 @@ //@ run-pass #![allow(unused_variables)] //@ compile-flags:--test -g +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device #[cfg(target_vendor = "apple")] #[test] diff --git a/tests/ui/process/core-run-destroy.rs b/tests/ui/process/core-run-destroy.rs index f4be54da8fe67..f381997ef7931 100644 --- a/tests/ui/process/core-run-destroy.rs +++ b/tests/ui/process/core-run-destroy.rs @@ -8,6 +8,10 @@ //@ needs-subprocess //@ ignore-vxworks no 'cat' and 'sleep' //@ ignore-fuchsia no 'cat' +//@ ignore-ios no 'cat' and 'sleep' +//@ ignore-tvos no 'cat' and 'sleep' +//@ ignore-watchos no 'cat' and 'sleep' +//@ ignore-visionos no 'cat' and 'sleep' // N.B., these tests kill child processes. Valgrind sees these children as leaking // memory, which makes for some *confusing* logs. That's why these are here diff --git a/tests/ui/process/env-funky-keys.rs b/tests/ui/process/env-funky-keys.rs index a4a71c94020cd..193659bea293e 100644 --- a/tests/ui/process/env-funky-keys.rs +++ b/tests/ui/process/env-funky-keys.rs @@ -1,8 +1,7 @@ //@ run-pass //@ edition: 2021 -// Ignore this test on Android, because it segfaults there. -//@ ignore-android +//@ ignore-android segfaults //@ ignore-windows //@ ignore-wasm32 no execve //@ ignore-sgx no execve @@ -24,6 +23,9 @@ use std::ptr; fn main() { if env::args_os().count() == 2 { for (key, value) in env::vars_os() { + if key == "DYLD_ROOT_PATH" { + continue; + } panic!("found env value {:?} {:?}", key, value); } return; @@ -35,7 +37,18 @@ fn main() { .as_bytes()).unwrap(); let filename: *const c_char = current_exe.as_ptr(); let argv: &[*const c_char] = &[filename, filename, ptr::null()]; - let envp: &[*const c_char] = &[c"FOOBAR".as_ptr(), ptr::null()]; + + let root; + let envp: &[*const c_char] = if cfg!(all(target_vendor = "apple", target_env = "sim")) { + // Workaround: iOS/tvOS/watchOS/visionOS simulators need the root path + // from the current process. + root = format!("DYLD_ROOT_PATH={}\0", std::env::var("DYLD_ROOT_PATH").unwrap()); + &[c"FOOBAR".as_ptr(), root.as_ptr().cast(), ptr::null()] + } else { + // Try to set an environment variable without a value. + &[c"FOOBAR".as_ptr(), ptr::null()] + }; + unsafe { execve(filename, &argv[0], &envp[0]); } diff --git a/tests/ui/process/fds-are-cloexec.rs b/tests/ui/process/fds-are-cloexec.rs index f6678379dd675..0fae7c2b5024d 100644 --- a/tests/ui/process/fds-are-cloexec.rs +++ b/tests/ui/process/fds-are-cloexec.rs @@ -74,8 +74,15 @@ fn child(args: &[String]) { let fd: libc::c_int = arg.parse().unwrap(); unsafe { assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1); - assert_eq!(io::Error::last_os_error().raw_os_error(), - Some(libc::EBADF)); + let raw = io::Error::last_os_error().raw_os_error(); + if cfg!(all(target_vendor = "apple", not(target_os = "macos"))) { + // Workaround: iOS/tvOS/watchOS/visionOS seems to treat `tcp6` + // as a directory? + if raw == Some(libc::EISDIR) { + continue; + } + } + assert_eq!(raw, Some(libc::EBADF)); } } } diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index 58b83a2dd9a2f..e87e207737027 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -5,6 +5,10 @@ //@ ignore-fuchsia //@ ignore-horizon //@ ignore-android +//@ ignore-ios no 'head' +//@ ignore-tvos no 'head' +//@ ignore-watchos no 'head' +//@ ignore-visionos no 'head' //@ ignore-backends: gcc //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ compile-flags: -Zon-broken-pipe=error diff --git a/tests/ui/process/process-envs.rs b/tests/ui/process/process-envs.rs index 98052f1d3a5d7..cbe16704a8e19 100644 --- a/tests/ui/process/process-envs.rs +++ b/tests/ui/process/process-envs.rs @@ -2,6 +2,10 @@ //@ needs-subprocess //@ ignore-vxworks no 'env' //@ ignore-fuchsia no 'env' +//@ ignore-ios no 'env' +//@ ignore-tvos no 'env' +//@ ignore-watchos no 'env' +//@ ignore-visionos no 'env' use std::process::Command; use std::env; diff --git a/tests/ui/process/process-panic-after-fork.rs b/tests/ui/process/process-panic-after-fork.rs index 6e0267e0a54f5..653ff6ce314d9 100644 --- a/tests/ui/process/process-panic-after-fork.rs +++ b/tests/ui/process/process-panic-after-fork.rs @@ -3,6 +3,8 @@ //@ only-unix //@ needs-subprocess //@ ignore-fuchsia no fork +//@ ignore-tvos fork is prohibited +//@ ignore-watchos fork is prohibited #![feature(rustc_private)] #![feature(never_type)] diff --git a/tests/ui/process/process-remove-from-env.rs b/tests/ui/process/process-remove-from-env.rs index c1a2b2daf5b63..68c3909b15ae0 100644 --- a/tests/ui/process/process-remove-from-env.rs +++ b/tests/ui/process/process-remove-from-env.rs @@ -2,6 +2,10 @@ //@ needs-subprocess //@ ignore-vxworks no 'env' //@ ignore-fuchsia no 'env' +//@ ignore-ios no 'env' +//@ ignore-tvos no 'env' +//@ ignore-watchos no 'env' +//@ ignore-visionos no 'env' use std::process::Command; use std::env; diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 3ecf271599d23..574d79ee1ddaf 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -15,6 +15,10 @@ //@ ignore-vxworks no 'sh' //@ ignore-fuchsia no 'sh' +//@ ignore-ios no 'sh' +//@ ignore-tvos no 'sh' +//@ ignore-watchos no 'sh' +//@ ignore-visionos no 'sh' //@ needs-threads //@ only-unix SIGPIPE is a unix feature diff --git a/tests/ui/process/process-spawn-failure.rs b/tests/ui/process/process-spawn-failure.rs index 0950b044c97ca..ac2c34bc7836d 100644 --- a/tests/ui/process/process-spawn-failure.rs +++ b/tests/ui/process/process-spawn-failure.rs @@ -9,6 +9,10 @@ //@ ignore-vxworks no 'ps' //@ ignore-fuchsia no 'ps' //@ ignore-nto no 'ps' +//@ ignore-ios no 'ps' +//@ ignore-tvos no 'ps' +//@ ignore-watchos no 'ps' +//@ ignore-visionos no 'ps' #![feature(rustc_private)] diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs index 5fb9943d6c3c4..5e91f22aec029 100644 --- a/tests/ui/runtime/backtrace-debuginfo.rs +++ b/tests/ui/runtime/backtrace-debuginfo.rs @@ -11,6 +11,10 @@ //@ compile-flags:-Cstrip=none //@ needs-subprocess //@ ignore-fuchsia Backtrace not symbolized, trace different line alignment +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device // FIXME(#117097): backtrace (possibly unwinding mechanism) seems to be different on at least // `i686-mingw` (32-bit windows-gnu)? cc #128911. diff --git a/tests/ui/runtime/on-broken-pipe/child-processes.rs b/tests/ui/runtime/on-broken-pipe/child-processes.rs index c0c8ad4e2f5e6..b7022e1b09d90 100644 --- a/tests/ui/runtime/on-broken-pipe/child-processes.rs +++ b/tests/ui/runtime/on-broken-pipe/child-processes.rs @@ -1,5 +1,6 @@ //@ revisions: default error kill inherit //@ ignore-cross-compile because aux-bin does not yet support it +//@ ignore-remote because aux-bin does not yet support it //@ only-unix because SIGPIPE is a unix thing //@ ignore-backends: gcc //@ run-pass diff --git a/tests/ui/runtime/on-broken-pipe/inherit.rs b/tests/ui/runtime/on-broken-pipe/inherit.rs index f3c8140eaaef1..e99c7c7a0fe4f 100644 --- a/tests/ui/runtime/on-broken-pipe/inherit.rs +++ b/tests/ui/runtime/on-broken-pipe/inherit.rs @@ -1,4 +1,5 @@ //@ ignore-cross-compile because aux-bin does not yet support it +//@ ignore-remote because aux-bin does not yet support it //@ only-unix because SIGPIPE is a unix thing //@ aux-bin: assert-inherit-sig_dfl.rs //@ aux-bin: assert-inherit-sig_ign.rs From 58814bce6cfb8faf62979c7d043347e0526d7e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 19 Sep 2025 16:21:34 +0200 Subject: [PATCH 4/9] Allow running `x ` from a different directory --- src/bootstrap/src/core/builder/mod.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 75c8ee365284e..8226b4325b6b8 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -590,18 +590,30 @@ impl StepDescription { // Attempt to resolve paths to be relative to the builder source directory. let mut paths: Vec = paths .iter() - .map(|p| { + .map(|original_path| { + let mut path = original_path.clone(); + + // Someone could run `x ` from a different repository than the source + // directory. + // In that case, we should not try to resolve the paths relative to the working + // directory, but rather relative to the source directory. + // So we forcefully "relocate" the path to the source directory here. + if !path.is_absolute() { + path = builder.src.join(path); + } + // If the path does not exist, it may represent the name of a Step, such as `tidy` in `x test tidy` - if !p.exists() { - return p.clone(); + if !path.exists() { + // Use the original path here + return original_path.clone(); } // Make the path absolute, strip the prefix, and convert to a PathBuf. - match std::path::absolute(p) { + match std::path::absolute(&path) { Ok(p) => p.strip_prefix(&builder.src).unwrap_or(&p).to_path_buf(), Err(e) => { eprintln!("ERROR: {e:?}"); - panic!("Due to the above error, failed to resolve path: {p:?}"); + panic!("Due to the above error, failed to resolve path: {path:?}"); } } }) From 54b15a66d89926c4e3e719f26a46b32653d1343f Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 19 Sep 2025 14:00:29 +0000 Subject: [PATCH 5/9] fixes for numerous clippy warnings --- compiler/rustc_driver_impl/src/lib.rs | 21 ++++++++++----------- compiler/rustc_driver_impl/src/print.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 4 ++-- compiler/rustc_hir_typeck/src/upvar.rs | 17 +++++++---------- compiler/rustc_hir_typeck/src/writeback.rs | 6 +++--- compiler/rustc_interface/src/passes.rs | 12 ++++++------ compiler/rustc_interface/src/queries.rs | 2 +- compiler/rustc_interface/src/util.rs | 4 ++-- 8 files changed, 32 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 4f875cf99ec21..8dab520cf36b9 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -206,7 +206,7 @@ impl Callbacks for TimePassesCallbacks { // time because it will mess up the --print output. See #64339. // self.time_passes = (config.opts.prints.is_empty() && config.opts.unstable_opts.time_passes) - .then(|| config.opts.unstable_opts.time_passes_format); + .then_some(config.opts.unstable_opts.time_passes_format); config.opts.trimmed_def_paths = true; } } @@ -439,8 +439,9 @@ fn make_input(early_dcx: &EarlyDiagCtxt, free_matches: &[String]) -> Option() + .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be a number"); FileName::doc_test_source_code(PathBuf::from(path), line) } Err(_) => FileName::anon_source_code(&input), @@ -474,8 +475,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col let mut text = String::new(); // Slice off the leading newline and print. for line in description.lines() { - let indent_level = - line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len()); + let indent_level = line.find(|c: char| !c.is_whitespace()).unwrap_or(line.len()); let dedented_line = &line[indent_level..]; if dedented_line.starts_with("```") { is_in_code_block = !is_in_code_block; @@ -547,7 +547,7 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { // The pager failed. Try to print pretty output to stdout. if let Some((bufwtr, mdbuf)) = &pretty_data - && bufwtr.print(&mdbuf).is_ok() + && bufwtr.print(mdbuf).is_ok() { return; } @@ -598,8 +598,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) { match sess.io.input { - Input::File(ref ifile) => { - let path = &(*ifile); + Input::File(ref path) => { let mut v = Vec::new(); locator::list_file_metadata( &sess.target, @@ -833,7 +832,7 @@ fn print_crate_info( SupportedCrateTypes => { let supported_crate_types = CRATE_TYPES .iter() - .filter(|(_, crate_type)| !invalid_output_for_target(&sess, *crate_type)) + .filter(|(_, crate_type)| !invalid_output_for_target(sess, *crate_type)) .filter(|(_, crate_type)| *crate_type != CrateType::Sdylib) .map(|(crate_type_sym, _)| *crate_type_sym) .collect::>(); @@ -1434,7 +1433,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&DiagCtxt)) eprintln!(); if let Some(ice_path) = ice_path() - && let Ok(mut out) = File::options().create(true).append(true).open(&ice_path) + && let Ok(mut out) = File::options().create(true).append(true).open(ice_path) { // The current implementation always returns `Some`. let location = info.location().unwrap(); @@ -1510,7 +1509,7 @@ fn report_ice( let file = if let Some(path) = ice_path() { // Create the ICE dump target file. - match crate::fs::File::options().create(true).append(true).open(&path) { + match crate::fs::File::options().create(true).append(true).open(path) { Ok(mut file) => { dcx.emit_note(session_diagnostics::IcePath { path: path.clone() }); if FIRST_PANIC.swap(false, Ordering::SeqCst) { diff --git a/compiler/rustc_driver_impl/src/print.rs b/compiler/rustc_driver_impl/src/print.rs index 70de55320f7ae..3f107eb7a61aa 100644 --- a/compiler/rustc_driver_impl/src/print.rs +++ b/compiler/rustc_driver_impl/src/print.rs @@ -14,7 +14,7 @@ macro_rules! safe_println { } pub(crate) fn print(args: fmt::Arguments<'_>) { - if let Err(_) = io::stdout().write_fmt(args) { + if io::stdout().write_fmt(args).is_err() { rustc_errors::FatalError.raise(); } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 7f5397a7926da..43a23822fd1e3 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -254,7 +254,7 @@ fn typeck_with_inspect<'tcx>( } fcx.select_obligations_where_possible(|_| {}); - if let None = fcx.infcx.tainted_by_errors() { + if fcx.infcx.tainted_by_errors().is_none() { fcx.report_ambiguity_errors(); } @@ -295,7 +295,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti } else if let Node::AnonConst(_) = node { let id = tcx.local_def_id_to_hir_id(def_id); match tcx.parent_hir_node(id) { - Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. }) + Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(anon_const), span, .. }) if anon_const.hir_id == id => { Some(fcx.next_ty_var(span)) diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 06acff06a51ac..0a7b458f3fb35 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -421,7 +421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Not all upvars are captured by ref, so use // `apply_capture_kind_on_capture_ty` to ensure that we // compute the right captured type. - return apply_capture_kind_on_capture_ty( + apply_capture_kind_on_capture_ty( self.tcx, upvar_ty, capture, @@ -430,7 +430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { self.tcx.lifetimes.re_erased }, - ); + ) }, ), ); @@ -529,11 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // process any deferred resolutions. let deferred_call_resolutions = self.remove_deferred_call_resolutions(closure_def_id); for deferred_call_resolution in deferred_call_resolutions { - deferred_call_resolution.resolve(&mut FnCtxt::new( - self, - self.param_env, - closure_def_id, - )); + deferred_call_resolution.resolve(&FnCtxt::new(self, self.param_env, closure_def_id)); } } @@ -1493,7 +1489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Notation: /// - Ty(place): Type of place /// - `(a, b)`: Represents the function parameters `base_path_ty` and `captured_by_move_projs` - /// respectively. + /// respectively. /// ```ignore (illustrative) /// (Ty(w), [ &[p, x], &[c] ]) /// // | @@ -2179,9 +2175,10 @@ fn restrict_precision_for_unsafe( (place, curr_mode) } -/// Truncate projections so that following rules are obeyed by the captured `place`: +/// Truncate projections so that the following rules are obeyed by the captured `place`: /// - No Index projections are captured, since arrays are captured completely. -/// - No unsafe block is required to capture `place` +/// - No unsafe block is required to capture `place`. +/// /// Returns the truncated place and updated capture mode. fn restrict_capture_precision( place: Place<'_>, diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 90301d1b391a0..6192420898f6e 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -220,7 +220,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // to use builtin indexing because the index type is known to be // usize-ish fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) { - if let hir::ExprKind::Index(ref base, ref index, _) = e.kind { + if let hir::ExprKind::Index(base, index, _) = e.kind { // All valid indexing looks like this; might encounter non-valid indexes at this point. let base_ty = self.typeck_results.expr_ty_adjusted(base); if let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() { @@ -583,7 +583,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } if let Err(err) = opaque_type_has_defining_use_args( - &self.fcx, + self.fcx, opaque_type_key, hidden_type.span, DefiningScopeKind::HirTypeck, @@ -792,7 +792,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn visit_potentially_region_dependent_goals(&mut self) { let obligations = self.fcx.take_hir_typeck_potentially_region_dependent_goals(); - if let None = self.fcx.tainted_by_errors() { + if self.fcx.tainted_by_errors().is_none() { for obligation in obligations { let (predicate, mut cause) = self.fcx.resolve_vars_if_possible((obligation.predicate, obligation.cause)); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d39219bfd660f..6cefe8875306a 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -192,7 +192,7 @@ fn configure_and_expand( unsafe { env::set_var( "PATH", - &env::join_paths( + env::join_paths( new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()), ) .unwrap(), @@ -446,7 +446,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { let prev_source = sess.psess.source_map().span_to_prev_source(first_span); let ferris_fix = prev_source .map_or(FerrisFix::SnakeCase, |source| { - let mut source_before_ferris = source.trim_end().split_whitespace().rev(); + let mut source_before_ferris = source.split_whitespace().rev(); match source_before_ferris.next() { Some("struct" | "trait" | "mod" | "union" | "type" | "enum") => { FerrisFix::PascalCase @@ -500,7 +500,7 @@ fn env_var_os<'tcx>(tcx: TyCtxt<'tcx>, key: &'tcx OsStr) -> Option<&'tcx OsStr> // properly change-tracked. tcx.sess.psess.env_depinfo.borrow_mut().insert(( Symbol::intern(&key.to_string_lossy()), - value.as_ref().and_then(|value| value.to_str()).map(|value| Symbol::intern(&value)), + value.as_ref().and_then(|value| value.to_str()).map(|value| Symbol::intern(value)), )); value_tcx @@ -824,7 +824,7 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) { let outputs = tcx.output_filenames(()); let output_paths = - generated_output_paths(tcx, &outputs, sess.io.output_file.is_some(), crate_name); + generated_output_paths(tcx, outputs, sess.io.output_file.is_some(), crate_name); // Ensure the source file isn't accidentally overwritten during compilation. if let Some(input_path) = sess.io.input.opt_path() { @@ -847,7 +847,7 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) { } } - write_out_deps(tcx, &outputs, &output_paths); + write_out_deps(tcx, outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1; @@ -1303,7 +1303,7 @@ pub(crate) fn parse_crate_name( let rustc_hir::Attribute::Parsed(AttributeKind::CrateName { name, name_span, .. }) = AttributeParser::parse_limited_should_emit( sess, - &attrs, + attrs, sym::crate_name, DUMMY_SP, rustc_ast::node_id::CRATE_NODE_ID, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 370e886c525fd..280214ab4183a 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -94,7 +94,7 @@ impl Linker { &rlink_file, &codegen_results, &self.metadata, - &*self.output_filenames, + &self.output_filenames, ) .unwrap_or_else(|error| { sess.dcx().emit_fatal(FailedWritingFile { path: &rlink_file, error }) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 061c764e619a3..26e09c95e7698 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -243,7 +243,7 @@ pub(crate) fn run_in_thread_pool_with_globals< let query_map = rustc_span::set_session_globals_then(unsafe { &*(session_globals as *const SessionGlobals) }, || { // Ensure there was no errors collecting all active jobs. // We need the complete map to ensure we find a cycle to break. - QueryCtxt::new(tcx).collect_active_jobs().ok().expect("failed to collect active queries in deadlock handler") + QueryCtxt::new(tcx).collect_active_jobs().expect("failed to collect active queries in deadlock handler") }); break_query_cycles(query_map, ®istry); }) @@ -561,7 +561,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu } Some(out_file.clone()) }; - if sess.io.output_dir != None { + if sess.io.output_dir.is_some() { sess.dcx().emit_warn(errors::IgnoringOutDir); } From 4841d8c5ffb6a7bd025c14d8e9d2c23e6c458792 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 19 Sep 2025 22:14:50 +0000 Subject: [PATCH 6/9] generate list of all variants with `target_spec_enum` This helps us avoid the hardcoded lists elsewhere. --- compiler/rustc_codegen_llvm/src/lib.rs | 16 +++------------- compiler/rustc_session/src/config/cfg.rs | 6 ++++-- compiler/rustc_target/src/lib.rs | 23 ++++++++++++----------- compiler/rustc_target/src/spec/mod.rs | 16 ---------------- 4 files changed, 19 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 6fb23d0984335..13bdb7cb1a274 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -45,6 +45,7 @@ use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest}; use rustc_span::Symbol; +use rustc_target::spec::{RelocModel, TlsModel}; mod abi; mod allocator; @@ -244,16 +245,7 @@ impl CodegenBackend for LlvmCodegenBackend { match req.kind { PrintKind::RelocationModels => { writeln!(out, "Available relocation models:").unwrap(); - for name in &[ - "static", - "pic", - "pie", - "dynamic-no-pic", - "ropi", - "rwpi", - "ropi-rwpi", - "default", - ] { + for name in RelocModel::ALL.iter().map(RelocModel::desc).chain(["default"]) { writeln!(out, " {name}").unwrap(); } writeln!(out).unwrap(); @@ -267,9 +259,7 @@ impl CodegenBackend for LlvmCodegenBackend { } PrintKind::TlsModels => { writeln!(out, "Available TLS models:").unwrap(); - for name in - &["global-dynamic", "local-dynamic", "initial-exec", "local-exec", "emulated"] - { + for name in TlsModel::ALL.iter().map(TlsModel::desc) { writeln!(out, " {name}").unwrap(); } writeln!(out).unwrap(); diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 8f63ce6f0ae88..7e970461ab731 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -374,11 +374,13 @@ impl CheckCfg { ins!(sym::overflow_checks, no_values); - ins!(sym::panic, empty_values).extend(&PanicStrategy::all()); + ins!(sym::panic, empty_values) + .extend(PanicStrategy::ALL.iter().map(PanicStrategy::desc_symbol)); ins!(sym::proc_macro, no_values); - ins!(sym::relocation_model, empty_values).extend(RelocModel::all()); + ins!(sym::relocation_model, empty_values) + .extend(RelocModel::ALL.iter().map(RelocModel::desc_symbol)); let sanitize_values = SanitizerSet::all() .into_iter() diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index b3fe1fffccebc..8c6a77cba8ba7 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -76,10 +76,10 @@ fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> { macro_rules! target_spec_enum { ( $( #[$attr:meta] )* - pub enum $name:ident { + pub enum $Name:ident { $( $( #[$variant_attr:meta] )* - $variant:ident = $string:literal, + $Variant:ident = $string:literal, )* } parse_error_type = $parse_error_type:literal; @@ -87,20 +87,20 @@ macro_rules! target_spec_enum { $( #[$attr] )* #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] #[derive(schemars::JsonSchema)] - pub enum $name { + pub enum $Name { $( $( #[$variant_attr] )* #[serde(rename = $string)] // for JSON schema generation only - $variant, + $Variant, )* } - impl FromStr for $name { + impl FromStr for $Name { type Err = String; fn from_str(s: &str) -> Result { Ok(match s { - $( $string => Self::$variant, )* + $( $string => Self::$Variant, )* _ => { let all = [$( concat!("'", $string, "'") ),*].join(", "); return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type)); @@ -109,24 +109,25 @@ macro_rules! target_spec_enum { } } - impl $name { + impl $Name { + pub const ALL: &'static [$Name] = &[ $( $Name::$Variant, )* ]; pub fn desc(&self) -> &'static str { match self { - $( Self::$variant => $string, )* + $( Self::$Variant => $string, )* } } } - impl crate::json::ToJson for $name { + impl crate::json::ToJson for $Name { fn to_json(&self) -> crate::json::Json { self.desc().to_json() } } - crate::json::serde_deserialize_from_str!($name); + crate::json::serde_deserialize_from_str!($Name); - impl std::fmt::Display for $name { + impl std::fmt::Display for $Name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(self.desc()) } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 07fb1ce63f7c4..f705af52bd868 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -854,10 +854,6 @@ impl PanicStrategy { PanicStrategy::Abort => sym::abort, } } - - pub const fn all() -> [Symbol; 2] { - [Self::Abort.desc_symbol(), Self::Unwind.desc_symbol()] - } } crate::target_spec_enum! { @@ -974,18 +970,6 @@ impl RelocModel { RelocModel::RopiRwpi => sym::ropi_rwpi, } } - - pub const fn all() -> [Symbol; 7] { - [ - RelocModel::Static.desc_symbol(), - RelocModel::Pic.desc_symbol(), - RelocModel::Pie.desc_symbol(), - RelocModel::DynamicNoPic.desc_symbol(), - RelocModel::Ropi.desc_symbol(), - RelocModel::Rwpi.desc_symbol(), - RelocModel::RopiRwpi.desc_symbol(), - ] - } } crate::target_spec_enum! { From 6a5838105d8496b9db5dc61b0bd12dda70f7bbe1 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 19 Sep 2025 18:13:21 -0600 Subject: [PATCH 7/9] Fix unsupported std::sys::thread Fixes building std for any platform with an unsupported thread abstraction. This includes {aarch64,armv7,x86_64}-unknown-trusty and riscv32im-risc0-zkvm-elf, which explicitly include the unsupported module, and platforms with no PAL. Bug fix for PR 145177 (std: move thread into sys). --- library/std/src/sys/pal/trusty/mod.rs | 2 -- library/std/src/sys/pal/unsupported/mod.rs | 1 - library/std/src/sys/pal/zkvm/mod.rs | 2 -- library/std/src/sys/process/unix/vxworks.rs | 3 +-- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/library/std/src/sys/pal/trusty/mod.rs b/library/std/src/sys/pal/trusty/mod.rs index 275f606246336..cf0c098f8a2f3 100644 --- a/library/std/src/sys/pal/trusty/mod.rs +++ b/library/std/src/sys/pal/trusty/mod.rs @@ -7,8 +7,6 @@ mod common; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/thread.rs"] -pub mod thread; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index 5e3295b1331a3..e64bbc7c6169d 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -2,7 +2,6 @@ pub mod os; pub mod pipe; -pub mod thread; pub mod time; mod common; diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index e1efa2406858f..9069c8d12fa1d 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -14,8 +14,6 @@ pub mod abi; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/thread.rs"] -pub mod thread; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/process/unix/vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs index 2275cbb946a9c..b9298f5fa44c1 100644 --- a/library/std/src/sys/process/unix/vxworks.rs +++ b/library/std/src/sys/process/unix/vxworks.rs @@ -4,8 +4,7 @@ use libc::{self, RTP_ID, c_char, c_int}; use super::common::*; use crate::io::{self, ErrorKind}; use crate::num::NonZero; -use crate::sys::cvt; -use crate::sys::pal::thread; +use crate::sys::{cvt, thread}; use crate::{fmt, sys}; //////////////////////////////////////////////////////////////////////////////// From 776c199c7bb7a26f2578087c28ee7be4d8941097 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 19 Sep 2025 18:30:18 -0600 Subject: [PATCH 8/9] Fix std build for xtensa --- library/core/src/ffi/va_list.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 643bd95df846d..0d4ccb5aeb28c 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -2,6 +2,7 @@ //! //! Better known as "varargs". +#[cfg(not(target_arch = "xtensa"))] use crate::ffi::c_void; #[allow(unused_imports)] use crate::fmt; From db4d4eff56a38c7c1096e0cf76ee3bd523bade05 Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Fri, 19 Sep 2025 18:57:49 -0600 Subject: [PATCH 9/9] Update cfg_if! to cfg_select! The macro is now builtin. --- library/std/src/sys/env_consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/env_consts.rs b/library/std/src/sys/env_consts.rs index 9683fd47cf96b..711ba0a5f8a92 100644 --- a/library/std/src/sys/env_consts.rs +++ b/library/std/src/sys/env_consts.rs @@ -2,7 +2,7 @@ // Replaces the #[else] gate with #[cfg(not(any(…)))] of all the other gates. // This ensures that they must be mutually exclusive and do not have precedence -// like cfg_if!. +// like cfg_select!. macro cfg_unordered( $(#[cfg($cfg:meta)] $os:item)* #[else] $fallback:item