From 614bac581b9b093ace4a7fc49c4f8c027e80d75d Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 27 Feb 2026 14:53:09 -0800 Subject: [PATCH 1/4] [win] Fix truncated unwinds for Arm64 Windows --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 8 +++++++- tests/ui/runtime/backtrace-debuginfo.rs | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 568335f7dcb51..effd29d79d7ad 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -347,7 +347,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( // option causes bugs in the LLVM WebAssembly backend. You should be able to // remove this check when Rust's minimum supported LLVM version is >= 18 // https://github.com/llvm/llvm-project/pull/65876 - if (!Trip.isWasm()) { + // + // Also keep traps after noreturn calls on Windows, because the trap is + // needed to keep the return address within the calling function's + // .pdata range. Without it, RtlLookupFunctionEntry resolves the wrong + // function and SEH unwinding (used for backtraces) terminates early. + // See https://github.com/rust-lang/rust/issues/140489 + if (!Trip.isWasm() && !Trip.isOSWindows()) { Options.NoTrapAfterNoreturn = true; } } diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs index d3b4d057e6d0f..cc6132495f4ce 100644 --- a/tests/ui/runtime/backtrace-debuginfo.rs +++ b/tests/ui/runtime/backtrace-debuginfo.rs @@ -47,14 +47,9 @@ macro_rules! dump_and_die { // there, even on i686-pc-windows-msvc. We do the best we can in // rust-lang/rust to test it as well, but sometimes we just gotta keep // landing PRs. - // - // aarch64-msvc/arm64ec-msvc is broken as its backtraces are truncated. - // See https://github.com/rust-lang/rust/issues/140489 if cfg!(any(target_os = "android", all(target_os = "linux", target_arch = "arm"), all(target_env = "msvc", target_arch = "x86"), - all(target_env = "msvc", target_arch = "aarch64"), - all(target_env = "msvc", target_arch = "arm64ec"), target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")) { From 71a31b30d91c02e0fffe86843481c9fecd6c8fce Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 5 Mar 2026 14:46:07 +0000 Subject: [PATCH 2/4] Always use the ThinLTO pipeline for pre-link optimizations When using cargo this was already effectively done for all dependencies as cargo passes -Clinker-plugin-lto without -Clto=fat/thin. -Clinker-plugin-lto assumes that ThinLTO will be used. The ThinLTO pre-link pipeline is faster than the fat LTO one. And according to the benchmarks in [1] there is barely any runtime performance difference between executables that used fat LTO with the fat vs ThinLTO pre-link pipeline. [1]: https://discourse.llvm.org/t/rfc-a-unified-lto-bitcode-frontend/61774 --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 568335f7dcb51..f42624700b596 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -840,11 +840,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( } break; case LLVMRustOptStage::PreLinkThinLTO: - MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel); - NeedThinLTOBufferPasses = false; - break; case LLVMRustOptStage::PreLinkFatLTO: - MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel); + MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel); NeedThinLTOBufferPasses = false; break; case LLVMRustOptStage::ThinLTO: From 4d314065a4e3e8d9b6823948c98a3441f5e2b55a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 5 Mar 2026 13:40:20 +0100 Subject: [PATCH 3/4] Revert "library/test: always enable unstable features for miri" This reverts commit 30d7ed4c472d61258a6ec3c84c2daef23d9e7296. It should not be needed any more. --- library/test/build.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/library/test/build.rs b/library/test/build.rs index 3f7a5c16e5b1e..8e31adbf2ca74 100644 --- a/library/test/build.rs +++ b/library/test/build.rs @@ -2,16 +2,11 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rustc-check-cfg=cfg(enable_unstable_features)"); - // Miri testing uses unstable features, so always enable that for its sysroot. - // Otherwise, only enable unstable if rustc looks like a nightly or dev build. - let enable_unstable_features = std::env::var("MIRI_CALLED_FROM_SETUP").is_ok() || { - let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); - let version = std::process::Command::new(rustc).arg("-vV").output().unwrap(); - let stdout = String::from_utf8(version.stdout).unwrap(); - stdout.contains("nightly") || stdout.contains("dev") - }; + let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); + let version = std::process::Command::new(rustc).arg("-vV").output().unwrap(); + let stdout = String::from_utf8(version.stdout).unwrap(); - if enable_unstable_features { + if stdout.contains("nightly") || stdout.contains("dev") { println!("cargo:rustc-cfg=enable_unstable_features"); } } From 6b7dbff2356b7dccc078c374ddcfad710d03810a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 5 Mar 2026 22:09:35 +0100 Subject: [PATCH 4/4] coretest in miri: fix using unstable libtest features --- src/bootstrap/src/core/build_steps/test.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 88f10775333d4..3b0e7b2e30afe 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -741,7 +741,13 @@ impl Step for Miri { // Run it again for mir-opt-level 4 to catch some miscompilations. if builder.config.test_args().is_empty() { - cargo.env("MIRIFLAGS", "-O -Zmir-opt-level=4 -Cdebug-assertions=yes"); + cargo.env( + "MIRIFLAGS", + format!( + "{} -O -Zmir-opt-level=4 -Cdebug-assertions=yes", + env::var("MIRIFLAGS").unwrap_or_default() + ), + ); // Optimizations can change backtraces cargo.env("MIRI_SKIP_UI_CHECKS", "1"); // `MIRI_SKIP_UI_CHECKS` and `RUSTC_BLESS` are incompatible @@ -3108,6 +3114,17 @@ impl Step for Crate { // does not set this directly, but relies on the rustc wrapper to set it, and we are not using // the wrapper -- hence we have to set it ourselves. cargo.rustflag("-Zforce-unstable-if-unmarked"); + // Miri is told to invoke the libtest runner and bootstrap sets unstable flags + // for that runner. That only works when RUSTC_BOOTSTRAP is set. Bootstrap sets + // that flag but Miri by default does not forward the host environment to the test. + // Here we set up MIRIFLAGS to forward that env var. + cargo.env( + "MIRIFLAGS", + format!( + "{} -Zmiri-env-forward=RUSTC_BOOTSTRAP", + env::var("MIRIFLAGS").unwrap_or_default() + ), + ); cargo } else { // Also prepare a sysroot for the target.