From f0fd9cdffd72659ec6308fa92e81dbb895e18e3e Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Thu, 21 Aug 2025 16:21:28 -0400 Subject: [PATCH 01/17] implement Extend<{Group, Literal, Punct, Ident}> for TokenStream --- library/proc_macro/src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 162b4fdcc8ae2..8178af15b7393 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -377,6 +377,21 @@ impl Extend for TokenStream { } } +macro_rules! extend_items { + ($($item:ident)*) => { + $( + #[stable(feature = "token_stream_extend_tt_items", since = "CURRENT_RUSTC_VERSION")] + impl Extend<$item> for TokenStream { + fn extend>(&mut self, iter: T) { + self.extend(iter.into_iter().map(|i| TokenTree::$item(i))); + } + } + )* + }; +} + +extend_items!(Group Literal Punct Ident); + /// Public implementation details for the `TokenStream` type, such as iterators. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub mod token_stream { From ff7081e6e25be74671d2fe775fe25a1015e4b32a Mon Sep 17 00:00:00 2001 From: Jeremy Smart Date: Tue, 26 Aug 2025 17:10:08 +0000 Subject: [PATCH 02/17] Update library/proc_macro/src/lib.rs Co-authored-by: David Tolnay --- library/proc_macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 8178af15b7393..97dc482689781 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -383,7 +383,7 @@ macro_rules! extend_items { #[stable(feature = "token_stream_extend_tt_items", since = "CURRENT_RUSTC_VERSION")] impl Extend<$item> for TokenStream { fn extend>(&mut self, iter: T) { - self.extend(iter.into_iter().map(|i| TokenTree::$item(i))); + self.extend(iter.into_iter().map(TokenTree::$item)); } } )* From 215c936aa0abd6a11daa8c4313f391163f15d6b8 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 7 Sep 2025 18:39:36 +0100 Subject: [PATCH 03/17] Promote armv7a-none-eabihf to Tier 2 This is the target for 32-bit Cortex-A bare-metal, when using the FPU. The target is well tested by the Embedded Devices Working Group, and the soft-float target (armv7a-none-eabi) is already Tier 2. --- compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs | 2 +- src/doc/rustc/src/platform-support.md | 2 +- src/doc/rustc/src/platform-support/armv7a-none-eabi.md | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index df3a76599a753..217a79d4571e9 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -30,7 +30,7 @@ pub(crate) fn target() -> Target { llvm_target: "armv7a-none-eabihf".into(), metadata: TargetMetadata { description: Some("Bare Armv7-A, hardfloat".into()), - tier: Some(3), + tier: Some(2), host_tools: Some(false), std: Some(false), }, diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e5e46f7263751..a0a228cad2a0f 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -165,6 +165,7 @@ target | std | notes `armv7-unknown-linux-musleabi` | ✓ | Armv7-A Linux with musl 1.2.3 `armv7-unknown-linux-musleabihf` | ✓ | Armv7-A Linux with musl 1.2.3, hardfloat [`armv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A +[`armv7a-none-eabihf`](platform-support/armv7a-none-eabi.md) | * | | Bare Armv7-A, hardfloat [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87] @@ -300,7 +301,6 @@ target | std | host | notes [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat -[`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * | | Bare Armv7-A, hardfloat [`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | ? | | Armv7-A Cortex-A9 VEX V5 Brain, VEXos [`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS [`armv7s-apple-ios`](platform-support/apple-ios.md) | ✓ | | Armv7-A Apple-A6 Apple iOS diff --git a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md index 3dadda86a5f54..4eeee6ae2c907 100644 --- a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md @@ -1,7 +1,6 @@ # `armv7a-none-eabi` and `armv7a-none-eabihf` -* **Tier: 2** for `armv7a-none-eabi` -* **Tier: 3** for `armv7a-none-eabihf` +* **Tier: 2** * **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv7-A architecture family, supporting From 89a5bb618050813e681fadea739a71fb6e629f24 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sun, 7 Sep 2025 18:37:38 +0100 Subject: [PATCH 04/17] Raise armv8r-none-eabihf to Tier 2 This is the target for supporting Arm Cortex-R52 bare-metal systems, which are common in safety-critical systems. --- src/doc/rustc/src/platform-support.md | 2 +- src/doc/rustc/src/platform-support/armv8r-none-eabihf.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e5e46f7263751..6fb1c78d3f31e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -167,6 +167,7 @@ target | std | notes [`armv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat +[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat `i586-unknown-linux-gnu` | ✓ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87] `i586-unknown-linux-musl` | ✓ | 32-bit Linux (musl 1.2.3, original Pentium) [^x86_32-floats-x87] [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android ([Pentium 4 plus various extensions](https://developer.android.com/ndk/guides/abis.html#x86)) [^x86_32-floats-return-ABI] @@ -304,7 +305,6 @@ target | std | host | notes [`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | ? | | Armv7-A Cortex-A9 VEX V5 Brain, VEXos [`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS [`armv7s-apple-ios`](platform-support/apple-ios.md) | ✓ | | Armv7-A Apple-A6 Apple iOS -[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat [`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX [`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat [`avr-none`](platform-support/avr-none.md) | * | | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...` diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index 0d5a36c3ee2d6..47186fdb2cdb8 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -1,6 +1,6 @@ # `armv8r-none-eabihf` -* **Tier: 3** +* **Tier: 2** * **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv8-R architecture family, supporting From bfddf29524878bb4ca9b43ab1912b440f3023c43 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Sat, 13 Sep 2025 20:16:32 +0100 Subject: [PATCH 05/17] Update target spec to say Tier 2. --- compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index 8cf1ff9575168..d6e3a03bbba8b 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { llvm_target: "armv8r-none-eabihf".into(), metadata: TargetMetadata { description: Some("Bare Armv8-R, hardfloat".into()), - tier: Some(3), + tier: Some(2), host_tools: Some(false), std: Some(false), }, From d6fdadb8e93401b4c98763e90c2e181390d0bfd5 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 3 Oct 2025 00:00:39 -0400 Subject: [PATCH 06/17] Mitigate `thread_local!` shadowing issues Mitigates https://github.com/rust-lang/rust/issues/147006 and https://github.com/rust-lang/rust/issues/99018 --- .../std/src/sys/thread_local/native/mod.rs | 26 +++++++++---------- .../std/src/sys/thread_local/no_threads.rs | 16 ++++++------ library/std/src/sys/thread_local/os.rs | 8 +++--- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/library/std/src/sys/thread_local/native/mod.rs b/library/std/src/sys/thread_local/native/mod.rs index 5dc142408047e..38b373be56c9d 100644 --- a/library/std/src/sys/thread_local/native/mod.rs +++ b/library/std/src/sys/thread_local/native/mod.rs @@ -55,7 +55,7 @@ pub macro thread_local_inner { // Used to generate the `LocalKey` value for const-initialized thread locals. (@key $t:ty, $(#[$align_attr:meta])*, const $init:expr) => {{ - const __INIT: $t = $init; + const __RUST_STD_INTERNAL_INIT: $t = $init; unsafe { $crate::thread::LocalKey::new(const { @@ -63,16 +63,16 @@ pub macro thread_local_inner { |_| { #[thread_local] $(#[$align_attr])* - static VAL: $crate::thread::local_impl::EagerStorage<$t> - = $crate::thread::local_impl::EagerStorage::new(__INIT); - VAL.get() + static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::EagerStorage<$t> + = $crate::thread::local_impl::EagerStorage::new(__RUST_STD_INTERNAL_INIT); + __RUST_STD_INTERNAL_VAL.get() } } else { |_| { #[thread_local] $(#[$align_attr])* - static VAL: $t = __INIT; - &VAL + static __RUST_STD_INTERNAL_VAL: $t = __RUST_STD_INTERNAL_INIT; + &__RUST_STD_INTERNAL_VAL } } }) @@ -82,27 +82,27 @@ pub macro thread_local_inner { // used to generate the `LocalKey` value for `thread_local!` (@key $t:ty, $(#[$align_attr:meta])*, $init:expr) => {{ #[inline] - fn __init() -> $t { + fn __rust_std_internal_init_fn() -> $t { $init } unsafe { $crate::thread::LocalKey::new(const { if $crate::mem::needs_drop::<$t>() { - |init| { + |__rust_std_internal_init| { #[thread_local] $(#[$align_attr])* - static VAL: $crate::thread::local_impl::LazyStorage<$t, ()> + static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::LazyStorage<$t, ()> = $crate::thread::local_impl::LazyStorage::new(); - VAL.get_or_init(init, __init) + __RUST_STD_INTERNAL_VAL.get_or_init(__rust_std_internal_init, __rust_std_internal_init_fn) } } else { - |init| { + |__rust_std_internal_init| { #[thread_local] $(#[$align_attr])* - static VAL: $crate::thread::local_impl::LazyStorage<$t, !> + static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::LazyStorage<$t, !> = $crate::thread::local_impl::LazyStorage::new(); - VAL.get_or_init(init, __init) + __RUST_STD_INTERNAL_VAL.get_or_init(__rust_std_internal_init, __rust_std_internal_init_fn) } } }) diff --git a/library/std/src/sys/thread_local/no_threads.rs b/library/std/src/sys/thread_local/no_threads.rs index 409dfb19518d9..936d464be9f1c 100644 --- a/library/std/src/sys/thread_local/no_threads.rs +++ b/library/std/src/sys/thread_local/no_threads.rs @@ -13,15 +13,15 @@ use crate::ptr; pub macro thread_local_inner { // used to generate the `LocalKey` value for const-initialized thread locals (@key $t:ty, $(#[$align_attr:meta])*, const $init:expr) => {{ - const __INIT: $t = $init; + const __RUST_STD_INTERNAL_INIT: $t = $init; // NOTE: Please update the shadowing test in `tests/thread.rs` if these types are renamed. unsafe { $crate::thread::LocalKey::new(|_| { $(#[$align_attr])* - static VAL: $crate::thread::local_impl::EagerStorage<$t> = - $crate::thread::local_impl::EagerStorage { value: __INIT }; - &VAL.value + static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::EagerStorage<$t> = + $crate::thread::local_impl::EagerStorage { value: __RUST_STD_INTERNAL_INIT }; + &__RUST_STD_INTERNAL_VAL.value }) } }}, @@ -29,13 +29,13 @@ pub macro thread_local_inner { // used to generate the `LocalKey` value for `thread_local!` (@key $t:ty, $(#[$align_attr:meta])*, $init:expr) => {{ #[inline] - fn __init() -> $t { $init } + fn __rust_std_internal_init_fn() -> $t { $init } unsafe { - $crate::thread::LocalKey::new(|init| { + $crate::thread::LocalKey::new(|__rust_std_internal_init| { $(#[$align_attr])* - static VAL: $crate::thread::local_impl::LazyStorage<$t> = $crate::thread::local_impl::LazyStorage::new(); - VAL.get(init, __init) + static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::LazyStorage<$t> = $crate::thread::local_impl::LazyStorage::new(); + __RUST_STD_INTERNAL_VAL.get(__rust_std_internal_init, __rust_std_internal_init_fn) }) } }}, diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 88bb5ae7c650d..9f7a29236e926 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -21,14 +21,14 @@ pub macro thread_local_inner { // used to generate the `LocalKey` value for `thread_local!`. (@key $t:ty, $($(#[$($align_attr:tt)*])+)?, $init:expr) => {{ #[inline] - fn __init() -> $t { $init } + fn __rust_std_internal_init_fn() -> $t { $init } // NOTE: this cannot import `LocalKey` or `Storage` with a `use` because that can shadow // user provided type or type alias with a matching name. Please update the shadowing test // in `tests/thread.rs` if these types are renamed. unsafe { - $crate::thread::LocalKey::new(|init| { - static VAL: $crate::thread::local_impl::Storage<$t, { + $crate::thread::LocalKey::new(|__rust_std_internal_init| { + static __RUST_STD_INTERNAL_VAL: $crate::thread::local_impl::Storage<$t, { $({ // Ensure that attributes have valid syntax // and that the proper feature gate is enabled @@ -43,7 +43,7 @@ pub macro thread_local_inner { final_align }> = $crate::thread::local_impl::Storage::new(); - VAL.get(init, __init) + __RUST_STD_INTERNAL_VAL.get(__rust_std_internal_init, __rust_std_internal_init_fn) }) } }}, From f3f83857d928d931171339910f37900fd5f03283 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 8 Oct 2025 21:08:40 +1100 Subject: [PATCH 07/17] Use the same directive lines for EarlyProps and ignore/only/needs --- src/tools/compiletest/src/directives.rs | 58 ++++++++----------- src/tools/compiletest/src/directives/file.rs | 24 ++++++++ src/tools/compiletest/src/directives/tests.rs | 12 ++-- src/tools/compiletest/src/lib.rs | 11 ++-- 4 files changed, 62 insertions(+), 43 deletions(-) create mode 100644 src/tools/compiletest/src/directives/file.rs diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 34a9d77ce0dfa..c96a1be38fee3 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -12,6 +12,7 @@ use crate::directives::auxiliary::{AuxProps, parse_and_update_aux}; use crate::directives::directive_names::{ KNOWN_DIRECTIVE_NAMES, KNOWN_HTMLDOCCK_DIRECTIVE_NAMES, KNOWN_JSONDOCCK_DIRECTIVE_NAMES, }; +pub(crate) use crate::directives::file::FileDirectives; use crate::directives::line::{DirectiveLine, line_directive}; use crate::directives::needs::CachedNeedsConditions; use crate::edition::{Edition, parse_edition}; @@ -23,6 +24,7 @@ use crate::{fatal, help}; pub(crate) mod auxiliary; mod cfg; mod directive_names; +mod file; mod line; mod needs; #[cfg(test)] @@ -41,31 +43,29 @@ impl DirectivesCache { /// Properties which must be known very early, before actually running /// the test. #[derive(Default)] -pub struct EarlyProps { +pub(crate) struct EarlyProps { /// Auxiliary crates that should be built and made available to this test. /// Included in [`EarlyProps`] so that the indicated files can participate /// in up-to-date checking. Building happens via [`TestProps::aux`] instead. pub(crate) aux: AuxProps, - pub revisions: Vec, + pub(crate) revisions: Vec, } impl EarlyProps { - pub fn from_file(config: &Config, testfile: &Utf8Path) -> Self { - let file_contents = - fs::read_to_string(testfile).expect("read test file to parse earlyprops"); - Self::from_file_contents(config, testfile, &file_contents) - } - - pub fn from_file_contents(config: &Config, testfile: &Utf8Path, file_contents: &str) -> Self { + pub(crate) fn from_file_directives( + config: &Config, + file_directives: &FileDirectives<'_>, + ) -> Self { + let testfile = file_directives.path; let mut props = EarlyProps::default(); let mut poisoned = false; + iter_directives( config.mode, &mut poisoned, - testfile, - file_contents, + file_directives, // (dummy comment to force args into vertical layout) - &mut |ref ln: DirectiveLine<'_>| { + &mut |ln: &DirectiveLine<'_>| { parse_and_update_aux(config, ln, testfile, &mut props.aux); config.parse_and_update_revisions(testfile, ln, &mut props.revisions); }, @@ -358,15 +358,15 @@ impl TestProps { let mut has_edition = false; if !testfile.is_dir() { let file_contents = fs::read_to_string(testfile).unwrap(); + let file_directives = FileDirectives::from_file_contents(testfile, &file_contents); let mut poisoned = false; iter_directives( config.mode, &mut poisoned, - testfile, - &file_contents, - &mut |ref ln: DirectiveLine<'_>| { + &file_directives, + &mut |ln: &DirectiveLine<'_>| { if !ln.applies_to_test_revision(test_revision) { return; } @@ -851,13 +851,10 @@ fn check_directive<'a>( fn iter_directives( mode: TestMode, poisoned: &mut bool, - testfile: &Utf8Path, - file_contents: &str, - it: &mut dyn FnMut(DirectiveLine<'_>), + file_directives: &FileDirectives<'_>, + it: &mut dyn FnMut(&DirectiveLine<'_>), ) { - if testfile.is_dir() { - return; - } + let testfile = file_directives.path; // Coverage tests in coverage-run mode always have these extra directives, without needing to // specify them manually in every test file. @@ -875,21 +872,15 @@ fn iter_directives( for directive_str in extra_directives { let directive_line = line_directive(0, directive_str) .unwrap_or_else(|| panic!("bad extra-directive line: {directive_str:?}")); - it(directive_line); + it(&directive_line); } } - for (line_number, ln) in (1..).zip(file_contents.lines()) { - let ln = ln.trim(); - - let Some(directive_line) = line_directive(line_number, ln) else { - continue; - }; - + for directive_line @ &DirectiveLine { line_number, .. } in &file_directives.lines { // Perform unknown directive check on Rust files. if testfile.extension() == Some("rs") { let CheckDirectiveResult { is_known_directive, trailing_directive } = - check_directive(&directive_line, mode); + check_directive(directive_line, mode); if !is_known_directive { *poisoned = true; @@ -1349,7 +1340,7 @@ pub(crate) fn make_test_description( name: String, path: &Utf8Path, filterable_path: &Utf8Path, - file_contents: &str, + file_directives: &FileDirectives<'_>, test_revision: Option<&str>, poisoned: &mut bool, ) -> CollectedTestDesc { @@ -1363,9 +1354,8 @@ pub(crate) fn make_test_description( iter_directives( config.mode, &mut local_poisoned, - path, - file_contents, - &mut |ref ln @ DirectiveLine { line_number, .. }| { + file_directives, + &mut |ln @ &DirectiveLine { line_number, .. }| { if !ln.applies_to_test_revision(test_revision) { return; } diff --git a/src/tools/compiletest/src/directives/file.rs b/src/tools/compiletest/src/directives/file.rs new file mode 100644 index 0000000000000..afb9bb188bd39 --- /dev/null +++ b/src/tools/compiletest/src/directives/file.rs @@ -0,0 +1,24 @@ +use camino::Utf8Path; + +use crate::directives::line::{DirectiveLine, line_directive}; + +pub(crate) struct FileDirectives<'a> { + pub(crate) path: &'a Utf8Path, + pub(crate) lines: Vec>, +} + +impl<'a> FileDirectives<'a> { + pub(crate) fn from_file_contents(path: &'a Utf8Path, file_contents: &'a str) -> Self { + let mut lines = vec![]; + + for (line_number, ln) in (1..).zip(file_contents.lines()) { + let ln = ln.trim(); + + if let Some(directive_line) = line_directive(line_number, ln) { + lines.push(directive_line); + } + } + + Self { path, lines } + } +} diff --git a/src/tools/compiletest/src/directives/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 77080c7469371..4e7ae6de76a52 100644 --- a/src/tools/compiletest/src/directives/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -3,7 +3,7 @@ use semver::Version; use crate::common::{Config, Debugger, TestMode}; use crate::directives::{ - DirectivesCache, EarlyProps, Edition, EditionRange, extract_llvm_version, + DirectivesCache, EarlyProps, Edition, EditionRange, FileDirectives, extract_llvm_version, extract_version_range, iter_directives, line_directive, parse_edition, parse_normalize_rule, }; use crate::executor::{CollectedTestDesc, ShouldPanic}; @@ -18,13 +18,15 @@ fn make_test_description( ) -> CollectedTestDesc { let cache = DirectivesCache::load(config); let mut poisoned = false; + let file_directives = FileDirectives::from_file_contents(path, file_contents); + let test = crate::directives::make_test_description( config, &cache, name, path, filterable_path, - file_contents, + &file_directives, revision, &mut poisoned, ); @@ -224,7 +226,8 @@ fn cfg() -> ConfigBuilder { } fn parse_rs(config: &Config, contents: &str) -> EarlyProps { - EarlyProps::from_file_contents(config, Utf8Path::new("a.rs"), contents) + let file_directives = FileDirectives::from_file_contents(Utf8Path::new("a.rs"), contents); + EarlyProps::from_file_directives(config, &file_directives) } fn check_ignore(config: &Config, contents: &str) -> bool { @@ -776,7 +779,8 @@ fn threads_support() { } fn run_path(poisoned: &mut bool, path: &Utf8Path, file_contents: &str) { - iter_directives(TestMode::Ui, poisoned, path, file_contents, &mut |_| {}); + let file_directives = FileDirectives::from_file_contents(path, file_contents); + iter_directives(TestMode::Ui, poisoned, &file_directives, &mut |_| {}); } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 48ae38b61b93d..4cfb1e20f9ae9 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -41,7 +41,7 @@ use crate::common::{ CodegenBackend, CompareMode, Config, Debugger, PassMode, TestMode, TestPaths, UI_EXTENSIONS, expected_output_path, output_base_dir, output_relative_path, }; -use crate::directives::DirectivesCache; +use crate::directives::{DirectivesCache, FileDirectives}; use crate::edition::parse_edition; use crate::executor::{CollectedTest, ColorConfig}; @@ -868,7 +868,10 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te }; // Scan the test file to discover its revisions, if any. - let early_props = EarlyProps::from_file(&cx.config, &test_path); + let file_contents = + fs::read_to_string(&test_path).expect("reading test file for directives should succeed"); + let file_directives = FileDirectives::from_file_contents(&test_path, &file_contents); + let early_props = EarlyProps::from_file_directives(&cx.config, &file_directives); // Normally we create one structure per revision, with two exceptions: // - If a test doesn't use revisions, create a dummy revision (None) so that @@ -886,8 +889,6 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te // `CollectedTest` that can be handed over to the test executor. collector.tests.extend(revisions.into_iter().map(|revision| { // Create a test name and description to hand over to the executor. - let file_contents = - fs::read_to_string(&test_path).expect("read test file to parse ignores"); let (test_name, filterable_path) = make_test_name_and_filterable_path(&cx.config, testpaths, revision); // Create a description struct for the test/revision. @@ -899,7 +900,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te test_name, &test_path, &filterable_path, - &file_contents, + &file_directives, revision, &mut collector.poisoned, ); From 690071c28a6fbce6cc1f6d958a8f60a5cd1b80be Mon Sep 17 00:00:00 2001 From: dianqk Date: Thu, 9 Oct 2025 20:14:21 +0800 Subject: [PATCH 08/17] Add regression test for 147485 --- tests/crashes/147485-2.rs | 16 +++++++++ tests/crashes/147485.rs | 14 ++++++++ ...buginfo_locals.DestinationPropagation.diff | 35 ++++++++++++++++++ tests/mir-opt/debuginfo/dest_prop.rs | 36 +++++++++++++++++++ ...debuginfo_locals.ReferencePropagation.diff | 33 +++++++++++++++++ tests/mir-opt/debuginfo/ref_prop.rs | 26 ++++++++++++++ 6 files changed, 160 insertions(+) create mode 100644 tests/crashes/147485-2.rs create mode 100644 tests/crashes/147485.rs create mode 100644 tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff create mode 100644 tests/mir-opt/debuginfo/dest_prop.rs create mode 100644 tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff create mode 100644 tests/mir-opt/debuginfo/ref_prop.rs diff --git a/tests/crashes/147485-2.rs b/tests/crashes/147485-2.rs new file mode 100644 index 0000000000000..da092a3af76aa --- /dev/null +++ b/tests/crashes/147485-2.rs @@ -0,0 +1,16 @@ +//@ known-bug: #147485 +//@ compile-flags: -g -O + +#![crate_type = "lib"] + +pub fn foo(a: bool, b: bool) -> bool { + let mut c = &a; + if false { + return *c; + } + let d = b && a; + if d { + c = &b; + } + b +} diff --git a/tests/crashes/147485.rs b/tests/crashes/147485.rs new file mode 100644 index 0000000000000..86f3705e636b4 --- /dev/null +++ b/tests/crashes/147485.rs @@ -0,0 +1,14 @@ +//@ known-bug: #147485 +//@ compile-flags: -g -O + +#![crate_type = "lib"] + +pub fn f(x: *const usize) -> &'static usize { + let mut a = unsafe { &*x }; + a = unsafe { &*x }; + a +} + +pub fn g() { + f(&0); +} diff --git a/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff b/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff new file mode 100644 index 0000000000000..6f3233d85c9fc --- /dev/null +++ b/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff @@ -0,0 +1,35 @@ +- // MIR for `remap_debuginfo_locals` before DestinationPropagation ++ // MIR for `remap_debuginfo_locals` after DestinationPropagation + + fn remap_debuginfo_locals(_1: bool, _2: &bool) -> &bool { +- debug c => _3; ++ debug c => _2; + let mut _0: &bool; + let mut _3: &bool; + let mut _4: bool; + + bb0: { + // DBG: _3 = &_1; +- StorageLive(_4); +- _4 = copy _1; +- _3 = copy _2; +- switchInt(copy _4) -> [1: bb1, otherwise: bb2]; ++ nop; ++ nop; ++ nop; ++ switchInt(copy _1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + goto -> bb2; + } + + bb2: { +- StorageDead(_4); +- _0 = copy _3; ++ nop; ++ _0 = copy _2; + return; + } + } + diff --git a/tests/mir-opt/debuginfo/dest_prop.rs b/tests/mir-opt/debuginfo/dest_prop.rs new file mode 100644 index 0000000000000..9c9d95ebfb3f3 --- /dev/null +++ b/tests/mir-opt/debuginfo/dest_prop.rs @@ -0,0 +1,36 @@ +// skip-filecheck +//@ test-mir-pass: DestinationPropagation +//@ compile-flags: -g -Zmir-enable-passes=+DeadStoreElimination-initial + +#![feature(core_intrinsics, custom_mir)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// EMIT_MIR dest_prop.remap_debuginfo_locals.DestinationPropagation.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn remap_debuginfo_locals(a: bool, b: &bool) -> &bool { + mir! { + let _3: &bool; + let _4: bool; + debug c => _3; + { + _3 = &a; + StorageLive(_4); + _4 = a; + _3 = b; + match _4 { + true => bb1, + _ => bb2, + } + } + bb1 = { + Goto(bb2) + } + bb2 = { + StorageDead(_4); + RET = _3; + Return() + } + } +} diff --git a/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff b/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff new file mode 100644 index 0000000000000..87941aadab4dd --- /dev/null +++ b/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff @@ -0,0 +1,33 @@ +- // MIR for `remap_debuginfo_locals` before ReferencePropagation ++ // MIR for `remap_debuginfo_locals` after ReferencePropagation + + fn remap_debuginfo_locals() -> () { + let mut _0: (); + let _1: &usize; + let mut _2: *const usize; + let _3: &usize; + let _4: usize; + let mut _5: &usize; + scope 1 (inlined foo) { +- debug a => _1; ++ debug a => _5; + } + + bb0: { +- StorageLive(_1); +- StorageLive(_2); +- StorageLive(_3); + _5 = const remap_debuginfo_locals::promoted[0]; +- _3 = &(*_5); +- _2 = &raw const (*_3); +- // DBG: _1 = &(*_2); +- _1 = &(*_2); +- StorageDead(_2); +- StorageDead(_3); +- StorageDead(_1); ++ // DBG: _1 = &(*_5); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/ref_prop.rs b/tests/mir-opt/debuginfo/ref_prop.rs new file mode 100644 index 0000000000000..5f2f1ce09c707 --- /dev/null +++ b/tests/mir-opt/debuginfo/ref_prop.rs @@ -0,0 +1,26 @@ +// skip-filecheck +//@ test-mir-pass: ReferencePropagation +//@ compile-flags: -g -Zub_checks=false -Zinline-mir -Zmir-enable-passes=+DeadStoreElimination-initial + +#![feature(core_intrinsics, custom_mir)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// EMIT_MIR ref_prop.remap_debuginfo_locals.ReferencePropagation.diff +pub fn remap_debuginfo_locals() { + foo(&0); +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +#[inline] +fn foo(x: *const usize) -> &'static usize { + mir! { + debug a => RET; + { + RET = &*x; + RET = &*x; + Return() + } + } +} From 9462e7301fb831f011b927494fd74c9f31c24b9b Mon Sep 17 00:00:00 2001 From: dianqk Date: Thu, 9 Oct 2025 21:32:23 +0800 Subject: [PATCH 09/17] MIR validation: ensure that debuginfo records are not emitted for locals that are not in debuginfo --- compiler/rustc_mir_transform/src/validate.rs | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 95873484b6529..6790dda780c5d 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::{ self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance, }; use rustc_middle::{bug, span_bug}; +use rustc_mir_dataflow::debuginfo::debuginfo_locals; use rustc_trait_selection::traits::ObligationCtxt; use crate::util::{self, is_within_packed}; @@ -80,6 +81,11 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { cfg_checker.fail(location, msg); } + // Ensure that debuginfo records are not emitted for locals that are not in debuginfo. + for (location, msg) in validate_debuginfos(body) { + cfg_checker.fail(location, msg); + } + if let MirPhase::Runtime(_) = body.phase && let ty::InstanceKind::Item(_) = body.source.instance && body.has_free_regions() @@ -1595,3 +1601,30 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.super_terminator(terminator, location); } } + +pub(super) fn validate_debuginfos<'tcx>(body: &Body<'tcx>) -> Vec<(Location, String)> { + let mut debuginfo_checker = + DebuginfoChecker { debuginfo_locals: debuginfo_locals(body), failures: Vec::new() }; + debuginfo_checker.visit_body(body); + debuginfo_checker.failures +} + +struct DebuginfoChecker { + debuginfo_locals: DenseBitSet, + failures: Vec<(Location, String)>, +} + +impl<'tcx> Visitor<'tcx> for DebuginfoChecker { + fn visit_statement_debuginfo( + &mut self, + stmt_debuginfo: &StmtDebugInfo<'tcx>, + location: Location, + ) { + let local = match stmt_debuginfo { + StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => *local, + }; + if !self.debuginfo_locals.contains(local) { + self.failures.push((location, format!("{local:?} is not in debuginfo"))); + } + } +} From b2e81b00e5cd6f0ad7f883413b983b2c6e25c25e Mon Sep 17 00:00:00 2001 From: dianqk Date: Thu, 9 Oct 2025 21:53:05 +0800 Subject: [PATCH 10/17] Replace locals in debuginfo records during ref_prop --- compiler/rustc_middle/src/mir/visit.rs | 8 ++-- compiler/rustc_mir_transform/src/ref_prop.rs | 45 +++++++++++++++---- ...debuginfo_locals.ReferencePropagation.diff | 2 +- tests/mir-opt/debuginfo/ref_prop.rs | 6 ++- .../debuginfo/ref_prop_debuginfo-147485.rs} | 4 +- 5 files changed, 49 insertions(+), 16 deletions(-) rename tests/{crashes/147485.rs => ui/debuginfo/ref_prop_debuginfo-147485.rs} (79%) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 9654e189f2edf..29cf3977dc807 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1098,6 +1098,10 @@ macro_rules! super_body { } } + for var_debug_info in &$($mutability)? $body.var_debug_info { + $self.visit_var_debug_info(var_debug_info); + } + for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) { $self.visit_basic_block_data(bb, data); } @@ -1127,10 +1131,6 @@ macro_rules! super_body { ); } - for var_debug_info in &$($mutability)? $body.var_debug_info { - $self.visit_var_debug_info(var_debug_info); - } - $self.visit_span($(& $mutability)? $body.span); if let Some(required_consts) = &$($mutability)? $body.required_consts { diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index deb0a146476c3..c5b53dbbd309b 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -302,6 +302,7 @@ fn compute_replacement<'tcx>( return Replacer { tcx, targets: finder.targets, + remap_var_debug_infos: IndexVec::from_elem(None, body.local_decls()), storage_to_remove, allowed_replacements, any_replacement: false, @@ -381,6 +382,7 @@ fn fully_replaceable_locals(ssa: &SsaLocals) -> DenseBitSet { struct Replacer<'tcx> { tcx: TyCtxt<'tcx>, targets: IndexVec>, + remap_var_debug_infos: IndexVec>, storage_to_remove: DenseBitSet, allowed_replacements: FxHashSet<(Local, Location)>, any_replacement: bool, @@ -392,21 +394,45 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { } fn visit_var_debug_info(&mut self, debuginfo: &mut VarDebugInfo<'tcx>) { - // If the debuginfo is a pointer to another place - // and it's a reborrow: see through it - while let VarDebugInfoContents::Place(ref mut place) = debuginfo.value + if let VarDebugInfoContents::Place(ref mut place) = debuginfo.value && place.projection.is_empty() - && let Value::Pointer(target, _) = self.targets[place.local] - && let &[PlaceElem::Deref] = &target.projection[..] { - *place = Place::from(target.local); - self.any_replacement = true; + let mut new_local = place.local; + + // If the debuginfo is a pointer to another place + // and it's a reborrow: see through it + while let Value::Pointer(target, _) = self.targets[new_local] + && let &[PlaceElem::Deref] = &target.projection[..] + { + new_local = target.local; + } + if place.local != new_local { + self.remap_var_debug_infos[place.local] = Some(new_local); + place.local = new_local; + + self.any_replacement = true; + } } // Simplify eventual projections left inside `debuginfo`. self.super_var_debug_info(debuginfo); } + fn visit_statement_debuginfo( + &mut self, + stmt_debuginfo: &mut StmtDebugInfo<'tcx>, + location: Location, + ) { + let local = match stmt_debuginfo { + StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => local, + }; + if let Some(target) = self.remap_var_debug_infos[*local] { + *local = target; + self.any_replacement = true; + } + self.super_statement_debuginfo(stmt_debuginfo, location); + } + fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) { loop { let Some((&PlaceElem::Deref, rest)) = place.projection.split_first() else { return }; @@ -437,8 +463,9 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> { { stmt.make_nop(true); } - // Do not remove assignments as they may still be useful for debuginfo. - _ => self.super_statement(stmt, loc), + _ => {} } + // Do not remove assignments as they may still be useful for debuginfo. + self.super_statement(stmt, loc); } } diff --git a/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff b/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff index 87941aadab4dd..2d93b1d842fa1 100644 --- a/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff +++ b/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff @@ -25,7 +25,7 @@ - StorageDead(_2); - StorageDead(_3); - StorageDead(_1); -+ // DBG: _1 = &(*_5); ++ // DBG: _5 = &(*_5); _0 = const (); return; } diff --git a/tests/mir-opt/debuginfo/ref_prop.rs b/tests/mir-opt/debuginfo/ref_prop.rs index 5f2f1ce09c707..60d68ba178a7b 100644 --- a/tests/mir-opt/debuginfo/ref_prop.rs +++ b/tests/mir-opt/debuginfo/ref_prop.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ test-mir-pass: ReferencePropagation //@ compile-flags: -g -Zub_checks=false -Zinline-mir -Zmir-enable-passes=+DeadStoreElimination-initial @@ -9,6 +8,11 @@ use std::intrinsics::mir::*; // EMIT_MIR ref_prop.remap_debuginfo_locals.ReferencePropagation.diff pub fn remap_debuginfo_locals() { + // CHECK-LABEL: fn remap_debuginfo_locals() + // CHECK: debug a => [[a:_.*]]; + // CHECK: bb0: + // CHECK-NEXT: [[a]] = const + // CHECK-NEXT: DBG: [[a]] = &(*[[a]]); foo(&0); } diff --git a/tests/crashes/147485.rs b/tests/ui/debuginfo/ref_prop_debuginfo-147485.rs similarity index 79% rename from tests/crashes/147485.rs rename to tests/ui/debuginfo/ref_prop_debuginfo-147485.rs index 86f3705e636b4..15899626aff7b 100644 --- a/tests/crashes/147485.rs +++ b/tests/ui/debuginfo/ref_prop_debuginfo-147485.rs @@ -1,6 +1,8 @@ -//@ known-bug: #147485 +//@ build-pass //@ compile-flags: -g -O +// Regression test for #147485. + #![crate_type = "lib"] pub fn f(x: *const usize) -> &'static usize { From 5ab4e18dfc73540220d015c09f2aa05bb7cfa51a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 10 Oct 2025 12:51:41 +0200 Subject: [PATCH 11/17] remove `#[rustc_inherit_overflow_checks]` from `is_multiple_of` --- library/core/src/num/uint_macros.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 752498bfbd815..b5b768cf677aa 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3552,7 +3552,6 @@ macro_rules! uint_impl { #[rustc_const_stable(feature = "unsigned_is_multiple_of", since = "1.87.0")] #[must_use] #[inline] - #[rustc_inherit_overflow_checks] pub const fn is_multiple_of(self, rhs: Self) -> bool { match rhs { 0 => self == 0, From 6660d75710a98b8a3a5ef455e68fdc8cd4aaf733 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 10 Oct 2025 07:52:49 -0400 Subject: [PATCH 12/17] Move to the tier 3 table --- src/doc/rustc/src/platform-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 7efeb216a886f..c833567e342a9 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -198,7 +198,6 @@ target | std | notes [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASIp1 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads [`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 -[`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | WebAssembly with WASIp3 [`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64 @@ -417,6 +416,7 @@ target | std | host | notes [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) +[`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | WebAssembly with WASIp3 [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-lynx-lynxos178`](platform-support/lynxos178.md) | | | x86_64 LynxOS-178 From c86474ca0719cc24a6686215ab0fae1c98ce3eb9 Mon Sep 17 00:00:00 2001 From: Vitali Borsak Date: Wed, 20 Aug 2025 09:57:14 +0000 Subject: [PATCH 13/17] Adding a regression test (const promotion with Option) --- ...on_ordering_eq.direct.PreCodegen.after.mir | 46 +++++++++++++++++ .../const_promotion_option_ordering_eq.rs | 30 ++++++++++++ ..._ordering_eq.with_let.PreCodegen.after.mir | 49 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir create mode 100644 tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs create mode 100644 tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir new file mode 100644 index 0000000000000..66b51ad48e7a5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir @@ -0,0 +1,46 @@ +// MIR for `direct` after PreCodegen + +fn direct(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 2 { + scope 3 (inlined ::eq) { + let _3: i8; + scope 4 { + scope 5 { + } + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = discriminant(_1); + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + } + + bb1: { + _0 = const false; + goto -> bb3; + } + + bb2: { + StorageLive(_3); + _3 = discriminant(((_1 as Some).0: std::cmp::Ordering)); + _0 = Eq(copy _3, const 0_i8); + StorageDead(_3); + goto -> bb3; + } + + bb3: { + StorageDead(_2); + return; + } + + bb4: { + unreachable; + } +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs new file mode 100644 index 0000000000000..3c1e96fa47484 --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs @@ -0,0 +1,30 @@ +//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 + +// Check that comparing `Option` to a constant inlined `Some(...)` +// does not produce unnecessarily complex MIR compared to using a local binding. +// +// Regression test for . +// Originally, inlined constants like `Some(Ordering::Equal)` would get promoted, +// leading to more MIR (and extra LLVM IR checks) than necessary. +// Both cases should now generate identical MIR. + +use std::cmp::Ordering; + +// EMIT_MIR const_promotion_option_ordering_eq.direct.PreCodegen.after.mir +pub fn direct(e: Option) -> bool { + // CHECK-LABEL: fn direct( + // CHECK-NOT: promoted[ + // CHECK: switchInt( + // CHECK: return + e == Some(Ordering::Equal) +} + +// EMIT_MIR const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir +pub fn with_let(e: Option) -> bool { + // CHECK-LABEL: fn with_let( + // CHECK-NOT: promoted[ + // CHECK: switchInt( + // CHECK: return + let eq = Ordering::Equal; + e == Some(eq) +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir new file mode 100644 index 0000000000000..f089e9ad960bd --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir @@ -0,0 +1,49 @@ +// MIR for `with_let` after PreCodegen + +fn with_let(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 { + debug eq => const Equal; + scope 2 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 3 { + scope 4 (inlined ::eq) { + let _3: i8; + scope 5 { + scope 6 { + } + } + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = discriminant(_1); + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + } + + bb1: { + _0 = const false; + goto -> bb3; + } + + bb2: { + StorageLive(_3); + _3 = discriminant(((_1 as Some).0: std::cmp::Ordering)); + _0 = Eq(copy _3, const 0_i8); + StorageDead(_3); + goto -> bb3; + } + + bb3: { + StorageDead(_2); + return; + } + + bb4: { + unreachable; + } +} From b7c2b3dc80e03dbbde6ff869c1f975c036703590 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Fri, 10 Oct 2025 01:48:09 +0000 Subject: [PATCH 14/17] Remove StatementKind::Deinit. --- compiler/rustc_borrowck/src/dataflow.rs | 1 - compiler/rustc_borrowck/src/def_use.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 1 - .../src/polonius/legacy/loan_invalidations.rs | 1 - compiler/rustc_borrowck/src/type_check/mod.rs | 1 - compiler/rustc_codegen_cranelift/src/base.rs | 1 - compiler/rustc_codegen_cranelift/src/constant.rs | 1 - compiler/rustc_codegen_ssa/src/mir/analyze.rs | 1 - compiler/rustc_codegen_ssa/src/mir/statement.rs | 5 ----- .../rustc_const_eval/src/check_consts/check.rs | 1 - compiler/rustc_const_eval/src/interpret/step.rs | 5 ----- compiler/rustc_middle/src/mir/pretty.rs | 1 - compiler/rustc_middle/src/mir/statement.rs | 1 - compiler/rustc_middle/src/mir/syntax.rs | 6 ------ compiler/rustc_middle/src/mir/visit.rs | 9 --------- .../src/builder/custom/parse/instruction.rs | 3 --- compiler/rustc_mir_dataflow/src/impls/liveness.rs | 5 ++--- .../src/impls/storage_liveness.rs | 3 +-- .../rustc_mir_dataflow/src/move_paths/builder.rs | 2 +- compiler/rustc_mir_transform/src/coroutine.rs | 1 - .../src/coverage/spans/from_mir.rs | 1 - .../rustc_mir_transform/src/cross_crate_inline.rs | 5 +---- .../rustc_mir_transform/src/dataflow_const_prop.rs | 4 ---- compiler/rustc_mir_transform/src/jump_threading.rs | 3 +-- .../rustc_mir_transform/src/known_panics_lint.rs | 1 - compiler/rustc_mir_transform/src/large_enums.rs | 3 --- .../src/remove_noop_landing_pads.rs | 1 - compiler/rustc_mir_transform/src/remove_zsts.rs | 3 +-- compiler/rustc_mir_transform/src/simplify.rs | 6 +++--- compiler/rustc_mir_transform/src/sroa.rs | 14 +------------- compiler/rustc_mir_transform/src/validate.rs | 10 ---------- compiler/rustc_public/src/mir/body.rs | 1 - compiler/rustc_public/src/mir/pretty.rs | 1 - compiler/rustc_public/src/mir/visit.rs | 1 - .../src/unstable/convert/stable/mir.rs | 3 --- library/core/src/intrinsics/mir.rs | 3 +-- .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- tests/mir-opt/building/custom/enums.rs | 1 - .../custom/enums.set_discr.built.after.mir | 1 - tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff | 2 -- tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff | 2 -- tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff | 2 -- tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff | 2 -- 43 files changed, 14 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index d3f6c01ab8c3a..84d5ffb947914 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -577,7 +577,6 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { mir::StatementKind::FakeRead(..) | mir::StatementKind::SetDiscriminant { .. } - | mir::StatementKind::Deinit(..) | mir::StatementKind::StorageLive(..) | mir::StatementKind::Retag { .. } | mir::StatementKind::PlaceMention(..) diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index b9ced81c46c19..502265a83523e 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -80,7 +80,7 @@ pub(crate) fn categorize(context: PlaceContext) -> Option { // Backwards incompatible drop hint is not a use, just a marker for linting. PlaceContext::NonUse(NonUseContext::BackwardIncompatibleDropHint) => None, - PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => { + PlaceContext::MutatingUse(MutatingUseContext::SetDiscriminant) => { bug!("These statements are not allowed in this MIR phase") } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a85dcf64d8d46..d13de8c972265 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -857,7 +857,6 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, } StatementKind::Nop | StatementKind::Retag { .. } - | StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index c2ad6fcb4b799..f6cf0212ef305 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -84,7 +84,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> { StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::Retag { .. } - | StatementKind::Deinit(..) | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 781fb5ba113ab..984a154853a98 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -748,7 +748,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::Nop => {} StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..)) - | StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index ebf2ccf74de20..b3f9f598926c2 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -932,7 +932,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: } StatementKind::StorageLive(_) | StatementKind::StorageDead(_) - | StatementKind::Deinit(_) | StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::FakeRead(..) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index faca92957e1a6..293459cc11c2f 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -597,7 +597,6 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( StatementKind::Assign(_) | StatementKind::FakeRead(_) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(_) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 0a37a904193fa..de755d5617801 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -229,7 +229,6 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer PlaceContext::MutatingUse( MutatingUseContext::Store - | MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant | MutatingUseContext::AsmOutput | MutatingUseContext::Borrow diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 88590b6271bce..d0121f7643800 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -50,11 +50,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::StatementKind::SetDiscriminant { box ref place, variant_index } => { self.codegen_place(bx, place.as_ref()).codegen_set_discr(bx, variant_index); } - mir::StatementKind::Deinit(..) => { - // For now, don't codegen this to anything. In the future it may be worth - // experimenting with what kind of information we can emit to LLVM without hurting - // perf here - } mir::StatementKind::StorageLive(local) => { if let LocalRef::Place(cg_place) = self.locals[local] { cg_place.storage_live(bx); diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 413aa5f8b8774..2c6dd5bd01f9c 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -732,7 +732,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { match statement.kind { StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(..) | StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 923e00ad4cf1a..088cacf2e6403 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -98,11 +98,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_discriminant(*variant_index, &dest)?; } - Deinit(place) => { - let dest = self.eval_place(**place)?; - self.write_uninit(&dest)?; - } - // Mark locals as alive StorageLive(local) => { self.storage_live(*local)?; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index d87e3abe3b2ea..60c2ef4d563e4 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -818,7 +818,6 @@ impl Debug for Statement<'_> { SetDiscriminant { ref place, variant_index } => { write!(fmt, "discriminant({place:?}) = {variant_index:?}") } - Deinit(ref place) => write!(fmt, "Deinit({place:?})"), PlaceMention(ref place) => { write!(fmt, "PlaceMention({place:?})") } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index f310e1e576250..74c39afbbc823 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -50,7 +50,6 @@ impl<'tcx> StatementKind<'tcx> { StatementKind::Assign(..) => "Assign", StatementKind::FakeRead(..) => "FakeRead", StatementKind::SetDiscriminant { .. } => "SetDiscriminant", - StatementKind::Deinit(..) => "Deinit", StatementKind::StorageLive(..) => "StorageLive", StatementKind::StorageDead(..) => "StorageDead", StatementKind::Retag(..) => "Retag", diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index a823c365394f7..0fffa009d9ad8 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -135,7 +135,6 @@ pub enum RuntimePhase { /// And the following variants are allowed: /// * [`StatementKind::Retag`] /// * [`StatementKind::SetDiscriminant`] - /// * [`StatementKind::Deinit`] /// /// Furthermore, `Copy` operands are allowed for non-`Copy` types. Initial = 0, @@ -362,11 +361,6 @@ pub enum StatementKind<'tcx> { /// the type. SetDiscriminant { place: Box>, variant_index: VariantIdx }, - /// Deinitializes the place. - /// - /// This writes `uninit` bytes to the entire place. - Deinit(Box>), - /// `StorageLive` and `StorageDead` statements mark the live range of a local. /// /// At any point during the execution of a function, each local is either allocated or diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 9654e189f2edf..fd81bdeb3f952 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -445,13 +445,6 @@ macro_rules! make_mir_visitor { location ); } - StatementKind::Deinit(place) => { - self.visit_place( - place, - PlaceContext::MutatingUse(MutatingUseContext::Deinit), - location - ) - } StatementKind::StorageLive(local) => { self.visit_local( $(& $mutability)? *local, @@ -1372,8 +1365,6 @@ pub enum MutatingUseContext { Store, /// Appears on `SetDiscriminant` SetDiscriminant, - /// Appears on `Deinit` - Deinit, /// Output operand of an inline assembly block. AsmOutput, /// Destination of a call. diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index 54490e0050902..b1d1d67947a05 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -24,9 +24,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> { let op = self.parse_operand(args[0])?; Ok(StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(op)))) }, - @call(mir_deinit, args) => { - Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?))) - }, @call(mir_retag, args) => { Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?))) }, diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index f6aaa65ad9fdd..596da18e3d1b4 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -159,8 +159,7 @@ impl DefUse { MutatingUseContext::Call | MutatingUseContext::Yield | MutatingUseContext::AsmOutput - | MutatingUseContext::Store - | MutatingUseContext::Deinit, + | MutatingUseContext::Store, ) => { // Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use. if place.is_indirect() { @@ -238,7 +237,7 @@ impl<'a> MaybeTransitiveLiveLocals<'a> { && (!debuginfo_locals.contains(place.local) || (place.as_local().is_some() && stmt_kind.as_debuginfo().is_some()))) .then_some(*place), - StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { + StatementKind::SetDiscriminant { place, .. } => { (!debuginfo_locals.contains(place.local)).then_some(**place) } StatementKind::FakeRead(_) diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index e3aa8f5a62014..026826fc379c7 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -156,8 +156,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { // If a place is assigned to in a statement, it needs storage for that statement. StatementKind::Assign(box (place, _)) - | StatementKind::SetDiscriminant { box place, .. } - | StatementKind::Deinit(box place) => { + | StatementKind::SetDiscriminant { box place, .. } => { state.gen_(place.local); } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 434f106302f5d..c60713cea0300 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -371,7 +371,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { self.gather_move(Place::from(*local)); } } - StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) => { + StatementKind::SetDiscriminant { .. } => { span_bug!( stmt.source_info.span, "SetDiscriminant/Deinit should not exist during borrowck" diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index c136df812a3f0..34e03ef69f30c 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1723,7 +1723,6 @@ impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> { StatementKind::FakeRead(..) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag(..) diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index dfeaa90dc2e22..c096f1e2632ce 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -91,7 +91,6 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option { ) | StatementKind::Assign(_) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(..) | StatementKind::Retag(_, _) | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(_, _) => Some(statement.source_info.span), diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index df98c07f54958..7fc9fb9cca2d7 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -115,10 +115,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { // Don't count StorageLive/StorageDead in the inlining cost. match statement.kind { - StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) - | StatementKind::Deinit(_) - | StatementKind::Nop => {} + StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Nop => {} _ => self.statements += 1, } } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index e970f7ff81adb..8451ebed4f705 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -178,10 +178,6 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { FlatSet::::BOTTOM, ); } - StatementKind::Deinit(box place) => { - // Deinit makes the place uninitialized. - state.flood_with(place.as_ref(), &self.map, FlatSet::::BOTTOM); - } StatementKind::Retag(..) => { // We don't track references. } diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 68298767e7fd8..37a3da94f9689 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -332,8 +332,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { stmt: &Statement<'tcx>, ) -> Option<(Place<'tcx>, Option)> { match stmt.kind { - StatementKind::Assign(box (place, _)) - | StatementKind::Deinit(box place) => Some((place, None)), + StatementKind::Assign(box (place, _)) => Some((place, None)), StatementKind::SetDiscriminant { box place, variant_index: _ } => { Some((place, Some(TrackElem::Discriminant))) } diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 93abc0f8860b9..c67e875175fee 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -926,7 +926,6 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { // mutations of the same local via `Store` | MutatingUse(MutatingUseContext::Call) | MutatingUse(MutatingUseContext::AsmOutput) - | MutatingUse(MutatingUseContext::Deinit) // Actual store that can possibly even propagate a value | MutatingUse(MutatingUseContext::Store) | MutatingUse(MutatingUseContext::SetDiscriminant) => { diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 1b90e9158f6b8..89bd91e7013da 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -126,8 +126,6 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty), ))); - let deinit_old = StatementKind::Deinit(Box::new(dst)); - let copy_bytes = StatementKind::Intrinsic(Box::new( NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src: Operand::Copy(src_cast_place), @@ -148,7 +146,6 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { dst_cast, src_ptr, src_cast, - deinit_old, copy_bytes, store_dead, ]; diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 38752bde6b417..f7105f62e4beb 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -113,7 +113,6 @@ impl RemoveNoopLandingPads { StatementKind::Assign { .. } | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(..) | StatementKind::Intrinsic(..) | StatementKind::Retag { .. } => { return false; diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 90c1b3520b96e..bebd8fab74565 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -122,8 +122,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { StatementKind::Assign(box (place, ref rvalue)) => { rvalue.is_safe_to_remove().then_some(place) } - StatementKind::Deinit(box place) - | StatementKind::SetDiscriminant { box place, variant_index: _ } + StatementKind::SetDiscriminant { box place, variant_index: _ } | StatementKind::AscribeUserType(box (place, _), _) | StatementKind::Retag(_, box place) | StatementKind::PlaceMention(box place) diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 8b5efb7420582..da31600e8324c 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -590,7 +590,6 @@ impl<'tcx> Visitor<'tcx> for UsedLocals { } StatementKind::SetDiscriminant { ref place, variant_index: _ } - | StatementKind::Deinit(ref place) | StatementKind::BackwardIncompatibleDropHint { ref place, reason: _ } => { self.visit_lhs(place, location); } @@ -630,8 +629,9 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod } StatementKind::Assign(box (place, _)) | StatementKind::SetDiscriminant { box place, .. } - | StatementKind::BackwardIncompatibleDropHint { box place, .. } - | StatementKind::Deinit(box place) => used_locals.is_used(place.local), + | StatementKind::BackwardIncompatibleDropHint { box place, .. } => { + used_locals.is_used(place.local) + } _ => continue, }; if keep_statement { diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 99f10b8d91d2c..801383493837d 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -136,9 +136,7 @@ fn escaping_locals<'tcx>( fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { match statement.kind { // Storage statements are expanded in run_pass. - StatementKind::StorageLive(..) - | StatementKind::StorageDead(..) - | StatementKind::Deinit(..) => return, + StatementKind::StorageLive(..) | StatementKind::StorageDead(..) => return, _ => self.super_statement(statement, location), } } @@ -331,16 +329,6 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { } return; } - StatementKind::Deinit(box place) => { - if let Some(final_locals) = self.replacements.place_fragments(place) { - for (_, _, fl) in final_locals { - self.patch - .add_statement(location, StatementKind::Deinit(Box::new(fl.into()))); - } - statement.make_nop(true); - return; - } - } // We have `a = Struct { 0: x, 1: y, .. }`. // We replace it by diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 95873484b6529..ed453a580e854 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -313,11 +313,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { self.fail(location, "`SetDiscriminant`is not allowed until deaggregation"); } } - StatementKind::Deinit(..) => { - if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { - self.fail(location, "`Deinit`is not allowed until deaggregation"); - } - } StatementKind::Retag(kind, _) => { // FIXME(JakobDegen) The validator should check that `self.body.phase < // DropsLowered`. However, this causes ICEs with generation of drop shims, which @@ -1501,11 +1496,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } - StatementKind::Deinit(..) => { - if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { - self.fail(location, "`Deinit`is not allowed until deaggregation"); - } - } StatementKind::Retag(kind, _) => { // FIXME(JakobDegen) The validator should check that `self.body.phase < // DropsLowered`. However, this causes ICEs with generation of drop shims, which diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs index 7bd06fee721ce..615a5a48d15b7 100644 --- a/compiler/rustc_public/src/mir/body.rs +++ b/compiler/rustc_public/src/mir/body.rs @@ -478,7 +478,6 @@ pub enum StatementKind { Assign(Place, Rvalue), FakeRead(FakeReadCause, Place), SetDiscriminant { place: Place, variant_index: VariantIdx }, - Deinit(Place), StorageLive(Local), StorageDead(Local), Retag(RetagKind, Place), diff --git a/compiler/rustc_public/src/mir/pretty.rs b/compiler/rustc_public/src/mir/pretty.rs index 9dd1ce4de0ea6..8904870f29e32 100644 --- a/compiler/rustc_public/src/mir/pretty.rs +++ b/compiler/rustc_public/src/mir/pretty.rs @@ -102,7 +102,6 @@ fn pretty_statement(writer: &mut W, statement: &StatementKind) -> io:: StatementKind::SetDiscriminant { place, variant_index } => { writeln!(writer, "{INDENT}discriminant({place:?}) = {};", variant_index.to_index()) } - StatementKind::Deinit(place) => writeln!(writer, "Deinit({place:?};"), StatementKind::StorageLive(local) => { writeln!(writer, "{INDENT}StorageLive(_{local});") } diff --git a/compiler/rustc_public/src/mir/visit.rs b/compiler/rustc_public/src/mir/visit.rs index 7563c9ca00820..1cb9bfe79a096 100644 --- a/compiler/rustc_public/src/mir/visit.rs +++ b/compiler/rustc_public/src/mir/visit.rs @@ -170,7 +170,6 @@ macro_rules! make_mir_visitor { self.visit_place(place, PlaceContext::NON_MUTATING, location); } StatementKind::SetDiscriminant { place, .. } - | StatementKind::Deinit(place) | StatementKind::Retag(_, place) => { self.visit_place(place, PlaceContext::MUTATING, location); } diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs index 62ab91d17baee..392347ce345a0 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs @@ -149,9 +149,6 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { variant_index: variant_index.stable(tables, cx), } } - mir::StatementKind::Deinit(place) => { - crate::mir::StatementKind::Deinit(place.stable(tables, cx)) - } mir::StatementKind::StorageLive(place) => { crate::mir::StatementKind::StorageLive(place.stable(tables, cx)) diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index a800ef1cb9375..8ddce1c758438 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -227,7 +227,7 @@ //! //! #### Statements //! - Assign statements work via normal Rust assignment. -//! - [`Retag`], [`StorageLive`], [`StorageDead`], [`Deinit`] statements have an associated function. +//! - [`Retag`], [`StorageLive`], [`StorageDead`] statements have an associated function. //! //! #### Rvalues //! @@ -400,7 +400,6 @@ define!("mir_unwind_resume", define!("mir_storage_live", fn StorageLive(local: T)); define!("mir_storage_dead", fn StorageDead(local: T)); define!("mir_assume", fn Assume(operand: bool)); -define!("mir_deinit", fn Deinit(place: T)); define!("mir_checked", fn Checked(binop: T) -> (T, bool)); define!( "mir_ptr_metadata", diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 1e3a7281bc734..b9027fea468eb 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -232,7 +232,7 @@ fn check_statement<'tcx>( StatementKind::FakeRead(box (_, place)) => check_place(cx, *place, span, body, msrv), // just an assignment - StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => { + StatementKind::SetDiscriminant { place, .. } => { check_place(cx, **place, span, body, msrv) }, diff --git a/tests/mir-opt/building/custom/enums.rs b/tests/mir-opt/building/custom/enums.rs index 88ec228986ab7..6fad373203a69 100644 --- a/tests/mir-opt/building/custom/enums.rs +++ b/tests/mir-opt/building/custom/enums.rs @@ -88,7 +88,6 @@ fn switch_option_repr(option: Bool) -> bool { fn set_discr(option: &mut Option<()>) { mir! { { - Deinit(*option); SetDiscriminant(*option, 0); Return() } diff --git a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir index 8cc66e7e50d6a..d9b46dff43aa4 100644 --- a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir +++ b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir @@ -4,7 +4,6 @@ fn set_discr(_1: &mut Option<()>) -> () { let mut _0: (); bb0: { - Deinit((*_1)); discriminant((*_1)) = 0; return; } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index 267a4c1cf6beb..cf850351c1d62 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index 8e5c403cd7e6b..dc5ea1add0005 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 96c5aadd85fd4..3cd2e74a0db6f 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index d20e2e08eaafd..10b0ec5a63fa4 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; From ce671f998f9093e9fb215cc7e6ee036bc7094c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 9 Oct 2025 11:27:35 +0200 Subject: [PATCH 15/17] Update rustc-perf submodule --- src/tools/rustc-perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rustc-perf b/src/tools/rustc-perf index dde879cf1087c..c0301bc44d175 160000 --- a/src/tools/rustc-perf +++ b/src/tools/rustc-perf @@ -1 +1 @@ -Subproject commit dde879cf1087cb34a32287bd8ccc4d545bb9fee5 +Subproject commit c0301bc44d175b9b2c5442b25049475c39d7700c From 1ee2c58e8925315a45500d73c5527b7a340cc8a5 Mon Sep 17 00:00:00 2001 From: dianqk Date: Fri, 10 Oct 2025 13:50:01 +0800 Subject: [PATCH 16/17] Replace locals in debuginfo records during dest_prop --- compiler/rustc_mir_transform/src/dest_prop.rs | 1 - ...t_prop.remap_debuginfo_locals.DestinationPropagation.diff | 3 ++- tests/mir-opt/debuginfo/dest_prop.rs | 5 ++++- .../debuginfo/dest_prop_debuginfo-147485.rs} | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) rename tests/{crashes/147485-2.rs => ui/debuginfo/dest_prop_debuginfo-147485.rs} (81%) diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 1f38433fa5a41..92556e7c5f6c5 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -277,7 +277,6 @@ impl<'tcx> MutVisitor<'tcx> for Merger<'tcx> { if self.merged_locals.contains(*local) => { statement.make_nop(true); - return; } _ => (), }; diff --git a/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff b/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff index 6f3233d85c9fc..fe00da67e8bb0 100644 --- a/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff +++ b/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff @@ -9,11 +9,12 @@ let mut _4: bool; bb0: { - // DBG: _3 = &_1; +- // DBG: _3 = &_1; - StorageLive(_4); - _4 = copy _1; - _3 = copy _2; - switchInt(copy _4) -> [1: bb1, otherwise: bb2]; ++ // DBG: _2 = &_1; + nop; + nop; + nop; diff --git a/tests/mir-opt/debuginfo/dest_prop.rs b/tests/mir-opt/debuginfo/dest_prop.rs index 9c9d95ebfb3f3..a734cacb4d29a 100644 --- a/tests/mir-opt/debuginfo/dest_prop.rs +++ b/tests/mir-opt/debuginfo/dest_prop.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ test-mir-pass: DestinationPropagation //@ compile-flags: -g -Zmir-enable-passes=+DeadStoreElimination-initial @@ -10,6 +9,10 @@ use std::intrinsics::mir::*; // EMIT_MIR dest_prop.remap_debuginfo_locals.DestinationPropagation.diff #[custom_mir(dialect = "runtime", phase = "post-cleanup")] pub fn remap_debuginfo_locals(a: bool, b: &bool) -> &bool { + // CHECK-LABEL: fn remap_debuginfo_locals( + // CHECK: debug c => [[c:_.*]]; + // CHECK: bb0: + // CHECK-NEXT: DBG: [[c]] = &_1; mir! { let _3: &bool; let _4: bool; diff --git a/tests/crashes/147485-2.rs b/tests/ui/debuginfo/dest_prop_debuginfo-147485.rs similarity index 81% rename from tests/crashes/147485-2.rs rename to tests/ui/debuginfo/dest_prop_debuginfo-147485.rs index da092a3af76aa..652660d473b15 100644 --- a/tests/crashes/147485-2.rs +++ b/tests/ui/debuginfo/dest_prop_debuginfo-147485.rs @@ -1,6 +1,8 @@ -//@ known-bug: #147485 +//@ build-pass //@ compile-flags: -g -O +// Regression test for #147485. + #![crate_type = "lib"] pub fn foo(a: bool, b: bool) -> bool { From 4eccd0222962bf3203b11f103f391c866e039512 Mon Sep 17 00:00:00 2001 From: Asger Hautop Drewsen Date: Fri, 10 Oct 2025 18:01:03 +0200 Subject: [PATCH 17/17] Stabilize unsigned_nonzero_div_ceil --- library/core/src/num/nonzero.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index d9184e3c9c229..fcdb65bd45c95 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1373,7 +1373,6 @@ macro_rules! nonzero_integer_signedness_dependent_impls { /// # Examples /// /// ``` - /// # #![feature(unsigned_nonzero_div_ceil)] /// # use std::num::NonZero; #[doc = concat!("let one = NonZero::new(1", stringify!($Int), ").unwrap();")] #[doc = concat!("let max = NonZero::new(", stringify!($Int), "::MAX).unwrap();")] @@ -1383,7 +1382,11 @@ macro_rules! nonzero_integer_signedness_dependent_impls { #[doc = concat!("let three = NonZero::new(3", stringify!($Int), ").unwrap();")] /// assert_eq!(three.div_ceil(two), two); /// ``` - #[unstable(feature = "unsigned_nonzero_div_ceil", issue = "132968")] + #[stable(feature = "unsigned_nonzero_div_ceil", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable( + feature = "unsigned_nonzero_div_ceil", + since = "CURRENT_RUSTC_VERSION" + )] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline]