From 68cfe93c112699e0651eb54e4a4de4b3a14cb5cc Mon Sep 17 00:00:00 2001 From: Zachary S Date: Mon, 15 Jun 2026 00:47:48 -0500 Subject: [PATCH 01/77] Add comments to randomize-layout implementation documenting guaranteed ZST struct/enums. Also add tests for the guaranteed types. --- compiler/rustc_abi/src/layout.rs | 4 +++ compiler/rustc_abi/src/lib.rs | 4 +++ tests/ui/layout/randomize.rs | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 003e811dc7855..a433761e73797 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -1124,6 +1124,10 @@ impl LayoutCalculator { // If `-Z randomize-layout` was enabled for the type definition we can shuffle // the field ordering to try and catch some code making assumptions about layouts // we don't guarantee. + // In the future, we might do more than shuffle field order (e.g. introduce extra padding), + // but never for `repr(Rust)` structs with only zero-sized fields or single-variant + // `repr(Rust)` enums with only zero-sized fields, which must remain zero-sized as per + // T-lang decision https://github.com/rust-lang/reference/pull/2262 if repr.can_randomize_type_layout() && cfg!(feature = "randomize") { #[cfg(feature = "randomize")] { diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index c2069432e6f8e..97bef297b6ef5 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -90,6 +90,10 @@ bitflags! { /// If true, the type's crate has opted into layout randomization. /// Other flags can still inhibit reordering and thus randomization. /// The seed stored in `ReprOptions.field_shuffle_seed`. + /// + /// `repr(Rust)` structs with only zero-sized fields and single-variant `repr(Rust)` enums with only + /// zero-sized fields must remain zero-sized as per T-lang decision + /// https://github.com/rust-lang/reference/pull/2262 const RANDOMIZE_LAYOUT = 1 << 4; /// If true, the type is always passed indirectly by non-Rustic ABIs. /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. diff --git a/tests/ui/layout/randomize.rs b/tests/ui/layout/randomize.rs index 27e99327a3196..f25ee23009049 100644 --- a/tests/ui/layout/randomize.rs +++ b/tests/ui/layout/randomize.rs @@ -49,6 +49,49 @@ const _: () = { assert!(std::mem::offset_of!(Result::<&usize, ()>, Ok.0) == 0); }; +// these types only have their size checked, they're never constructed. +// these repr(Rust) types must remain zero-sized. +#[allow(dead_code)] +pub struct UnitStruct; +#[allow(dead_code)] +pub struct EmptyTupleStruct(); +#[allow(dead_code)] +pub struct EmptyStruct {} +#[allow(dead_code)] +pub struct ZstFieldsTupleStruct((), [u64; 0], [u8; 0], [(); 42]); +#[allow(dead_code)] +pub struct ZstFieldsStruct { + a: (), + b: [u64; 0], + c: [u8; 0], + d: [(); 42], +} +#[allow(dead_code)] +pub enum SingleUnitVariantEnum { A } +#[allow(dead_code)] +pub enum SingleZstFieldTupleVariantEnum { A((), [u64; 0], [u8; 0], [(); 42]) } +#[allow(dead_code)] +pub enum SingleZstFieldVariantEnum { + A { + a: (), + b: [u64; 0], + c: [u8; 0], + d: [(); 42], + } +} + +// all these types must remain zero-sized. +const _: () = { + assert!(size_of::() == 0); + assert!(size_of::() == 0); + assert!(size_of::() == 0); + assert!(size_of::() == 0); + assert!(size_of::() == 0); + assert!(size_of::() == 0); + assert!(size_of::() == 0); + assert!(size_of::() == 0); +}; + #[allow(dead_code)] struct Unsizable(usize, T); From bec5d880be77a942f3fc88eb20732e67e029dd93 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Mon, 15 Jun 2026 00:49:32 -0500 Subject: [PATCH 02/77] Add zero-variant enums to randomize-layout comments and tests. --- compiler/rustc_abi/src/layout.rs | 7 ++++--- compiler/rustc_abi/src/lib.rs | 6 +++--- tests/ui/layout/randomize.rs | 3 +++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index a433761e73797..7f1a7021f5bcc 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -1125,9 +1125,10 @@ impl LayoutCalculator { // the field ordering to try and catch some code making assumptions about layouts // we don't guarantee. // In the future, we might do more than shuffle field order (e.g. introduce extra padding), - // but never for `repr(Rust)` structs with only zero-sized fields or single-variant - // `repr(Rust)` enums with only zero-sized fields, which must remain zero-sized as per - // T-lang decision https://github.com/rust-lang/reference/pull/2262 + // but never for `repr(Rust)` structs with only zero-sized fields, single-variant + // `repr(Rust)` enums with only zero-sized fields, or zero-variant `repr(Rust)` enums, + // which must remain zero-sized as per T-lang decisions in + // https://github.com/rust-lang/reference/pull/2262 and https://github.com/rust-lang/reference/pull/2293 if repr.can_randomize_type_layout() && cfg!(feature = "randomize") { #[cfg(feature = "randomize")] { diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 97bef297b6ef5..2a7dde3b8840e 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -91,9 +91,9 @@ bitflags! { /// Other flags can still inhibit reordering and thus randomization. /// The seed stored in `ReprOptions.field_shuffle_seed`. /// - /// `repr(Rust)` structs with only zero-sized fields and single-variant `repr(Rust)` enums with only - /// zero-sized fields must remain zero-sized as per T-lang decision - /// https://github.com/rust-lang/reference/pull/2262 + /// `repr(Rust)` structs with only zero-sized fields, single-variant `repr(Rust)` enums with only + /// zero-sized fields, and zero-variant `repr(Rust)` enums must remain zero-sized as per + /// T-lang decisions in https://github.com/rust-lang/reference/pull/2262 and https://github.com/rust-lang/reference/pull/2293 const RANDOMIZE_LAYOUT = 1 << 4; /// If true, the type is always passed indirectly by non-Rustic ABIs. /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. diff --git a/tests/ui/layout/randomize.rs b/tests/ui/layout/randomize.rs index f25ee23009049..eaeb527f191cb 100644 --- a/tests/ui/layout/randomize.rs +++ b/tests/ui/layout/randomize.rs @@ -67,6 +67,8 @@ pub struct ZstFieldsStruct { d: [(); 42], } #[allow(dead_code)] +pub enum EmptyEnum {} +#[allow(dead_code)] pub enum SingleUnitVariantEnum { A } #[allow(dead_code)] pub enum SingleZstFieldTupleVariantEnum { A((), [u64; 0], [u8; 0], [(); 42]) } @@ -87,6 +89,7 @@ const _: () = { assert!(size_of::() == 0); assert!(size_of::() == 0); assert!(size_of::() == 0); + assert!(size_of::() == 0); assert!(size_of::() == 0); assert!(size_of::() == 0); assert!(size_of::() == 0); From 715a61625e63c83d87141c2badf9f0cd1bdc5d94 Mon Sep 17 00:00:00 2001 From: zedddie Date: Thu, 9 Jul 2026 23:32:40 +0200 Subject: [PATCH 03/77] move batch --- .../issue-37131.rs => crate-loading/missing-target-error.rs} | 0 .../missing-target-error.stderr} | 0 .../if/mut-borrow-in-else-if-after-if-let.rs} | 0 tests/ui/{issues/issue-38556.rs => imports/macro-use-as.rs} | 0 .../lifetime-errors/iterator-next-extra-named-lifetime.rs} | 0 .../lifetime-errors/iterator-next-extra-named-lifetime.stderr} | 0 .../ambig-method-call-in-trait-impl.rs} | 0 .../ambig-method-call-in-trait-impl.stderr} | 0 .../{issues/issue-3847.rs => parser/other-module-struct-match.rs} | 0 .../issue-3753.rs => parser/pub-method-after-attribute.rs} | 0 .../issue-3702.rs => traits/object/nested-trait-method-call.rs} | 0 .../issue-37665.rs => unpretty/mir-unpretty-type-error.rs} | 0 .../mir-unpretty-type-error.stderr} | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-37131.rs => crate-loading/missing-target-error.rs} (100%) rename tests/ui/{issues/issue-37131.stderr => crate-loading/missing-target-error.stderr} (100%) rename tests/ui/{issues/issue-37510.rs => expr/if/mut-borrow-in-else-if-after-if-let.rs} (100%) rename tests/ui/{issues/issue-38556.rs => imports/macro-use-as.rs} (100%) rename tests/ui/{issues/issue-37884.rs => lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs} (100%) rename tests/ui/{issues/issue-37884.stderr => lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr} (100%) rename tests/ui/{issues/issue-3702-2.rs => methods/ambig-method-call-in-trait-impl.rs} (100%) rename tests/ui/{issues/issue-3702-2.stderr => methods/ambig-method-call-in-trait-impl.stderr} (100%) rename tests/ui/{issues/issue-3847.rs => parser/other-module-struct-match.rs} (100%) rename tests/ui/{issues/issue-3753.rs => parser/pub-method-after-attribute.rs} (100%) rename tests/ui/{issues/issue-3702.rs => traits/object/nested-trait-method-call.rs} (100%) rename tests/ui/{issues/issue-37665.rs => unpretty/mir-unpretty-type-error.rs} (100%) rename tests/ui/{issues/issue-37665.stderr => unpretty/mir-unpretty-type-error.stderr} (100%) diff --git a/tests/ui/issues/issue-37131.rs b/tests/ui/crate-loading/missing-target-error.rs similarity index 100% rename from tests/ui/issues/issue-37131.rs rename to tests/ui/crate-loading/missing-target-error.rs diff --git a/tests/ui/issues/issue-37131.stderr b/tests/ui/crate-loading/missing-target-error.stderr similarity index 100% rename from tests/ui/issues/issue-37131.stderr rename to tests/ui/crate-loading/missing-target-error.stderr diff --git a/tests/ui/issues/issue-37510.rs b/tests/ui/expr/if/mut-borrow-in-else-if-after-if-let.rs similarity index 100% rename from tests/ui/issues/issue-37510.rs rename to tests/ui/expr/if/mut-borrow-in-else-if-after-if-let.rs diff --git a/tests/ui/issues/issue-38556.rs b/tests/ui/imports/macro-use-as.rs similarity index 100% rename from tests/ui/issues/issue-38556.rs rename to tests/ui/imports/macro-use-as.rs diff --git a/tests/ui/issues/issue-37884.rs b/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs similarity index 100% rename from tests/ui/issues/issue-37884.rs rename to tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs diff --git a/tests/ui/issues/issue-37884.stderr b/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr similarity index 100% rename from tests/ui/issues/issue-37884.stderr rename to tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr diff --git a/tests/ui/issues/issue-3702-2.rs b/tests/ui/methods/ambig-method-call-in-trait-impl.rs similarity index 100% rename from tests/ui/issues/issue-3702-2.rs rename to tests/ui/methods/ambig-method-call-in-trait-impl.rs diff --git a/tests/ui/issues/issue-3702-2.stderr b/tests/ui/methods/ambig-method-call-in-trait-impl.stderr similarity index 100% rename from tests/ui/issues/issue-3702-2.stderr rename to tests/ui/methods/ambig-method-call-in-trait-impl.stderr diff --git a/tests/ui/issues/issue-3847.rs b/tests/ui/parser/other-module-struct-match.rs similarity index 100% rename from tests/ui/issues/issue-3847.rs rename to tests/ui/parser/other-module-struct-match.rs diff --git a/tests/ui/issues/issue-3753.rs b/tests/ui/parser/pub-method-after-attribute.rs similarity index 100% rename from tests/ui/issues/issue-3753.rs rename to tests/ui/parser/pub-method-after-attribute.rs diff --git a/tests/ui/issues/issue-3702.rs b/tests/ui/traits/object/nested-trait-method-call.rs similarity index 100% rename from tests/ui/issues/issue-3702.rs rename to tests/ui/traits/object/nested-trait-method-call.rs diff --git a/tests/ui/issues/issue-37665.rs b/tests/ui/unpretty/mir-unpretty-type-error.rs similarity index 100% rename from tests/ui/issues/issue-37665.rs rename to tests/ui/unpretty/mir-unpretty-type-error.rs diff --git a/tests/ui/issues/issue-37665.stderr b/tests/ui/unpretty/mir-unpretty-type-error.stderr similarity index 100% rename from tests/ui/issues/issue-37665.stderr rename to tests/ui/unpretty/mir-unpretty-type-error.stderr From dd8996db14204ce70a6a016f211d51839afaace7 Mon Sep 17 00:00:00 2001 From: zedddie Date: Thu, 9 Jul 2026 23:34:43 +0200 Subject: [PATCH 04/77] bless batch --- tests/ui/crate-loading/missing-target-error.rs | 7 ++++--- .../if/mut-borrow-in-else-if-after-if-let.rs | 2 ++ tests/ui/imports/macro-use-as.rs | 3 +++ tests/ui/issues/issue-3779.rs | 8 -------- tests/ui/issues/issue-3779.stderr | 17 ----------------- .../iterator-next-extra-named-lifetime.rs | 2 ++ .../iterator-next-extra-named-lifetime.stderr | 4 ++-- .../methods/ambig-method-call-in-trait-impl.rs | 3 +++ .../ambig-method-call-in-trait-impl.stderr | 6 +++--- tests/ui/parser/other-module-struct-match.rs | 3 +++ tests/ui/parser/pub-method-after-attribute.rs | 5 ++--- .../traits/object/nested-trait-method-call.rs | 3 +++ tests/ui/unpretty/mir-unpretty-type-error.rs | 2 ++ .../ui/unpretty/mir-unpretty-type-error.stderr | 2 +- 14 files changed, 30 insertions(+), 37 deletions(-) delete mode 100644 tests/ui/issues/issue-3779.rs delete mode 100644 tests/ui/issues/issue-3779.stderr diff --git a/tests/ui/crate-loading/missing-target-error.rs b/tests/ui/crate-loading/missing-target-error.rs index 875495d08ed77..3a75d568d2c8e 100644 --- a/tests/ui/crate-loading/missing-target-error.rs +++ b/tests/ui/crate-loading/missing-target-error.rs @@ -1,8 +1,9 @@ -//~ ERROR can't find crate for `std` +//! Regression test for . +//! Tests that compiling for a target which is not installed will result in a helpful +//! error message. +//~^^^ ERROR can't find crate for `std` //~| NOTE target may not be installed //~| NOTE can't find crate -// Tests that compiling for a target which is not installed will result in a helpful -// error message. //@ compile-flags: --target=thumbv6m-none-eabi //@ ignore-arm diff --git a/tests/ui/expr/if/mut-borrow-in-else-if-after-if-let.rs b/tests/ui/expr/if/mut-borrow-in-else-if-after-if-let.rs index 62a90c5604bd9..7c95752f760c1 100644 --- a/tests/ui/expr/if/mut-borrow-in-else-if-after-if-let.rs +++ b/tests/ui/expr/if/mut-borrow-in-else-if-after-if-let.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test that else-if after if-let is not considered a pattern guard. //@ check-pass fn foo(_: &mut i32) -> bool { true } diff --git a/tests/ui/imports/macro-use-as.rs b/tests/ui/imports/macro-use-as.rs index b04558707e148..e26a831e74b57 100644 --- a/tests/ui/imports/macro-use-as.rs +++ b/tests/ui/imports/macro-use-as.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Reexport in macro caused ICE. //@ run-pass + #![allow(dead_code)] pub struct Foo; diff --git a/tests/ui/issues/issue-3779.rs b/tests/ui/issues/issue-3779.rs deleted file mode 100644 index 901c1be80ca06..0000000000000 --- a/tests/ui/issues/issue-3779.rs +++ /dev/null @@ -1,8 +0,0 @@ -struct S { - //~^ ERROR E0072 - element: Option -} - -fn main() { - let x = S { element: None }; -} diff --git a/tests/ui/issues/issue-3779.stderr b/tests/ui/issues/issue-3779.stderr deleted file mode 100644 index d4f4b79102d5e..0000000000000 --- a/tests/ui/issues/issue-3779.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0072]: recursive type `S` has infinite size - --> $DIR/issue-3779.rs:1:1 - | -LL | struct S { - | ^^^^^^^^ -LL | -LL | element: Option - | - recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle - | -LL | element: Option> - | ++++ + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0072`. diff --git a/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs b/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs index 3480942d9d282..11a1397c8ef09 100644 --- a/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs +++ b/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! This used to leak compiler data structures in error message. //@ dont-require-annotations: NOTE struct RepeatMut<'a, T>(T, &'a ()); diff --git a/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr b/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr index a7a19e3c6dfdc..c3e1ed6e2641e 100644 --- a/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr +++ b/tests/ui/lifetimes/lifetime-errors/iterator-next-extra-named-lifetime.stderr @@ -1,5 +1,5 @@ error[E0308]: method not compatible with trait - --> $DIR/issue-37884.rs:8:5 + --> $DIR/iterator-next-extra-named-lifetime.rs:10:5 | LL | fn next(&'a mut self) -> Option | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch @@ -9,7 +9,7 @@ LL | fn next(&'a mut self) -> Option note: the anonymous lifetime as defined here... --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/issue-37884.rs:5:6 + --> $DIR/iterator-next-extra-named-lifetime.rs:7:6 | LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { | ^^ diff --git a/tests/ui/methods/ambig-method-call-in-trait-impl.rs b/tests/ui/methods/ambig-method-call-in-trait-impl.rs index d47f6d248f708..260ca0b546a3f 100644 --- a/tests/ui/methods/ambig-method-call-in-trait-impl.rs +++ b/tests/ui/methods/ambig-method-call-in-trait-impl.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to trigger LLVM assertion. + pub trait ToPrimitive { fn to_int(&self) -> isize { 0 } } diff --git a/tests/ui/methods/ambig-method-call-in-trait-impl.stderr b/tests/ui/methods/ambig-method-call-in-trait-impl.stderr index 448263aafd44e..0482346d9a482 100644 --- a/tests/ui/methods/ambig-method-call-in-trait-impl.stderr +++ b/tests/ui/methods/ambig-method-call-in-trait-impl.stderr @@ -1,16 +1,16 @@ error[E0034]: multiple applicable items in scope - --> $DIR/issue-3702-2.rs:16:14 + --> $DIR/ambig-method-call-in-trait-impl.rs:19:14 | LL | self.to_int() + other.to_int() | ^^^^^^ multiple `to_int` found | note: candidate #1 is defined in an impl of the trait `Add` for the type `isize` - --> $DIR/issue-3702-2.rs:14:5 + --> $DIR/ambig-method-call-in-trait-impl.rs:17:5 | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl of the trait `ToPrimitive` for the type `isize` - --> $DIR/issue-3702-2.rs:2:5 + --> $DIR/ambig-method-call-in-trait-impl.rs:5:5 | LL | fn to_int(&self) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/parser/other-module-struct-match.rs b/tests/ui/parser/other-module-struct-match.rs index 73aaab4183694..c9c7a9d52dbc1 100644 --- a/tests/ui/parser/other-module-struct-match.rs +++ b/tests/ui/parser/other-module-struct-match.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Pattern matching struct from different module caused parser to fail. //@ run-pass + mod buildings { pub struct Tower { pub height: usize } } diff --git a/tests/ui/parser/pub-method-after-attribute.rs b/tests/ui/parser/pub-method-after-attribute.rs index a243ceab83ebe..828fc52189b32 100644 --- a/tests/ui/parser/pub-method-after-attribute.rs +++ b/tests/ui/parser/pub-method-after-attribute.rs @@ -1,7 +1,6 @@ +//! Regression test for . +//! Pub keyword after attribute caused parser to fail. //@ run-pass -// Issue #3656 -// Issue Name: pub method preceded by attribute can't be parsed -// Abstract: Visibility parsing failed when compiler parsing use std::f64; diff --git a/tests/ui/traits/object/nested-trait-method-call.rs b/tests/ui/traits/object/nested-trait-method-call.rs index bb79e3a7f9384..c63671ba48a43 100644 --- a/tests/ui/traits/object/nested-trait-method-call.rs +++ b/tests/ui/traits/object/nested-trait-method-call.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Calling method of trait defined in function used to trigger LLVM assertion. //@ run-pass + #![allow(dead_code)] pub fn main() { diff --git a/tests/ui/unpretty/mir-unpretty-type-error.rs b/tests/ui/unpretty/mir-unpretty-type-error.rs index db74b1f025987..4b48a0126ac51 100644 --- a/tests/ui/unpretty/mir-unpretty-type-error.rs +++ b/tests/ui/unpretty/mir-unpretty-type-error.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test type error when compiling with `unpretty=mir` doesn't ICE. //@ compile-flags: -Z unpretty=mir use std::path::MAIN_SEPARATOR; diff --git a/tests/ui/unpretty/mir-unpretty-type-error.stderr b/tests/ui/unpretty/mir-unpretty-type-error.stderr index 2c404b4e74473..f0c19a23ed0e4 100644 --- a/tests/ui/unpretty/mir-unpretty-type-error.stderr +++ b/tests/ui/unpretty/mir-unpretty-type-error.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-37665.rs:9:17 + --> $DIR/mir-unpretty-type-error.rs:11:17 | LL | let x: () = 0; | -- ^ expected `()`, found integer From b1bddeba186921c7889d8343c184a551f334748a Mon Sep 17 00:00:00 2001 From: zedddie Date: Fri, 10 Jul 2026 23:23:01 +0200 Subject: [PATCH 05/77] move batch --- tests/ui/{issues/issue-3991.rs => borrowck/push-on-nested-vec.rs} | 0 .../repr-u64-enum-discriminant-cast.rs} | 0 .../issue-39827.rs => intrinsics/volatile-zst-intrinsics.rs} | 0 .../issue-39848.rs => macros/macro-adjacent-ident-on-token.rs} | 0 .../macro-adjacent-ident-on-token.stderr} | 0 .../issue-39709.rs => macros/macro-rules-def-in-block-expr.rs} | 0 tests/ui/{issues/issue-3895.rs => match/guard-arm-and-or-arm.rs} | 0 .../locally-pub-private-module-access.rs} | 0 .../locally-pub-private-module-access.stderr} | 0 .../default-method/nested-supertrait-method-in-default-body.rs} | 0 .../default-method/supertrait-method-in-default-body.rs} | 0 .../diverging-expr-unconstrained-type-param.rs} | 0 .../ui/{issues/issue-38954.rs => unsized/unsized-ref-fn-param.rs} | 0 .../issue-38954.stderr => unsized/unsized-ref-fn-param.stderr} | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-3991.rs => borrowck/push-on-nested-vec.rs} (100%) rename tests/ui/{issues/issue-38942.rs => enum-discriminant/repr-u64-enum-discriminant-cast.rs} (100%) rename tests/ui/{issues/issue-39827.rs => intrinsics/volatile-zst-intrinsics.rs} (100%) rename tests/ui/{issues/issue-39848.rs => macros/macro-adjacent-ident-on-token.rs} (100%) rename tests/ui/{issues/issue-39848.stderr => macros/macro-adjacent-ident-on-token.stderr} (100%) rename tests/ui/{issues/issue-39709.rs => macros/macro-rules-def-in-block-expr.rs} (100%) rename tests/ui/{issues/issue-3895.rs => match/guard-arm-and-or-arm.rs} (100%) rename tests/ui/{issues/issue-38857.rs => privacy/locally-pub-private-module-access.rs} (100%) rename tests/ui/{issues/issue-38857.stderr => privacy/locally-pub-private-module-access.stderr} (100%) rename tests/ui/{issues/issue-3979-2.rs => traits/default-method/nested-supertrait-method-in-default-body.rs} (100%) rename tests/ui/{issues/issue-3979.rs => traits/default-method/supertrait-method-in-default-body.rs} (100%) rename tests/ui/{issues/issue-39808.rs => type-inference/diverging-expr-unconstrained-type-param.rs} (100%) rename tests/ui/{issues/issue-38954.rs => unsized/unsized-ref-fn-param.rs} (100%) rename tests/ui/{issues/issue-38954.stderr => unsized/unsized-ref-fn-param.stderr} (100%) diff --git a/tests/ui/issues/issue-3991.rs b/tests/ui/borrowck/push-on-nested-vec.rs similarity index 100% rename from tests/ui/issues/issue-3991.rs rename to tests/ui/borrowck/push-on-nested-vec.rs diff --git a/tests/ui/issues/issue-38942.rs b/tests/ui/enum-discriminant/repr-u64-enum-discriminant-cast.rs similarity index 100% rename from tests/ui/issues/issue-38942.rs rename to tests/ui/enum-discriminant/repr-u64-enum-discriminant-cast.rs diff --git a/tests/ui/issues/issue-39827.rs b/tests/ui/intrinsics/volatile-zst-intrinsics.rs similarity index 100% rename from tests/ui/issues/issue-39827.rs rename to tests/ui/intrinsics/volatile-zst-intrinsics.rs diff --git a/tests/ui/issues/issue-39848.rs b/tests/ui/macros/macro-adjacent-ident-on-token.rs similarity index 100% rename from tests/ui/issues/issue-39848.rs rename to tests/ui/macros/macro-adjacent-ident-on-token.rs diff --git a/tests/ui/issues/issue-39848.stderr b/tests/ui/macros/macro-adjacent-ident-on-token.stderr similarity index 100% rename from tests/ui/issues/issue-39848.stderr rename to tests/ui/macros/macro-adjacent-ident-on-token.stderr diff --git a/tests/ui/issues/issue-39709.rs b/tests/ui/macros/macro-rules-def-in-block-expr.rs similarity index 100% rename from tests/ui/issues/issue-39709.rs rename to tests/ui/macros/macro-rules-def-in-block-expr.rs diff --git a/tests/ui/issues/issue-3895.rs b/tests/ui/match/guard-arm-and-or-arm.rs similarity index 100% rename from tests/ui/issues/issue-3895.rs rename to tests/ui/match/guard-arm-and-or-arm.rs diff --git a/tests/ui/issues/issue-38857.rs b/tests/ui/privacy/locally-pub-private-module-access.rs similarity index 100% rename from tests/ui/issues/issue-38857.rs rename to tests/ui/privacy/locally-pub-private-module-access.rs diff --git a/tests/ui/issues/issue-38857.stderr b/tests/ui/privacy/locally-pub-private-module-access.stderr similarity index 100% rename from tests/ui/issues/issue-38857.stderr rename to tests/ui/privacy/locally-pub-private-module-access.stderr diff --git a/tests/ui/issues/issue-3979-2.rs b/tests/ui/traits/default-method/nested-supertrait-method-in-default-body.rs similarity index 100% rename from tests/ui/issues/issue-3979-2.rs rename to tests/ui/traits/default-method/nested-supertrait-method-in-default-body.rs diff --git a/tests/ui/issues/issue-3979.rs b/tests/ui/traits/default-method/supertrait-method-in-default-body.rs similarity index 100% rename from tests/ui/issues/issue-3979.rs rename to tests/ui/traits/default-method/supertrait-method-in-default-body.rs diff --git a/tests/ui/issues/issue-39808.rs b/tests/ui/type-inference/diverging-expr-unconstrained-type-param.rs similarity index 100% rename from tests/ui/issues/issue-39808.rs rename to tests/ui/type-inference/diverging-expr-unconstrained-type-param.rs diff --git a/tests/ui/issues/issue-38954.rs b/tests/ui/unsized/unsized-ref-fn-param.rs similarity index 100% rename from tests/ui/issues/issue-38954.rs rename to tests/ui/unsized/unsized-ref-fn-param.rs diff --git a/tests/ui/issues/issue-38954.stderr b/tests/ui/unsized/unsized-ref-fn-param.stderr similarity index 100% rename from tests/ui/issues/issue-38954.stderr rename to tests/ui/unsized/unsized-ref-fn-param.stderr From b23c2ee07c39fd4a7e5bbc99604d0d05dcd31c6d Mon Sep 17 00:00:00 2001 From: zedddie Date: Fri, 10 Jul 2026 23:23:28 +0200 Subject: [PATCH 06/77] bless batch --- tests/ui/borrowck/push-on-nested-vec.rs | 4 +++- .../repr-u64-enum-discriminant-cast.rs | 3 ++- tests/ui/intrinsics/volatile-zst-intrinsics.rs | 10 +++++----- tests/ui/macros/macro-adjacent-ident-on-token.rs | 3 +++ tests/ui/macros/macro-adjacent-ident-on-token.stderr | 4 ++-- tests/ui/macros/macro-rules-def-in-block-expr.rs | 3 +++ tests/ui/match/guard-arm-and-or-arm.rs | 3 +++ tests/ui/privacy/locally-pub-private-module-access.rs | 3 +++ .../privacy/locally-pub-private-module-access.stderr | 4 ++-- .../nested-supertrait-method-in-default-body.rs | 2 ++ .../supertrait-method-in-default-body.rs | 3 +++ .../diverging-expr-unconstrained-type-param.rs | 10 +++++----- tests/ui/unsized/unsized-ref-fn-param.rs | 3 +++ tests/ui/unsized/unsized-ref-fn-param.stderr | 2 +- 14 files changed, 40 insertions(+), 17 deletions(-) diff --git a/tests/ui/borrowck/push-on-nested-vec.rs b/tests/ui/borrowck/push-on-nested-vec.rs index e69c693ed49ea..bbab952e85355 100644 --- a/tests/ui/borrowck/push-on-nested-vec.rs +++ b/tests/ui/borrowck/push-on-nested-vec.rs @@ -1,6 +1,8 @@ +//! Regression test for . +//! Test borrowck doesn't complain on nested vector mutable reference. //@ check-pass -#![allow(dead_code)] +#![allow(dead_code)] struct HasNested { nest: Vec > , diff --git a/tests/ui/enum-discriminant/repr-u64-enum-discriminant-cast.rs b/tests/ui/enum-discriminant/repr-u64-enum-discriminant-cast.rs index 3f80beb53f357..c9f6d6a65ea35 100644 --- a/tests/ui/enum-discriminant/repr-u64-enum-discriminant-cast.rs +++ b/tests/ui/enum-discriminant/repr-u64-enum-discriminant-cast.rs @@ -1,5 +1,6 @@ +//! Regression test for . +//! This used to ICE when compiling for `i686-apple-darwin`. //@ run-pass -// See https://github.com/rust-lang/rust/issues/38942 #[repr(u64)] pub enum NSEventType { diff --git a/tests/ui/intrinsics/volatile-zst-intrinsics.rs b/tests/ui/intrinsics/volatile-zst-intrinsics.rs index e3248c9e9ac72..0927442268d1f 100644 --- a/tests/ui/intrinsics/volatile-zst-intrinsics.rs +++ b/tests/ui/intrinsics/volatile-zst-intrinsics.rs @@ -1,3 +1,8 @@ +//! Regression test for . +//! This test ensures that volatile intrinsics can be specialised with +//! zero-sized types and, in case of copy/set functions, can accept +//! number of elements equal to zero. + //@ run-pass #![feature(core_intrinsics)] @@ -5,11 +10,6 @@ use std::intrinsics::{ volatile_copy_memory, volatile_store, volatile_load, volatile_copy_nonoverlapping_memory, volatile_set_memory }; -// -// This test ensures that volatile intrinsics can be specialised with -// zero-sized types and, in case of copy/set functions, can accept -// number of elements equal to zero. -// fn main () { let mut dst_pair = (1, 2); let src_pair = (3, 4); diff --git a/tests/ui/macros/macro-adjacent-ident-on-token.rs b/tests/ui/macros/macro-adjacent-ident-on-token.rs index 2a059120e8175..5e57f427724aa 100644 --- a/tests/ui/macros/macro-adjacent-ident-on-token.rs +++ b/tests/ui/macros/macro-adjacent-ident-on-token.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to ice on `IllFormedSpan`. + macro_rules! get_opt { ($tgt:expr, $field:ident) => { if $tgt.has_$field() {} //~ ERROR expected `{`, found identifier `foo` diff --git a/tests/ui/macros/macro-adjacent-ident-on-token.stderr b/tests/ui/macros/macro-adjacent-ident-on-token.stderr index 1ffed2d4a1da1..b13a3d45828d3 100644 --- a/tests/ui/macros/macro-adjacent-ident-on-token.stderr +++ b/tests/ui/macros/macro-adjacent-ident-on-token.stderr @@ -1,5 +1,5 @@ error: expected `{`, found identifier `foo` - --> $DIR/issue-39848.rs:3:21 + --> $DIR/macro-adjacent-ident-on-token.rs:6:21 | LL | if $tgt.has_$field() {} | ^^^^^^ expected `{` @@ -8,7 +8,7 @@ LL | get_opt!(bar, foo); | ------------------ in this macro invocation | note: the `if` expression is missing a block after this condition - --> $DIR/issue-39848.rs:3:12 + --> $DIR/macro-adjacent-ident-on-token.rs:6:12 | LL | if $tgt.has_$field() {} | ^^^^^^^^^ diff --git a/tests/ui/macros/macro-rules-def-in-block-expr.rs b/tests/ui/macros/macro-rules-def-in-block-expr.rs index df3286721f51f..4074c6c9cac1e 100644 --- a/tests/ui/macros/macro-rules-def-in-block-expr.rs +++ b/tests/ui/macros/macro-rules-def-in-block-expr.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Macro definition inside block expression caused ICE. //@ run-pass + #![allow(unused_macros)] fn main() { println!("{}", { macro_rules! x { ($(t:tt)*) => {} } 33 }); diff --git a/tests/ui/match/guard-arm-and-or-arm.rs b/tests/ui/match/guard-arm-and-or-arm.rs index 6bd173d48785b..0296ee0d3cc3c 100644 --- a/tests/ui/match/guard-arm-and-or-arm.rs +++ b/tests/ui/match/guard-arm-and-or-arm.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Match with guard arm and or pattern used to ICE. //@ run-pass + #![allow(dead_code)] pub fn main() { diff --git a/tests/ui/privacy/locally-pub-private-module-access.rs b/tests/ui/privacy/locally-pub-private-module-access.rs index 63a0af759a3de..7939219b6a999 100644 --- a/tests/ui/privacy/locally-pub-private-module-access.rs +++ b/tests/ui/privacy/locally-pub-private-module-access.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Trying to access locally pub but inaccessible items caused ICE. + fn main() { let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; //~^ ERROR: cannot find `imp` in `sys` [E0433] diff --git a/tests/ui/privacy/locally-pub-private-module-access.stderr b/tests/ui/privacy/locally-pub-private-module-access.stderr index 85a0c266ac657..5f69f1a660923 100644 --- a/tests/ui/privacy/locally-pub-private-module-access.stderr +++ b/tests/ui/privacy/locally-pub-private-module-access.stderr @@ -1,11 +1,11 @@ error[E0433]: cannot find `imp` in `sys` - --> $DIR/issue-38857.rs:2:23 + --> $DIR/locally-pub-private-module-access.rs:5:23 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; | ^^^ could not find `imp` in `sys` error[E0603]: module `sys` is private - --> $DIR/issue-38857.rs:2:18 + --> $DIR/locally-pub-private-module-access.rs:5:18 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; | ^^^ private module diff --git a/tests/ui/traits/default-method/nested-supertrait-method-in-default-body.rs b/tests/ui/traits/default-method/nested-supertrait-method-in-default-body.rs index 98b6e85225db5..5516b58e57624 100644 --- a/tests/ui/traits/default-method/nested-supertrait-method-in-default-body.rs +++ b/tests/ui/traits/default-method/nested-supertrait-method-in-default-body.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test calling nested supertrait's method in default method body works. //@ check-pass trait A { diff --git a/tests/ui/traits/default-method/supertrait-method-in-default-body.rs b/tests/ui/traits/default-method/supertrait-method-in-default-body.rs index 238df225f0f34..597ff6375c7a2 100644 --- a/tests/ui/traits/default-method/supertrait-method-in-default-body.rs +++ b/tests/ui/traits/default-method/supertrait-method-in-default-body.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Test calling supertrait's method in default method body works. //@ run-pass + #![allow(dead_code)] #![allow(non_snake_case)] diff --git a/tests/ui/type-inference/diverging-expr-unconstrained-type-param.rs b/tests/ui/type-inference/diverging-expr-unconstrained-type-param.rs index 99e3d9b4bcdfd..1e523dcc66ea0 100644 --- a/tests/ui/type-inference/diverging-expr-unconstrained-type-param.rs +++ b/tests/ui/type-inference/diverging-expr-unconstrained-type-param.rs @@ -1,10 +1,10 @@ +//! Regression test for . +//! The type parameter of `Owned` was considered to be "unconstrained" +//! because the type resulting from `format!` (`String`) was not being +//! propagated upward, owing to the fact that the expression diverges. //@ run-pass -#![allow(unreachable_code)] -// Regression test for #39808. The type parameter of `Owned` was -// considered to be "unconstrained" because the type resulting from -// `format!` (`String`) was not being propagated upward, owing to the -// fact that the expression diverges. +#![allow(unreachable_code)] use std::borrow::Cow; diff --git a/tests/ui/unsized/unsized-ref-fn-param.rs b/tests/ui/unsized/unsized-ref-fn-param.rs index 61df411b1f92b..9a36e82b049fe 100644 --- a/tests/ui/unsized/unsized-ref-fn-param.rs +++ b/tests/ui/unsized/unsized-ref-fn-param.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test we emit helpful error message instead of silently failing. + fn _test(ref _p: str) {} //~^ ERROR the size for values of type diff --git a/tests/ui/unsized/unsized-ref-fn-param.stderr b/tests/ui/unsized/unsized-ref-fn-param.stderr index bd9c5e4197bc7..3fa5758d2083a 100644 --- a/tests/ui/unsized/unsized-ref-fn-param.stderr +++ b/tests/ui/unsized/unsized-ref-fn-param.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/issue-38954.rs:1:18 + --> $DIR/unsized-ref-fn-param.rs:4:18 | LL | fn _test(ref _p: str) {} | ^^^ doesn't have a size known at compile-time From c703f8a4e8449fafe610d1e55493f8d7db0faf1f Mon Sep 17 00:00:00 2001 From: Xuyang Zhang Date: Sat, 11 Jul 2026 23:38:43 +0800 Subject: [PATCH 07/77] doc: document wasm import symbol mangling --- src/doc/rustc/src/symbol-mangling/index.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/symbol-mangling/index.md b/src/doc/rustc/src/symbol-mangling/index.md index 3f7d55063ca6a..f1f242698602a 100644 --- a/src/doc/rustc/src/symbol-mangling/index.md +++ b/src/doc/rustc/src/symbol-mangling/index.md @@ -17,13 +17,18 @@ The [`#[export_name]`attribute][reference-export_name] can be used to specify th Items listed in an [`extern` block][reference-extern-block] use the identifier of the item without mangling to refer to the item. The [`#[link_name]` attribute][reference-link_name] can be used to change that name. - +### WebAssembly import modules + +On WebAssembly targets, foreign items in an `extern` block using +[`#[link(wasm_import_module = "...")]`][reference-link-attribute] are mangled even if +`#[no_mangle]` or `#[link_name]` is used. This distinguishes imports with the same name from +different WebAssembly modules. The requested module and import name are emitted separately in +the WebAssembly import metadata. [reference-no_mangle]: ../../reference/abi.html#the-no_mangle-attribute [reference-export_name]: ../../reference/abi.html#the-export_name-attribute [reference-link_name]: ../../reference/items/external-blocks.html#the-link_name-attribute +[reference-link-attribute]: ../../reference/items/external-blocks.html#the-link-attribute [reference-extern-block]: ../../reference/items/external-blocks.html ## Decoding From c100acadff82a6fea8660e6a9bbaf64f4d0768fa Mon Sep 17 00:00:00 2001 From: Xuyang Zhang Date: Mon, 13 Jul 2026 18:26:11 +0800 Subject: [PATCH 08/77] doc: clarify wasm import symbol mangling --- src/doc/rustc/src/symbol-mangling/index.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc/src/symbol-mangling/index.md b/src/doc/rustc/src/symbol-mangling/index.md index f1f242698602a..3bb3937f9c16e 100644 --- a/src/doc/rustc/src/symbol-mangling/index.md +++ b/src/doc/rustc/src/symbol-mangling/index.md @@ -19,11 +19,14 @@ The [`#[link_name]` attribute][reference-link_name] can be used to change that n ### WebAssembly import modules -On WebAssembly targets, foreign items in an `extern` block using -[`#[link(wasm_import_module = "...")]`][reference-link-attribute] are mangled even if -`#[no_mangle]` or `#[link_name]` is used. This distinguishes imports with the same name from -different WebAssembly modules. The requested module and import name are emitted separately in -the WebAssembly import metadata. +On WebAssembly targets, rustc currently mangles foreign items in an `extern` block using +[`#[link(wasm_import_module = "...")]`][reference-link-attribute], even if `#[no_mangle]` or +`#[link_name]` is used. + +This is an implementation detail of the current WebAssembly code generation and linking setup, +and may change. It avoids current linker and code generation behavior that can conflate +same-named imports from different WebAssembly modules. The requested module and import name are +emitted as the `wasm-import-module` and `wasm-import-name` LLVM attributes. [reference-no_mangle]: ../../reference/abi.html#the-no_mangle-attribute [reference-export_name]: ../../reference/abi.html#the-export_name-attribute From f2663375c0163972e8009725eb348a089d514e0d Mon Sep 17 00:00:00 2001 From: Xuyang Zhang Date: Mon, 13 Jul 2026 20:52:14 +0800 Subject: [PATCH 09/77] doc: describe wasm import conflict behavior --- src/doc/rustc/src/symbol-mangling/index.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/doc/rustc/src/symbol-mangling/index.md b/src/doc/rustc/src/symbol-mangling/index.md index 3bb3937f9c16e..67df4f0a9b07f 100644 --- a/src/doc/rustc/src/symbol-mangling/index.md +++ b/src/doc/rustc/src/symbol-mangling/index.md @@ -19,14 +19,9 @@ The [`#[link_name]` attribute][reference-link_name] can be used to change that n ### WebAssembly import modules -On WebAssembly targets, rustc currently mangles foreign items in an `extern` block using -[`#[link(wasm_import_module = "...")]`][reference-link-attribute], even if `#[no_mangle]` or -`#[link_name]` is used. - -This is an implementation detail of the current WebAssembly code generation and linking setup, -and may change. It avoids current linker and code generation behavior that can conflate -same-named imports from different WebAssembly modules. The requested module and import name are -emitted as the `wasm-import-module` and `wasm-import-name` LLVM attributes. +On WebAssembly targets, foreign items in `extern` blocks can use the same import name without +conflicting when they use different [`#[link(wasm_import_module = "...")]`][reference-link-attribute] +values. [reference-no_mangle]: ../../reference/abi.html#the-no_mangle-attribute [reference-export_name]: ../../reference/abi.html#the-export_name-attribute From 032d95925f7f1f8cb28be62e67d669c2d293910d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 15 Jul 2026 08:10:46 +0200 Subject: [PATCH 10/77] ensure to check that the overview is current --- src/doc/rustc-dev-guide/src/about-this-guide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index 56fbc1f6b7a85..b716bd7184dee 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -1,5 +1,7 @@ # About this guide + + This guide is meant to help document how rustc – the Rust compiler – works, as well as to help new contributors get involved in rustc development. From a61a054a1781b7681fe7155c570a33efb2fa65a5 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 15 Jul 2026 08:12:52 +0200 Subject: [PATCH 11/77] use sentence case for titles --- src/doc/rustc-dev-guide/src/SUMMARY.md | 6 +++--- src/doc/rustc-dev-guide/src/about-this-guide.md | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index bf2de84575d69..b01afcaf78496 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -86,7 +86,7 @@ - [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md) - [cfg(bootstrap) in dependencies](./building/bootstrapping/bootstrap-in-dependencies.md) -# High-level Compiler Architecture +# High-level compiler architecture - [Prologue](./part-2-intro.md) - [Overview of the compiler](./overview.md) @@ -115,7 +115,7 @@ - [Autodiff flags](./autodiff/flags.md) - [Type Trees](./autodiff/type-trees.md) -# Source Code Representation +# Source code representation - [Prologue](./part-3-intro.md) - [Syntax and the AST](./syntax-intro.md) @@ -140,7 +140,7 @@ - [MIR queries and passes: getting the MIR](./mir/passes.md) - [Inline assembly](./asm.md) -# Supporting Infrastructure +# Supporting infrastructure - [Command-line arguments](./cli.md) - [rustc_driver and rustc_interface](./rustc-driver/intro.md) diff --git a/src/doc/rustc-dev-guide/src/about-this-guide.md b/src/doc/rustc-dev-guide/src/about-this-guide.md index b716bd7184dee..6282a66e13b07 100644 --- a/src/doc/rustc-dev-guide/src/about-this-guide.md +++ b/src/doc/rustc-dev-guide/src/about-this-guide.md @@ -16,18 +16,18 @@ There are several parts to this guide: 1. [Bootstrapping][p3]: Describes how the Rust compiler builds itself using previous versions, including an introduction to the bootstrap process and debugging methods. -1. [High-level Compiler Architecture][p4]: +1. [High-level compiler architecture][p4]: Discusses the high-level architecture of the compiler and stages of the compile process. -1. [Source Code Representation][p5]: +1. [Source code representation][p5]: Describes the process of taking raw source code from the user and transforming it into various forms that the compiler can work with easily. -1. [Supporting Infrastructure][p6]: +1. [Supporting infrastructure][p6]: Covers command-line argument conventions, compiler entry points like rustc_driver and rustc_interface, and the design and implementation of errors and lints. 1. [Analysis][p7]: Discusses the analyses that the compiler uses to check various properties of the code and inform later stages of the compile process (e.g., type checking). -1. [MIR to Binaries][p8]: How linked executable machine code is generated. +1. [Mir to binaries][p8]: How linked executable machine code is generated. 1. [Appendices][p9] at the end with useful reference information. There are a few of these with different information, including a glossary. From 821701a993edfac79bc29c0be76660bcc0d372b0 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Wed, 15 Jul 2026 16:46:52 +0800 Subject: [PATCH 12/77] fix rustup update command for autodiff --- src/doc/rustc-dev-guide/src/autodiff/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/autodiff/installation.md b/src/doc/rustc-dev-guide/src/autodiff/installation.md index c0da9621f9777..acbb7c9eb09f3 100644 --- a/src/doc/rustc-dev-guide/src/autodiff/installation.md +++ b/src/doc/rustc-dev-guide/src/autodiff/installation.md @@ -20,7 +20,7 @@ rustup +nightly component add enzyme Older rustup versions are not aware of this component, so if you run into issues try updating rustup itself: ```console -rustup update +rustup self update rustup +nightly component add enzyme ``` From 905a7e08b83e9d28d27e6336cfe05694a30ab22c Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Thu, 16 Jul 2026 10:56:16 -0300 Subject: [PATCH 13/77] Track placeholder assumptions for created universes --- .../src/canonical/mod.rs | 8 ++++++- .../src/placeholder.rs | 24 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index b2f6ac78040b6..0b98f312481da 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -160,7 +160,13 @@ where let prev_universe = delegate.universe(); let universes_created_in_query = response.max_universe.index(); for _ in 0..universes_created_in_query { - delegate.create_next_universe(); + let new_universe = delegate.create_next_universe(); + if delegate.cx().assumptions_on_binders() { + delegate.insert_placeholder_assumptions( + new_universe, + Some(rustc_type_ir::region_constraint::Assumptions::empty()), + ); + } } let var_values = response.value.var_values(); diff --git a/compiler/rustc_next_trait_solver/src/placeholder.rs b/compiler/rustc_next_trait_solver/src/placeholder.rs index b5bb488c43b89..cc463304c5152 100644 --- a/compiler/rustc_next_trait_solver/src/placeholder.rs +++ b/compiler/rustc_next_trait_solver/src/placeholder.rs @@ -47,6 +47,7 @@ where IndexMap, ty::BoundTy>, IndexMap, ty::BoundConst>, ) { + let old_universes = universe_indices.clone(); let mut replacer = BoundVarReplacer { infcx, mapped_regions: Default::default(), @@ -57,8 +58,29 @@ where }; let value = value.fold_with(&mut replacer); + let BoundVarReplacer { + mapped_regions, + mapped_types, + mapped_consts, + universe_indices, + infcx: _, + current_index: _, + } = replacer; + + if infcx.cx().assumptions_on_binders() { + for (old, new) in old_universes.into_iter().zip(universe_indices.iter()) { + if let (None, Some(new)) = (old, new) { + // FIXME(-Zassumptions-on-binders): `replace_bound_vars` does not have enough + // context to compute placeholder assumptions for the binders it enters. + infcx.insert_placeholder_assumptions( + *new, + Some(rustc_type_ir::region_constraint::Assumptions::empty()), + ); + } + } + } - (value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts) + (value, mapped_regions, mapped_types, mapped_consts) } fn universe_for(&mut self, debruijn: ty::DebruijnIndex) -> ty::UniverseIndex { From 8211f9061397ec204877641153254f5ac8406002 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Thu, 16 Jul 2026 10:56:31 -0300 Subject: [PATCH 14/77] Add coverage for placeholder assumption ICE --- .../placeholder-assumptions-issue-157840.rs | 17 +++++++++++++++++ .../placeholder-assumptions-issue-157840.stderr | 14 ++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs create mode 100644 tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs new file mode 100644 index 0000000000000..74f0618e4291f --- /dev/null +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Znext-solver=globally -Zassumptions-on-binders + +trait Trait {} + +trait Proj<'a> { + type Assoc; +} + +fn foo<'a, T>() +where + T: Proj<'a, Assoc = fn(::Assoc)>, + (): Trait<>::Assoc>, + //~^ ERROR the trait bound `(): Trait fn(>::Assoc))>` is not satisfied +{ +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr new file mode 100644 index 0000000000000..5e8e131addd28 --- /dev/null +++ b/tests/ui/assumptions_on_binders/placeholder-assumptions-issue-157840.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `(): Trait fn(>::Assoc))>` is not satisfied + --> $DIR/placeholder-assumptions-issue-157840.rs:12:9 + | +LL | (): Trait<>::Assoc>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait fn(>::Assoc))>` is not implemented for `()` + | +help: consider extending the `where` clause, but there might be an alternative better way to express this requirement + | +LL | (): Trait<>::Assoc>, (): Trait fn(>::Assoc))> + | +++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 4f1921c367350d7f328667bcb79468173a56aee7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 16 Jul 2026 18:01:35 +0200 Subject: [PATCH 15/77] use sentence case for titles --- src/doc/rustc-dev-guide/src/SUMMARY.md | 6 +++--- src/doc/rustc-dev-guide/src/const-generics.md | 10 +++++----- src/doc/rustc-dev-guide/src/normalization.md | 12 ++++++------ src/doc/rustc-dev-guide/src/typing-parameter-envs.md | 10 +++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index b01afcaf78496..91bb143eb318f 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -167,8 +167,8 @@ - [ADTs and Generic Arguments](./ty-module/generic-arguments.md) - [Parameter types/consts/regions](./ty-module/param-ty-const-regions.md) - [`TypeFolder` and `TypeFoldable`](./ty-fold.md) -- [Aliases and Normalization](./normalization.md) -- [Typing/Param Envs](./typing-parameter-envs.md) +- [Aliases and normalization](./normalization.md) +- [Typing/Param envs](./typing-parameter-envs.md) - [Type inference](./type-inference.md) - [Trait solving](./traits/resolution.md) - [Higher-ranked trait bounds](./traits/hrtb.md) @@ -199,7 +199,7 @@ - [HIR Type checking](./hir-typeck/summary.md) - [Coercions](./hir-typeck/coercions.md) - [Method lookup](./hir-typeck/method-lookup.md) -- [Const Generics](./const-generics.md) +- [Const generics](./const-generics.md) - [Opaque types](./opaque-types-type-alias-impl-trait.md) - [Inference details](./opaque-types-impl-trait-inference.md) - [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md) diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md index 3f84b99fb637e..8e1a46a14f151 100644 --- a/src/doc/rustc-dev-guide/src/const-generics.md +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -1,4 +1,4 @@ -# Const Generics +# Const generics ## Kinds of const arguments @@ -15,9 +15,9 @@ Inference Variables are quite boring and treated equivalently to type inference Const Parameters are also similarly boring and equivalent to uses of type parameters almost everywhere. However, there are some interesting subtleties with how they are handled during parsing, name resolution, and AST lowering: [ambig-unambig-ty-and-consts]. -## Anon Consts +## Anon consts -Anon Consts (short for anonymous const items) are how arbitrary expression are represented in const generics, for example an array length of `1 + 1` or `foo()` or even just `0`. +Anon consts (short for anonymous const items) are how arbitrary expression are represented in const generics, for example an array length of `1 + 1` or `foo()` or even just `0`. These are unique to const generics and have no real type equivalent. ### Desugaring @@ -85,7 +85,7 @@ After all of this desugaring has taken place the final representation in the typ This allows the representation for const "aliases" to be the same as the representation of `TyKind::Alias`. Having a proper HIR body also allows for a *lot* of code re-use, e.g. we can reuse HIR typechecking and all of the lowering steps to MIR where we can then reuse const eval. -### Enforcing lack of Generic Parameters +### Enforcing lack of generic parameters There are three ways that we enforce anon consts can't use generic parameters: 1. Name Resolution will not resolve paths to generic parameters when inside of an anon const @@ -182,7 +182,7 @@ It is currently unclear what the right way to make `generic_const_parameter_type `min_generic_const_args` will allow for some expressions (for example array construction) to be representable without an anon const and therefore without running into these issues, though whether this is *enough* has yet to be determined. -## Checking types of Const Arguments +## Checking types of const arguments In order for a const argument to be well formed it must have the same type as the const parameter it is an argument to. For example, a const argument of type `bool` for an array length is not well formed, as an array's length parameter has type `usize`. diff --git a/src/doc/rustc-dev-guide/src/normalization.md b/src/doc/rustc-dev-guide/src/normalization.md index 6e98ff8f4b8a3..8c7500cb754b9 100644 --- a/src/doc/rustc-dev-guide/src/normalization.md +++ b/src/doc/rustc-dev-guide/src/normalization.md @@ -1,4 +1,4 @@ -# Aliases and Normalization +# Aliases and normalization ## Aliases @@ -17,7 +17,7 @@ so this chapter mostly discusses things in the context of types (even though the [`TyKind::Alias`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/enum.TyKind.html#variant.Alias [`AliasTyKind`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/enum.AliasTyKind.html -### Rigid, Ambiguous and Unnormalized Aliases +### Rigid, ambiguous and unnormalized aliases Aliases can either be "rigid", "ambiguous", or simply unnormalized. @@ -68,7 +68,7 @@ only it just hasn't been done yet. It is worth noting that Free and Inherent aliases cannot be rigid or ambiguous as naming them also implies having resolved the definition of the alias, which specifies the underlying type of the alias. -### Diverging Aliases +### Diverging aliases An alias is considered to "diverge" if its definition does not specify an underlying non-alias type to normalize to. A concrete example of diverging aliases: @@ -126,11 +126,11 @@ fn main() { In this example, we only encounter an error from the diverging alias during codegen of `foo::<()>`. If the call to `foo` is removed, then no compilation error will be emitted. -### Opaque Types +### Opaque types Opaque types are a relatively special kind of alias, and are covered in [their own chapter](opaque-types-type-alias-impl-trait.md). -### Const Aliases +### Const aliases Unlike type aliases, const aliases are not represented directly in the type system. Instead, const aliases are always an anonymous body containing a path expression to a const item. @@ -157,7 +157,7 @@ fn bar() { This is likely to change as const generics functionality is improved. For example, `feature(associated_const_equality)` and `feature(min_generic_const_args)` both require handling const aliases similarly to types (without an anonymous constant wrapping all const args). -## What is Normalization +## What is normalization ### Structural vs deep normalization diff --git a/src/doc/rustc-dev-guide/src/typing-parameter-envs.md b/src/doc/rustc-dev-guide/src/typing-parameter-envs.md index 45635ebfa15d6..db9f369d2659e 100644 --- a/src/doc/rustc-dev-guide/src/typing-parameter-envs.md +++ b/src/doc/rustc-dev-guide/src/typing-parameter-envs.md @@ -1,6 +1,6 @@ -# Typing/Parameter Environments +# Typing/Parameter environments -## Typing Environments +## Typing environments When interacting with the type system there are a few variables to consider that can affect the results of trait solving. The set of in-scope where clauses, and what phase of the compiler type system operations are being performed in (the [`ParamEnv`][penv] and [`TypingMode`][tmode] structs respectively). @@ -14,7 +14,7 @@ whereas different `ParamEnv`s can be used on a per-goal basis. [ocx]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/struct.ObligationCtxt.html [fnctxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html -## Parameter Environments +## Parameter environments ### What is a `ParamEnv` @@ -197,7 +197,7 @@ impl Other for T { // `foo`'s unnormalized `ParamEnv` would be: // `[T: Sized, U: Sized, U: Trait]` -fn foo(a: U) +fn foo(a: U) where U: Trait<::Bar>, { @@ -222,7 +222,7 @@ In the next-gen trait solver the requirement for all where clauses in the `Param [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html [normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html -## Typing Modes +## Typing modes Depending on what context we are performing type system operations in, different behaviour may be required. From 1a180c01fbeb1ef72de0c023752f4313aed04d22 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 16 Jul 2026 18:03:20 +0200 Subject: [PATCH 16/77] reflow --- src/doc/rustc-dev-guide/src/const-generics.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/const-generics.md b/src/doc/rustc-dev-guide/src/const-generics.md index 8e1a46a14f151..9e26a174d8cf6 100644 --- a/src/doc/rustc-dev-guide/src/const-generics.md +++ b/src/doc/rustc-dev-guide/src/const-generics.md @@ -134,7 +134,9 @@ fn foo() { } ``` -However, to avoid most of the problems involved in allowing generic parameters in anon const const arguments we require that the constant be evaluated before monomorphization (e.g. during type checking). In some sense we only allow generic parameters here when they are semantically unused. +However, to avoid most of the problems involved in allowing generic parameters in anon const const arguments, +we require that the constant be evaluated before monomorphization (e.g. during type checking). +In some sense we only allow generic parameters here when they are semantically unused. In the previous example the anon const can be evaluated for any type parameter `T` because raw pointers to sized types always have the same size (e.g. `8` on 64bit platforms). From 75870305c3883068577e154c7fa3986b5f4d3f4d Mon Sep 17 00:00:00 2001 From: zedddie Date: Thu, 16 Jul 2026 23:51:04 +0200 Subject: [PATCH 17/77] move batch --- .../cache/poison-copy-via-projection.rs} | 0 .../cache/poison-copy-via-projection.stderr} | 0 .../coherence-overlap-downstream-fundamental.rs} | 0 .../coherence-overlap-downstream-fundamental.stderr} | 0 .../issue-43250.rs => lowering/expr-metavar-in-let-pattern.rs} | 0 .../expr-metavar-in-let-pattern.stderr} | 0 .../issue-43424.rs => macros/attr-path-metavar-generic-args.rs} | 0 .../attr-path-metavar-generic-args.stderr} | 0 .../issue-42880.rs => pattern/type-alias-as-variant-pattern.rs} | 0 .../type-alias-as-variant-pattern.stderr} | 0 .../instant-add-duration-overflow.rs} | 0 .../instant-sub-duration-overflow.rs} | 0 .../system-time-add-duration-overflow.rs} | 0 .../system-time-sub-duration-overflow.rs} | 0 .../issue-43853.rs => traits/coerce-diverging-through-from.rs} | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-42796.rs => associated-types/cache/poison-copy-via-projection.rs} (100%) rename tests/ui/{issues/issue-42796.stderr => associated-types/cache/poison-copy-via-projection.stderr} (100%) rename tests/ui/{issues/issue-43355.rs => coherence/coherence-overlap-downstream-fundamental.rs} (100%) rename tests/ui/{issues/issue-43355.stderr => coherence/coherence-overlap-downstream-fundamental.stderr} (100%) rename tests/ui/{issues/issue-43250.rs => lowering/expr-metavar-in-let-pattern.rs} (100%) rename tests/ui/{issues/issue-43250.stderr => lowering/expr-metavar-in-let-pattern.stderr} (100%) rename tests/ui/{issues/issue-43424.rs => macros/attr-path-metavar-generic-args.rs} (100%) rename tests/ui/{issues/issue-43424.stderr => macros/attr-path-metavar-generic-args.stderr} (100%) rename tests/ui/{issues/issue-42880.rs => pattern/type-alias-as-variant-pattern.rs} (100%) rename tests/ui/{issues/issue-42880.stderr => pattern/type-alias-as-variant-pattern.stderr} (100%) rename tests/ui/{issues/issue-44216-add-instant.rs => std/instant-add-duration-overflow.rs} (100%) rename tests/ui/{issues/issue-44216-sub-instant.rs => std/instant-sub-duration-overflow.rs} (100%) rename tests/ui/{issues/issue-44216-add-system-time.rs => std/system-time-add-duration-overflow.rs} (100%) rename tests/ui/{issues/issue-44216-sub-system-time.rs => std/system-time-sub-duration-overflow.rs} (100%) rename tests/ui/{issues/issue-43853.rs => traits/coerce-diverging-through-from.rs} (100%) diff --git a/tests/ui/issues/issue-42796.rs b/tests/ui/associated-types/cache/poison-copy-via-projection.rs similarity index 100% rename from tests/ui/issues/issue-42796.rs rename to tests/ui/associated-types/cache/poison-copy-via-projection.rs diff --git a/tests/ui/issues/issue-42796.stderr b/tests/ui/associated-types/cache/poison-copy-via-projection.stderr similarity index 100% rename from tests/ui/issues/issue-42796.stderr rename to tests/ui/associated-types/cache/poison-copy-via-projection.stderr diff --git a/tests/ui/issues/issue-43355.rs b/tests/ui/coherence/coherence-overlap-downstream-fundamental.rs similarity index 100% rename from tests/ui/issues/issue-43355.rs rename to tests/ui/coherence/coherence-overlap-downstream-fundamental.rs diff --git a/tests/ui/issues/issue-43355.stderr b/tests/ui/coherence/coherence-overlap-downstream-fundamental.stderr similarity index 100% rename from tests/ui/issues/issue-43355.stderr rename to tests/ui/coherence/coherence-overlap-downstream-fundamental.stderr diff --git a/tests/ui/issues/issue-43250.rs b/tests/ui/lowering/expr-metavar-in-let-pattern.rs similarity index 100% rename from tests/ui/issues/issue-43250.rs rename to tests/ui/lowering/expr-metavar-in-let-pattern.rs diff --git a/tests/ui/issues/issue-43250.stderr b/tests/ui/lowering/expr-metavar-in-let-pattern.stderr similarity index 100% rename from tests/ui/issues/issue-43250.stderr rename to tests/ui/lowering/expr-metavar-in-let-pattern.stderr diff --git a/tests/ui/issues/issue-43424.rs b/tests/ui/macros/attr-path-metavar-generic-args.rs similarity index 100% rename from tests/ui/issues/issue-43424.rs rename to tests/ui/macros/attr-path-metavar-generic-args.rs diff --git a/tests/ui/issues/issue-43424.stderr b/tests/ui/macros/attr-path-metavar-generic-args.stderr similarity index 100% rename from tests/ui/issues/issue-43424.stderr rename to tests/ui/macros/attr-path-metavar-generic-args.stderr diff --git a/tests/ui/issues/issue-42880.rs b/tests/ui/pattern/type-alias-as-variant-pattern.rs similarity index 100% rename from tests/ui/issues/issue-42880.rs rename to tests/ui/pattern/type-alias-as-variant-pattern.rs diff --git a/tests/ui/issues/issue-42880.stderr b/tests/ui/pattern/type-alias-as-variant-pattern.stderr similarity index 100% rename from tests/ui/issues/issue-42880.stderr rename to tests/ui/pattern/type-alias-as-variant-pattern.stderr diff --git a/tests/ui/issues/issue-44216-add-instant.rs b/tests/ui/std/instant-add-duration-overflow.rs similarity index 100% rename from tests/ui/issues/issue-44216-add-instant.rs rename to tests/ui/std/instant-add-duration-overflow.rs diff --git a/tests/ui/issues/issue-44216-sub-instant.rs b/tests/ui/std/instant-sub-duration-overflow.rs similarity index 100% rename from tests/ui/issues/issue-44216-sub-instant.rs rename to tests/ui/std/instant-sub-duration-overflow.rs diff --git a/tests/ui/issues/issue-44216-add-system-time.rs b/tests/ui/std/system-time-add-duration-overflow.rs similarity index 100% rename from tests/ui/issues/issue-44216-add-system-time.rs rename to tests/ui/std/system-time-add-duration-overflow.rs diff --git a/tests/ui/issues/issue-44216-sub-system-time.rs b/tests/ui/std/system-time-sub-duration-overflow.rs similarity index 100% rename from tests/ui/issues/issue-44216-sub-system-time.rs rename to tests/ui/std/system-time-sub-duration-overflow.rs diff --git a/tests/ui/issues/issue-43853.rs b/tests/ui/traits/coerce-diverging-through-from.rs similarity index 100% rename from tests/ui/issues/issue-43853.rs rename to tests/ui/traits/coerce-diverging-through-from.rs From 74c230edd24e3507d7a7212ef91b54e6e1c3457b Mon Sep 17 00:00:00 2001 From: sgasho Date: Fri, 10 Jul 2026 11:00:59 +0000 Subject: [PATCH 18/77] ci: Enable autodiff tests on x86_64 linux * Enable autodiff tests on x86_64 linux * move autodiff job def * remove redundant ./x build --- .../optional-x86_64-gnu-autodiff/Dockerfile | 37 +++++++++++++++++++ src/ci/docker/scripts/autodiff.sh | 9 +++++ src/ci/github-actions/jobs.yml | 4 ++ 3 files changed, 50 insertions(+) create mode 100644 src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile create mode 100755 src/ci/docker/scripts/autodiff.sh diff --git a/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile b/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile new file mode 100644 index 0000000000000..f4633f951c645 --- /dev/null +++ b/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile @@ -0,0 +1,37 @@ +FROM ubuntu:24.04 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + pkg-config \ + xz-utils \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +COPY scripts/autodiff.sh /scripts/ + +ENV NO_DOWNLOAD_CI_LLVM 1 +ENV CODEGEN_BACKENDS llvm + +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --enable-llvm-enzyme \ + --enable-llvm-link-shared \ + --enable-ninja \ + --enable-option-checking \ + --disable-docs \ + --set llvm.download-ci-llvm=false + +ENV SCRIPT /scripts/autodiff.sh diff --git a/src/ci/docker/scripts/autodiff.sh b/src/ci/docker/scripts/autodiff.sh new file mode 100755 index 0000000000000..90b36078faccd --- /dev/null +++ b/src/ci/docker/scripts/autodiff.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -ex + +../x.py test --stage 2 --no-fail-fast \ + tests/codegen-llvm/autodiff \ + tests/pretty/autodiff \ + tests/ui/autodiff \ + tests/ui/feature-gates/feature-gate-autodiff.rs diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index a8eebe7599fda..a6b23fe516c89 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -469,6 +469,10 @@ auto: - name: x86_64-gnu-miri <<: *job-linux-4c + - name: optional-x86_64-gnu-autodiff + continue_on_error: true + <<: *job-linux-4c + #################### # macOS Builders # #################### From 377748d2835bfa5413baa2e52bd8e42fc2358b5d Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 18 Jul 2026 01:14:40 +0200 Subject: [PATCH 19/77] move batch --- .../issue-48728.rs => coherence/clone-impl-unsized-slice.rs} | 0 .../issue-4759-1.rs => methods/by-value-self-method-on-int.rs} | 0 .../issue-4759.rs => methods/destructure-and-call-self-method.rs} | 0 .../issue-50415.rs => range/inclusive-range-in-closure.rs} | 0 .../issue-47094.rs => repr/conflicting-repr-enum-attrs.rs} | 0 .../conflicting-repr-enum-attrs.stderr} | 0 .../tuple-struct-init-with-named-field.rs} | 0 .../tuple-struct-init-with-named-field.stderr} | 0 .../borrow-cast-or-binexpr-with-parens.fixed} | 0 .../borrow-cast-or-binexpr-with-parens.rs} | 0 .../borrow-cast-or-binexpr-with-parens.stderr} | 0 .../default-method/mono-item-collector-on-impl-with-lifetimes.rs} | 0 .../{issues/issue-46771.rs => typeck/call-unit-struct-as-fn.rs} | 0 .../issue-46771.stderr => typeck/call-unit-struct-as-fn.stderr} | 0 .../issue-48131.rs => unsafe/unused-unsafe-in-nested-fn-lint.rs} | 0 .../unused-unsafe-in-nested-fn-lint.stderr} | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-48728.rs => coherence/clone-impl-unsized-slice.rs} (100%) rename tests/ui/{issues/issue-4759-1.rs => methods/by-value-self-method-on-int.rs} (100%) rename tests/ui/{issues/issue-4759.rs => methods/destructure-and-call-self-method.rs} (100%) rename tests/ui/{issues/issue-50415.rs => range/inclusive-range-in-closure.rs} (100%) rename tests/ui/{issues/issue-47094.rs => repr/conflicting-repr-enum-attrs.rs} (100%) rename tests/ui/{issues/issue-47094.stderr => repr/conflicting-repr-enum-attrs.stderr} (100%) rename tests/ui/{issues/issue-4736.rs => structs/tuple-struct-init-with-named-field.rs} (100%) rename tests/ui/{issues/issue-4736.stderr => structs/tuple-struct-init-with-named-field.stderr} (100%) rename tests/ui/{issues/issue-46756-consider-borrowing-cast-or-binexpr.fixed => suggestions/borrow-cast-or-binexpr-with-parens.fixed} (100%) rename tests/ui/{issues/issue-46756-consider-borrowing-cast-or-binexpr.rs => suggestions/borrow-cast-or-binexpr-with-parens.rs} (100%) rename tests/ui/{issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr => suggestions/borrow-cast-or-binexpr-with-parens.stderr} (100%) rename tests/ui/{issues/issue-47309.rs => traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs} (100%) rename tests/ui/{issues/issue-46771.rs => typeck/call-unit-struct-as-fn.rs} (100%) rename tests/ui/{issues/issue-46771.stderr => typeck/call-unit-struct-as-fn.stderr} (100%) rename tests/ui/{issues/issue-48131.rs => unsafe/unused-unsafe-in-nested-fn-lint.rs} (100%) rename tests/ui/{issues/issue-48131.stderr => unsafe/unused-unsafe-in-nested-fn-lint.stderr} (100%) diff --git a/tests/ui/issues/issue-48728.rs b/tests/ui/coherence/clone-impl-unsized-slice.rs similarity index 100% rename from tests/ui/issues/issue-48728.rs rename to tests/ui/coherence/clone-impl-unsized-slice.rs diff --git a/tests/ui/issues/issue-4759-1.rs b/tests/ui/methods/by-value-self-method-on-int.rs similarity index 100% rename from tests/ui/issues/issue-4759-1.rs rename to tests/ui/methods/by-value-self-method-on-int.rs diff --git a/tests/ui/issues/issue-4759.rs b/tests/ui/methods/destructure-and-call-self-method.rs similarity index 100% rename from tests/ui/issues/issue-4759.rs rename to tests/ui/methods/destructure-and-call-self-method.rs diff --git a/tests/ui/issues/issue-50415.rs b/tests/ui/range/inclusive-range-in-closure.rs similarity index 100% rename from tests/ui/issues/issue-50415.rs rename to tests/ui/range/inclusive-range-in-closure.rs diff --git a/tests/ui/issues/issue-47094.rs b/tests/ui/repr/conflicting-repr-enum-attrs.rs similarity index 100% rename from tests/ui/issues/issue-47094.rs rename to tests/ui/repr/conflicting-repr-enum-attrs.rs diff --git a/tests/ui/issues/issue-47094.stderr b/tests/ui/repr/conflicting-repr-enum-attrs.stderr similarity index 100% rename from tests/ui/issues/issue-47094.stderr rename to tests/ui/repr/conflicting-repr-enum-attrs.stderr diff --git a/tests/ui/issues/issue-4736.rs b/tests/ui/structs/tuple-struct-init-with-named-field.rs similarity index 100% rename from tests/ui/issues/issue-4736.rs rename to tests/ui/structs/tuple-struct-init-with-named-field.rs diff --git a/tests/ui/issues/issue-4736.stderr b/tests/ui/structs/tuple-struct-init-with-named-field.stderr similarity index 100% rename from tests/ui/issues/issue-4736.stderr rename to tests/ui/structs/tuple-struct-init-with-named-field.stderr diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.fixed b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.fixed similarity index 100% rename from tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.fixed rename to tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.fixed diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.rs similarity index 100% rename from tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs rename to tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.rs diff --git a/tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.stderr similarity index 100% rename from tests/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr rename to tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.stderr diff --git a/tests/ui/issues/issue-47309.rs b/tests/ui/traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs similarity index 100% rename from tests/ui/issues/issue-47309.rs rename to tests/ui/traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs diff --git a/tests/ui/issues/issue-46771.rs b/tests/ui/typeck/call-unit-struct-as-fn.rs similarity index 100% rename from tests/ui/issues/issue-46771.rs rename to tests/ui/typeck/call-unit-struct-as-fn.rs diff --git a/tests/ui/issues/issue-46771.stderr b/tests/ui/typeck/call-unit-struct-as-fn.stderr similarity index 100% rename from tests/ui/issues/issue-46771.stderr rename to tests/ui/typeck/call-unit-struct-as-fn.stderr diff --git a/tests/ui/issues/issue-48131.rs b/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs similarity index 100% rename from tests/ui/issues/issue-48131.rs rename to tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs diff --git a/tests/ui/issues/issue-48131.stderr b/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr similarity index 100% rename from tests/ui/issues/issue-48131.stderr rename to tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr From a2730fa8f0a7427cd7a276c438e1b049c667be73 Mon Sep 17 00:00:00 2001 From: Walnut <39544927+Walnut356@users.noreply.github.com> Date: Sat, 18 Jul 2026 04:56:27 -0500 Subject: [PATCH 20/77] replace codeview.pdf with link to archived webpage --- .../rustc-dev-guide/src/debuginfo/CodeView.pdf | Bin 214354 -> 0 bytes src/doc/rustc-dev-guide/src/debuginfo/intro.md | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) delete mode 100644 src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf diff --git a/src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf b/src/doc/rustc-dev-guide/src/debuginfo/CodeView.pdf deleted file mode 100644 index f899d25178458c24bf49cb9ab086761fbdc86f08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214354 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

Qy!5YFK=h&x?Vf?_B_Sa|t` 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 APXGV_ diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md index 0f1e59fa65e26..00fc38a0f8d08 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/intro.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -63,7 +63,10 @@ Due to its proprietary nature, it is very difficult to find information about PD of the sources were made at vastly different times and contain incomplete or somewhat contradictory information. As such this page will aim to collect as many sources as possible. -* [CodeView 1.0 specification](./CodeView.pdf) +* [TIS PE specification](https://web.archive.org/web/20260315080740/http://x-ways.net/winhex/kb/ff/PE_EXE.pdf) +which includes a lengthy section titled "Microsoft Symbol and Type Information", detailing much of +the CodeView format. The document was created in 1993, but the information is still detailed, +accurate, and has useful diagrams. * LLVM * [CodeView Overview](https://llvm.org/docs/SourceLevelDebugging.html#codeview-debug-info-format) * [PDB Overview and technical details](https://llvm.org/docs/PDB/index.html) @@ -78,6 +81,8 @@ information. As such this page will aim to collect as many sources as possible. * [Debug Interface Access SDK](https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/getting-started-debug-interface-access-sdk). While it does not document the PDB format directly, details can be gleaned from the interface itself. + * [PDB-Documentation](https://github.com/PascalBeyer/PDB-Documentation) - a resource compiling + much of the plubicly available information about PDB and CodeView. # Debuggers @@ -111,4 +116,4 @@ in the future. specifically to debug Rust programs. While promising, it is still in early development. * [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. It has a custom debug info format that PDB is translated into. The project also includes a linker that can -generate their new debug info format during the linking phase. \ No newline at end of file +generate their new debug info format during the linking phase. From 2d0b4b3a9c4ce65b42d58a2f6059e35242a82917 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Sat, 18 Jul 2026 13:24:03 +0200 Subject: [PATCH 21/77] typo --- src/doc/rustc-dev-guide/src/debuginfo/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md index 00fc38a0f8d08..4fcf4901beefb 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/intro.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -82,7 +82,7 @@ accurate, and has useful diagrams. While it does not document the PDB format directly, details can be gleaned from the interface itself. * [PDB-Documentation](https://github.com/PascalBeyer/PDB-Documentation) - a resource compiling - much of the plubicly available information about PDB and CodeView. + much of the publicly available information about PDB and CodeView. # Debuggers From 6d6092cd52252a7e604921eea680c3a01d632b9b Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 18 Jul 2026 01:14:59 +0200 Subject: [PATCH 22/77] bless batch --- tests/ui/coherence/clone-impl-unsized-slice.rs | 4 ++-- tests/ui/methods/by-value-self-method-on-int.rs | 3 +++ tests/ui/methods/destructure-and-call-self-method.rs | 3 +++ tests/ui/range/inclusive-range-in-closure.rs | 3 +++ tests/ui/repr/conflicting-repr-enum-attrs.rs | 4 ++++ tests/ui/repr/conflicting-repr-enum-attrs.stderr | 8 ++++---- tests/ui/structs/tuple-struct-init-with-named-field.rs | 3 +++ .../ui/structs/tuple-struct-init-with-named-field.stderr | 2 +- .../suggestions/borrow-cast-or-binexpr-with-parens.fixed | 2 ++ .../ui/suggestions/borrow-cast-or-binexpr-with-parens.rs | 2 ++ .../suggestions/borrow-cast-or-binexpr-with-parens.stderr | 8 ++++---- .../mono-item-collector-on-impl-with-lifetimes.rs | 6 +++--- tests/ui/typeck/call-unit-struct-as-fn.rs | 3 +++ tests/ui/typeck/call-unit-struct-as-fn.stderr | 2 +- tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs | 2 ++ tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr | 6 +++--- 16 files changed, 43 insertions(+), 18 deletions(-) diff --git a/tests/ui/coherence/clone-impl-unsized-slice.rs b/tests/ui/coherence/clone-impl-unsized-slice.rs index 8ad9289c65cf2..6a36df0166354 100644 --- a/tests/ui/coherence/clone-impl-unsized-slice.rs +++ b/tests/ui/coherence/clone-impl-unsized-slice.rs @@ -1,5 +1,5 @@ -// Regression test for #48728, an ICE that occurred computing -// coherence "help" information. +//! Regression test for . +//! ICE occurred computing coherence "help" information. //@ check-pass #[derive(Clone)] diff --git a/tests/ui/methods/by-value-self-method-on-int.rs b/tests/ui/methods/by-value-self-method-on-int.rs index 7368a7b2f845b..c27898b156d86 100644 --- a/tests/ui/methods/by-value-self-method-on-int.rs +++ b/tests/ui/methods/by-value-self-method-on-int.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! This used to trigger LLVM assertion. //@ run-pass + trait U { fn f(self); } impl U for isize { fn f(self) {} } pub fn main() { 4.f(); } diff --git a/tests/ui/methods/destructure-and-call-self-method.rs b/tests/ui/methods/destructure-and-call-self-method.rs index 4b49442b4010f..a88276ec774f1 100644 --- a/tests/ui/methods/destructure-and-call-self-method.rs +++ b/tests/ui/methods/destructure-and-call-self-method.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Destructuring a struct and calling consuming method used to segfault. //@ run-pass + #![allow(non_shorthand_field_patterns)] struct T { a: Box } diff --git a/tests/ui/range/inclusive-range-in-closure.rs b/tests/ui/range/inclusive-range-in-closure.rs index 5f6211eb149dd..b842fed586608 100644 --- a/tests/ui/range/inclusive-range-in-closure.rs +++ b/tests/ui/range/inclusive-range-in-closure.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Test inclusive ranges in closures don't ICE. //@ run-pass + fn main() { // Simplified test case let _ = || 0..=1; diff --git a/tests/ui/repr/conflicting-repr-enum-attrs.rs b/tests/ui/repr/conflicting-repr-enum-attrs.rs index c5d37feb1447f..d7e629d230c02 100644 --- a/tests/ui/repr/conflicting-repr-enum-attrs.rs +++ b/tests/ui/repr/conflicting-repr-enum-attrs.rs @@ -1,3 +1,7 @@ +//! Regression test for . +//! Test `conflicting representation hints` warning is being triggered +//! when there are multiple repr attributes. + #[repr(C, u8)] //~ ERROR conflicting representation hints //~^ WARN this was previously accepted enum Foo { diff --git a/tests/ui/repr/conflicting-repr-enum-attrs.stderr b/tests/ui/repr/conflicting-repr-enum-attrs.stderr index da414d68214a8..6810a2a2a1171 100644 --- a/tests/ui/repr/conflicting-repr-enum-attrs.stderr +++ b/tests/ui/repr/conflicting-repr-enum-attrs.stderr @@ -1,5 +1,5 @@ error[E0566]: conflicting representation hints - --> $DIR/issue-47094.rs:1:8 + --> $DIR/conflicting-repr-enum-attrs.rs:5:8 | LL | #[repr(C, u8)] | ^ ^^ @@ -9,7 +9,7 @@ LL | #[repr(C, u8)] = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default error[E0566]: conflicting representation hints - --> $DIR/issue-47094.rs:8:8 + --> $DIR/conflicting-repr-enum-attrs.rs:12:8 | LL | #[repr(C)] | ^ @@ -25,7 +25,7 @@ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0566`. Future incompatibility report: Future breakage diagnostic: error[E0566]: conflicting representation hints - --> $DIR/issue-47094.rs:1:8 + --> $DIR/conflicting-repr-enum-attrs.rs:5:8 | LL | #[repr(C, u8)] | ^ ^^ @@ -36,7 +36,7 @@ LL | #[repr(C, u8)] Future breakage diagnostic: error[E0566]: conflicting representation hints - --> $DIR/issue-47094.rs:8:8 + --> $DIR/conflicting-repr-enum-attrs.rs:12:8 | LL | #[repr(C)] | ^ diff --git a/tests/ui/structs/tuple-struct-init-with-named-field.rs b/tests/ui/structs/tuple-struct-init-with-named-field.rs index 799d2d4809860..586d96284e170 100644 --- a/tests/ui/structs/tuple-struct-init-with-named-field.rs +++ b/tests/ui/structs/tuple-struct-init-with-named-field.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to ICE. + struct NonCopyable(()); fn main() { diff --git a/tests/ui/structs/tuple-struct-init-with-named-field.stderr b/tests/ui/structs/tuple-struct-init-with-named-field.stderr index b099e528ca8a8..1fb3b0be0b02e 100644 --- a/tests/ui/structs/tuple-struct-init-with-named-field.stderr +++ b/tests/ui/structs/tuple-struct-init-with-named-field.stderr @@ -1,5 +1,5 @@ error[E0560]: struct `NonCopyable` has no field named `p` - --> $DIR/issue-4736.rs:4:26 + --> $DIR/tuple-struct-init-with-named-field.rs:7:26 | LL | struct NonCopyable(()); | ----------- `NonCopyable` defined here diff --git a/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.fixed b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.fixed index d8402cdf07e38..157ed7e609d07 100644 --- a/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.fixed +++ b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.fixed @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test reference suggestion correctly puts cast in parentheses. //@ run-rustfix #![allow(unused)] diff --git a/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.rs b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.rs index 0e04680911c80..3657cc67f7588 100644 --- a/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.rs +++ b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test reference suggestion correctly puts cast in parentheses. //@ run-rustfix #![allow(unused)] diff --git a/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.stderr b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.stderr index 211dd51289595..61b309291438c 100644 --- a/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.stderr +++ b/tests/ui/suggestions/borrow-cast-or-binexpr-with-parens.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42 + --> $DIR/borrow-cast-or-binexpr-with-parens.rs:14:42 | LL | light_flows_our_war_of_mocking_words(behold as usize); | ------------------------------------ ^^^^^^^^^^^^^^^ expected `&usize`, found `usize` @@ -7,7 +7,7 @@ LL | light_flows_our_war_of_mocking_words(behold as usize); | arguments to this function are incorrect | note: function defined here - --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:5:4 + --> $DIR/borrow-cast-or-binexpr-with-parens.rs:7:4 | LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- @@ -17,7 +17,7 @@ LL | light_flows_our_war_of_mocking_words(&(behold as usize)); | ++ + error[E0308]: mismatched types - --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42 + --> $DIR/borrow-cast-or-binexpr-with-parens.rs:16:42 | LL | light_flows_our_war_of_mocking_words(with_tears + 4); | ------------------------------------ ^^^^^^^^^^^^^^ expected `&usize`, found `usize` @@ -25,7 +25,7 @@ LL | light_flows_our_war_of_mocking_words(with_tears + 4); | arguments to this function are incorrect | note: function defined here - --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:5:4 + --> $DIR/borrow-cast-or-binexpr-with-parens.rs:7:4 | LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- diff --git a/tests/ui/traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs b/tests/ui/traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs index 99f1ccbc5758c..44c1e171835c8 100644 --- a/tests/ui/traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs +++ b/tests/ui/traits/default-method/mono-item-collector-on-impl-with-lifetimes.rs @@ -1,6 +1,6 @@ -// Make sure that the mono-item collector does not crash when trying to -// instantiate a default impl of a method with lifetime parameters. -// See https://github.com/rust-lang/rust/issues/47309 +//! Regression test for . +//! Make sure that the mono-item collector does not crash when trying to +//! instantiate a default impl of a method with lifetime parameters. //@ compile-flags:-Clink-dead-code //@ build-pass diff --git a/tests/ui/typeck/call-unit-struct-as-fn.rs b/tests/ui/typeck/call-unit-struct-as-fn.rs index 22be8d6af8a7f..2fe2085dd72a9 100644 --- a/tests/ui/typeck/call-unit-struct-as-fn.rs +++ b/tests/ui/typeck/call-unit-struct-as-fn.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test calling unit struct as fn doesn't ICE. + fn main() { struct Foo; (1 .. 2).find(|_| Foo(0) == 0); //~ ERROR expected function, found `Foo` diff --git a/tests/ui/typeck/call-unit-struct-as-fn.stderr b/tests/ui/typeck/call-unit-struct-as-fn.stderr index fab55fbfd704a..8056d0df57f99 100644 --- a/tests/ui/typeck/call-unit-struct-as-fn.stderr +++ b/tests/ui/typeck/call-unit-struct-as-fn.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found `Foo` - --> $DIR/issue-46771.rs:3:23 + --> $DIR/call-unit-struct-as-fn.rs:6:23 | LL | struct Foo; | ---------- `Foo` defined here diff --git a/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs b/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs index a1084ea243b26..92b9bbfefc88e 100644 --- a/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs +++ b/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.rs @@ -1,3 +1,5 @@ +//! Regression test for . + // This note is annotated because the purpose of the test // is to ensure that certain other notes are not generated. #![deny(unused_unsafe)] diff --git a/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr b/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr index fe0cd4efae891..cc5fab4fcdf94 100644 --- a/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr +++ b/tests/ui/unsafe/unused-unsafe-in-nested-fn-lint.stderr @@ -1,17 +1,17 @@ error: unnecessary `unsafe` block - --> $DIR/issue-48131.rs:9:9 + --> $DIR/unused-unsafe-in-nested-fn-lint.rs:11:9 | LL | unsafe { /* unnecessary */ } | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/issue-48131.rs:3:9 + --> $DIR/unused-unsafe-in-nested-fn-lint.rs:5:9 | LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/issue-48131.rs:19:13 + --> $DIR/unused-unsafe-in-nested-fn-lint.rs:21:13 | LL | unsafe { /* unnecessary */ } | ^^^^^^ unnecessary `unsafe` block From fb119e011fe1295738e092956956bf889c053d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maty=C3=A1=C5=A1=20Racek?= Date: Sun, 19 Jul 2026 00:17:32 +0200 Subject: [PATCH 23/77] Clarify what to do when you break a subtree build --- src/doc/rustc-dev-guide/src/external-repos.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/external-repos.md b/src/doc/rustc-dev-guide/src/external-repos.md index 7ae1c881be8f7..1aca1b2eab1c5 100644 --- a/src/doc/rustc-dev-guide/src/external-repos.md +++ b/src/doc/rustc-dev-guide/src/external-repos.md @@ -34,6 +34,9 @@ to these tools should be filed against the tools directly in their respective up The exception is that when rustc changes are required to implement a new tool feature or test, that should happen in one collective rustc PR. +Similarly, if your rustc changes break the build of some subtree dependency, +you should include fixes for those in the rustc PR as well. + `subtree` dependencies are currently managed by two distinct approaches: * Using `git subtree` From 4ee71fea02ec90e3031966ee46ea28bfabe91142 Mon Sep 17 00:00:00 2001 From: sgasho Date: Sun, 19 Jul 2026 18:13:29 +0900 Subject: [PATCH 24/77] docs: add autodiff CI job document --- src/ci/github-actions/jobs.yml | 1 + src/doc/rustc-dev-guide/src/SUMMARY.md | 1 + .../src/tests/autodiff-ci-job.md | 45 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index a6b23fe516c89..706095890b114 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -471,6 +471,7 @@ auto: - name: optional-x86_64-gnu-autodiff continue_on_error: true + doc_url: https://rustc-dev-guide.rust-lang.org/tests/autodiff-ci-job.html <<: *job-linux-4c #################### diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index bf2de84575d69..6a3a5a0a936f3 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -34,6 +34,7 @@ - [Codegen backend testing](./tests/codegen-backend-tests/intro.md) - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md) - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md) + - [Autodiff CI job](./tests/autodiff-ci-job.md) - [Performance testing](./tests/perf.md) - [Pre-stabilization CI job for the next solver and polonius alpha](./tests/x86_64-gnu-next-trait-solver-polonius-ci-job.md) - [Misc info](./tests/misc.md) diff --git a/src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md b/src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md new file mode 100644 index 0000000000000..3e5d55fbc81a9 --- /dev/null +++ b/src/doc/rustc-dev-guide/src/tests/autodiff-ci-job.md @@ -0,0 +1,45 @@ +# Autodiff CI job + +The [`optional-x86_64-gnu-autodiff`] job provides continuous test coverage for +the experimental `autodiff` feature and its integration with LLVM Enzyme. It is +an optional [auto job](./ci.md#auto-builds), so a failure does not prevent a +pull request from being merged. + +For more context about the feature, see the [autodiff tracking issue] and the +[autodiff internals](../autodiff/internals.md) chapter. + +## What is tested + +The job checks: + +- forward- and reverse-mode macro expansion and diagnostics; +- LLVM IR generation for autodiff; +- enforcement of the `autodiff` feature gate. + +## Running the job + +To run the job in a try build, comment on a pull request: + +```text +@bors try jobs=optional-x86_64-gnu-autodiff +``` + +To run the job locally, run this command from a Rust checkout: + +```console +$ cargo run --manifest-path src/ci/citool/Cargo.toml run-local optional-x86_64-gnu-autodiff +``` + +See [Testing with Docker](./docker.md) for more information about running CI +jobs locally. + +## Point of contact + +If you have questions or need help with a failure in this job, open a new topic +in the [autodiff Zulip channel]. For suspected Enzyme backend failures, see the +[autodiff debugging guide]. + +[autodiff Zulip channel]: https://rust-lang.zulipchat.com/#narrow/channel/390790-wg-autodiff +[autodiff debugging guide]: ../autodiff/debugging.md +[autodiff tracking issue]: https://github.com/rust-lang/rust/issues/124509 +[`optional-x86_64-gnu-autodiff`]: https://github.com/rust-lang/rust/blob/HEAD/src/ci/github-actions/jobs.yml From 2851cef01a6a8cc8afc5770eba31362b944cc4e2 Mon Sep 17 00:00:00 2001 From: zedddie Date: Mon, 20 Jul 2026 01:59:03 +0200 Subject: [PATCH 25/77] move batch --- .../const_in_pattern/const-bytes-slice-pattern.rs} | 0 .../auxiliary/cross-crate-multibyte-debuginfo-comments.rs} | 0 .../auxiliary/cross-crate-multibyte-debuginfo.rs} | 0 .../main.rs => debuginfo/cross-crate-multibyte-debuginfo.rs} | 0 .../fru-unknown-field-in-closure.rs} | 0 .../fru-unknown-field-in-closure.stderr} | 0 .../need_type_info/for-loop-nested-array-inference.rs} | 0 .../need_type_info/for-loop-nested-array-inference.stderr} | 0 .../repetition-matches-empty-token-tree.rs} | 0 .../repetition-matches-empty-token-tree.stderr} | 0 .../issue-52262.rs => moves/move-out-of-shared-ref-deref.rs} | 0 .../move-out-of-shared-ref-deref.stderr} | 0 .../struct-pattern-nonexistent-field.rs} | 0 .../struct-pattern-nonexistent-field.stderr} | 0 .../call-tuple-struct-ctor-as-fn.rs} | 0 .../object/extern-c-trait-object-methods.rs} | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-51655.rs => consts/const_in_pattern/const-bytes-slice-pattern.rs} (100%) rename tests/ui/{issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs => debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs} (100%) rename tests/ui/{issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs => debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs} (100%) rename tests/ui/{issues/issue-24687-embed-debuginfo/main.rs => debuginfo/cross-crate-multibyte-debuginfo.rs} (100%) rename tests/ui/{issues/issue-50618.rs => functional-struct-update/fru-unknown-field-in-closure.rs} (100%) rename tests/ui/{issues/issue-50618.stderr => functional-struct-update/fru-unknown-field-in-closure.stderr} (100%) rename tests/ui/{issues/issue-51116.rs => inference/need_type_info/for-loop-nested-array-inference.rs} (100%) rename tests/ui/{issues/issue-51116.stderr => inference/need_type_info/for-loop-nested-array-inference.stderr} (100%) rename tests/ui/{issues/issue-5067.rs => macros/repetition-matches-empty-token-tree.rs} (100%) rename tests/ui/{issues/issue-5067.stderr => macros/repetition-matches-empty-token-tree.stderr} (100%) rename tests/ui/{issues/issue-52262.rs => moves/move-out-of-shared-ref-deref.rs} (100%) rename tests/ui/{issues/issue-52262.stderr => moves/move-out-of-shared-ref-deref.stderr} (100%) rename tests/ui/{issues/issue-51102.rs => pattern/struct-pattern-nonexistent-field.rs} (100%) rename tests/ui/{issues/issue-51102.stderr => pattern/struct-pattern-nonexistent-field.stderr} (100%) rename tests/ui/{issues/issue-5315.rs => structs-enums/call-tuple-struct-ctor-as-fn.rs} (100%) rename tests/ui/{issues/issue-51907.rs => traits/object/extern-c-trait-object-methods.rs} (100%) diff --git a/tests/ui/issues/issue-51655.rs b/tests/ui/consts/const_in_pattern/const-bytes-slice-pattern.rs similarity index 100% rename from tests/ui/issues/issue-51655.rs rename to tests/ui/consts/const_in_pattern/const-bytes-slice-pattern.rs diff --git a/tests/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs b/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs similarity index 100% rename from tests/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs rename to tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs diff --git a/tests/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs b/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs similarity index 100% rename from tests/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs rename to tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs diff --git a/tests/ui/issues/issue-24687-embed-debuginfo/main.rs b/tests/ui/debuginfo/cross-crate-multibyte-debuginfo.rs similarity index 100% rename from tests/ui/issues/issue-24687-embed-debuginfo/main.rs rename to tests/ui/debuginfo/cross-crate-multibyte-debuginfo.rs diff --git a/tests/ui/issues/issue-50618.rs b/tests/ui/functional-struct-update/fru-unknown-field-in-closure.rs similarity index 100% rename from tests/ui/issues/issue-50618.rs rename to tests/ui/functional-struct-update/fru-unknown-field-in-closure.rs diff --git a/tests/ui/issues/issue-50618.stderr b/tests/ui/functional-struct-update/fru-unknown-field-in-closure.stderr similarity index 100% rename from tests/ui/issues/issue-50618.stderr rename to tests/ui/functional-struct-update/fru-unknown-field-in-closure.stderr diff --git a/tests/ui/issues/issue-51116.rs b/tests/ui/inference/need_type_info/for-loop-nested-array-inference.rs similarity index 100% rename from tests/ui/issues/issue-51116.rs rename to tests/ui/inference/need_type_info/for-loop-nested-array-inference.rs diff --git a/tests/ui/issues/issue-51116.stderr b/tests/ui/inference/need_type_info/for-loop-nested-array-inference.stderr similarity index 100% rename from tests/ui/issues/issue-51116.stderr rename to tests/ui/inference/need_type_info/for-loop-nested-array-inference.stderr diff --git a/tests/ui/issues/issue-5067.rs b/tests/ui/macros/repetition-matches-empty-token-tree.rs similarity index 100% rename from tests/ui/issues/issue-5067.rs rename to tests/ui/macros/repetition-matches-empty-token-tree.rs diff --git a/tests/ui/issues/issue-5067.stderr b/tests/ui/macros/repetition-matches-empty-token-tree.stderr similarity index 100% rename from tests/ui/issues/issue-5067.stderr rename to tests/ui/macros/repetition-matches-empty-token-tree.stderr diff --git a/tests/ui/issues/issue-52262.rs b/tests/ui/moves/move-out-of-shared-ref-deref.rs similarity index 100% rename from tests/ui/issues/issue-52262.rs rename to tests/ui/moves/move-out-of-shared-ref-deref.rs diff --git a/tests/ui/issues/issue-52262.stderr b/tests/ui/moves/move-out-of-shared-ref-deref.stderr similarity index 100% rename from tests/ui/issues/issue-52262.stderr rename to tests/ui/moves/move-out-of-shared-ref-deref.stderr diff --git a/tests/ui/issues/issue-51102.rs b/tests/ui/pattern/struct-pattern-nonexistent-field.rs similarity index 100% rename from tests/ui/issues/issue-51102.rs rename to tests/ui/pattern/struct-pattern-nonexistent-field.rs diff --git a/tests/ui/issues/issue-51102.stderr b/tests/ui/pattern/struct-pattern-nonexistent-field.stderr similarity index 100% rename from tests/ui/issues/issue-51102.stderr rename to tests/ui/pattern/struct-pattern-nonexistent-field.stderr diff --git a/tests/ui/issues/issue-5315.rs b/tests/ui/structs-enums/call-tuple-struct-ctor-as-fn.rs similarity index 100% rename from tests/ui/issues/issue-5315.rs rename to tests/ui/structs-enums/call-tuple-struct-ctor-as-fn.rs diff --git a/tests/ui/issues/issue-51907.rs b/tests/ui/traits/object/extern-c-trait-object-methods.rs similarity index 100% rename from tests/ui/issues/issue-51907.rs rename to tests/ui/traits/object/extern-c-trait-object-methods.rs From 4e53ac1907b713026674cf110961e2f4fe844f06 Mon Sep 17 00:00:00 2001 From: Yukang Date: Tue, 14 Jul 2026 23:18:54 +0800 Subject: [PATCH 26/77] Add allow_list checking for eii implementation attributes --- .../rustc_ast_passes/src/ast_validation.rs | 46 +++++++- compiler/rustc_ast_passes/src/diagnostics.rs | 11 ++ compiler/rustc_passes/src/check_attr.rs | 16 --- compiler/rustc_passes/src/diagnostics.rs | 10 -- ...tation-attribute-allowlist-issue-159015.rs | 102 ++++++++++++++++++ ...on-attribute-allowlist-issue-159015.stderr | 67 ++++++++++++ tests/ui/eii/track_caller_errors.stderr | 3 +- 7 files changed, 226 insertions(+), 29 deletions(-) create mode 100644 tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs create mode 100644 tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 478dbc0dd7684..f7d9acef6eb84 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1202,6 +1202,48 @@ impl<'a> AstValidator<'a> { self.visit_vis(vis); self.visit_ident(ident); } + + // Check EII implementation attributes against an allowlist. + fn check_eii_impl_attrs(&self, attrs: &[Attribute], eii_impls: &[EiiImpl]) { + if eii_impls.is_empty() { + return; + } + + let allowed_attrs: &[Symbol] = &[ + sym::allow, + sym::warn, + sym::deny, + sym::forbid, + sym::expect, + sym::doc, + sym::inline, + sym::cold, + sym::optimize, + sym::coverage, + sym::sanitize, + sym::must_use, + sym::deprecated, + ]; + + for attr in attrs { + let AttrKind::Normal(normal) = &attr.kind else { + continue; + }; + if attr.has_any_name(allowed_attrs) { + continue; + } + + let attr_name = pprust::path_to_string(&normal.item.path); + for eii_impl in eii_impls { + self.dcx().emit_err(diagnostics::EiiImplAttributeNotSupported { + attr_span: attr.span, + attr_name: &attr_name, + eii_span: eii_impl.span, + eii_name: pprust::path_to_string(&eii_impl.eii_macro_path), + }); + } + } + } } /// Checks that generic parameters are in the correct order, @@ -1391,6 +1433,7 @@ impl Visitor<'_> for AstValidator<'_> { for EiiImpl { eii_macro_path, .. } in eii_impls { self.visit_path(eii_macro_path); } + self.check_eii_impl_attrs(&item.attrs, eii_impls); let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic)); if body.is_none() && !is_intrinsic && !self.is_sdylib_interface { @@ -1566,8 +1609,9 @@ impl Visitor<'_> for AstValidator<'_> { visit::walk_item(self, item); } - ItemKind::Static(StaticItem { expr, safety, .. }) => { + ItemKind::Static(StaticItem { expr, safety, eii_impls, .. }) => { self.check_item_safety(item.span, *safety); + self.check_eii_impl_attrs(&item.attrs, eii_impls); if matches!(safety, Safety::Unsafe(_)) { self.dcx().emit_err(diagnostics::UnsafeStatic { span: item.span }); } diff --git a/compiler/rustc_ast_passes/src/diagnostics.rs b/compiler/rustc_ast_passes/src/diagnostics.rs index 0cf7ef5c1de19..5bcffe96f6086 100644 --- a/compiler/rustc_ast_passes/src/diagnostics.rs +++ b/compiler/rustc_ast_passes/src/diagnostics.rs @@ -189,6 +189,17 @@ pub(crate) struct FnParamForbiddenAttr { pub span: Span, } +#[derive(Diagnostic)] +#[diag("`#[{$eii_name}]` is not allowed to have `#[{$attr_name}]`")] +pub(crate) struct EiiImplAttributeNotSupported<'a> { + #[primary_span] + pub attr_span: Span, + pub attr_name: &'a str, + pub eii_name: String, + #[label("`#[{$eii_name}]` is not allowed to have `#[{$attr_name}]`")] + pub eii_span: Span, +} + #[derive(Diagnostic)] #[diag("`self` parameter is only allowed in associated functions")] #[note("associated functions are those in `impl` or `trait` definitions")] diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3139c8746b95a..8408b2e889063 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -791,22 +791,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { sig_span: sig.span, }); } - - if let Some(impls) = find_attr!(attrs, EiiImpls(impls) => impls) { - let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); - for i in impls { - let name = match i.resolution { - EiiImplResolution::Macro(def_id) => self.tcx.item_name(def_id), - EiiImplResolution::Known(def_id) => self.tcx.item_name(def_id), - EiiImplResolution::Error(_eg) => continue, - }; - self.dcx().emit_err(diagnostics::EiiWithTrackCaller { - attr_span, - name, - sig_span: sig.span, - }); - } - } } _ => {} } diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 2589941d7dae1..860cc435db330 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -1077,16 +1077,6 @@ pub(crate) struct EiiImplRequiresUnsafeSuggestion { pub right: Span, } -#[derive(Diagnostic)] -#[diag("`#[{$name}]` is not allowed to have `#[track_caller]`")] -pub(crate) struct EiiWithTrackCaller { - #[primary_span] - pub attr_span: Span, - pub name: Symbol, - #[label("`#[{$name}]` is not allowed to have `#[track_caller]`")] - pub sig_span: Span, -} - #[derive(Diagnostic)] #[diag("`#[{$name}]` {$kind} required, but not found")] pub(crate) struct EiiWithoutImpl { diff --git a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs new file mode 100644 index 0000000000000..d27ea2a833e0f --- /dev/null +++ b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.rs @@ -0,0 +1,102 @@ +// EII implementations only accept attributes from a conservative allowlist. +// Regression test for #159015 + +//@ edition: 2024 +//@ needs-asm-support + +#![feature(coverage_attribute)] +#![feature(extern_item_impls)] +#![feature(optimize_attribute)] +#![feature(sanitize)] + +#[eii] +fn allowed(); + +/// Sugared and explicit documentation attributes are both allowed. +#[allowed] +#[allow(dead_code)] +#[warn(unreachable_code)] +#[deny(unused_mut)] +#[forbid(unsafe_code)] +#[expect(unused_variables)] +#[cfg(all())] +#[doc = "An allowed EII implementation."] +#[cold] +#[optimize(none)] +#[coverage(off)] +#[sanitize(address = "off")] +#[must_use] +#[deprecated] +fn allowed_impl() { + let unused = (); +} + +#[eii] +fn allowed_inline(); + +#[allowed_inline] +#[allow(unused_attributes)] +#[cfg_attr(all(), inline)] +fn allowed_inline_impl() {} + +#[eii] +fn foo(); + +#[foo] +#[unsafe(no_mangle)] +//~^ ERROR `#[foo]` is not allowed to have `#[no_mangle]` +fn bar() {} + +#[eii] +fn baz(); + +#[baz] +#[unsafe(export_name = "qux")] +//~^ ERROR `#[baz]` is not allowed to have `#[export_name]` +fn qux() {} + +#[eii] +fn quux(); + +#[quux] +#[unsafe(link_section = "__TEXT,__text")] +//~^ ERROR `#[quux]` is not allowed to have `#[link_section]` +fn corge() {} + +#[eii] +fn grault(); + +#[grault] +#[track_caller] +//~^ ERROR `#[grault]` is not allowed to have `#[track_caller]` +fn garply() {} + +#[eii] +extern "C" fn naked_attr(); + +#[naked_attr] +#[unsafe(naked)] +//~^ ERROR `#[naked_attr]` is not allowed to have `#[naked]` +extern "C" fn naked_attr_impl() { + core::arch::naked_asm!("") +} + +#[eii] +fn multiple_invalid_attrs(); + +#[multiple_invalid_attrs] +#[unsafe(no_mangle)] +//~^ ERROR `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` +#[track_caller] +//~^ ERROR `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` +fn multiple_invalid_attrs_impl() {} + +#[eii(static_eii)] +static STATIC_EII: u8; + +#[static_eii] +#[used] +//~^ ERROR `#[static_eii]` is not allowed to have `#[used]` +static STATIC_EII_IMPL: u8 = 0; + +fn main() {} diff --git a/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr new file mode 100644 index 0000000000000..af9673099f20f --- /dev/null +++ b/tests/ui/eii/implementation-attribute-allowlist-issue-159015.stderr @@ -0,0 +1,67 @@ +error: `#[foo]` is not allowed to have `#[no_mangle]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:46:1 + | +LL | #[foo] + | ------ `#[foo]` is not allowed to have `#[no_mangle]` +LL | #[unsafe(no_mangle)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `#[baz]` is not allowed to have `#[export_name]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:54:1 + | +LL | #[baz] + | ------ `#[baz]` is not allowed to have `#[export_name]` +LL | #[unsafe(export_name = "qux")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[quux]` is not allowed to have `#[link_section]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:62:1 + | +LL | #[quux] + | ------- `#[quux]` is not allowed to have `#[link_section]` +LL | #[unsafe(link_section = "__TEXT,__text")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[grault]` is not allowed to have `#[track_caller]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:70:1 + | +LL | #[grault] + | --------- `#[grault]` is not allowed to have `#[track_caller]` +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: `#[naked_attr]` is not allowed to have `#[naked]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:78:1 + | +LL | #[naked_attr] + | ------------- `#[naked_attr]` is not allowed to have `#[naked]` +LL | #[unsafe(naked)] + | ^^^^^^^^^^^^^^^^ + +error: `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:88:1 + | +LL | #[multiple_invalid_attrs] + | ------------------------- `#[multiple_invalid_attrs]` is not allowed to have `#[no_mangle]` +LL | #[unsafe(no_mangle)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:90:1 + | +LL | #[multiple_invalid_attrs] + | ------------------------- `#[multiple_invalid_attrs]` is not allowed to have `#[track_caller]` +... +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: `#[static_eii]` is not allowed to have `#[used]` + --> $DIR/implementation-attribute-allowlist-issue-159015.rs:98:1 + | +LL | #[static_eii] + | ------------- `#[static_eii]` is not allowed to have `#[used]` +LL | #[used] + | ^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/eii/track_caller_errors.stderr b/tests/ui/eii/track_caller_errors.stderr index e096146b67830..356f86093d638 100644 --- a/tests/ui/eii/track_caller_errors.stderr +++ b/tests/ui/eii/track_caller_errors.stderr @@ -4,8 +4,7 @@ error: `#[decl1]` is not allowed to have `#[track_caller]` LL | #[track_caller] | ^^^^^^^^^^^^^^^ LL | #[decl1] -LL | fn impl1(x: u64) { - | ---------------- `#[decl1]` is not allowed to have `#[track_caller]` + | -------- `#[decl1]` is not allowed to have `#[track_caller]` error: aborting due to 1 previous error From 7726456e92260a1f3080a0a4a0cd0714684e8048 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 15:47:03 +0200 Subject: [PATCH 27/77] extraneous word --- src/doc/rustc-dev-guide/src/hir-typeck/summary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md index 23df97a9cf833..b519e8374d768 100644 --- a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md +++ b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md @@ -3,7 +3,7 @@ The [`hir_analysis`] crate contains the source for "type collection" as well as a bunch of related functionality. Checking the bodies of functions is implemented in the [`hir_typeck`] crate. -These crates draw heavily on the [type inference] and [trait solving]. +These crates draw heavily on [type inference] and [trait solving]. [`hir_analysis`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/index.html [`hir_typeck`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/index.html From 216b07a86c9785de2755b28ee4ef37c187bf518f Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 15:50:10 +0200 Subject: [PATCH 28/77] deserves own sentence --- src/doc/rustc-dev-guide/src/hir-typeck/summary.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md index b519e8374d768..ae84c1e676751 100644 --- a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md +++ b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md @@ -14,8 +14,8 @@ These crates draw heavily on [type inference] and [trait solving]. Type "collection" is the process of converting the types found in the HIR (`hir::Ty`), which represent the syntactic things that the user wrote, into the -**internal representation** used by the compiler (`Ty<'tcx>`) – we also do -similar conversions for where-clauses and other bits of the function signature. +**internal representation** used by the compiler (`Ty<'tcx>`). +Note that we also do similar conversions for where-clauses and other bits of the function signature. To try and get a sense of the difference, consider this function: From 6c5df713317b31612051b9f741d7d8b236a2aab6 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 18:47:13 +0200 Subject: [PATCH 29/77] update thir output --- src/doc/rustc-dev-guide/src/thir.md | 191 +++++++++++----------------- 1 file changed, 73 insertions(+), 118 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/thir.md b/src/doc/rustc-dev-guide/src/thir.md index 802df2286095d..1ba30d86a6913 100644 --- a/src/doc/rustc-dev-guide/src/thir.md +++ b/src/doc/rustc-dev-guide/src/thir.md @@ -48,7 +48,7 @@ which is useful to keep peak memory in check. Having a THIR representation of all bodies of a crate in memory at the same time would be very heavy. -You can get a debug representation of the THIR by passing the `-Zunpretty=thir-tree` flag +You can get a debug representation of the THIR by passing the `-Zunpretty=thir-flat` flag to `rustc`. To demonstrate, let's use the following example: @@ -59,213 +59,168 @@ fn main() { } ``` -Here is how that gets represented in THIR (as of Aug 2022): +Here is how that gets represented in THIR (as of Jul 2026): ```rust,no_run +DefId(0:3 ~ main[26fd]::main): Thir { + body_type: Fn( + fn(), + ), + attributes: {}, // no match arms arms: [], + blocks: [ + Block { + targeted_by_break: false, + region_scope: Node(1), + span: main.rs:1:11: 3:2 (#0), + stmts: [ + s0, + ], + expr: None, + safety_mode: Safe, + }, + ], exprs: [ // expression 0, a literal with a value of 1 Expr { - ty: i32, - temp_lifetime: Some( - Node(1), - ), - span: oneplustwo.rs:2:13: 2:14 (#0), kind: Literal { lit: Spanned { node: Int( - 1, + Pu128( + 1, + ), Unsuffixed, ), - span: oneplustwo.rs:2:13: 2:14 (#0), + span: main.rs:2:13: 2:14 (#0), }, neg: false, }, + ty: i32, + temp_scope_id: 4, + span: main.rs:2:13: 2:14 (#0), }, // expression 1, scope surrounding literal 1 Expr { - ty: i32, - temp_lifetime: Some( - Node(1), - ), - span: oneplustwo.rs:2:13: 2:14 (#0), kind: Scope { + region_scope: Node(4), + hir_id: HirId(DefId(0:3 ~ main[26fd]::main).4), // reference to expression 0 above - region_scope: Node(3), - lint_level: Explicit( - HirId { - owner: DefId(0:3 ~ oneplustwo[6932]::main), - local_id: 3, - }, - ), value: e0, }, + ty: i32, + temp_scope_id: 4, + span: main.rs:2:13: 2:14 (#0), }, // expression 2, literal 2 Expr { - ty: i32, - temp_lifetime: Some( - Node(1), - ), - span: oneplustwo.rs:2:17: 2:18 (#0), kind: Literal { lit: Spanned { node: Int( - 2, + Pu128( + 2, + ), Unsuffixed, ), - span: oneplustwo.rs:2:17: 2:18 (#0), + span: main.rs:2:17: 2:18 (#0), }, neg: false, }, + ty: i32, + temp_scope_id: 5, + span: main.rs:2:17: 2:18 (#0), }, // expression 3, scope surrounding literal 2 Expr { - ty: i32, - temp_lifetime: Some( - Node(1), - ), - span: oneplustwo.rs:2:17: 2:18 (#0), kind: Scope { - region_scope: Node(4), - lint_level: Explicit( - HirId { - owner: DefId(0:3 ~ oneplustwo[6932]::main), - local_id: 4, - }, - ), - // reference to expression 2 above + region_scope: Node(5), + hir_id: HirId(DefId(0:3 ~ main[26fd]::main).5), + // reference to expression 0 above value: e2, }, + ty: i32, + temp_scope_id: 5, + span: main.rs:2:17: 2:18 (#0), }, // expression 4, represents 1 + 2 Expr { - ty: i32, - temp_lifetime: Some( - Node(1), - ), - span: oneplustwo.rs:2:13: 2:18 (#0), kind: Binary { op: Add, // references to scopes surrounding literals above lhs: e1, rhs: e3, }, + ty: i32, + temp_scope_id: 3, + span: main.rs:2:13: 2:18 (#0), }, // expression 5, scope surrounding expression 4 Expr { - ty: i32, - temp_lifetime: Some( - Node(1), - ), - span: oneplustwo.rs:2:13: 2:18 (#0), kind: Scope { - region_scope: Node(5), - lint_level: Explicit( - HirId { - owner: DefId(0:3 ~ oneplustwo[6932]::main), - local_id: 5, - }, - ), + region_scope: Node(3), + hir_id: HirId(DefId(0:3 ~ main[26fd]::main).3), value: e4, }, + ty: i32, + temp_scope_id: 3, + span: main.rs:2:13: 2:18 (#0), }, // expression 6, block around statement Expr { - ty: (), - temp_lifetime: Some( - Node(9), - ), - span: oneplustwo.rs:1:11: 3:2 (#0), kind: Block { - body: Block { - targeted_by_break: false, - region_scope: Node(8), - opt_destruction_scope: None, - span: oneplustwo.rs:1:11: 3:2 (#0), - // reference to statement 0 below - stmts: [ - s0, - ], - expr: None, - safety_mode: Safe, - }, + block: b0, }, + ty: (), + temp_scope_id: 8, + span: main.rs:1:11: 3:2 (#0), }, // expression 7, scope around block in expression 6 Expr { - ty: (), - temp_lifetime: Some( - Node(9), - ), - span: oneplustwo.rs:1:11: 3:2 (#0), kind: Scope { - region_scope: Node(9), - lint_level: Explicit( - HirId { - owner: DefId(0:3 ~ oneplustwo[6932]::main), - local_id: 9, - }, - ), + region_scope: Node(8), + hir_id: HirId(DefId(0:3 ~ main[26fd]::main).8), value: e6, }, - }, - // destruction scope around expression 7 - Expr { ty: (), - temp_lifetime: Some( - Node(9), - ), - span: oneplustwo.rs:1:11: 3:2 (#0), - kind: Scope { - region_scope: Destruction(9), - lint_level: Inherited, - value: e7, - }, + temp_scope_id: 8, + span: main.rs:1:11: 3:2 (#0), }, ], stmts: [ - // let statement Stmt { kind: Let { - remainder_scope: Remainder { block: 8, first_statement_index: 0}, - init_scope: Node(1), + remainder_scope: Remainder { block: 1, first_statement_index: 0}, + init_scope: Node(2), pattern: Pat { ty: i32, - span: oneplustwo.rs:2:9: 2:10 (#0), + span: main.rs:2:9: 2:10 (#0), + extra: None, kind: Binding { - mutability: Not, name: "x", - mode: ByValue, + mode: BindingMode( + No, + Not, + ), var: LocalVarId( - HirId { - owner: DefId(0:3 ~ oneplustwo[6932]::main), - local_id: 7, - }, + HirId(DefId(0:3 ~ main[26fd]::main).7), ), ty: i32, subpattern: None, is_primary: true, + is_shorthand: false, }, }, initializer: Some( e5, ), else_block: None, - lint_level: Explicit( - HirId { - owner: DefId(0:3 ~ oneplustwo[6932]::main), - local_id: 6, - }, - ), + hir_id: HirId(DefId(0:3 ~ main[26fd]::main).6), + span: main.rs:2:5: 2:18 (#0), }, - opt_destruction_scope: Some( - Destruction(1), - ), }, ], + params: [], } ``` From 4809e4c16d77f949f22546905fd465e5d982022a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 18:50:22 +0200 Subject: [PATCH 30/77] sembr src/hir-typeck/summary.md --- src/doc/rustc-dev-guide/src/hir-typeck/summary.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md index ae84c1e676751..a64f6c5adaf4d 100644 --- a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md +++ b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md @@ -26,8 +26,9 @@ fn foo(x: Foo, y: self::Foo) { ... } ``` Those two parameters `x` and `y` each have the same type: but they will have -distinct `hir::Ty` nodes. Those nodes will have different spans, and of course -they encode the path somewhat differently. But once they are "collected" into +distinct `hir::Ty` nodes. +Those nodes will have different spans, and of course they encode the path somewhat differently. +But once they are "collected" into `Ty<'tcx>` nodes, they will be represented by the exact same internal type. Collection is defined as a bundle of [queries] for computing information about @@ -35,8 +36,7 @@ the various functions, traits, and other items in the crate being compiled. Note that each of these queries is concerned with *interprocedural* things – for example, for a function definition, collection will figure out the type and signature of the function, but it will not visit the *body* of the function in -any way, nor examine type annotations on local variables (that's the job of -type *checking*). +any way, nor examine type annotations on local variables (that's the job of type *checking*). For more details, see the [`collect`][collect] module. From 775b4799d659cb2c8fa8e81526a25ed3e9875b34 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 18:51:43 +0200 Subject: [PATCH 31/77] unusual use of colon --- src/doc/rustc-dev-guide/src/hir-typeck/summary.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md index a64f6c5adaf4d..5fd10663694c5 100644 --- a/src/doc/rustc-dev-guide/src/hir-typeck/summary.md +++ b/src/doc/rustc-dev-guide/src/hir-typeck/summary.md @@ -25,8 +25,8 @@ fn foo(x: Foo, y: self::Foo) { ... } // ^^^ ^^^^^^^^^ ``` -Those two parameters `x` and `y` each have the same type: but they will have -distinct `hir::Ty` nodes. +Those two parameters `x` and `y` each have the same type, +but they will have distinct `hir::Ty` nodes. Those nodes will have different spans, and of course they encode the path somewhat differently. But once they are "collected" into `Ty<'tcx>` nodes, they will be represented by the exact same internal type. From ef6ce2290a02ef8974f6dff275556cfcc96ca95b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 18:52:25 +0200 Subject: [PATCH 32/77] sembr src/debuginfo/intro.md --- .../rustc-dev-guide/src/debuginfo/intro.md | 76 ++++++++++++------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md index 4fcf4901beefb..693aa5863fba2 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/intro.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -1,13 +1,14 @@ # Debug Info Debug info is a collection of information generated by the compiler that allows debuggers to -correctly interpret the state of a program while it is running. That includes things like mapping +correctly interpret the state of a program while it is running. +That includes things like mapping instruction addresses to lines of code in the source file, and type layout information so that bytes in memory can be read and displayed in a meaningful way. Debug info can be a slightly overloaded term, covering all the layers between Rust MIR, and the -end-user seeing the output of their debugger onscreen. In brief, the stack from beginning to end is -as follows: +end-user seeing the output of their debugger onscreen. +In brief, the stack from beginning to end is as follows: 1. Rustc inspects the MIR and communicates the relevant source, symbol, and type information to LLVM 2. LLVM translates this information into a target-specific debug info format during compilation @@ -33,51 +34,62 @@ API layers (e.g. VSCode extension by way of the # DWARF -The is the primary debug info format for `*-gnu` targets. It is typically bundled in with the -binary, but it [can be generated as a separate file](https://gcc.gnu.org/wiki/DebugFission). The -DWARF standard is available [here](https://dwarfstd.org/). +The is the primary debug info format for `*-gnu` targets. +It is typically bundled in with the +binary, but it [can be generated as a separate file](https://gcc.gnu.org/wiki/DebugFission). +The DWARF standard is available [here](https://dwarfstd.org/). > NOTE: To inspect DWARF debug info, [gimli](https://crates.io/crates/gimli) can be used > programatically. If you prefer a GUI, the author recommends [DWEX](https://github.com/sevaa/dwex) # PDB/CodeView -The primary debug info format for `*-msvc` targets. PDB is a proprietary container format created by -Microsoft that, unfortunately, +The primary debug info format for `*-msvc` targets. +PDB is a proprietary container format created by Microsoft that, unfortunately, [has multiple meanings](https://docs.rs/ms-pdb/0.1.10/ms_pdb/taster/enum.Flavor.html). -We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Net applications. PDB -files are separate from the compiled binary and use the `.pdb` extension. +We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Net applications. +PDB files are separate from the compiled binary and use the `.pdb` extension. -PDB files contain CodeView objects, equivalent to DWARF's tags. CodeView, the debugger that +PDB files contain CodeView objects, equivalent to DWARF's tags. +CodeView, the debugger that consumed CodeView objects, was originally released in 1985. Its original intent was for C debugging, -and was later extended to support Visual C++. There are still minor alterations to the format to +and was later extended to support Visual C++. +There are still minor alterations to the format to support modern architectures and languages, but many of these changes are undocumented and/or sparsely used. -It is important to keep this context in mind when working with CodeView objects. Due to its origins, -the "feature-set" of these objects is very limited, and focused around the core features of C. It -does not have many of the convenience or features of modern DWARF standards. A fair number of +It is important to keep this context in mind when working with CodeView objects. +Due to its origins, +the "feature-set" of these objects is very limited, and focused around the core features of C. +It does not have many of the convenience or features of modern DWARF standards. +A fair number of workarounds exist within the debug info stack to compensate for CodeView's shortcomings. -Due to its proprietary nature, it is very difficult to find information about PDB and CodeView. Many +Due to its proprietary nature, it is very difficult to find information about PDB and CodeView. +Many of the sources were made at vastly different times and contain incomplete or somewhat contradictory -information. As such this page will aim to collect as many sources as possible. +information. +As such this page will aim to collect as many sources as possible. * [TIS PE specification](https://web.archive.org/web/20260315080740/http://x-ways.net/winhex/kb/ff/PE_EXE.pdf) which includes a lengthy section titled "Microsoft Symbol and Type Information", detailing much of -the CodeView format. The document was created in 1993, but the information is still detailed, +the CodeView format. +The document was created in 1993, but the information is still detailed, accurate, and has useful diagrams. * LLVM * [CodeView Overview](https://llvm.org/docs/SourceLevelDebugging.html#codeview-debug-info-format) * [PDB Overview and technical details](https://llvm.org/docs/PDB/index.html) * Microsoft * [microsoft-pdb](https://github.com/microsoft/microsoft-pdb) - A C/C++ implementation of a PDB - reader. The implementation does not contain the full PDB or CodeView specification, but does - contain enough information for other PDB consumers to be written. At time of writing (Nov 2025), + reader. + The implementation does not contain the full PDB or CodeView specification, but does + contain enough information for other PDB consumers to be written. + At time of writing (Nov 2025), this repo has been archived for several years. * [pdb-rs](https://github.com/microsoft/pdb-rs/) - A Rust-based PDB reader and writer based on - other publicly-available information. Does not guarantee stability or spec compliance. Also - contains `pdbtool`, which can dump PDB files (`cargo install pdbtool`) + other publicly-available information. + Does not guarantee stability or spec compliance. + Also contains `pdbtool`, which can dump PDB files (`cargo install pdbtool`) * [Debug Interface Access SDK](https://learn.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/getting-started-debug-interface-access-sdk). While it does not document the PDB format directly, details can be gleaned from the interface itself. @@ -86,16 +98,20 @@ accurate, and has useful diagrams. # Debuggers -Rust supports 3 major debuggers: GDB, LLDB, and CDB. Each has its own set of requirements, -limitations, and quirks. This unfortunately creates a large surface area to account for. +Rust supports 3 major debuggers: GDB, LLDB, and CDB. +Each has its own set of requirements, +limitations, and quirks. +This unfortunately creates a large surface area to account for. > NOTE: CDB is a proprietary debugger created by Microsoft. The underlying engine also powers >WinDbg, KD, the Microsoft C/C++ extension for VSCode, and part of the Visual Studio Debugger. In >these docs, it will be referred to as CDB for consistency While GDB and LLDB do offer facilities to natively support Rust's value layout, this isn't -completely necessary. Rust currently outputs debug info very similar to that of C++, allowing -debuggers without Rust support to work with a slightly degraded experience. More detail will be +completely necessary. +Rust currently outputs debug info very similar to that of C++, allowing +debuggers without Rust support to work with a slightly degraded experience. +More detail will be included in later sections, but here is a quick reference for the capabilities of each debugger: | Debugger | Debug Info Format | Native Rust support | Expression Style | Visualizer Scripts | @@ -113,7 +129,9 @@ Below, are several unsupported debuggers that are of particular note due to thei in the future. * [Bugstalker](https://github.com/godzie44/BugStalker) is an x86-64 Linux debugger written in Rust, -specifically to debug Rust programs. While promising, it is still in early development. -* [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. It has -a custom debug info format that PDB is translated into. The project also includes a linker that can +specifically to debug Rust programs. +While promising, it is still in early development. +* [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. + It has a custom debug info format that PDB is translated into. +The project also includes a linker that can generate their new debug info format during the linking phase. From c0c28290421f55efcc50d3967cc44ffd09636df7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:05:48 +0200 Subject: [PATCH 33/77] reflow --- .../rustc-dev-guide/src/debuginfo/intro.md | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md index 693aa5863fba2..1fa0f620024a8 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/intro.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -2,9 +2,8 @@ Debug info is a collection of information generated by the compiler that allows debuggers to correctly interpret the state of a program while it is running. -That includes things like mapping -instruction addresses to lines of code in the source file, and type layout information so that -bytes in memory can be read and displayed in a meaningful way. +That includes things like mapping instruction addresses to lines of code in the source file, +and type layout information so that bytes in memory can be read and displayed in a meaningful way. Debug info can be a slightly overloaded term, covering all the layers between Rust MIR, and the end-user seeing the output of their debugger onscreen. @@ -51,25 +50,23 @@ We are concerned with ordinary PDB files, as Portable PDB is used mainly for .Ne PDB files are separate from the compiled binary and use the `.pdb` extension. PDB files contain CodeView objects, equivalent to DWARF's tags. -CodeView, the debugger that -consumed CodeView objects, was originally released in 1985. Its original intent was for C debugging, +CodeView, the debugger that consumed CodeView objects, was originally released in 1985. +Its original intent was for C debugging, and was later extended to support Visual C++. -There are still minor alterations to the format to -support modern architectures and languages, but many of these changes are undocumented and/or -sparsely used. +There are still minor alterations to the format to support modern architectures and languages, +but many of these changes are undocumented and/or sparsely used. It is important to keep this context in mind when working with CodeView objects. Due to its origins, the "feature-set" of these objects is very limited, and focused around the core features of C. It does not have many of the convenience or features of modern DWARF standards. -A fair number of -workarounds exist within the debug info stack to compensate for CodeView's shortcomings. +A fair number of workarounds exist within the debug info stack +to compensate for CodeView's shortcomings. Due to its proprietary nature, it is very difficult to find information about PDB and CodeView. -Many -of the sources were made at vastly different times and contain incomplete or somewhat contradictory -information. -As such this page will aim to collect as many sources as possible. +Many of the sources were made at vastly different times +and contain incomplete or somewhat contradictory information. +As such, this page will aim to collect as many sources as possible. * [TIS PE specification](https://web.archive.org/web/20260315080740/http://x-ways.net/winhex/kb/ff/PE_EXE.pdf) which includes a lengthy section titled "Microsoft Symbol and Type Information", detailing much of @@ -103,16 +100,17 @@ Each has its own set of requirements, limitations, and quirks. This unfortunately creates a large surface area to account for. -> NOTE: CDB is a proprietary debugger created by Microsoft. The underlying engine also powers ->WinDbg, KD, the Microsoft C/C++ extension for VSCode, and part of the Visual Studio Debugger. In ->these docs, it will be referred to as CDB for consistency +> NOTE: CDB is a proprietary debugger created by Microsoft. +> The underlying engine also powers WinDbg, KD, the Microsoft C/C++ extension for VSCode, +> and part of the Visual Studio Debugger. +> In these docs, it will be referred to as CDB for consistency While GDB and LLDB do offer facilities to natively support Rust's value layout, this isn't completely necessary. Rust currently outputs debug info very similar to that of C++, allowing debuggers without Rust support to work with a slightly degraded experience. -More detail will be -included in later sections, but here is a quick reference for the capabilities of each debugger: +More detail will be included in later sections, +but here is a quick reference for the capabilities of each debugger: | Debugger | Debug Info Format | Native Rust support | Expression Style | Visualizer Scripts | | --- | --- | --- | --- | --- | @@ -129,9 +127,9 @@ Below, are several unsupported debuggers that are of particular note due to thei in the future. * [Bugstalker](https://github.com/godzie44/BugStalker) is an x86-64 Linux debugger written in Rust, -specifically to debug Rust programs. -While promising, it is still in early development. + specifically to debug Rust programs. + While promising, it is still in early development. * [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) is a Windows-only GUI debugger. It has a custom debug info format that PDB is translated into. -The project also includes a linker that can -generate their new debug info format during the linking phase. + The project also includes a linker that can generate their new debug info format + during the linking phase. From 53e1b93c494aedf85c3009c29f6c45ce6bdec2f9 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:09:57 +0200 Subject: [PATCH 34/77] sembr src/debuginfo/rust-codegen.md --- .../src/debuginfo/rust-codegen.md | 60 +++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 73fa68d36076a..869e209b7b0a4 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -1,8 +1,10 @@ # Rust Codegen The first phase in debug info generation requires Rust to inspect the MIR of the program and -communicate it to LLVM. This is primarily done in [`rustc_codegen_llvm/debuginfo`][llvm_di], though -some type-name processing exists in [`rustc_codegen_ssa/debuginfo`][ssa_di]. Rust communicates to +communicate it to LLVM. +This is primarily done in [`rustc_codegen_llvm/debuginfo`][llvm_di], though +some type-name processing exists in [`rustc_codegen_ssa/debuginfo`][ssa_di]. +Rust communicates to LLVM via the `DIBuilder` API - a thin wrapper around LLVM's internals that exists in [rustc_llvm][rustc_llvm]. @@ -13,31 +15,33 @@ LLVM via the `DIBuilder` API - a thin wrapper around LLVM's internals that exist # Type Information Type information typically consists of the type name, size, alignment, as well as things like -fields, generic parameters, and storage modifiers if they are relevant. Much of this work happens in -[rustc_codegen_llvm/src/debuginfo/metadata][di_metadata]. +fields, generic parameters, and storage modifiers if they are relevant. +Much of this work happens in [rustc_codegen_llvm/src/debuginfo/metadata][di_metadata]. [di_metadata]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs It is important to keep in mind that the goal is not necessarily "represent types exactly how they appear in Rust", rather it is to represent them in a way that allows debuggers to most accurately -reconstruct the data during debugging. This distinction is vital to understanding the core work that +reconstruct the data during debugging. +This distinction is vital to understanding the core work that occurs on this layer; many changes made here will be for the purpose of working around debugger limitations when no other option will work. ## Quirks -Rust's generated DI nodes "pretend" to be C/C++ for both CDB and LLDB's sake. This can result in -some unintuitive and non-idiomatic debug info. +Rust's generated DI nodes "pretend" to be C/C++ for both CDB and LLDB's sake. +This can result in some unintuitive and non-idiomatic debug info. ### Pointers and Reference Wide pointers/references/`Box` are treated as a struct with 2 fields: `data_ptr` and `length`. All non-wide pointers, references, and `Box` pointers are output as pointer nodes, and no -distinction is made between `mut` and non-`mut`. Several attempts have been made to rectify this, -but unfortunately there is not a straightforward solution. Using the `reference` DI nodes of the -respective formats has pitfalls. There is a semantic difference between C++ references and Rust -references that is unreconcilable. +distinction is made between `mut` and non-`mut`. +Several attempts have been made to rectify this, +but unfortunately there is not a straightforward solution. +Using the `reference` DI nodes of the respective formats has pitfalls. +There is a semantic difference between C++ references and Rust references that is unreconcilable. >From [cppreference](https://en.cppreference.com/w/cpp/language/reference.html): > @@ -54,16 +58,19 @@ The current proposed solution is to simply [typedef the pointer nodes][issue_144 Using the `const` qualifier to denote non-`mut` poses potential issues due to LLDB's internal optimizations. In short, LLDB attempts to cache the child-values of variables (e.g. struct fields, -array elements) when stepping through code. A heuristic is used to determine which values are safely -cache-able, and `const` is part of that heuristic. Research has not been done into how this would +array elements) when stepping through code. +A heuristic is used to determine which values are safely +cache-able, and `const` is part of that heuristic. +Research has not been done into how this would interact with things like Rust's interior mutability constructs. ### DWARF vs PDB While most of the type information is fairly straight forward, one notable issue is the debug info -format of the target. Each format has different semantics and limitations, as such they require -slightly different debug info in some cases. This is gated by calls to -[`cpp_like_debuginfo`][cpp_like]. +format of the target. +Each format has different semantics and limitations, as such they require +slightly different debug info in some cases. +This is gated by calls to [`cpp_like_debuginfo`][cpp_like]. [cpp_like]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs#L813 @@ -97,7 +104,8 @@ consecutive `>`'s with a space (`> >`) in type names. [^2]: While these type names are generated as part of the debug info node (which is then wrapped in a typedef node with the Rust name), once the LLVM-IR node is converted to a CodeView node, the type -name information is lost. This is because CodeView has special shorthand nodes for primitive types, +name information is lost. +This is because CodeView has special shorthand nodes for primitive types, and those shorthand nodes to not have a "name" field. ### Generics @@ -106,8 +114,10 @@ Rust outputs generic *type* information (`T` in `ArrayVec`), but no information (`N` in `ArrayVec`). CodeView does not have a leaf node for generics/C++ templates, so all generic information is lost -when generating PDB debug info. There are workarounds that allow the debugger to retrieve the -generic arguments via the type name, but it is fragile solution at best. Efforts are being made to +when generating PDB debug info. +There are workarounds that allow the debugger to retrieve the +generic arguments via the type name, but it is fragile solution at best. +Efforts are being made to contact Microsoft to correct this deficiency, and/or to use one of the unused CodeView node types as a suitable equivalent. @@ -126,9 +136,10 @@ Enum DI nodes are generated in [rustc_codegen_llvm/src/debuginfo/metadata/enums] #### DWARF -DWARF has a dedicated node for discriminated unions: `DW_TAG_variant`. It is a container that -references `DW_TAG_variant_part` nodes that may or may not contain a discriminant value. The -hierarchy looks as follows: +DWARF has a dedicated node for discriminated unions: `DW_TAG_variant`. +It is a container that +references `DW_TAG_variant_part` nodes that may or may not contain a discriminant value. +The hierarchy looks as follows: ```txt DW_TAG_structure_type (top-level type for the coroutine) @@ -175,9 +186,10 @@ union enum2$ { ``` An important note is that due to limitations in LLDB, the `DISCR_*` value generated is always a -`u64` even if the value is not `#[repr(u64)]`. This is largely a non-issue for LLDB because the +`u64` even if the value is not `#[repr(u64)]`. +This is largely a non-issue for LLDB because the `DISCR_*` value and the `tag` are read into `uint64_t` values regardless of their type. # Source Information -TODO \ No newline at end of file +TODO From ff8c0c5d8fa4773313b7d5ae8262ea313be61925 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:20:57 +0200 Subject: [PATCH 35/77] reflow --- .../rustc-dev-guide/src/debuginfo/rust-codegen.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 869e209b7b0a4..2228007f9bcd1 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -4,9 +4,8 @@ The first phase in debug info generation requires Rust to inspect the MIR of the communicate it to LLVM. This is primarily done in [`rustc_codegen_llvm/debuginfo`][llvm_di], though some type-name processing exists in [`rustc_codegen_ssa/debuginfo`][ssa_di]. -Rust communicates to -LLVM via the `DIBuilder` API - a thin wrapper around LLVM's internals that exists in -[rustc_llvm][rustc_llvm]. +Rust communicates to LLVM via the `DIBuilder` API, +a thin wrapper around LLVM's internals that exists in [rustc_llvm][rustc_llvm]. [llvm_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_llvm/src/debuginfo [ssa_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_ssa/src/debuginfo @@ -117,9 +116,8 @@ CodeView does not have a leaf node for generics/C++ templates, so all generic in when generating PDB debug info. There are workarounds that allow the debugger to retrieve the generic arguments via the type name, but it is fragile solution at best. -Efforts are being made to -contact Microsoft to correct this deficiency, and/or to use one of the unused CodeView node types as -a suitable equivalent. +Efforts are being made to contact Microsoft to correct this deficiency, +and/or to use one of the unused CodeView node types as a suitable equivalent. ### Type aliases @@ -137,8 +135,8 @@ Enum DI nodes are generated in [rustc_codegen_llvm/src/debuginfo/metadata/enums] #### DWARF DWARF has a dedicated node for discriminated unions: `DW_TAG_variant`. -It is a container that -references `DW_TAG_variant_part` nodes that may or may not contain a discriminant value. +It is a container that references `DW_TAG_variant_part` nodes +that may or may not contain a discriminant value. The hierarchy looks as follows: ```txt From 5fab7f9448553dc5c19940bd2936a8aa6c91a4ef Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Mon, 20 Jul 2026 17:24:43 +0000 Subject: [PATCH 36/77] Prepare for merging from rust-lang/rust This updates the rust-version file to 9e71b3bc704eea68d39bd0f6a46703c7d22f5d3b. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index f930573748e28..a48a44e5d15fb 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -7fb284d9037fa54f6a9b24261c82b394472cbfd7 +9e71b3bc704eea68d39bd0f6a46703c7d22f5d3b From 890741bf2600904b9adc6d5131d1a8aa8ebe98fd Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:29:46 +0200 Subject: [PATCH 37/77] lighter markup --- src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index 2228007f9bcd1..b68536e43b6f7 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -5,7 +5,7 @@ communicate it to LLVM. This is primarily done in [`rustc_codegen_llvm/debuginfo`][llvm_di], though some type-name processing exists in [`rustc_codegen_ssa/debuginfo`][ssa_di]. Rust communicates to LLVM via the `DIBuilder` API, -a thin wrapper around LLVM's internals that exists in [rustc_llvm][rustc_llvm]. +a thin wrapper around LLVM's internals that exists in [rustc_llvm]. [llvm_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_llvm/src/debuginfo [ssa_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_ssa/src/debuginfo @@ -51,9 +51,9 @@ There is a semantic difference between C++ references and Rust references that i > >Because references are not objects, **there are no arrays of references, no pointers to references, and no references to references** -The current proposed solution is to simply [typedef the pointer nodes][issue_144394]. +The current proposed solution is to simply [typedef the pointer nodes]. -[issue_144394]: https://github.com/rust-lang/rust/pull/144394 +[typedef the pointer nodes]: https://github.com/rust-lang/rust/pull/144394 Using the `const` qualifier to denote non-`mut` poses potential issues due to LLDB's internal optimizations. In short, LLDB attempts to cache the child-values of variables (e.g. struct fields, @@ -69,9 +69,9 @@ While most of the type information is fairly straight forward, one notable issue format of the target. Each format has different semantics and limitations, as such they require slightly different debug info in some cases. -This is gated by calls to [`cpp_like_debuginfo`][cpp_like]. +This is gated by calls to [`cpp_like_debuginfo`]. -[cpp_like]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs#L813 +[`cpp_like_debuginfo`]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs#L813 ### Naming From d6be727b10cbbcfffcad49814f5c758cca04133b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:33:16 +0200 Subject: [PATCH 38/77] use sentence case for titles --- src/doc/rustc-dev-guide/src/SUMMARY.md | 4 ++-- src/doc/rustc-dev-guide/src/debuginfo/intro.md | 2 +- src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 91bb143eb318f..cc3fece79dd78 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -239,8 +239,8 @@ - [Debugging LLVM](./backend/debugging.md) - [Backend Agnostic Codegen](./backend/backend-agnostic.md) - [Implicit caller location](./backend/implicit-caller-location.md) -- [Debug Info](./debuginfo/intro.md) - - [Rust Codegen](./debuginfo/rust-codegen.md) +- [Debug info](./debuginfo/intro.md) + - [Rust codegen](./debuginfo/rust-codegen.md) - [LLVM Codegen](./debuginfo/llvm-codegen.md) - [Debugger Internals](./debuginfo/debugger-internals.md) - [LLDB Internals](./debuginfo/lldb-internals.md) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/intro.md b/src/doc/rustc-dev-guide/src/debuginfo/intro.md index 1fa0f620024a8..e8c4d11d12b0a 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/intro.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/intro.md @@ -1,4 +1,4 @@ -# Debug Info +# Debug info Debug info is a collection of information generated by the compiler that allows debuggers to correctly interpret the state of a program while it is running. diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index b68536e43b6f7..fc3b5270a2e8b 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -1,4 +1,4 @@ -# Rust Codegen +# Rust codegen The first phase in debug info generation requires Rust to inspect the MIR of the program and communicate it to LLVM. @@ -11,7 +11,7 @@ a thin wrapper around LLVM's internals that exists in [rustc_llvm]. [ssa_di]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_codegen_ssa/src/debuginfo [rustc_llvm]: https://github.com/rust-lang/rust/tree/main/compiler/rustc_llvm -# Type Information +# Type information Type information typically consists of the type name, size, alignment, as well as things like fields, generic parameters, and storage modifiers if they are relevant. @@ -31,7 +31,7 @@ limitations when no other option will work. Rust's generated DI nodes "pretend" to be C/C++ for both CDB and LLDB's sake. This can result in some unintuitive and non-idiomatic debug info. -### Pointers and Reference +### Pointers and reference Wide pointers/references/`Box` are treated as a struct with 2 fields: `data_ptr` and `length`. @@ -188,6 +188,6 @@ An important note is that due to limitations in LLDB, the `DISCR_*` value genera This is largely a non-issue for LLDB because the `DISCR_*` value and the `tag` are read into `uint64_t` values regardless of their type. -# Source Information +# Source information TODO From 147ffe4a55bf32f7d1c1a27ec40b35587c3c4be3 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:33:41 +0200 Subject: [PATCH 39/77] fix section title --- src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md index fc3b5270a2e8b..f879579de9907 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/rust-codegen.md @@ -31,7 +31,7 @@ limitations when no other option will work. Rust's generated DI nodes "pretend" to be C/C++ for both CDB and LLDB's sake. This can result in some unintuitive and non-idiomatic debug info. -### Pointers and reference +### Pointers and references Wide pointers/references/`Box` are treated as a struct with 2 fields: `data_ptr` and `length`. From 1064b07aafff40e0d326c0f9c44be850088ac612 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:36:58 +0200 Subject: [PATCH 40/77] it will happen when it does --- src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md | 2 +- src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md | 2 +- src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md | 2 +- src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md | 2 +- src/doc/rustc-dev-guide/src/debuginfo/testing.md | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md index 95f543c8e94a0..619fb86e158a7 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md @@ -1,4 +1,4 @@ -# (WIP) GDB Internals +# GDB internals GDB's Rust support lives at `gdb/rust-lang.h` and `gdb/rust-lang.c`. The expression parsing support can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` \ No newline at end of file diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md index 4027ef897f28a..3f8fb3bf439a5 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-visualizers.md @@ -1,4 +1,4 @@ -# (WIP) GDB - Python Providers +# GDB - Python Providers Below are links to relevant parts of the GDB documentation diff --git a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md index cc052b6b965f1..67df1092bd3ba 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md @@ -1,4 +1,4 @@ -# (WIP) LLVM Codegen +# LLVM codegen When Rust calls an LLVM `DIBuilder` function, LLVM translates the given information to a ["debug record"][dbg_record] that is format-agnostic. These records can be inspected in the LLVM-IR. diff --git a/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md index 653e7d5d65555..1b156465f4f85 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/natvis-visualizers.md @@ -1,3 +1,3 @@ -# (WIP) CDB - Natvis +# CDB - Natvis Official documentation for Natvis can be found [here](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects) and [here](https://code.visualstudio.com/docs/cpp/natvis) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/testing.md b/src/doc/rustc-dev-guide/src/debuginfo/testing.md index f58050875e1a0..7aec83aa97ac6 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/testing.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/testing.md @@ -1,8 +1,8 @@ -# (WIP) Testing +# Testing The debug info test suite is undergoing a substantial rewrite. This section will be filled out as the rewrite makes progress. Please see [this tracking issue][148483] for more information. -[148483]: https://github.com/rust-lang/rust/issues/148483 \ No newline at end of file +[148483]: https://github.com/rust-lang/rust/issues/148483 From 6af61079b4a73e6274fb5b8490394ebc64ef752b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:44:50 +0200 Subject: [PATCH 41/77] use sentence case for titles --- src/doc/rustc-dev-guide/src/SUMMARY.md | 12 ++++++------ .../src/debuginfo/debugger-internals.md | 4 ++-- .../src/debuginfo/debugger-visualizers.md | 4 ++-- .../rustc-dev-guide/src/debuginfo/gdb-internals.md | 2 +- .../rustc-dev-guide/src/debuginfo/lldb-internals.md | 12 ++++++------ .../src/debuginfo/lldb-visualizers.md | 4 ++-- .../rustc-dev-guide/src/debuginfo/llvm-codegen.md | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index cc3fece79dd78..3b6d0a5032974 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -241,16 +241,16 @@ - [Implicit caller location](./backend/implicit-caller-location.md) - [Debug info](./debuginfo/intro.md) - [Rust codegen](./debuginfo/rust-codegen.md) - - [LLVM Codegen](./debuginfo/llvm-codegen.md) - - [Debugger Internals](./debuginfo/debugger-internals.md) - - [LLDB Internals](./debuginfo/lldb-internals.md) - - [GDB Internals](./debuginfo/gdb-internals.md) - - [Debugger Visualizers](./debuginfo/debugger-visualizers.md) + - [LLVM codegen](./debuginfo/llvm-codegen.md) + - [Debugger internals](./debuginfo/debugger-internals.md) + - [LLDB internals](./debuginfo/lldb-internals.md) + - [GDB internals](./debuginfo/gdb-internals.md) + - [Debugger visualizers](./debuginfo/debugger-visualizers.md) - [LLDB - Python Providers](./debuginfo/lldb-visualizers.md) - [GDB - Python Providers](./debuginfo/gdb-visualizers.md) - [CDB - Natvis](./debuginfo/natvis-visualizers.md) - [Testing](./debuginfo/testing.md) - - [(Lecture Notes) Debugging support in the Rust compiler](./debugging-support-in-rustc.md) + - [(Lecture notes) Debugging support in the Rust compiler](./debugging-support-in-rustc.md) - [Libraries and metadata](./backend/libs-and-metadata.md) - [Profile-guided optimization](./profile-guided-optimization.md) - [LLVM source-based code coverage](./llvm-coverage-instrumentation.md) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md index 114ce8a998c58..4aec0befcf76c 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md @@ -1,4 +1,4 @@ -# Debugger Internals +# Debugger internals It is the debugger's job to convert the debug info into an in-memory representation. Both the interpretation of the debug info and the in-memory representation are arbitrary; anything will do @@ -11,4 +11,4 @@ interpret and display the data, a way for users to interact with it, and an API Debuggers are vast systems and cannot be covered completely here. This section will provide a brief overview of the subsystems directly relevant to the Rust debugging experience. -Microsoft's debugging engine is closed source, so it will not be covered here. \ No newline at end of file +Microsoft's debugging engine is closed source, so it will not be covered here. diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md index 831acbd2f8f8e..e3b82b1d4a421 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -1,4 +1,4 @@ -# Debugger Visualizers +# Debugger visualizers These are typically the last step before the debugger displays the information, but the results may be piped through a debug adapter such as an IDE's debugger API. @@ -108,4 +108,4 @@ noticable amount. This does require you to name your fields in advance and initi * List comprehensions are typically faster than loops, generator comprehensions are a bit slower than list comprehensions, but use less memory. You can think of comprehensions as equivalent to Rust's `iter.map()`. List comprehensions effectively call `collect::>` at the end, whereas -generator comprehensions do not. \ No newline at end of file +generator comprehensions do not. diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md index 619fb86e158a7..8959f5d719c4e 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md @@ -1,4 +1,4 @@ # GDB internals GDB's Rust support lives at `gdb/rust-lang.h` and `gdb/rust-lang.c`. The expression parsing support -can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` \ No newline at end of file +can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md index e104f1d245327..8119662b3d791 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -1,4 +1,4 @@ -# LLDB Internals +# LLDB internals LLDB's debug info processing relies on a set of extensible interfaces largely defined in [lldb/src/Plugins][lldb_plugins]. These are meant to allow third-party compiler developers to add @@ -19,7 +19,7 @@ Here are some existing implementations of LLDB's plugin API: This was written before the `TypeSystem` API was created. Due to the freeform nature of expression parsing, the underlyng lexing, parsing, function calling, etc. should still offer valuable insights. -## Rust Support and TypeSystemClang +## Rust support and TypeSystemClang As mentioned in the debug info overview, LLDB has partial Rust support. To further clarify, Rust uses the plugin-pipeline that was built for C/C++ (though it contains some helpers for Rust enum @@ -63,7 +63,7 @@ from scratch using publicly available information about the PDB format. [dia_discourse]: https://discourse.llvm.org/t/rfc-removing-the-dia-pdb-plugin-from-lldb/87827 [dia_tracking]: https://github.com/llvm/llvm-project/issues/114906 -## Debug Node Parsing +## Debug node parsing The first step is to process the raw debug nodes into something usable. This primarily occurs in the [`DWARFASTParser`][dwarf_ast] and [`PdbAstBuilder`][pdb_ast] classes. These classes are fed a @@ -135,7 +135,7 @@ impl TypeSystem for TypeSystemLang { } ``` -## Type Systems +## Type systems The [`TypeSystem` interface][ts_interface] has 3 major purposes: @@ -172,7 +172,7 @@ alterations as possible. LLDB's synthetics and frontend can handle making the ty piece of information is useless, the Rust compiler should be altered to not output that debug info in the first place. -## Expression Parsing +## Expression parsing The `TypeSystem` is typically written to have a counterpart that can handle expression parsing. It requires implementing a few extra functions in the `TypeSystem` interface. The bulk of the @@ -205,4 +205,4 @@ may be a good stepping stone towards full language support in LLDB. ## Visualizers -WIP \ No newline at end of file +WIP diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md index 83e2b0d5794e8..58d4bd068f5bb 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-visualizers.md @@ -330,7 +330,7 @@ of the synthetic. By implementing an instance summary, we can retrieve the variant name via `self.variant.GetTypeName()` and some string manipulation. -# Writing Visualizer Scripts +# Writing visualizer scripts > IMPORTANT: Unlike GDB and CDB, LLDB can debug executables with either DWARF or PDB debug info. >Visualizers must be written to account for both formats whenever possible. See: @@ -373,7 +373,7 @@ use depending on what version of LLDB the script detects. This is vital for backwards compatibility once we begin using recognizer functions, as recognizers were added in lldb 19.0. -## Visualizer Resolution +## Visualizer resolution The order that visualizers resolve in is listed [here][formatters_101]. In short: diff --git a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md index 67df1092bd3ba..3b6bd454b29f2 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md @@ -9,4 +9,4 @@ It is important to note that tags within the debug records are **always stored a the target calls for PDB debug info, during codegen the debug records will then be passed through [a module that translates the DWARF tags to their CodeView counterparts][cv]. -[cv]:https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp \ No newline at end of file +[cv]:https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp From df163d8428f96e5eea47d4b9ba85ca1f586b6327 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 19:46:38 +0200 Subject: [PATCH 42/77] sembr src/debuginfo/debugger-internals.md --- .../src/debuginfo/debugger-internals.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md index 4aec0befcf76c..574bb3be6a0d2 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md @@ -1,14 +1,16 @@ # Debugger internals -It is the debugger's job to convert the debug info into an in-memory representation. Both the +It is the debugger's job to convert the debug info into an in-memory representation. +Both the interpretation of the debug info and the in-memory representation are arbitrary; anything will do -so long as meaningful information can be reconstructed while the program is running. The pipeline -from raw debug info to usable types can be quite complicated. +so long as meaningful information can be reconstructed while the program is running. +The pipeline from raw debug info to usable types can be quite complicated. Once the information is in a workable format, the debugger front-end then must provide a way to interpret and display the data, a way for users to interact with it, and an API for extensibility. -Debuggers are vast systems and cannot be covered completely here. This section will provide a brief +Debuggers are vast systems and cannot be covered completely here. +This section will provide a brief overview of the subsystems directly relevant to the Rust debugging experience. Microsoft's debugging engine is closed source, so it will not be covered here. From 3b999caee652bc1c9c8c9fc7f59eb925fd78f3f5 Mon Sep 17 00:00:00 2001 From: zedddie Date: Mon, 20 Jul 2026 01:59:14 +0200 Subject: [PATCH 43/77] bless batch --- .../const-bytes-slice-pattern.rs | 3 ++ ...ross-crate-multibyte-debuginfo-comments.rs | 11 +++--- .../cross-crate-multibyte-debuginfo.rs | 10 +++--- .../cross-crate-multibyte-debuginfo.rs | 5 +-- .../fru-unknown-field-in-closure.rs | 3 ++ .../fru-unknown-field-in-closure.stderr | 2 +- .../for-loop-nested-array-inference.rs | 3 ++ .../for-loop-nested-array-inference.stderr | 2 +- .../issue-67039-unsound-pin-partialeq.rs | 27 -------------- .../issue-67039-unsound-pin-partialeq.stderr | 13 ------- .../repetition-matches-empty-token-tree.rs | 9 ++--- ...repetition-matches-empty-token-tree.stderr | 36 +++++++++---------- .../ui/moves/move-out-of-shared-ref-deref.rs | 2 ++ .../moves/move-out-of-shared-ref-deref.stderr | 2 +- .../struct-pattern-nonexistent-field.rs | 3 ++ .../struct-pattern-nonexistent-field.stderr | 6 ++-- .../call-tuple-struct-ctor-as-fn.rs | 2 ++ .../object/extern-c-trait-object-methods.rs | 3 ++ 18 files changed, 62 insertions(+), 80 deletions(-) delete mode 100644 tests/ui/issues/issue-67039-unsound-pin-partialeq.rs delete mode 100644 tests/ui/issues/issue-67039-unsound-pin-partialeq.stderr diff --git a/tests/ui/consts/const_in_pattern/const-bytes-slice-pattern.rs b/tests/ui/consts/const_in_pattern/const-bytes-slice-pattern.rs index 05f71623d1419..028c7a74bd640 100644 --- a/tests/ui/consts/const_in_pattern/const-bytes-slice-pattern.rs +++ b/tests/ui/consts/const_in_pattern/const-bytes-slice-pattern.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! This used to ICE. //@ check-pass + #![allow(dead_code)] const PATH_DOT: &[u8] = &[b'.']; diff --git a/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs b/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs index 215145a64b177..eec8c8e1d0d4e 100644 --- a/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs +++ b/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo-comments.rs @@ -1,9 +1,10 @@ -use std::fmt; +//! Auxiliary file for . +//! This is a file with many multi-byte characters, to try to encourage +//! the compiler to trip on them. The Drop implementation below will +//! need to have its source location embedded into the debug info for +//! the output file. -// This ia file with many multi-byte characters, to try to encourage -// the compiler to trip on them. The Drop implementation below will -// need to have its source location embedded into the debug info for -// the output file. +use std::fmt; // αααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααα // ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ diff --git a/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs b/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs index 5b1b1389cebb3..695fccc4519a8 100644 --- a/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs +++ b/tests/ui/debuginfo/auxiliary/cross-crate-multibyte-debuginfo.rs @@ -1,10 +1,10 @@ +//! Auxiliary file for . +//! This is a file that pulls in a separate file as a submodule, where +//! that separate file has many multi-byte characters, to try to +//! encourage the compiler to trip on them. #![crate_type="lib"] -// This is a file that pulls in a separate file as a submodule, where -// that separate file has many multi-byte characters, to try to -// encourage the compiler to trip on them. - -#[path = "issue-24687-mbcs-in-comments.rs"] +#[path = "cross-crate-multibyte-debuginfo-comments.rs"] mod issue_24687_mbcs_in_comments; pub use issue_24687_mbcs_in_comments::D; diff --git a/tests/ui/debuginfo/cross-crate-multibyte-debuginfo.rs b/tests/ui/debuginfo/cross-crate-multibyte-debuginfo.rs index d1ab717264b4c..026aecaa5f277 100644 --- a/tests/ui/debuginfo/cross-crate-multibyte-debuginfo.rs +++ b/tests/ui/debuginfo/cross-crate-multibyte-debuginfo.rs @@ -1,8 +1,9 @@ +//! Regression test for . //@ run-pass -//@ aux-build:issue-24687-lib.rs +//@ aux-build:cross-crate-multibyte-debuginfo.rs //@ compile-flags:-g -extern crate issue_24687_lib as d; +extern crate cross_crate_multibyte_debuginfo as d; fn main() { // Create a `D`, which has a destructor whose body will be codegen'ed diff --git a/tests/ui/functional-struct-update/fru-unknown-field-in-closure.rs b/tests/ui/functional-struct-update/fru-unknown-field-in-closure.rs index 5f762bc431e12..c9fb4e2774938 100644 --- a/tests/ui/functional-struct-update/fru-unknown-field-in-closure.rs +++ b/tests/ui/functional-struct-update/fru-unknown-field-in-closure.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to ICE. + struct Point { pub x: u64, pub y: u64, diff --git a/tests/ui/functional-struct-update/fru-unknown-field-in-closure.stderr b/tests/ui/functional-struct-update/fru-unknown-field-in-closure.stderr index 1a3514fb715d1..990e65c87aaae 100644 --- a/tests/ui/functional-struct-update/fru-unknown-field-in-closure.stderr +++ b/tests/ui/functional-struct-update/fru-unknown-field-in-closure.stderr @@ -1,5 +1,5 @@ error[E0560]: struct `Point` has no field named `nonexistent` - --> $DIR/issue-50618.rs:14:13 + --> $DIR/fru-unknown-field-in-closure.rs:17:13 | LL | nonexistent: 0, | ^^^^^^^^^^^ `Point` does not have this field diff --git a/tests/ui/inference/need_type_info/for-loop-nested-array-inference.rs b/tests/ui/inference/need_type_info/for-loop-nested-array-inference.rs index 4c21cbfc61d43..a6f35620fcc9b 100644 --- a/tests/ui/inference/need_type_info/for-loop-nested-array-inference.rs +++ b/tests/ui/inference/need_type_info/for-loop-nested-array-inference.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! This used to leak internal `__next` ident into suggestion. + fn main() { let tiles = Default::default(); for row in &mut tiles { diff --git a/tests/ui/inference/need_type_info/for-loop-nested-array-inference.stderr b/tests/ui/inference/need_type_info/for-loop-nested-array-inference.stderr index 4839a0d46095f..75f84797cecd9 100644 --- a/tests/ui/inference/need_type_info/for-loop-nested-array-inference.stderr +++ b/tests/ui/inference/need_type_info/for-loop-nested-array-inference.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-51116.rs:5:13 + --> $DIR/for-loop-nested-array-inference.rs:8:13 | LL | *tile = 0; | ^^^^^ cannot infer type diff --git a/tests/ui/issues/issue-67039-unsound-pin-partialeq.rs b/tests/ui/issues/issue-67039-unsound-pin-partialeq.rs deleted file mode 100644 index a496e58a79bdd..0000000000000 --- a/tests/ui/issues/issue-67039-unsound-pin-partialeq.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Pin's PartialEq implementation allowed to access the pointer allowing for -// unsoundness by using Rc::get_mut to move value within Rc. -// See https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73 for more details. - -use std::ops::Deref; -use std::pin::Pin; -use std::rc::Rc; - -struct Apple; - -impl Deref for Apple { - type Target = Apple; - fn deref(&self) -> &Apple { - &Apple - } -} - -impl PartialEq> for Apple { - fn eq(&self, _rc: &Rc) -> bool { - unreachable!() - } -} - -fn main() { - let _ = Pin::new(Apple) == Rc::pin(Apple); - //~^ ERROR type mismatch resolving -} diff --git a/tests/ui/issues/issue-67039-unsound-pin-partialeq.stderr b/tests/ui/issues/issue-67039-unsound-pin-partialeq.stderr deleted file mode 100644 index 9164e4696eb34..0000000000000 --- a/tests/ui/issues/issue-67039-unsound-pin-partialeq.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0271]: type mismatch resolving ` as Deref>::Target == Rc` - --> $DIR/issue-67039-unsound-pin-partialeq.rs:25:29 - | -LL | let _ = Pin::new(Apple) == Rc::pin(Apple); - | ^^ expected `Rc`, found `Apple` - | - = note: expected struct `Rc` - found struct `Apple` - = note: required for `Pin` to implement `PartialEq>>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/macros/repetition-matches-empty-token-tree.rs b/tests/ui/macros/repetition-matches-empty-token-tree.rs index 47d07f0df014c..eb722764fc63a 100644 --- a/tests/ui/macros/repetition-matches-empty-token-tree.rs +++ b/tests/ui/macros/repetition-matches-empty-token-tree.rs @@ -1,10 +1,11 @@ -#![allow(unused_macros)] - -// Tests that repetition matchers cannot match the empty token tree (since that would be -// ambiguous). +//! Regression test for . +//! Tests that repetition matchers cannot match the empty token tree (since that would be +//! ambiguous). //@ edition:2018 +#![allow(unused_macros)] + macro_rules! foo { ( $()* ) => {}; //~^ ERROR repetition matches empty token tree diff --git a/tests/ui/macros/repetition-matches-empty-token-tree.stderr b/tests/ui/macros/repetition-matches-empty-token-tree.stderr index 7ffc6071407c5..eba436c233ca7 100644 --- a/tests/ui/macros/repetition-matches-empty-token-tree.stderr +++ b/tests/ui/macros/repetition-matches-empty-token-tree.stderr @@ -1,107 +1,107 @@ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:9:8 + --> $DIR/repetition-matches-empty-token-tree.rs:10:8 | LL | ( $()* ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:11:8 + --> $DIR/repetition-matches-empty-token-tree.rs:12:8 | LL | ( $()+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:13:8 + --> $DIR/repetition-matches-empty-token-tree.rs:14:8 | LL | ( $()? ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:18:9 + --> $DIR/repetition-matches-empty-token-tree.rs:19:9 | LL | ( [$()*] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:20:9 + --> $DIR/repetition-matches-empty-token-tree.rs:21:9 | LL | ( [$()+] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:22:9 + --> $DIR/repetition-matches-empty-token-tree.rs:23:9 | LL | ( [$()?] ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:27:8 + --> $DIR/repetition-matches-empty-token-tree.rs:28:8 | LL | ( $($()* $(),* $(a)* $(a),* )* ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:29:8 + --> $DIR/repetition-matches-empty-token-tree.rs:30:8 | LL | ( $($()* $(),* $(a)* $(a),* )+ ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:31:8 + --> $DIR/repetition-matches-empty-token-tree.rs:32:8 | LL | ( $($()* $(),* $(a)* $(a),* )? ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:33:8 + --> $DIR/repetition-matches-empty-token-tree.rs:34:8 | LL | ( $($()? $(),* $(a)? $(a),* )* ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:35:8 + --> $DIR/repetition-matches-empty-token-tree.rs:36:8 | LL | ( $($()? $(),* $(a)? $(a),* )+ ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:37:8 + --> $DIR/repetition-matches-empty-token-tree.rs:38:8 | LL | ( $($()? $(),* $(a)? $(a),* )? ) => {}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:47:12 + --> $DIR/repetition-matches-empty-token-tree.rs:48:12 | LL | ( $(a $()+)* ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:49:12 + --> $DIR/repetition-matches-empty-token-tree.rs:50:12 | LL | ( $(a $()*)+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:51:12 + --> $DIR/repetition-matches-empty-token-tree.rs:52:12 | LL | ( $(a $()+)? ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:53:12 + --> $DIR/repetition-matches-empty-token-tree.rs:54:12 | LL | ( $(a $()?)+ ) => {}; | ^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:60:18 + --> $DIR/repetition-matches-empty-token-tree.rs:61:18 | LL | (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]); | ^^^^^^^^^^^^^^^^^^ error: repetition matches empty token tree - --> $DIR/issue-5067.rs:71:8 + --> $DIR/repetition-matches-empty-token-tree.rs:72:8 | LL | ( $()* ) => {}; | ^^ diff --git a/tests/ui/moves/move-out-of-shared-ref-deref.rs b/tests/ui/moves/move-out-of-shared-ref-deref.rs index 547643f0d6e20..6adb7811c5d4d 100644 --- a/tests/ui/moves/move-out-of-shared-ref-deref.rs +++ b/tests/ui/moves/move-out-of-shared-ref-deref.rs @@ -1,3 +1,5 @@ +//! Regression test for . + #[derive(Debug)] enum MyError { NotFound { key: Vec }, diff --git a/tests/ui/moves/move-out-of-shared-ref-deref.stderr b/tests/ui/moves/move-out-of-shared-ref-deref.stderr index 51959f22b97a4..7a7158dfbdbef 100644 --- a/tests/ui/moves/move-out-of-shared-ref-deref.stderr +++ b/tests/ui/moves/move-out-of-shared-ref-deref.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `*key` which is behind a shared reference - --> $DIR/issue-52262.rs:15:35 + --> $DIR/move-out-of-shared-ref-deref.rs:17:35 | LL | String::from_utf8(*key).unwrap() | ^^^^ move occurs because `*key` has type `Vec`, which does not implement the `Copy` trait diff --git a/tests/ui/pattern/struct-pattern-nonexistent-field.rs b/tests/ui/pattern/struct-pattern-nonexistent-field.rs index b5ddc7221d06a..ed74bdf937145 100644 --- a/tests/ui/pattern/struct-pattern-nonexistent-field.rs +++ b/tests/ui/pattern/struct-pattern-nonexistent-field.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test matching non-existing fields via struct pattern syntax in closures doesn't ICE. + enum SimpleEnum { NoState, } diff --git a/tests/ui/pattern/struct-pattern-nonexistent-field.stderr b/tests/ui/pattern/struct-pattern-nonexistent-field.stderr index 09c52292dccaf..4eddc55bb5490 100644 --- a/tests/ui/pattern/struct-pattern-nonexistent-field.stderr +++ b/tests/ui/pattern/struct-pattern-nonexistent-field.stderr @@ -1,5 +1,5 @@ error[E0026]: struct `SimpleStruct` does not have a field named `state` - --> $DIR/issue-51102.rs:13:17 + --> $DIR/struct-pattern-nonexistent-field.rs:16:17 | LL | state: 0, | ^^^^^ @@ -8,7 +8,7 @@ LL | state: 0, | help: `SimpleStruct` has a field named `no_state_here` error[E0025]: field `no_state_here` bound multiple times in the pattern - --> $DIR/issue-51102.rs:24:17 + --> $DIR/struct-pattern-nonexistent-field.rs:27:17 | LL | no_state_here: 0, | ---------------- first use of `no_state_here` @@ -16,7 +16,7 @@ LL | no_state_here: 1 | ^^^^^^^^^^^^^^^^ multiple uses of `no_state_here` in pattern error[E0026]: variant `SimpleEnum::NoState` does not have a field named `state` - --> $DIR/issue-51102.rs:33:17 + --> $DIR/struct-pattern-nonexistent-field.rs:36:17 | LL | state: 0 | ^^^^^ variant `SimpleEnum::NoState` does not have this field diff --git a/tests/ui/structs-enums/call-tuple-struct-ctor-as-fn.rs b/tests/ui/structs-enums/call-tuple-struct-ctor-as-fn.rs index 29a6f8f2934a1..b715c9d3eaab2 100644 --- a/tests/ui/structs-enums/call-tuple-struct-ctor-as-fn.rs +++ b/tests/ui/structs-enums/call-tuple-struct-ctor-as-fn.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test calling tuple struct constructor doesn't cause segfault. //@ run-pass struct A(#[allow(dead_code)] bool); diff --git a/tests/ui/traits/object/extern-c-trait-object-methods.rs b/tests/ui/traits/object/extern-c-trait-object-methods.rs index bf3f629df4970..f1ee19fc67cf2 100644 --- a/tests/ui/traits/object/extern-c-trait-object-methods.rs +++ b/tests/ui/traits/object/extern-c-trait-object-methods.rs @@ -1,4 +1,7 @@ +//! Regression test for . +//! Test extern `C` trait object methods don't ICE. //@ run-pass + trait Foo { extern "C" fn borrow(&self); extern "C" fn take(self: Box); From 7ff730b2ce77db89e81d78026e1ed809ab9102fa Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Tue, 21 Jul 2026 13:12:25 +0200 Subject: [PATCH 44/77] run `tests/assembly-llvm/asm/aarch64-types.rs` for `aarch64_be` --- tests/assembly-llvm/asm/aarch64-types.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/assembly-llvm/asm/aarch64-types.rs b/tests/assembly-llvm/asm/aarch64-types.rs index fde0aad946951..47e7917c85a94 100644 --- a/tests/assembly-llvm/asm/aarch64-types.rs +++ b/tests/assembly-llvm/asm/aarch64-types.rs @@ -1,8 +1,10 @@ //@ add-minicore -//@ revisions: aarch64 arm64ec +//@ revisions: aarch64 aarch64_be arm64ec //@ assembly-output: emit-asm //@ [aarch64] compile-flags: --target aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 +//@ [aarch64_be] compile-flags: --target aarch64_be-unknown-linux-gnu +//@ [aarch64_be] needs-llvm-components: aarch64 //@ [arm64ec] compile-flags: --target arm64ec-pc-windows-msvc //@ [arm64ec] needs-llvm-components: aarch64 //@ compile-flags: -Zmerge-functions=disabled From f68af893b54f5280f04fdcda2e964961b051ced1 Mon Sep 17 00:00:00 2001 From: sgasho Date: Tue, 21 Jul 2026 22:22:31 +0900 Subject: [PATCH 45/77] rdg: Move Autodiff CI job below performance testing --- src/doc/rustc-dev-guide/src/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 6a3a5a0a936f3..a2b386cc83071 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -34,8 +34,8 @@ - [Codegen backend testing](./tests/codegen-backend-tests/intro.md) - [Cranelift codegen backend](./tests/codegen-backend-tests/cg_clif.md) - [GCC codegen backend](./tests/codegen-backend-tests/cg_gcc.md) - - [Autodiff CI job](./tests/autodiff-ci-job.md) - [Performance testing](./tests/perf.md) + - [Autodiff CI job](./tests/autodiff-ci-job.md) - [Pre-stabilization CI job for the next solver and polonius alpha](./tests/x86_64-gnu-next-trait-solver-polonius-ci-job.md) - [Misc info](./tests/misc.md) - [Debugging the compiler](./compiler-debugging.md) From 2bb8a3b44ab94616e7757364c8e567f351e72de1 Mon Sep 17 00:00:00 2001 From: sgasho Date: Tue, 21 Jul 2026 22:23:34 +0900 Subject: [PATCH 46/77] Delete autodiff.sh and move the test command to the Dockerfile --- .../host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile | 8 +++++--- src/ci/docker/scripts/autodiff.sh | 9 --------- 2 files changed, 5 insertions(+), 12 deletions(-) delete mode 100755 src/ci/docker/scripts/autodiff.sh diff --git a/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile b/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile index f4633f951c645..a7b6dc620e967 100644 --- a/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile +++ b/src/ci/docker/host-x86_64/optional-x86_64-gnu-autodiff/Dockerfile @@ -20,8 +20,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -COPY scripts/autodiff.sh /scripts/ - ENV NO_DOWNLOAD_CI_LLVM 1 ENV CODEGEN_BACKENDS llvm @@ -34,4 +32,8 @@ ENV RUST_CONFIGURE_ARGS \ --disable-docs \ --set llvm.download-ci-llvm=false -ENV SCRIPT /scripts/autodiff.sh +ENV SCRIPT="../x.py test --stage 2 --no-fail-fast \ + tests/codegen-llvm/autodiff \ + tests/pretty/autodiff \ + tests/ui/autodiff \ + tests/ui/feature-gates/feature-gate-autodiff.rs" diff --git a/src/ci/docker/scripts/autodiff.sh b/src/ci/docker/scripts/autodiff.sh deleted file mode 100755 index 90b36078faccd..0000000000000 --- a/src/ci/docker/scripts/autodiff.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -ex - -../x.py test --stage 2 --no-fail-fast \ - tests/codegen-llvm/autodiff \ - tests/pretty/autodiff \ - tests/ui/autodiff \ - tests/ui/feature-gates/feature-gate-autodiff.rs From 737220233d0c8c591b96546e83eec7b2194d555e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 21 Jul 2026 15:50:58 +0000 Subject: [PATCH 47/77] Make some parser structured suggestions verbose Replace most of the `.span_suggestion(` in `rustc_parse` with `.span_suggestion_verbose(`, as they are more readabale, if more verbose. Verbose suggestions also tend to highlight off-by-one `Span` errors better. --- compiler/rustc_parse/src/lexer/mod.rs | 2 +- .../src/lexer/unescape_error_reporting.rs | 10 ++--- .../rustc_parse/src/parser/diagnostics.rs | 16 ++++---- compiler/rustc_parse/src/parser/expr.rs | 13 ++++-- compiler/rustc_parse/src/parser/item.rs | 16 ++++---- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/path.rs | 4 +- .../in-trait/bad-signatures.stderr | 11 +++-- tests/ui/async-await/no-async-const.stderr | 10 +++-- tests/ui/async-await/no-unsafe-async.stderr | 20 ++++++---- .../attribute/attr-with-a-semicolon.stderr | 8 +--- tests/ui/parser/duplicate-visibility.stderr | 10 +++-- tests/ui/parser/eq-less-to-less-eq.stderr | 10 +++-- tests/ui/parser/inverted-parameters.stderr | 33 +++++++++------ tests/ui/parser/issues/issue-113342.stderr | 11 +++-- tests/ui/parser/issues/issue-19398.stderr | 10 +++-- .../ui/parser/issues/issue-76437-async.stderr | 11 +++-- .../issue-76437-const-async-unsafe.stderr | 11 +++-- .../issues/issue-76437-const-async.stderr | 11 +++-- .../ui/parser/issues/issue-76437-const.stderr | 11 +++-- .../issue-76437-pub-crate-unsafe.stderr | 11 +++-- .../parser/issues/issue-76437-unsafe.stderr | 11 +++-- .../const-async-const.stderr | 10 +++-- .../issue-87217-keyword-order/recovery.stderr | 20 ++++++---- .../several-kw-jump.stderr | 10 +++-- .../wrong-async.stderr | 10 +++-- .../wrong-const.stderr | 10 +++-- .../wrong-unsafe-abi.stderr | 10 +++-- .../wrong-unsafe.stderr | 10 +++-- .../issues/issue-87694-duplicated-pub.stderr | 10 +++-- .../issues/issue-87694-misplaced-pub.stderr | 11 +++-- tests/ui/parser/issues/issue-89396.stderr | 21 ++++++---- .../issues/recover-ge-as-fat-arrow.stderr | 11 +++-- .../kw-in-item-pos-recovery-151238.stderr | 11 +++-- .../macro/misspelled-macro-rules.stderr | 10 +++-- .../ui/parser/range-exclusive-dotdotlt.stderr | 40 +++++++++++++------ .../ui/parser/raw/raw-byte-string-eof.stderr | 8 ++-- tests/ui/parser/raw/raw-str-unbalanced.stderr | 24 +++++++++-- tests/ui/parser/raw/raw-string-2.stderr | 6 ++- tests/ui/parser/raw/raw-string.stderr | 8 ++-- .../removed-syntax-field-let-2.stderr | 20 ++++++---- .../removed-syntax-field-let.stderr | 10 +++-- .../suggest-add-self-issue-131084.stderr | 11 +++-- .../ice-120503-async-const-method.stderr | 10 +++-- 44 files changed, 339 insertions(+), 204 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 1a30d5f1e79a0..4f7c76e7df816 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -987,7 +987,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let lo = start + BytePos(possible_offset); let hi = lo + BytePos(found_terminators); let span = self.mk_sp(lo, hi); - err.span_suggestion( + err.span_suggestion_verbose( span, "consider terminating the string here", "#".repeat(n_hashes as usize), diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 54c8f3c09ec48..9176192c95640 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -162,7 +162,7 @@ pub(crate) fn emit_unescape_error( ); } else { if mode == Mode::Str || mode == Mode::Char { - diag.span_suggestion( + diag.span_suggestion_verbose( full_lit_span, "if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal", format!("r\"{lit}\""), @@ -204,7 +204,7 @@ pub(crate) fn emit_unescape_error( // Note: the \\xHH suggestions are not given for raw byte string // literals, because they are araw and so cannot use any escapes. if (c as u32) <= 0xFF && mode != Mode::RawByteStr { - err.span_suggestion( + err.span_suggestion_verbose( span, format!( "if you meant to use the unicode code point for {c:?}, use a \\xHH escape" @@ -217,7 +217,7 @@ pub(crate) fn emit_unescape_error( } else if mode != Mode::RawByteStr { let mut utf8 = String::new(); utf8.push(c); - err.span_suggestion( + err.span_suggestion_verbose( span, format!("if you meant to use the UTF-8 encoding of {c:?}, use \\xHH escapes"), utf8.as_bytes() @@ -313,7 +313,7 @@ fn foreign_escape_suggestion( err_span: Span, ) { if escaped_char == "?" { - diag.span_suggestion( + diag.span_suggestion_verbose( err_span, "if you meant to write a literal question mark, don't escape the character", "?", @@ -336,7 +336,7 @@ fn foreign_escape_suggestion( _ => return, }; - diag.span_suggestion( + diag.span_suggestion_verbose( escape_span, format!("if you meant to write {name}, use a hex escape"), format!("x{hex}"), diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index e5be778458135..9ee4576e3483c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -597,7 +597,7 @@ impl<'a> Parser<'a> { .iter() .any(|tok| matches!(tok, TokenType::FatArrow | TokenType::CloseBrace)) { - err.span_suggestion( + err.span_suggestion_verbose( self.token.span, "you might have meant to write a \"greater than or equal to\" comparison", ">=", @@ -942,7 +942,7 @@ impl<'a> Parser<'a> { count += 1; } err.span(span); - err.span_suggestion( + err.span_suggestion_verbose( span, format!("remove the extra `#`{}", pluralize!(count)), "", @@ -2062,7 +2062,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.span_suggestion(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); + err.span_suggestion_verbose(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); let guar = err.emit(); Ok(self.mk_expr_err(lo.to(hi), guar)) } else { @@ -2243,7 +2243,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident_common(true).unwrap(); let span = pat.span.with_hi(ident.span.hi()); - err.span_suggestion( + err.span_suggestion_verbose( span, "declare the type after the parameter binding", ": ", @@ -2641,7 +2641,7 @@ impl<'a> Parser<'a> { Ok((expr, _)) => { // Find a mistake like `MyTrait`. if snapshot.token == token::EqEq { - err.span_suggestion( + err.span_suggestion_verbose( snapshot.token.span, "if you meant to use an associated type binding, replace `==` with `=`", "=", @@ -2655,7 +2655,7 @@ impl<'a> Parser<'a> { && matches!(expr.kind, ExprKind::Path(..)) { // Find a mistake like "foo::var:A". - err.span_suggestion( + err.span_suggestion_verbose( snapshot.token.span, "write a path separator here", "::", @@ -2938,7 +2938,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); if let CommaRecoveryMode::EitherTupleOrPipe = rt { - err.span_suggestion( + err.span_suggestion_verbose( comma_span, "...or a vertical bar to match on alternatives", " |", @@ -2975,7 +2975,7 @@ impl<'a> Parser<'a> { && (self.expected_token_types.contains(TokenType::Gt) || matches!(self.token.kind, token::Literal(..))) { - err.span_suggestion( + err.span_suggestion_verbose( maybe_lt.span, "remove the `<` to write an exclusive range", "", diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 92e8f5eefadb2..a3dea980e67c2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1699,7 +1699,12 @@ impl<'a> Parser<'a> { // directly adjacent (i.e. '=<') if maybe_eq_tok == TokenKind::Eq && maybe_eq_tok.span.hi() == lt_span.lo() { let eq_lt = maybe_eq_tok.span.to(lt_span); - err.span_suggestion(eq_lt, "did you mean", "<=", Applicability::Unspecified); + err.span_suggestion_verbose( + eq_lt, + "did you mean", + "<=", + Applicability::Unspecified, + ); } err })?; @@ -2755,7 +2760,7 @@ impl<'a> Parser<'a> { && let maybe_let = self.look_ahead(1, |t| t.clone()) && maybe_let.is_keyword(kw::Let) { - err.span_suggestion( + err.span_suggestion_verbose( self.prev_token.span, "consider removing this semicolon to parse the `let` as part of the same chain", "", @@ -2767,7 +2772,7 @@ impl<'a> Parser<'a> { } else { // Look for usages of '=>' where '>=' might be intended if maybe_fatarrow == token::FatArrow { - err.span_suggestion( + err.span_suggestion_verbose( maybe_fatarrow.span, "you might have meant to write a \"greater than or equal to\" comparison", ">=", @@ -3381,7 +3386,7 @@ impl<'a> Parser<'a> { if let Err(mut err) = this.expect(exp!(FatArrow)) { // We might have a `=>` -> `=` or `->` typo (issue #89396). if is_almost_fat_arrow { - err.span_suggestion( + err.span_suggestion_verbose( this.token.span, "use a fat arrow to start a match arm", "=>", diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 192cd7668f518..6de9240c64a91 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -601,7 +601,7 @@ impl<'a> Parser<'a> { && let [segment] = path.segments.as_slice() && edit_distance("macro_rules", &segment.ident.to_string(), 2).is_some() { - err.span_suggestion( + err.span_suggestion_verbose( path.span, "perhaps you meant to define a macro", "macro_rules", @@ -627,7 +627,7 @@ impl<'a> Parser<'a> { if end.is_doc_comment() { err.span_label(end.span, "this doc comment doesn't document anything"); } else if self.token == TokenKind::Semi { - err.span_suggestion_verbose( + err.span_suggestion( self.token.span, "consider removing this semicolon", "", @@ -2474,7 +2474,7 @@ impl<'a> Parser<'a> { .map_err(|err| err.cancel()) && self.token == TokenKind::Colon { - err.span_suggestion( + err.span_suggestion_verbose( removal_span, "remove this `let` keyword", String::new(), @@ -2632,7 +2632,7 @@ impl<'a> Parser<'a> { vec![(open, "{".to_string()), (close, '}'.to_string())], Applicability::MaybeIncorrect, ); - err.span_suggestion( + err.span_suggestion_verbose( span.with_neighbor(self.token.span).shrink_to_hi(), "add a semicolon", ';', @@ -3248,7 +3248,7 @@ impl<'a> Parser<'a> { .span_to_snippet(original_sp) .expect("Span extracted directly from keyword should always work"); - err.span_suggestion( + err.span_suggestion_verbose( self.token_uninterpolated_span(), format!("`{original_kw}` already used earlier, remove this one"), "", @@ -3263,7 +3263,7 @@ impl<'a> Parser<'a> { let misplaced_qual_sp = self.token_uninterpolated_span(); let misplaced_qual = self.span_to_snippet(misplaced_qual_sp).unwrap(); - err.span_suggestion( + err.span_suggestion_verbose( correct_pos_sp.to(misplaced_qual_sp), format!("`{misplaced_qual}` must come before `{current_qual}`"), format!("{misplaced_qual} {current_qual}"), @@ -3287,7 +3287,7 @@ impl<'a> Parser<'a> { // There was no explicit visibility if matches!(orig_vis.kind, VisibilityKind::Inherited) { - err.span_suggestion( + err.span_suggestion_verbose( sp_start.to(self.prev_token.span), format!("visibility `{vs}` must come before `{snippet}`"), format!("{vs} {snippet}"), @@ -3296,7 +3296,7 @@ impl<'a> Parser<'a> { } // There was an explicit visibility else { - err.span_suggestion( + err.span_suggestion_verbose( current_vis.span, "there is already a visibility modifier, remove one", "", diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 09ac1acb74f51..dff6afdc893a7 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1805,7 +1805,7 @@ impl<'a> Parser<'a> { format!("the {kind_desc} was parsed as having {op_desc} binary expression"), ); - err.span_suggestion( + err.span_suggestion_verbose( lhs_end_span, format!("you may have meant to write a `;` to terminate the {kind_desc} earlier"), ";", diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 2dfcbccfe60ec..8ed2734b7de9c 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -817,13 +817,13 @@ impl<'a> Parser<'a> { .dcx() .struct_span_err(after_eq.to(before_next), "missing type to the right of `=`"); if matches!(self.token.kind, token::Comma | token::Gt) { - err.span_suggestion( + err.span_suggestion_verbose( self.psess.source_map().next_point(eq_span).to(before_next), "to constrain the associated type, add a type after `=`", " TheType", Applicability::HasPlaceholders, ); - err.span_suggestion( + err.span_suggestion_verbose( prev_token_span.shrink_to_hi().to(before_next), format!("remove the `=` if `{ident}` is a type"), "", diff --git a/tests/ui/async-await/in-trait/bad-signatures.stderr b/tests/ui/async-await/in-trait/bad-signatures.stderr index 127a343a93016..1f2f0537af3d1 100644 --- a/tests/ui/async-await/in-trait/bad-signatures.stderr +++ b/tests/ui/async-await/in-trait/bad-signatures.stderr @@ -8,10 +8,13 @@ error: expected one of `:`, `@`, or `|`, found keyword `self` --> $DIR/bad-signatures.rs:5:23 | LL | async fn bar(&abc self); - | -----^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - async fn bar(&abc self); +LL + async fn bar(: ); + | error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/no-async-const.stderr b/tests/ui/async-await/no-async-const.stderr index d692ba8f47375..be02ba17dbe67 100644 --- a/tests/ui/async-await/no-async-const.stderr +++ b/tests/ui/async-await/no-async-const.stderr @@ -2,12 +2,14 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const --> $DIR/no-async-const.rs:4:11 | LL | pub async const fn x() {} - | ------^^^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: `const` must come before `async`: `const async` + | ^^^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `async` + | +LL - pub async const fn x() {} +LL + pub const async fn x() {} + | error: functions cannot be both `const` and `async` --> $DIR/no-async-const.rs:4:5 diff --git a/tests/ui/async-await/no-unsafe-async.stderr b/tests/ui/async-await/no-unsafe-async.stderr index 49b112f9313d4..8db98f3c75493 100644 --- a/tests/ui/async-await/no-unsafe-async.stderr +++ b/tests/ui/async-await/no-unsafe-async.stderr @@ -2,23 +2,27 @@ error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/no-unsafe-async.rs:7:12 | LL | unsafe async fn g() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `async` must come before `unsafe` + | +LL - unsafe async fn g() {} +LL + async unsafe fn g() {} + | error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/no-unsafe-async.rs:11:8 | LL | unsafe async fn f() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `async` must come before `unsafe` + | +LL - unsafe async fn f() {} +LL + async unsafe fn f() {} + | error: aborting due to 2 previous errors diff --git a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr index b77f30fdb5934..0431d3e524fe4 100644 --- a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr +++ b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr @@ -2,13 +2,7 @@ error: expected item after attributes --> $DIR/attr-with-a-semicolon.rs:1:1 | LL | #[derive(Debug, Clone)]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider removing this semicolon - | -LL - #[derive(Debug, Clone)]; -LL + #[derive(Debug, Clone)] - | + | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider removing this semicolon error: aborting due to 1 previous error diff --git a/tests/ui/parser/duplicate-visibility.stderr b/tests/ui/parser/duplicate-visibility.stderr index e00ebe6a8cf6d..a7d5a36c58bfd 100644 --- a/tests/ui/parser/duplicate-visibility.stderr +++ b/tests/ui/parser/duplicate-visibility.stderr @@ -4,10 +4,7 @@ error: expected one of `(`, `async`, `const`, `default`, `extern`, `final`, `fn` LL | extern "C" { | - while parsing this item list starting here LL | pub pub fn foo(); - | ^^^ - | | - | expected one of 10 possible tokens - | help: there is already a visibility modifier, remove one + | ^^^ expected one of 10 possible tokens ... LL | } | - the item list ends here @@ -17,6 +14,11 @@ note: explicit visibility first seen here | LL | pub pub fn foo(); | ^^^ +help: there is already a visibility modifier, remove one + | +LL - pub pub fn foo(); +LL + pub fn foo(); + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/eq-less-to-less-eq.stderr b/tests/ui/parser/eq-less-to-less-eq.stderr index 4717d8287ff7b..b365aa9769470 100644 --- a/tests/ui/parser/eq-less-to-less-eq.stderr +++ b/tests/ui/parser/eq-less-to-less-eq.stderr @@ -2,9 +2,13 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` --> $DIR/eq-less-to-less-eq.rs:4:15 | LL | if a =< b { - | -- ^ expected one of 7 possible tokens - | | - | help: did you mean: `<=` + | ^ expected one of 7 possible tokens + | +help: did you mean + | +LL - if a =< b { +LL + if a <= b { + | error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` --> $DIR/eq-less-to-less-eq.rs:12:15 diff --git a/tests/ui/parser/inverted-parameters.stderr b/tests/ui/parser/inverted-parameters.stderr index 93b95a756087d..8eea01b19ccba 100644 --- a/tests/ui/parser/inverted-parameters.stderr +++ b/tests/ui/parser/inverted-parameters.stderr @@ -2,19 +2,25 @@ error: expected one of `:`, `@`, or `|`, found `bar` --> $DIR/inverted-parameters.rs:6:24 | LL | fn foo(&self, &str bar) {} - | -----^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn foo(&self, &str bar) {} +LL + fn foo(&self, : ) {} + | error: expected one of `:`, `@`, or `|`, found `quux` --> $DIR/inverted-parameters.rs:12:10 | LL | fn baz(S quux, xyzzy: i32) {} - | --^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn baz(S quux, xyzzy: i32) {} +LL + fn baz(: , xyzzy: i32) {} + | error: expected one of `:`, `@`, or `|`, found `a` --> $DIR/inverted-parameters.rs:17:12 @@ -47,10 +53,13 @@ error: expected one of `:`, `@`, or `|`, found `S` --> $DIR/inverted-parameters.rs:28:23 | LL | fn missing_colon(quux S) {} - | -----^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn missing_colon(quux S) {} +LL + fn missing_colon(: ) {} + | error: aborting due to 6 previous errors diff --git a/tests/ui/parser/issues/issue-113342.stderr b/tests/ui/parser/issues/issue-113342.stderr index 6d9f22f6a7ce8..bc7aad3c03fbe 100644 --- a/tests/ui/parser/issues/issue-113342.stderr +++ b/tests/ui/parser/issues/issue-113342.stderr @@ -2,10 +2,13 @@ error: expected `fn`, found keyword `pub` --> $DIR/issue-113342.rs:7:12 | LL | extern "C" pub fn id(x: i32) -> i32 { x } - | -----------^^^ - | | | - | | expected `fn` - | help: visibility `pub` must come before `extern "C"`: `pub extern "C"` + | ^^^ expected `fn` + | +help: visibility `pub` must come before `extern "C"` + | +LL - extern "C" pub fn id(x: i32) -> i32 { x } +LL + pub extern "C" fn id(x: i32) -> i32 { x } + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-19398.stderr b/tests/ui/parser/issues/issue-19398.stderr index 2b97ec50c9172..3fd8bb40a0b8e 100644 --- a/tests/ui/parser/issues/issue-19398.stderr +++ b/tests/ui/parser/issues/issue-19398.stderr @@ -2,12 +2,14 @@ error: expected `fn`, found keyword `unsafe` --> $DIR/issue-19398.rs:2:19 | LL | extern "Rust" unsafe fn foo(); - | --------------^^^^^^ - | | | - | | expected `fn` - | help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"` + | ^^^^^^ expected `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `unsafe` must come before `extern "Rust"` + | +LL - extern "Rust" unsafe fn foo(); +LL + unsafe extern "Rust" fn foo(); + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-async.stderr b/tests/ui/parser/issues/issue-76437-async.stderr index 483599135f566..4a02c045c7cf2 100644 --- a/tests/ui/parser/issues/issue-76437-async.stderr +++ b/tests/ui/parser/issues/issue-76437-async.stderr @@ -2,10 +2,13 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub` --> $DIR/issue-76437-async.rs:4:11 | LL | async pub fn t() {} - | ------^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `async`: `pub async` + | ^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `async` + | +LL - async pub fn t() {} +LL + pub async fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr b/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr index a703fc4e8a452..b296add2beb0a 100644 --- a/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr +++ b/tests/ui/parser/issues/issue-76437-const-async-unsafe.stderr @@ -2,10 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `pub` --> $DIR/issue-76437-const-async-unsafe.rs:4:24 | LL | const async unsafe pub fn t() {} - | -------------------^^^ - | | | - | | expected one of `extern` or `fn` - | help: visibility `pub` must come before `const async unsafe`: `pub const async unsafe` + | ^^^ expected one of `extern` or `fn` + | +help: visibility `pub` must come before `const async unsafe` + | +LL - const async unsafe pub fn t() {} +LL + pub const async unsafe fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-const-async.stderr b/tests/ui/parser/issues/issue-76437-const-async.stderr index 81fa8a5f557e0..3d1fc4dc4fdd8 100644 --- a/tests/ui/parser/issues/issue-76437-const-async.stderr +++ b/tests/ui/parser/issues/issue-76437-const-async.stderr @@ -2,10 +2,13 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub` --> $DIR/issue-76437-const-async.rs:4:17 | LL | const async pub fn t() {} - | ------------^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `const async`: `pub const async` + | ^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `const async` + | +LL - const async pub fn t() {} +LL + pub const async fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-const.stderr b/tests/ui/parser/issues/issue-76437-const.stderr index 005a27b7c2498..2ebf2042ebd67 100644 --- a/tests/ui/parser/issues/issue-76437-const.stderr +++ b/tests/ui/parser/issues/issue-76437-const.stderr @@ -2,10 +2,13 @@ error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keywo --> $DIR/issue-76437-const.rs:4:11 | LL | const pub fn t() {} - | ------^^^ - | | | - | | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `const`: `pub const` + | ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `const` + | +LL - const pub fn t() {} +LL + pub const fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr b/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr index 4ea76179be3f6..1cae371ae57ea 100644 --- a/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr +++ b/tests/ui/parser/issues/issue-76437-pub-crate-unsafe.stderr @@ -2,10 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `pub` --> $DIR/issue-76437-pub-crate-unsafe.rs:4:12 | LL | unsafe pub(crate) fn t() {} - | -------^^^------- - | | | - | | expected one of `extern` or `fn` - | help: visibility `pub(crate)` must come before `unsafe`: `pub(crate) unsafe` + | ^^^ expected one of `extern` or `fn` + | +help: visibility `pub(crate)` must come before `unsafe` + | +LL - unsafe pub(crate) fn t() {} +LL + pub(crate) unsafe fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-76437-unsafe.stderr b/tests/ui/parser/issues/issue-76437-unsafe.stderr index 69f7927750bf0..fb3abb7e9a669 100644 --- a/tests/ui/parser/issues/issue-76437-unsafe.stderr +++ b/tests/ui/parser/issues/issue-76437-unsafe.stderr @@ -2,10 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `pub` --> $DIR/issue-76437-unsafe.rs:4:12 | LL | unsafe pub fn t() {} - | -------^^^ - | | | - | | expected one of `extern` or `fn` - | help: visibility `pub` must come before `unsafe`: `pub unsafe` + | ^^^ expected one of `extern` or `fn` + | +help: visibility `pub` must come before `unsafe` + | +LL - unsafe pub fn t() {} +LL + pub unsafe fn t() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr index ed2e4d8154929..692fbc0350953 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr @@ -2,16 +2,18 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const --> $DIR/const-async-const.rs:5:13 | LL | const async const fn test() {} - | ^^^^^ - | | - | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: `const` already used earlier, remove this one + | ^^^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` | note: `const` first seen here --> $DIR/const-async-const.rs:5:1 | LL | const async const fn test() {} | ^^^^^ +help: `const` already used earlier, remove this one + | +LL - const async const fn test() {} +LL + const async fn test() {} + | error: functions cannot be both `const` and `async` --> $DIR/const-async-const.rs:5:1 diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr index 3f504a9ebfc49..a1b3a29c2dd27 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/recovery.stderr @@ -2,27 +2,31 @@ error: expected one of `extern` or `fn`, found keyword `const` --> $DIR/recovery.rs:6:12 | LL | unsafe const fn from_u32(val: u32) {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `unsafe` + | +LL - unsafe const fn from_u32(val: u32) {} +LL + const unsafe fn from_u32(val: u32) {} + | error: expected one of `extern` or `fn`, found keyword `unsafe` --> $DIR/recovery.rs:14:12 | LL | unsafe unsafe fn from_u32(val: u32) {} - | ^^^^^^ - | | - | expected one of `extern` or `fn` - | help: `unsafe` already used earlier, remove this one + | ^^^^^^ expected one of `extern` or `fn` | note: `unsafe` first seen here --> $DIR/recovery.rs:14:5 | LL | unsafe unsafe fn from_u32(val: u32) {} | ^^^^^^ +help: `unsafe` already used earlier, remove this one + | +LL - unsafe unsafe fn from_u32(val: u32) {} +LL + unsafe fn from_u32(val: u32) {} + | error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr index 489e8eefb052e..ccab054540691 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.stderr @@ -2,12 +2,14 @@ error: expected one of `extern` or `fn`, found keyword `const` --> $DIR/several-kw-jump.rs:9:14 | LL | async unsafe const fn test() {} - | -------------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `async unsafe`: `const async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `async unsafe` + | +LL - async unsafe const fn test() {} +LL + const async unsafe fn test() {} + | error: functions cannot be both `const` and `async` --> $DIR/several-kw-jump.rs:9:1 diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr index 74989502e7f5d..5423f72fc786b 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-async.stderr @@ -2,12 +2,14 @@ error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/wrong-async.rs:9:8 | LL | unsafe async fn test() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `async` must come before `unsafe`: `async unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `async` must come before `unsafe` + | +LL - unsafe async fn test() {} +LL + async unsafe fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr index 5958f0c7d2ddd..9d68538ec804f 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-const.stderr @@ -2,12 +2,14 @@ error: expected one of `extern` or `fn`, found keyword `const` --> $DIR/wrong-const.rs:9:8 | LL | unsafe const fn test() {} - | -------^^^^^ - | | | - | | expected one of `extern` or `fn` - | help: `const` must come before `unsafe`: `const unsafe` + | ^^^^^ expected one of `extern` or `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `unsafe` + | +LL - unsafe const fn test() {} +LL + const unsafe fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr index 8ed037869c829..eee9b0b8b8270 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe-abi.stderr @@ -2,12 +2,14 @@ error: expected `fn`, found keyword `unsafe` --> $DIR/wrong-unsafe-abi.rs:9:12 | LL | extern "C" unsafe fn test() {} - | -----------^^^^^^ - | | | - | | expected `fn` - | help: `unsafe` must come before `extern "C"`: `unsafe extern "C"` + | ^^^^^^ expected `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `unsafe` must come before `extern "C"` + | +LL - extern "C" unsafe fn test() {} +LL + unsafe extern "C" fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr index 232da9acef309..e6ea40f15ae8a 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr +++ b/tests/ui/parser/issues/issue-87217-keyword-order/wrong-unsafe.stderr @@ -2,12 +2,14 @@ error: expected `fn`, found keyword `unsafe` --> $DIR/wrong-unsafe.rs:10:8 | LL | extern unsafe fn test() {} - | -------^^^^^^ - | | | - | | expected `fn` - | help: `unsafe` must come before `extern`: `unsafe extern` + | ^^^^^^ expected `fn` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `unsafe` must come before `extern` + | +LL - extern unsafe fn test() {} +LL + unsafe extern fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr b/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr index dd75f32f68ff2..50d58ffb2fb35 100644 --- a/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr +++ b/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr @@ -2,16 +2,18 @@ error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keywo --> $DIR/issue-87694-duplicated-pub.rs:1:11 | LL | pub const pub fn test() {} - | ^^^ - | | - | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` - | help: there is already a visibility modifier, remove one + | ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` | note: explicit visibility first seen here --> $DIR/issue-87694-duplicated-pub.rs:1:1 | LL | pub const pub fn test() {} | ^^^ +help: there is already a visibility modifier, remove one + | +LL - pub const pub fn test() {} +LL + pub const fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr b/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr index d35e09dceaf7f..fcdd07a91182c 100644 --- a/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr +++ b/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr @@ -2,10 +2,13 @@ error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keywo --> $DIR/issue-87694-misplaced-pub.rs:1:7 | LL | const pub fn test() {} - | ------^^^ - | | | - | | expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` - | help: visibility `pub` must come before `const`: `pub const` + | ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe` + | +help: visibility `pub` must come before `const` + | +LL - const pub fn test() {} +LL + pub const fn test() {} + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-89396.stderr b/tests/ui/parser/issues/issue-89396.stderr index 41ce07050746a..8773a7516ff88 100644 --- a/tests/ui/parser/issues/issue-89396.stderr +++ b/tests/ui/parser/issues/issue-89396.stderr @@ -2,19 +2,24 @@ error: expected one of `=>`, `if`, or `|`, found `=` --> $DIR/issue-89396.rs:9:17 | LL | Some(_) = true, - | ^ - | | - | expected one of `=>`, `if`, or `|` - | help: use a fat arrow to start a match arm: `=>` + | ^ expected one of `=>`, `if`, or `|` + | +help: use a fat arrow to start a match arm + | +LL | Some(_) => true, + | + error: expected one of `=>`, `@`, `if`, or `|`, found `->` --> $DIR/issue-89396.rs:12:14 | LL | None -> false, - | ^^ - | | - | expected one of `=>`, `@`, `if`, or `|` - | help: use a fat arrow to start a match arm: `=>` + | ^^ expected one of `=>`, `@`, `if`, or `|` + | +help: use a fat arrow to start a match arm + | +LL - None -> false, +LL + None => false, + | error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr b/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr index 997d080f1deed..2a8c78a776b9e 100644 --- a/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr +++ b/tests/ui/parser/issues/recover-ge-as-fat-arrow.stderr @@ -2,10 +2,13 @@ error: expected one of `...`, `..=`, `..`, `=>`, `if`, or `|`, found `>=` --> $DIR/recover-ge-as-fat-arrow.rs:4:11 | LL | 1 >= {} - | ^^ - | | - | expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` - | help: use a fat arrow to start a match arm: `=>` + | ^^ expected one of `...`, `..=`, `..`, `=>`, `if`, or `|` + | +help: use a fat arrow to start a match arm + | +LL - 1 >= {} +LL + 1 => {} + | error[E0308]: mismatched types --> $DIR/recover-ge-as-fat-arrow.rs:5:29 diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr index 81151edaf0c0c..3a7e4779aadfb 100644 --- a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr @@ -8,10 +8,13 @@ error: expected one of `:`, `@`, or `|`, found keyword `self` --> $DIR/kw-in-item-pos-recovery-151238.rs:7:28 | LL | trait MyTrait { fn bar(c self) } - | --^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^^^^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - trait MyTrait { fn bar(c self) } +LL + trait MyTrait { fn bar(: ) } + | error: expected one of `->`, `;`, `where`, or `{`, found `}` --> $DIR/kw-in-item-pos-recovery-151238.rs:7:34 diff --git a/tests/ui/parser/macro/misspelled-macro-rules.stderr b/tests/ui/parser/macro/misspelled-macro-rules.stderr index fc718d8556dfe..bf401caff318b 100644 --- a/tests/ui/parser/macro/misspelled-macro-rules.stderr +++ b/tests/ui/parser/macro/misspelled-macro-rules.stderr @@ -2,9 +2,13 @@ error: expected one of `(`, `[`, or `{`, found `thing` --> $DIR/misspelled-macro-rules.rs:7:14 | LL | marco_rules! thing { - | ----------- ^^^^^ expected one of `(`, `[`, or `{` - | | - | help: perhaps you meant to define a macro: `macro_rules` + | ^^^^^ expected one of `(`, `[`, or `{` + | +help: perhaps you meant to define a macro + | +LL - marco_rules! thing { +LL + macro_rules! thing { + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/range-exclusive-dotdotlt.stderr b/tests/ui/parser/range-exclusive-dotdotlt.stderr index af25e1df343de..9a38473b64403 100644 --- a/tests/ui/parser/range-exclusive-dotdotlt.stderr +++ b/tests/ui/parser/range-exclusive-dotdotlt.stderr @@ -2,17 +2,25 @@ error: expected type, found `10` --> $DIR/range-exclusive-dotdotlt.rs:2:17 | LL | let _ = 0..<10; - | -^^ expected type - | | - | help: remove the `<` to write an exclusive range + | ^^ expected type + | +help: remove the `<` to write an exclusive range + | +LL - let _ = 0..<10; +LL + let _ = 0..10; + | error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `;` --> $DIR/range-exclusive-dotdotlt.rs:8:20 | LL | let _ = 0.. $DIR/range-exclusive-dotdotlt.rs:14:18 @@ -24,17 +32,25 @@ error: expected type, found `1` --> $DIR/range-exclusive-dotdotlt.rs:19:26 | LL | let _ = [1, 2, 3][..<1]; - | -^ expected type - | | - | help: remove the `<` to write an exclusive range + | ^ expected type + | +help: remove the `<` to write an exclusive range + | +LL - let _ = [1, 2, 3][..<1]; +LL + let _ = [1, 2, 3][..1]; + | error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `]` --> $DIR/range-exclusive-dotdotlt.rs:25:29 | LL | let _ = [1, 2, 3][.. $DIR/range-exclusive-dotdotlt.rs:31:30 diff --git a/tests/ui/parser/raw/raw-byte-string-eof.stderr b/tests/ui/parser/raw/raw-byte-string-eof.stderr index 88fd53904c43f..96bc893a4d4cb 100644 --- a/tests/ui/parser/raw/raw-byte-string-eof.stderr +++ b/tests/ui/parser/raw/raw-byte-string-eof.stderr @@ -2,11 +2,13 @@ error[E0748]: unterminated raw string --> $DIR/raw-byte-string-eof.rs:2:5 | LL | br##"a"#; - | ^ - help: consider terminating the string here: `##` - | | - | unterminated raw string + | ^ unterminated raw string | = note: this raw string should be terminated with `"##` +help: consider terminating the string here + | +LL | br##"a"##; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/raw/raw-str-unbalanced.stderr b/tests/ui/parser/raw/raw-str-unbalanced.stderr index eac8c06c1df5c..d957e555883b6 100644 --- a/tests/ui/parser/raw/raw-str-unbalanced.stderr +++ b/tests/ui/parser/raw/raw-str-unbalanced.stderr @@ -2,18 +2,30 @@ error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:2:10 | LL | r#""## - | -----^ help: remove the extra `#` + | -----^ | | | this raw string started with 1 `#` + | +help: remove the extra `#` + | +LL - r#""## +LL + r#""# + | error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:7:9 | LL | / r#" LL | | "#### - | | -^^^ help: remove the extra `#`s + | | -^^^ | |________| | this raw string started with 1 `#` + | +help: remove the extra `#`s + | +LL - "#### +LL + "# + | error: expected `;`, found `#` --> $DIR/raw-str-unbalanced.rs:10:28 @@ -28,9 +40,15 @@ error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:16:28 | LL | const B: &'static str = r""## - | ---^^ help: remove the extra `#`s + | ---^^ | | | this raw string started with 0 `#`s + | +help: remove the extra `#`s + | +LL - const B: &'static str = r""## +LL + const B: &'static str = r"" + | error: aborting due to 4 previous errors diff --git a/tests/ui/parser/raw/raw-string-2.stderr b/tests/ui/parser/raw/raw-string-2.stderr index 90dd9775e62e4..f390155904f69 100644 --- a/tests/ui/parser/raw/raw-string-2.stderr +++ b/tests/ui/parser/raw/raw-string-2.stderr @@ -2,9 +2,13 @@ error[E0748]: unterminated raw string --> $DIR/raw-string-2.rs:2:13 | LL | let x = r###"here's a long string"# "# "##; - | ^ unterminated raw string -- help: consider terminating the string here: `###` + | ^ unterminated raw string | = note: this raw string should be terminated with `"###` +help: consider terminating the string here + | +LL | let x = r###"here's a long string"# "# "###; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/raw/raw-string.stderr b/tests/ui/parser/raw/raw-string.stderr index 6654ef7a75a42..07a664ef1aad3 100644 --- a/tests/ui/parser/raw/raw-string.stderr +++ b/tests/ui/parser/raw/raw-string.stderr @@ -2,11 +2,13 @@ error[E0748]: unterminated raw string --> $DIR/raw-string.rs:2:13 | LL | let x = r##"lol"#; - | ^ - help: consider terminating the string here: `##` - | | - | unterminated raw string + | ^ unterminated raw string | = note: this raw string should be terminated with `"##` +help: consider terminating the string here + | +LL | let x = r##"lol"##; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr b/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr index fda0919b9b647..7a3561c205300 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr @@ -2,25 +2,29 @@ error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let-2.rs:2:5 | LL | let x: i32, - | ^^^- - | | - | expected identifier, found keyword - | help: remove this `let` keyword + | ^^^ expected identifier, found keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information +help: remove this `let` keyword + | +LL - let x: i32, +LL + x: i32, + | error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let-2.rs:4:5 | LL | let y: i32, - | ^^^- - | | - | expected identifier, found keyword - | help: remove this `let` keyword + | ^^^ expected identifier, found keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information +help: remove this `let` keyword + | +LL - let y: i32, +LL + y: i32, + | error[E0063]: missing fields `x` and `y` in initializer of `Foo` --> $DIR/removed-syntax-field-let-2.rs:9:13 diff --git a/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr b/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr index 339d056e6360f..48e439c8c2c34 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr @@ -2,13 +2,15 @@ error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let.rs:2:5 | LL | let foo: (), - | ^^^- - | | - | expected identifier, found keyword - | help: remove this `let` keyword + | ^^^ expected identifier, found keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information +help: remove this `let` keyword + | +LL - let foo: (), +LL + foo: (), + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-add-self-issue-131084.stderr b/tests/ui/suggestions/suggest-add-self-issue-131084.stderr index 1af7eec726273..5a78b4daaefd5 100644 --- a/tests/ui/suggestions/suggest-add-self-issue-131084.stderr +++ b/tests/ui/suggestions/suggest-add-self-issue-131084.stderr @@ -41,10 +41,13 @@ error: expected one of `:`, `@`, or `|`, found `s` --> $DIR/suggest-add-self-issue-131084.rs:21:32 | LL | fn type_before_name(String s) { - | -------^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` + | ^ expected one of `:`, `@`, or `|` + | +help: declare the type after the parameter binding + | +LL - fn type_before_name(String s) { +LL + fn type_before_name(: ) { + | error[E0424]: expected value, found module `self` --> $DIR/suggest-add-self-issue-131084.rs:11:9 diff --git a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr index d2eea3a805d99..6140de3974b00 100644 --- a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr +++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr @@ -2,12 +2,14 @@ error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const --> $DIR/ice-120503-async-const-method.rs:6:11 | LL | async const fn bar(&self) { - | ------^^^^^ - | | | - | | expected one of `extern`, `fn`, `safe`, or `unsafe` - | help: `const` must come before `async`: `const async` + | ^^^^^ expected one of `extern`, `fn`, `safe`, or `unsafe` | = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` +help: `const` must come before `async` + | +LL - async const fn bar(&self) { +LL + const async fn bar(&self) { + | error[E0379]: functions in trait impls cannot be declared const --> $DIR/ice-120503-async-const-method.rs:6:11 From 1b7ae04e212b9a12b43fcf8c04c32e90d52dd581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 21 Jul 2026 16:11:09 +0000 Subject: [PATCH 48/77] Tweak code and diagnostic formatting and messages --- .../rustc_parse/src/parser/diagnostics.rs | 10 +++++- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 35 ++++++++++++------- .../ui/attributes/attr-bad-crate-attr.stderr | 2 +- .../parser/attribute/attr-before-eof.stderr | 2 +- .../attribute/attr-dangling-in-mod.stderr | 2 +- .../attribute/attr-with-a-semicolon.stderr | 8 ++++- .../attribute/attrs-after-extern-mod.stderr | 2 +- tests/ui/parser/doc-before-attr.stderr | 2 +- tests/ui/parser/eq-less-to-less-eq.stderr | 2 +- tests/ui/parser/issues/issue-20711-2.stderr | 2 +- tests/ui/parser/issues/issue-20711.stderr | 2 +- .../removed-syntax-field-let-2.stderr | 4 +-- .../removed-syntax-field-let.stderr | 2 +- 14 files changed, 50 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9ee4576e3483c..3064c0b22592d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2062,7 +2062,15 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.span_suggestion_verbose(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); + err.span_suggestion_verbose( + lo.shrink_to_lo(), + format!( + "{prefix}you can still access the deprecated `try!()` macro using the \ + \"raw identifier\" syntax" + ), + "r#", + Applicability::MachineApplicable, + ); let guar = err.emit(); Ok(self.mk_expr_err(lo.to(hi), guar)) } else { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index a3dea980e67c2..e09b7b5d1c513 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1701,7 +1701,7 @@ impl<'a> Parser<'a> { let eq_lt = maybe_eq_tok.span.to(lt_span); err.span_suggestion_verbose( eq_lt, - "did you mean", + "you might have meant to write a \"less than or equal to\" comparison", "<=", Applicability::Unspecified, ); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6de9240c64a91..1dc8823862507 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -626,13 +626,16 @@ impl<'a> Parser<'a> { let mut err = self.dcx().struct_span_err(end.span, msg); if end.is_doc_comment() { err.span_label(end.span, "this doc comment doesn't document anything"); - } else if self.token == TokenKind::Semi { - err.span_suggestion( - self.token.span, - "consider removing this semicolon", - "", - Applicability::MaybeIncorrect, - ); + } else { + err.span_label(end.span, "expected an item after this"); + if self.token == TokenKind::Semi { + err.span_suggestion_verbose( + self.token.span, + "remove the semicolon after the attribute", + "", + Applicability::MaybeIncorrect, + ); + } } if let [.., penultimate, _] = attrs { err.span_label(start.span.to(penultimate.span), "other attributes here"); @@ -2429,16 +2432,19 @@ impl<'a> Parser<'a> { &inherited_vis, Case::Insensitive, ) { - Ok(_) => { - self.dcx().struct_span_err( + Ok(_) => self + .dcx() + .struct_span_err( lo.to(self.prev_token.span), format!("functions are not allowed in {adt_ty} definitions"), ) .with_help( "unlike in C++, Java, and C#, functions are declared in `impl` blocks", ) - .with_help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information") - } + .with_help( + "see https://doc.rust-lang.org/book/ch05-03-method-syntax.html \ + for more information", + ), Err(err) => { err.cancel(); self.restore_snapshot(snapshot); @@ -2476,12 +2482,15 @@ impl<'a> Parser<'a> { { err.span_suggestion_verbose( removal_span, - "remove this `let` keyword", + "remove the `let` keyword", String::new(), Applicability::MachineApplicable, ); err.note("the `let` keyword is not allowed in `struct` fields"); - err.note("see for more information"); + err.note( + "see \ + for more information", + ); err.emit(); return Ok(ident); } else { diff --git a/tests/ui/attributes/attr-bad-crate-attr.stderr b/tests/ui/attributes/attr-bad-crate-attr.stderr index 22522896bd1a9..885afa445efbd 100644 --- a/tests/ui/attributes/attr-bad-crate-attr.stderr +++ b/tests/ui/attributes/attr-bad-crate-attr.stderr @@ -2,7 +2,7 @@ error: expected item after attributes --> $DIR/attr-bad-crate-attr.rs:7:1 | LL | #[attr = "val"] // Unterminated - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attr-before-eof.stderr b/tests/ui/parser/attribute/attr-before-eof.stderr index 18a9d77bf719c..849d7881b4ed3 100644 --- a/tests/ui/parser/attribute/attr-before-eof.stderr +++ b/tests/ui/parser/attribute/attr-before-eof.stderr @@ -2,7 +2,7 @@ error: expected item after attributes --> $DIR/attr-before-eof.rs:3:1 | LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr index 22cc092109d1d..6ab08317a6690 100644 --- a/tests/ui/parser/attribute/attr-dangling-in-mod.stderr +++ b/tests/ui/parser/attribute/attr-dangling-in-mod.stderr @@ -2,7 +2,7 @@ error: expected item after attributes --> $DIR/attr-dangling-in-mod.rs:4:1 | LL | #[foo = "bar"] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr index 0431d3e524fe4..3edc60a3cba5c 100644 --- a/tests/ui/parser/attribute/attr-with-a-semicolon.stderr +++ b/tests/ui/parser/attribute/attr-with-a-semicolon.stderr @@ -2,7 +2,13 @@ error: expected item after attributes --> $DIR/attr-with-a-semicolon.rs:1:1 | LL | #[derive(Debug, Clone)]; - | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider removing this semicolon + | ^^^^^^^^^^^^^^^^^^^^^^^ expected an item after this + | +help: remove the semicolon after the attribute + | +LL - #[derive(Debug, Clone)]; +LL + #[derive(Debug, Clone)] + | error: aborting due to 1 previous error diff --git a/tests/ui/parser/attribute/attrs-after-extern-mod.stderr b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr index f2bafa54f8dfe..639c575438bf7 100644 --- a/tests/ui/parser/attribute/attrs-after-extern-mod.stderr +++ b/tests/ui/parser/attribute/attrs-after-extern-mod.stderr @@ -4,7 +4,7 @@ error: expected item after attributes LL | extern "C" { | - while parsing this item list starting here LL | #[cfg(stage37)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ expected an item after this LL | } | - the item list ends here diff --git a/tests/ui/parser/doc-before-attr.stderr b/tests/ui/parser/doc-before-attr.stderr index 0298b9b60d2f3..3111df9187d69 100644 --- a/tests/ui/parser/doc-before-attr.stderr +++ b/tests/ui/parser/doc-before-attr.stderr @@ -4,7 +4,7 @@ error: expected item after attributes LL | /// hi | ------ other attributes here LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ expected an item after this error: aborting due to 1 previous error diff --git a/tests/ui/parser/eq-less-to-less-eq.stderr b/tests/ui/parser/eq-less-to-less-eq.stderr index b365aa9769470..efed3e2096f30 100644 --- a/tests/ui/parser/eq-less-to-less-eq.stderr +++ b/tests/ui/parser/eq-less-to-less-eq.stderr @@ -4,7 +4,7 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `>`, or `as`, found `{` LL | if a =< b { | ^ expected one of 7 possible tokens | -help: did you mean +help: you might have meant to write a "less than or equal to" comparison | LL - if a =< b { LL + if a <= b { diff --git a/tests/ui/parser/issues/issue-20711-2.stderr b/tests/ui/parser/issues/issue-20711-2.stderr index 9fb7298955b38..738675999144f 100644 --- a/tests/ui/parser/issues/issue-20711-2.stderr +++ b/tests/ui/parser/issues/issue-20711-2.stderr @@ -5,7 +5,7 @@ LL | impl Foo { | - while parsing this item list starting here ... LL | #[stable(feature = "rust1", since = "1.0.0")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an item after this LL | LL | } | - the item list ends here diff --git a/tests/ui/parser/issues/issue-20711.stderr b/tests/ui/parser/issues/issue-20711.stderr index 256fb0ade7212..e5911c033ac9d 100644 --- a/tests/ui/parser/issues/issue-20711.stderr +++ b/tests/ui/parser/issues/issue-20711.stderr @@ -4,7 +4,7 @@ error: expected item after attributes LL | impl Foo { | - while parsing this item list starting here LL | #[stable(feature = "rust1", since = "1.0.0")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an item after this LL | LL | } | - the item list ends here diff --git a/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr b/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr index 7a3561c205300..e9d6630bd629f 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-field-let-2.stderr @@ -6,7 +6,7 @@ LL | let x: i32, | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information -help: remove this `let` keyword +help: remove the `let` keyword | LL - let x: i32, LL + x: i32, @@ -20,7 +20,7 @@ LL | let y: i32, | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information -help: remove this `let` keyword +help: remove the `let` keyword | LL - let y: i32, LL + y: i32, diff --git a/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr b/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr index 48e439c8c2c34..e470031207631 100644 --- a/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr +++ b/tests/ui/parser/removed-syntax/removed-syntax-field-let.stderr @@ -6,7 +6,7 @@ LL | let foo: (), | = note: the `let` keyword is not allowed in `struct` fields = note: see for more information -help: remove this `let` keyword +help: remove the `let` keyword | LL - let foo: (), LL + foo: (), From fe44964da881a80118968d151b063a1dfa6c1141 Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Thu, 18 Jun 2026 18:28:53 +0000 Subject: [PATCH 49/77] rustc_llvm: Emit module summaries when using -Clto=fat Currently, module summaries are only emitted with thin lto. If we would link full/fat lto'd rust code against lto'd c++ code built with CFI (or WPD), those passes would fail during the link step because the participating rust modules are missing module summaries. Rust code does not know at compile-time if it would be participating in some special link which may require module summaries, so this PR ensures module summaries are unconditionally emitted for full/fat lto, just like with thin lto. The WriteBitcodeToFile function just invokes the normal BitcodeWriterPass under the hood, but doesn't provide a way to set the argument for emitting module summaries. So this patch just adds the pass directly and sets that argument. Finally, now that we're generating module summaries for `-Clto=fat` without using ThinLTO, we need to update `rustc-metadata` to keep around a temporary directory that contains the `.rmeta` for a little longer before we deserialize it. --- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 64 +++++++++++++------ compiler/rustc_metadata/src/fs.rs | 2 +- tests/run-make/fat-lto-module-summary/foo.rs | 1 + .../run-make/fat-lto-module-summary/rmake.rs | 10 +++ 4 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 tests/run-make/fat-lto-module-summary/foo.rs create mode 100644 tests/run-make/fat-lto-module-summary/rmake.rs diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index e4807f10805c9..3ad59c53a5bf3 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -603,6 +603,27 @@ struct LLVMRustSanitizerOptions { extern "C" typedef void (*registerEnzymeAndPassPipelineFn)( llvm::PassBuilder &PB, bool augment); +/// Forces the bitcode writer to emit full LTO summary instead of thin LTO +/// summary for embedded bitcode under Fat LTO. +/// +/// Note the bitcode writer will only emit the full LTO block ID if the +/// "ThinLTO" metadata is defined and explicitly set to zero. Otherwise, the +/// thin LTO block ID will be emitted. +static void forceFullLTOSummary(Module *M) { + // This function may be called twice, such as if you call it with `-C lto=fat + // --emit=llvm-bc`, so exit early if if we've already set up the module to + // emit full LTO summaries. + if (auto *Existing = M->getModuleFlag("ThinLTO")) { + auto *Const = mdconst::extract(Existing); + assert(Const->getZExtValue() == 0 && + "ThinLTO flag already set to non-zero"); + return; + } + + auto *Zero = ConstantInt::get(Type::getInt32Ty(M->getContext()), 0); + M->addModuleFlag(Module::Error, "ThinLTO", Zero); +} + extern "C" LLVMRustResult LLVMRustOptimize( LLVMModuleRef ModuleRef, LLVMTargetMachineRef TMRef, LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage, @@ -943,14 +964,17 @@ extern "C" LLVMRustResult LLVMRustOptimize( } // For `-Copt-level=0`, and the pre-link fat/thin LTO stages. if (ThinLTOBufferRef && *ThinLTOBufferRef == nullptr) { - // thin lto summaries prevent fat lto, so do not emit them if fat - // lto is requested. See PR #136840 for background information. + // thin lto summaries prevent fat lto, so emit a full summary instead if + // fat lto is requested. See PR #136840 for background information. if (OptStage != LLVMRustOptStage::PreLinkFatLTO) { MPM.addPass(ThinLTOBitcodeWriterPass( ThinLTODataOS, ThinLTOSummaryBufferRef ? &ThinLinkDataOS : nullptr)); } else { - MPM.addPass(BitcodeWriterPass(ThinLTODataOS)); + forceFullLTOSummary(TheModule); + MPM.addPass(BitcodeWriterPass(ThinLTODataOS, + /*ShouldPreserveUseListOrder=*/false, + /*EmitSummaryIndex=*/true)); } *ThinLTOBufferRef = ThinLTOBuffer.release(); if (ThinLTOSummaryBufferRef) { @@ -1469,26 +1493,30 @@ extern "C" LLVMRustBuffer *LLVMRustModuleSerialize(LLVMModuleRef M, { auto OS = raw_string_ostream(Ret->data); { - if (is_thin) { - PassBuilder PB; - LoopAnalysisManager LAM; - FunctionAnalysisManager FAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; - PB.registerModuleAnalyses(MAM); - PB.registerCGSCCAnalyses(CGAM); - PB.registerFunctionAnalyses(FAM); - PB.registerLoopAnalyses(LAM); - PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - ModulePassManager MPM; + PassBuilder PB; + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + ModulePassManager MPM; #if LLVM_VERSION_GE(23, 0) - MPM.addPass(AssignGUIDPass()); + MPM.addPass(AssignGUIDPass()); #endif + + if (is_thin) { MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr)); - MPM.run(*unwrap(M), MAM); } else { - WriteBitcodeToFile(*unwrap(M), OS); + forceFullLTOSummary(unwrap(M)); + MPM.addPass(BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, + /*EmitSummaryIndex=*/true)); } + MPM.run(*unwrap(M), MAM); } } return Ret.release(); diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs index 5759b4afada7e..044ec5345cdcd 100644 --- a/compiler/rustc_metadata/src/fs.rs +++ b/compiler/rustc_metadata/src/fs.rs @@ -96,7 +96,7 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { if tcx.sess.opts.json_artifact_notifications { tcx.dcx().emit_artifact_notification(out_filename.as_path(), "metadata"); } - (filename, None) + (filename, Some(metadata_tmpdir)) } else { (metadata_filename, Some(metadata_tmpdir)) }; diff --git a/tests/run-make/fat-lto-module-summary/foo.rs b/tests/run-make/fat-lto-module-summary/foo.rs new file mode 100644 index 0000000000000..b76b4321d62aa --- /dev/null +++ b/tests/run-make/fat-lto-module-summary/foo.rs @@ -0,0 +1 @@ +pub fn foo() {} diff --git a/tests/run-make/fat-lto-module-summary/rmake.rs b/tests/run-make/fat-lto-module-summary/rmake.rs new file mode 100644 index 0000000000000..f04416c68fd96 --- /dev/null +++ b/tests/run-make/fat-lto-module-summary/rmake.rs @@ -0,0 +1,10 @@ +use run_make_support::{llvm_bcanalyzer, rustc}; + +fn main() { + rustc().input("foo.rs").crate_type("lib").arg("-Clto=fat").arg("--emit=llvm-bc").run(); + + llvm_bcanalyzer() + .input("foo.bc") + .run() + .assert_stdout_contains("FULL_LTO_GLOBALVAL_SUMMARY_BLOCK"); +} From fe9408070ec51de32a609fbd1245b062a12509f4 Mon Sep 17 00:00:00 2001 From: Senthilnathan Date: Wed, 22 Jul 2026 19:04:22 +0530 Subject: [PATCH 50/77] tests: add UI test for `.swap()` suggestion --- tests/ui/suggestions/suggest-swap.rs | 13 +++++++++++++ tests/ui/suggestions/suggest-swap.stderr | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/ui/suggestions/suggest-swap.rs create mode 100644 tests/ui/suggestions/suggest-swap.stderr diff --git a/tests/ui/suggestions/suggest-swap.rs b/tests/ui/suggestions/suggest-swap.rs new file mode 100644 index 0000000000000..13d86a4b706f4 --- /dev/null +++ b/tests/ui/suggestions/suggest-swap.rs @@ -0,0 +1,13 @@ +use std::mem; + +fn main() { + let mut arr = [1, 2, 3]; + + let i = 0usize; + let j = 1usize; + + mem::swap( + &mut arr[i], + &mut arr[j], //~ ERROR cannot borrow `arr[_]` as mutable more than once at a time + ); +} diff --git a/tests/ui/suggestions/suggest-swap.stderr b/tests/ui/suggestions/suggest-swap.stderr new file mode 100644 index 0000000000000..4c321ca8939f4 --- /dev/null +++ b/tests/ui/suggestions/suggest-swap.stderr @@ -0,0 +1,22 @@ +error[E0499]: cannot borrow `arr[_]` as mutable more than once at a time + --> $DIR/suggest-swap.rs:11:9 + | +LL | mem::swap( + | --------- first borrow later used by call +LL | &mut arr[i], + | ----------- first mutable borrow occurs here +LL | &mut arr[j], + | ^^^^^^^^^^^ second mutable borrow occurs here + | +help: use `.swap()` to swap elements at the specified indices instead + | +LL - mem::swap( +LL - &mut arr[i], +LL - &mut arr[j], +LL - ); +LL + arr.swap(j, i); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. From 6860c6b379315cb765b126c3efec0c79d6bc21c4 Mon Sep 17 00:00:00 2001 From: Joao Roberto Date: Wed, 22 Jul 2026 13:07:05 -0300 Subject: [PATCH 51/77] Drop redundant canonical universe assumptions --- compiler/rustc_next_trait_solver/src/canonical/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 0b98f312481da..b2f6ac78040b6 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -160,13 +160,7 @@ where let prev_universe = delegate.universe(); let universes_created_in_query = response.max_universe.index(); for _ in 0..universes_created_in_query { - let new_universe = delegate.create_next_universe(); - if delegate.cx().assumptions_on_binders() { - delegate.insert_placeholder_assumptions( - new_universe, - Some(rustc_type_ir::region_constraint::Assumptions::empty()), - ); - } + delegate.create_next_universe(); } let var_values = response.value.var_values(); From b1342c92174f6c10795365e8b16633cfe7df59c5 Mon Sep 17 00:00:00 2001 From: Lars Schumann Date: Wed, 22 Jul 2026 22:14:58 +0000 Subject: [PATCH 52/77] constify vec![1, 2, 3] macro arm functions --- library/alloc/src/boxed.rs | 15 +- library/alloc/src/slice.rs | 3 +- library/alloctests/tests/lib.rs | 1 + library/alloctests/tests/vec.rs | 23 +++ .../min_const_fn/bad_const_fn_body_ice.rs | 7 - .../min_const_fn/bad_const_fn_body_ice.stderr | 21 --- tests/ui/statics/check-values-constraints.rs | 23 ++- .../statics/check-values-constraints.stderr | 148 ++---------------- 8 files changed, 57 insertions(+), 184 deletions(-) delete mode 100644 tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs delete mode 100644 tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 4ee41bc807243..58996703023ce 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -246,7 +246,8 @@ pub struct Box< #[rustc_no_mir_inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg(not(no_global_oom_handling))] -fn box_new_uninit(layout: Layout) -> *mut u8 { +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] +const fn box_new_uninit(layout: Layout) -> *mut u8 { match Global.allocate(layout) { Ok(ptr) => ptr.as_mut_ptr(), Err(_) => handle_alloc_error(layout), @@ -258,10 +259,11 @@ fn box_new_uninit(layout: Layout) -> *mut u8 { /// This is unsafe, but has to be marked as safe or else we couldn't use it in `vec!`. #[doc(hidden)] #[unstable(feature = "liballoc_internals", issue = "none")] +#[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline(always)] #[cfg(not(no_global_oom_handling))] #[rustc_diagnostic_item = "box_assume_init_into_vec_unsafe"] -pub fn box_assume_init_into_vec_unsafe( +pub const fn box_assume_init_into_vec_unsafe( b: Box>, ) -> crate::vec::Vec { unsafe { (b.assume_init() as Box<[T]>).into_vec() } @@ -307,10 +309,11 @@ impl Box { /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "new_uninit", since = "1.82.0")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[must_use] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub fn new_uninit() -> Box> { + pub const fn new_uninit() -> Box> { // This is the same as `Self::new_uninit_in(Global)`, but manually inlined (just like // `Box::new`). @@ -1197,8 +1200,9 @@ impl Box, A> { /// assert_eq!(*five, 5) /// ``` #[stable(feature = "new_uninit", since = "1.82.0")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline(always)] - pub unsafe fn assume_init(self) -> Box { + pub const unsafe fn assume_init(self) -> Box { // This is used in the `vec!` macro, so we optimize for minimal IR generation // even in debug builds. // SAFETY: `Box` and `Box>` have the same layout. @@ -1668,8 +1672,9 @@ impl Box { /// [memory layout]: self#memory-layout #[must_use = "losing the pointer will leak memory"] #[unstable(feature = "allocator_api", issue = "32838")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] - pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let mut b = mem::ManuallyDrop::new(b); // We carefully get the raw pointer out in a way that Miri's aliasing model understands what // is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 39e72e383eacb..da9b40c2c3ce0 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -476,8 +476,9 @@ impl [T] { /// ``` #[rustc_allow_incoherent_impl] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] - pub fn into_vec(self: Box) -> Vec { + pub const fn into_vec(self: Box) -> Vec { unsafe { let len = self.len(); let (b, alloc) = Box::into_raw_with_allocator(self); diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 96dcde71fc071..296d0708a5f0e 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -8,6 +8,7 @@ #![feature(binary_heap_pop_if)] #![feature(casefold)] #![feature(const_btree_len)] +#![feature(const_cmp)] #![feature(const_heap)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index fc58e4364fe66..4620a9f373d6c 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -2807,3 +2807,26 @@ fn const_make_global_empty_or_zst_regression() { assert_eq!(ZST_SLICE, &[(), (), ()]); } + +#[test] +fn const_heap_vec_macro() { + const X: &'static [u32] = { + let x: Vec = vec![]; + assert!(x == []); + x.const_make_global() + }; + + const Y: &'static [u32] = { + let y: Vec = vec![1, 2, 3]; + assert!(y == [1, 2, 3]); + y.const_make_global() + }; + + // This arm isn't const yet. + // const Z: &'static [u32] = { + // vec![4; 2].const_make_global() + // }; + + assert_eq!(X, []); + assert_eq!(Y, [1, 2, 3]); +} diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs deleted file mode 100644 index 74e0a36560b08..0000000000000 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs +++ /dev/null @@ -1,7 +0,0 @@ -const fn foo(a: i32) -> Vec { - vec![1, 2, 3] - //~^ ERROR cannot call non-const - //~| ERROR cannot call non-const -} - -fn main() {} diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr deleted file mode 100644 index a7e8fdf37ae29..0000000000000 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0015]: cannot call non-const associated function `Box::<[i32; 3]>::new_uninit` in constant functions - --> $DIR/bad_const_fn_body_ice.rs:2:5 - | -LL | vec![1, 2, 3] - | ^^^^^^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in constant functions - --> $DIR/bad_const_fn_body_ice.rs:2:5 - | -LL | vec![1, 2, 3] - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/statics/check-values-constraints.rs b/tests/ui/statics/check-values-constraints.rs index c62abd75a304b..6f1635b761b07 100644 --- a/tests/ui/statics/check-values-constraints.rs +++ b/tests/ui/statics/check-values-constraints.rs @@ -1,5 +1,6 @@ // Verifies all possible restrictions for statics values. +#![feature(const_heap)] #![allow(warnings)] use std::marker; @@ -79,8 +80,6 @@ static STATIC10: UnsafeStruct = UnsafeStruct; struct MyOwned; static STATIC11: Vec = vec![MyOwned]; -//~^ ERROR cannot call non-const function -//~| ERROR cannot call non-const static mut STATIC12: UnsafeStruct = UnsafeStruct; @@ -93,29 +92,25 @@ static mut STATIC14: SafeStruct = SafeStruct { }; static STATIC15: &'static [Vec] = &[ - vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const - vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const + vec![MyOwned], + vec![MyOwned], ]; static STATIC16: (&'static Vec, &'static Vec) = ( - &vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const - &vec![MyOwned], //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const + &vec![MyOwned], + &vec![MyOwned], ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Vec = vec![3]; -//~^ ERROR cannot call non-const function -//~| ERROR cannot call non-const +//~^ ERROR encountered `const_allocate` pointer in final value that was not made global + pub fn main() { let y = { - static x: Vec = vec![3]; //~ ERROR cannot call non-const function - //~| ERROR cannot call non-const + static x: Vec = vec![3]; + //~^ ERROR encountered `const_allocate` pointer in final value that was not made global x //~^ ERROR cannot move out of static }; diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index 94d2b8ce80641..a3d49400703be 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -1,5 +1,5 @@ error[E0493]: destructor of `SafeStruct` cannot be evaluated at compile-time - --> $DIR/check-values-constraints.rs:64:7 + --> $DIR/check-values-constraints.rs:65:7 | LL | ..SafeStruct { | _______^ @@ -11,28 +11,8 @@ LL | | } LL | }; | - value is dropped here -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:81:33 - | -LL | static STATIC11: Vec = vec![MyOwned]; - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:81:33 - | -LL | static STATIC11: Vec = vec![MyOwned]; - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - error[E0015]: cannot call non-const method `::to_string` in statics - --> $DIR/check-values-constraints.rs:92:38 + --> $DIR/check-values-constraints.rs:91:38 | LL | field2: SafeEnum::Variant4("str".to_string()), | ^^^^^^^^^^^ @@ -47,128 +27,24 @@ note: method `to_string` is not const because trait `ToString` is not const = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:96:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:96:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:98:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:98:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:103:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:103:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:105:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:105:6 - | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:111:31 +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/check-values-constraints.rs:106:1 | LL | static STATIC19: Vec = vec![3]; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:111:31 - | -LL | static STATIC19: Vec = vec![3]; - | ^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` + = note: use `const_make_global` to turn allocated pointers into immutable globals before returning -error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics - --> $DIR/check-values-constraints.rs:117:32 +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/check-values-constraints.rs:112:9 | LL | static x: Vec = vec![3]; - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ | - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics - --> $DIR/check-values-constraints.rs:117:32 - | -LL | static x: Vec = vec![3]; - | ^^^^^^^ - | -note: function `box_assume_init_into_vec_unsafe` is not const - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL - = note: calls in statics are limited to constant functions, tuple structs and tuple variants - = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` + = note: use `const_make_global` to turn allocated pointers into immutable globals before returning error[E0507]: cannot move out of static item `x` - --> $DIR/check-values-constraints.rs:119:9 + --> $DIR/check-values-constraints.rs:114:9 | LL | x | ^ move occurs because `x` has type `Vec`, which does not implement the `Copy` trait @@ -182,7 +58,7 @@ help: consider cloning the value if the performance cost is acceptable LL | x.clone() | ++++++++ -error: aborting due to 17 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0015, E0493, E0507. For more information about an error, try `rustc --explain E0015`. From f9d9939467a5185a72f0ee8da778a0b71fc966ae Mon Sep 17 00:00:00 2001 From: jprochazk Date: Wed, 22 Jul 2026 15:18:28 +0200 Subject: [PATCH 53/77] make `DocLinkResMap` an `FxIndexMap` also add regression test for rmeta reproducibility when unrelated `rlib` are in the search path Co-authored-by: mejrs <59372212+mejrs@users.noreply.github.com> --- compiler/rustc_hir/src/def.rs | 6 ++-- .../client.rs | 5 ++++ .../rmeta-unrelated-search-path-files/foo.rs | 1 + .../foo_bar.rs | 1 + .../rmake.rs | 30 +++++++++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/run-make/rmeta-unrelated-search-path-files/client.rs create mode 100644 tests/run-make/rmeta-unrelated-search-path-files/foo.rs create mode 100644 tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs create mode 100644 tests/run-make/rmeta-unrelated-search-path-files/rmake.rs diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 9d1cf7046f4b0..1481cb0726082 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use rustc_ast as ast; use rustc_ast::NodeId; -use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_span::Symbol; @@ -962,4 +962,6 @@ pub enum LifetimeRes { ElidedAnchor { start: NodeId, end: NodeId }, } -pub type DocLinkResMap = UnordMap<(Symbol, Namespace), Option>>; +// FxIndexMap is necessary because its data ends up in .rmeta files, +// so its iteration order must be consistent. See #159677 for context. +pub type DocLinkResMap = FxIndexMap<(Symbol, Namespace), Option>>; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/client.rs b/tests/run-make/rmeta-unrelated-search-path-files/client.rs new file mode 100644 index 0000000000000..a0fb04732fef1 --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/client.rs @@ -0,0 +1,5 @@ +//! [crate::Client] + +extern crate foo; + +pub struct Client; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/foo.rs b/tests/run-make/rmeta-unrelated-search-path-files/foo.rs new file mode 100644 index 0000000000000..4a835673a596b --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/foo.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs b/tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs new file mode 100644 index 0000000000000..1c6a3b4c6cce8 --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/foo_bar.rs @@ -0,0 +1 @@ +pub struct FooBar; diff --git a/tests/run-make/rmeta-unrelated-search-path-files/rmake.rs b/tests/run-make/rmeta-unrelated-search-path-files/rmake.rs new file mode 100644 index 0000000000000..3bd402c5c6b79 --- /dev/null +++ b/tests/run-make/rmeta-unrelated-search-path-files/rmake.rs @@ -0,0 +1,30 @@ +//@ needs-target-std +// +// Regression test for . +// +// Ensures two builds of `client.rs` produce identical metadata +// even if there is an unrelated crate on the search path. + +use run_make_support::{rfs, rustc}; + +fn main() { + rustc().input("foo.rs").crate_type("rlib").run(); + rustc() + .input("client.rs") + .crate_type("rlib") + .emit("metadata") + .library_search_path(".") + .output("client1.rmeta") + .run(); + + rustc().input("foo_bar.rs").crate_type("rlib").run(); + rustc() + .input("client.rs") + .crate_type("rlib") + .emit("metadata") + .library_search_path(".") + .output("client2.rmeta") + .run(); + + assert_eq!(rfs::read("client1.rmeta"), rfs::read("client2.rmeta")); +} From 5c012f598c320ebfde4a280d93216541466ab0b9 Mon Sep 17 00:00:00 2001 From: E Shattow Date: Thu, 28 May 2026 14:23:28 -0700 Subject: [PATCH 54/77] Promote riscv64-unknown-linux-musl to tier 2 with host tools Implements MCP 982 via issue 156191 --- .../targets/riscv64gc_unknown_linux_musl.rs | 2 +- src/bootstrap/src/core/build_steps/llvm.rs | 1 + src/bootstrap/src/core/download.rs | 1 + src/ci/docker/README.md | 16 +++++++ .../Dockerfile | 2 +- .../riscv64-unknown-linux-gnu.defconfig | 0 .../dist-riscv64-linux-musl/Dockerfile | 39 ++++++++++++++++ .../riscv64-unknown-linux-musl.defconfig | 16 +++++++ src/ci/github-actions/jobs.yml | 5 +- src/doc/rustc/src/platform-support.md | 2 +- .../riscv64gc-unknown-linux-gnu.md | 15 +++--- .../riscv64gc-unknown-linux-musl.md | 46 +++++++++++-------- 12 files changed, 116 insertions(+), 29 deletions(-) rename src/ci/docker/host-x86_64/{dist-riscv64-linux => dist-riscv64-linux-gnu}/Dockerfile (92%) rename src/ci/docker/host-x86_64/{dist-riscv64-linux => dist-riscv64-linux-gnu}/riscv64-unknown-linux-gnu.defconfig (100%) create mode 100644 src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile create mode 100644 src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs index 8ed4e09adbbfe..088d4821042d8 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_linux_musl.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("RISC-V Linux (kernel 4.20, musl 1.2.5)".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 572df47d3a62c..b13759cfdaa25 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -248,6 +248,7 @@ pub(crate) fn is_ci_llvm_available_for_target( ("powerpc64le-unknown-linux-gnu", false), ("powerpc64le-unknown-linux-musl", false), ("riscv64gc-unknown-linux-gnu", false), + ("riscv64gc-unknown-linux-musl", false), ("s390x-unknown-linux-gnu", false), ("x86_64-pc-windows-gnullvm", false), ("x86_64-unknown-freebsd", false), diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 76fd2cb0bc14b..4058f1482a951 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -481,6 +481,7 @@ pub(crate) fn is_download_ci_available(target_triple: &str, llvm_assertions: boo "powerpc64le-unknown-linux-gnu", "powerpc64le-unknown-linux-musl", "riscv64gc-unknown-linux-gnu", + "riscv64gc-unknown-linux-musl", "s390x-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-gnu", diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 6e5a38a3c515a..b113adc2008cd 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -462,6 +462,22 @@ For targets: `riscv64-unknown-linux-gnu` - C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM +### `riscv64-unknown-linux-musl.defconfig` + +For targets: `riscv64-unknown-linux-musl` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc +- Target options > Target Architecture = riscv +- Target options > Bitness = 64-bit +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 4.20.17 +- Binary utilities > Version of binutils = 2.40 +- C-library > musl version = 1.2.5 +- C compiler > gcc version = 8.5.0 +- C compiler > C++ = ENABLE -- to cross compile LLVM + ### `s390x-linux-gnu.defconfig` For targets: `s390x-unknown-linux-gnu` diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/Dockerfile similarity index 92% rename from src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile rename to src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/Dockerfile index 5186c99c4f430..57f3b68a96e3f 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/Dockerfile @@ -12,7 +12,7 @@ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp COPY scripts/crosstool-ng-build.sh /scripts/ -COPY host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig +COPY host-x86_64/dist-riscv64-linux-gnu/riscv64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig RUN /scripts/crosstool-ng-build.sh COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/riscv64-unknown-linux-gnu.defconfig similarity index 100% rename from src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig rename to src/ci/docker/host-x86_64/dist-riscv64-linux-gnu/riscv64-unknown-linux-gnu.defconfig diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile new file mode 100644 index 0000000000000..bb7537fc7d279 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/Dockerfile @@ -0,0 +1,39 @@ +FROM ubuntu:22.04 + +COPY scripts/cross-apt-packages.sh /scripts/ +RUN sh /scripts/cross-apt-packages.sh + +COPY scripts/crosstool-ng.sh /scripts/ +COPY scripts/crosstool-ng-sha256-20260705.diff /scripts/ +RUN sh /scripts/crosstool-ng.sh + +COPY scripts/rustbuild-setup.sh /scripts/ +RUN sh /scripts/rustbuild-setup.sh + +WORKDIR /tmp + +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV PATH=$PATH:/x-tools/riscv64-unknown-linux-musl/bin + +ENV CC_riscv64gc_unknown_linux_musl=riscv64-unknown-linux-musl-gcc \ + AR_riscv64gc_unknown_linux_musl=riscv64-unknown-linux-musl-ar \ + CXX_riscv64gc_unknown_linux_musl=riscv64-unknown-linux-musl-g++ + +ENV HOSTS=riscv64gc-unknown-linux-musl +ENV TARGETS=riscv64gc-unknown-linux-musl + +ENV RUST_CONFIGURE_ARGS="--enable-extended \ + --enable-full-tools \ + --enable-profiler \ + --enable-sanitizers \ + --disable-docs \ + --set target.riscv64gc-unknown-linux-musl.crt-static=false \ + --musl-root-riscv64gc=/x-tools/riscv64-unknown-linux-musl/riscv64-unknown-linux-musl/sysroot/usr" + +ENV SCRIPT="python3 ../x.py dist --target $TARGETS --host $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig new file mode 100644 index 0000000000000..435a2bea80d36 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux-musl/riscv64-unknown-linux-musl.defconfig @@ -0,0 +1,16 @@ +CT_CONFIG_VERSION="4" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_VERIFY_DOWNLOAD_DIGEST_SHA256=y +CT_ARCH_RISCV=y +CT_ARCH_USE_MMU=y +CT_ARCH_64=y +CT_ARCH_ARCH="rv64gc" +CT_KERNEL_LINUX=y +CT_LINUX_V_4_20=y +CT_LIBC_MUSL=y +CT_BINUTILS_V_2_40=y +CT_MUSL_V_1_2_5=y +CT_GCC_V_8=y +CT_CC_LANG_CXX=y diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index a236effaa9b40..c374888ac8909 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -270,7 +270,10 @@ auto: - name: dist-powerpc64le-linux-musl <<: *job-linux-4c - - name: dist-riscv64-linux + - name: dist-riscv64-linux-gnu + <<: *job-linux-4c + + - name: dist-riscv64-linux-musl <<: *job-linux-4c - name: dist-s390x-linux diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ce4d55c2d2b00..c527911bc96a2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -105,6 +105,7 @@ target | notes [`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10+, glibc 2.17) [`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19+, musl 1.2.5) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20+, glibc 2.29) +[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20+, musl 1.2.5) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2+, glibc 2.17) [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+) [`x86_64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | 64-bit x86 MinGW (Windows 10+), LLVM ABI @@ -196,7 +197,6 @@ target | std | notes [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39) -[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) [`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index d62a65b21904f..119c3053cda7e 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -2,7 +2,8 @@ **Tier: 2 (with Host Tools)** -RISC-V targets using the *RV64I* base instruction set with the *G* collection of extensions, as well as the *C* extension. +Linux GNU libc RISC-V target using the *RV64I* base instruction set with the +*G* collection of extensions, as well as the *C* extension. ## Target maintainers @@ -22,10 +23,10 @@ This target requires: ## Building the target -These targets are distributed through `rustup`, and otherwise require no +This target is distributed through `rustup`, and otherwise requires no special configuration. -If you need to build your own Rust for some reason though, the targets can be +If you need to build your own Rust for some reason though, the target can be enabled in `bootstrap.toml`. For example: ```toml @@ -37,10 +38,10 @@ target = ["riscv64gc-unknown-linux-gnu"] ## Building Rust programs -On a RISC-V host, the `riscv64gc-unknown-linux-gnu` target should be automatically -installed and used by default. +On a riscv64gc-unknown-linux-gnu host, the `riscv64gc-unknown-linux-gnu` +target should be automatically installed and used by default. -On a non-RISC-V host, add the target: +On all other hosts, add the target: ```bash rustup target add riscv64gc-unknown-linux-gnu @@ -55,7 +56,7 @@ cargo build --target riscv64gc-unknown-linux-gnu ## Testing -There are no special requirements for testing and running the targets. +There are no special requirements for testing and running the target. For testing cross builds on the host, please refer to the "Cross-compilation toolchains and C code" section below. diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md index 2e88b5aa813ff..4ac2a894117c1 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md @@ -1,8 +1,10 @@ # riscv64gc-unknown-linux-musl -**Tier: 2** +**Tier: 2 (with Host Tools)** + +Linux musl libc RISC-V target using the *RV64I* base instruction set with the +*G* collection of extensions, as well as the *C* extension. -Target for RISC-V Linux programs using musl libc. ## Target maintainers @@ -11,37 +13,45 @@ Target for RISC-V Linux programs using musl libc. ## Requirements -Building the target itself requires a RISC-V compiler that is supported by `cc-rs`. +This target requires: + +* Linux Kernel version 4.20 or later +* musl libc 1.2.5 or later + ## Building the target -The target can be built by enabling it for a `rustc` build. +This target is distributed through `rustup`, and otherwise requires no +special configuration. + +If you need to build your own Rust then the targets can be enabled in +`bootstrap.toml`. For example: ```toml [build] target = ["riscv64gc-unknown-linux-musl"] ``` -Make sure your C compiler is included in `$PATH`, then add it to the `bootstrap.toml`: - -```toml -[target.riscv64gc-unknown-linux-musl] -cc = "riscv64-linux-gnu-gcc" -cxx = "riscv64-linux-gnu-g++" -ar = "riscv64-linux-gnu-ar" -linker = "riscv64-linux-gnu-gcc" -``` ## Building Rust programs -This target are distributed through `rustup`, and otherwise require no -special configuration. -## Cross-compilation +On a riscv64gc-unknown-linux-musl host, the `riscv64gc-unknown-linux-musl` +target should be automatically installed and used by default. -This target can be cross-compiled from any host. +On all other hosts, add the target: + +```bash +rustup target add riscv64gc-unknown-linux-musl +``` + +Then cross compile crates with: + +```bash +cargo build --target riscv64gc-unknown-linux-musl +``` ## Testing -This target can be tested as normal with `x.py` on a RISC-V host or via QEMU +The target can be tested as normal with `x.py` on a RISC-V host or via QEMU emulation. From 3086aff340346d1ef047dd556298e66532eb4983 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:50:26 +0200 Subject: [PATCH 55/77] don't build riscv64gc-unknown-linux-musl twice --- .../docker/host-x86_64/dist-various-2/Dockerfile | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index f07fb91edaf0b..12705809e4290 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -24,8 +24,7 @@ RUN apt-get update && apt-get build-dep -y clang llvm && apt-get install -y --no # Needed for apt-key to work: dirmngr \ gpg-agent \ - g++-9-arm-linux-gnueabi \ - g++-11-riscv64-linux-gnu + g++-9-arm-linux-gnueabi ENV \ AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \ @@ -71,10 +70,6 @@ RUN env \ CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \ CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \ bash musl.sh armv7 && \ - env \ - CC=riscv64-linux-gnu-gcc-11 \ - CXX=riscv64-linux-gnu-g++-11 \ - bash musl.sh riscv64gc && \ rm -rf /build/* WORKDIR /tmp @@ -120,7 +115,6 @@ ENV TARGETS=$TARGETS,x86_64-unknown-none ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi -ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-musl ENV TARGETS_SANITIZERS=x86_64-unknown-linux-gnuasan ENV TARGETS_SANITIZERS=$TARGETS_SANITIZERS,x86_64-unknown-linux-gnumsan @@ -132,11 +126,7 @@ ENV TARGETS_SANITIZERS=$TARGETS_SANITIZERS,x86_64-unknown-linux-gnutsan # Luckily one of the folders is /usr/local/include so symlink /usr/include/x86_64-linux-gnu/asm there RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm -# musl-gcc can't find libgcc_s.so.1 since it doesn't use the standard search paths. -RUN ln -s /usr/riscv64-linux-gnu/lib/libgcc_s.so.1 /usr/lib/gcc-cross/riscv64-linux-gnu/11/ - ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \ - --musl-root-armv7=/musl-armv7 \ - --musl-root-riscv64gc=/musl-riscv64gc" + --musl-root-armv7=/musl-armv7" ENV SCRIPT="python3 ../x.py dist --host= --target $TARGETS && python3 ../x.py dist --host= --set build.sanitizers=true --target $TARGETS_SANITIZERS" From d5482401250fef44346e03ab35df9e1fac005016 Mon Sep 17 00:00:00 2001 From: Senthilnathan Date: Thu, 23 Jul 2026 11:03:10 +0530 Subject: [PATCH 56/77] fix: add comment on top of test file to follow style spec --- tests/ui/suggestions/suggest-swap.rs | 1 + tests/ui/suggestions/suggest-swap.stderr | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ui/suggestions/suggest-swap.rs b/tests/ui/suggestions/suggest-swap.rs index 13d86a4b706f4..ef6604a42b2c0 100644 --- a/tests/ui/suggestions/suggest-swap.rs +++ b/tests/ui/suggestions/suggest-swap.rs @@ -1,3 +1,4 @@ +//! Regression test for use std::mem; fn main() { diff --git a/tests/ui/suggestions/suggest-swap.stderr b/tests/ui/suggestions/suggest-swap.stderr index 4c321ca8939f4..85fbbfb7e743c 100644 --- a/tests/ui/suggestions/suggest-swap.stderr +++ b/tests/ui/suggestions/suggest-swap.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `arr[_]` as mutable more than once at a time - --> $DIR/suggest-swap.rs:11:9 + --> $DIR/suggest-swap.rs:12:9 | LL | mem::swap( | --------- first borrow later used by call From 2af4af2fb1abcdd12eb116c3f5c451e20b8b82f1 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:13:59 +0200 Subject: [PATCH 57/77] update download-ci-llvm-stamp --- src/bootstrap/download-ci-llvm-stamp | 2 +- .../rustc/src/platform-support/riscv64gc-unknown-linux-musl.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index b61c7b18bad01..ba6dcfc761c5a 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/157385 +Last change is for: https://github.com/rust-lang/rust/pull/158766 diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md index 4ac2a894117c1..12872b74b6820 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-musl.md @@ -35,7 +35,6 @@ target = ["riscv64gc-unknown-linux-musl"] ## Building Rust programs - On a riscv64gc-unknown-linux-musl host, the `riscv64gc-unknown-linux-musl` target should be automatically installed and used by default. From f46856816629ab21354fd766225e9dea9540c388 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 09:38:06 +0200 Subject: [PATCH 58/77] reflow --- .../rustc-dev-guide/src/debuginfo/debugger-internals.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md index 574bb3be6a0d2..3da43fe898dae 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-internals.md @@ -1,8 +1,8 @@ # Debugger internals It is the debugger's job to convert the debug info into an in-memory representation. -Both the -interpretation of the debug info and the in-memory representation are arbitrary; anything will do +Both the interpretation of the debug info and the in-memory representation are arbitrary; +anything will do, so long as meaningful information can be reconstructed while the program is running. The pipeline from raw debug info to usable types can be quite complicated. @@ -10,7 +10,7 @@ Once the information is in a workable format, the debugger front-end then must p interpret and display the data, a way for users to interact with it, and an API for extensibility. Debuggers are vast systems and cannot be covered completely here. -This section will provide a brief -overview of the subsystems directly relevant to the Rust debugging experience. +This section will provide a brief overview of the subsystems +directly relevant to the Rust debugging experience. Microsoft's debugging engine is closed source, so it will not be covered here. From 31f2f1518a59fdd67bdc763de02c137c05371458 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 09:38:59 +0200 Subject: [PATCH 59/77] sembr src/debuginfo/lldb-internals.md --- .../src/debuginfo/lldb-internals.md | 119 +++++++++++------- 1 file changed, 74 insertions(+), 45 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md index 8119662b3d791..eaa7a022762e5 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -1,7 +1,8 @@ # LLDB internals LLDB's debug info processing relies on a set of extensible interfaces largely defined in -[lldb/src/Plugins][lldb_plugins]. These are meant to allow third-party compiler developers to add +[lldb/src/Plugins][lldb_plugins]. +These are meant to allow third-party compiler developers to add language support that is loaded at run-time by LLDB, but at time of writing (Nov 2025) the public API has not been settled on, so plugins exist either in LLDB itself or in standalone forks of LLDB. @@ -16,27 +17,32 @@ Here are some existing implementations of LLDB's plugin API: * [CodeLLDB's former fork with support for Rust](https://archive.softwareheritage.org/browse/origin/directory/?branch=refs/heads/codelldb/16.x&origin_url=https://github.com/vadimcn/llvm-project&path=lldb/source/Plugins/TypeSystem/Rust×tamp=2023-09-11T04:55:10Z) * [A work in progress reimplementation of Rust support](https://github.com/Walnut356/llvm-project/tree/lldbrust/19.x) * [A Rust expression parser plugin](https://github.com/tromey/lldb/tree/a0fc10ce0dacb3038b7302fff9f6cb8cb34b37c6/source/Plugins/ExpressionParser/Rust). -This was written before the `TypeSystem` API was created. Due to the freeform nature of expression parsing, the +This was written before the `TypeSystem` API was created. +Due to the freeform nature of expression parsing, the underlyng lexing, parsing, function calling, etc. should still offer valuable insights. ## Rust support and TypeSystemClang -As mentioned in the debug info overview, LLDB has partial Rust support. To further clarify, Rust +As mentioned in the debug info overview, LLDB has partial Rust support. +To further clarify, Rust uses the plugin-pipeline that was built for C/C++ (though it contains some helpers for Rust enum -types), which relies directly on the `clang` compiler's representation of types. This imposes heavy -restrictions on how much we can change when LLDB's output doesn't match what we want. Some +types), which relies directly on the `clang` compiler's representation of types. +This imposes heavy +restrictions on how much we can change when LLDB's output doesn't match what we want. +Some workarounds can help, but at the end of the day Rust's needs are secondary compared to making sure C and C++ compilation and debugging work correctly. -LLDB is receptive to adding a `TypeSystemRust`, but it is a massive undertaking. This section serves +LLDB is receptive to adding a `TypeSystemRust`, but it is a massive undertaking. +This section serves to not only document how we currently interact with [`TypeSystemClang`][ts_clang], but also as light guidance on implementing a `TypeSystemRust` in the future. [ts_clang]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/TypeSystem/Clang It is worth noting that a `TypeSystem` directly interacting with the target language's compiler is -the intention, but it is not a requirement. One can create all the necessary supporting types within -their plugin implementation. +the intention, but it is not a requirement. +One can create all the necessary supporting types within their plugin implementation. > Note: LLDB's documentation, including comments in the source code, is pretty sparse. Trying to > understand how language support works by reading `TypeSystemClang`'s implementation is somewhat @@ -47,8 +53,9 @@ their plugin implementation. ## DWARF vs PDB -LLDB is unique in being able to handle both DWARF and PDB debug information. This does come with -some added complexity. To complicate matters further, PDB support is split between `dia`, which +LLDB is unique in being able to handle both DWARF and PDB debug information. +This does come with some added complexity. +To complicate matters further, PDB support is split between `dia`, which relies on the `msdia140.dll` library distributed with Visual Studio, and `native`, which is written from scratch using publicly available information about the PDB format. @@ -65,48 +72,59 @@ from scratch using publicly available information about the PDB format. ## Debug node parsing -The first step is to process the raw debug nodes into something usable. This primarily occurs in -the [`DWARFASTParser`][dwarf_ast] and [`PdbAstBuilder`][pdb_ast] classes. These classes are fed a +The first step is to process the raw debug nodes into something usable. +This primarily occurs in the [`DWARFASTParser`][dwarf_ast] and [`PdbAstBuilder`][pdb_ast] classes. +These classes are fed a deserialized form of the debug info generated from [`SymbolFileDWARF`][sf_dwarf] and -[`SymbolFileNativePDB`][sf_pdb] respectively. The `SymbolFile` implementers make almost no -transformations to the underlying debug info before passing it to the parsers. For both PDB and -DWARF, the debug info is read using LLVM's debug info handlers. +[`SymbolFileNativePDB`][sf_pdb] respectively. +The `SymbolFile` implementers make almost no +transformations to the underlying debug info before passing it to the parsers. +For both PDB and DWARF, the debug info is read using LLVM's debug info handlers. [dwarf_ast]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/SymbolFile/DWARF [pdb_ast]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/SymbolFile/NativePDB [sf_dwarf]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h [sf_pdb]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h -The parsers translate the nodes into more convenient formats for LLDB's purposes. For `clang`, these +The parsers translate the nodes into more convenient formats for LLDB's purposes. +For `clang`, these formats are `clang::QualType`, `clang::Decl`, and `clang::DeclContext`, which are the types `clang` -uses internally when compiling C and C++. Again, using the compiler's representation of types is not a +uses internally when compiling C and C++. +Again, using the compiler's representation of types is not a requirement, but the plugin system was built with it as a possibility. > Note: The above types will be referred to language-agnostically as `LangType`, `Decl`, and `DeclContext` when the specific implementation details of `TypeSystemClang` are not relevant. -`LangType` represents a type. This includes information such as the name of the type, the size and +`LangType` represents a type. +This includes information such as the name of the type, the size and alignment, its classification (e.g. struct, primitive, pointer), its qualifiers (e.g. `const`, `volatile`), template arguments, function argument and return types, etc. [Here][rust_type] is an example of what a `RustType` might look like. [rust_type]: https://github.com/Walnut356/llvm-project/blob/13bcfd502452606d69faeea76aec3a06db554af9/lldb/source/Plugins/TypeSystem/Rust/TypeSystemRust.h#L618 -`Decl` represents any kind of declaration. It could be a type, a variable, a static field of a +`Decl` represents any kind of declaration. +It could be a type, a variable, a static field of a struct, the value that a static or const is initialized with, etc. -`DeclContext` more or less represents a scope. `DeclContext`s typically contain `Decl`s and other -`DeclContexts`, though the relationship isn't that straight forward. For example, a function can be +`DeclContext` more or less represents a scope. +`DeclContext`s typically contain `Decl`s and other +`DeclContexts`, though the relationship isn't that straight forward. +For example, a function can be both a `Decl` (because function signatures are types), **and** a `DeclContext` (because functions contain variable declarations, nested functions declarations, etc.). -The translation process can be quite verbose, but is usually straightforward. Much of the work here +The translation process can be quite verbose, but is usually straightforward. +Much of the work here is dependant on the exact information needed to fill out `LangType`, `Decl`, and `DeclContext`. Once a node is translated, a pointer to it is type-erased (`void*`) and wrapped in `CompilerType`, -`CompilerDecl`, or `CompilerDeclContext`. These wrappers associate the them with the `TypeSystem` -that owns them. Methods on these objects delegates to the `TypeSystem`, which casts the `void*` back -to the appropriate `LangType*`/`Decl*`/`DeclContext*` and operates on the internals. In Rust terms, +`CompilerDecl`, or `CompilerDeclContext`. +These wrappers associate the them with the `TypeSystem` that owns them. +Methods on these objects delegates to the `TypeSystem`, which casts the `void*` back +to the appropriate `LangType*`/`Decl*`/`DeclContext*` and operates on the internals. +In Rust terms, the relationship looks something like this: ```Rust @@ -141,9 +159,11 @@ The [`TypeSystem` interface][ts_interface] has 3 major purposes: [ts_interface]: https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Symbol/TypeSystem.h#L69 -1. Act as the "sole authority" of a language's types. This allows the type system to be added to -LLDB's "pool" of type systems. When an executable is loaded, the target language is determined, and -the pool is queried to find a `TypeSystem` that claims it can handle the language. One can also use +1. Act as the "sole authority" of a language's types. + This allows the type system to be added to LLDB's "pool" of type systems. +When an executable is loaded, the target language is determined, and +the pool is queried to find a `TypeSystem` that claims it can handle the language. +One can also use the `TypeSystem` to retrieve the backing `SymbolFile`, search for types, and synthesize basic types that might not exist in the debug info (e.g. primitives, arrays-of-`T`, pointers-to-`T`). 2. Manage the lifetimes of the `LangType`, `Decl`, and `DeclContext` objects @@ -152,41 +172,49 @@ that might not exist in the debug info (e.g. primitives, arrays-of-`T`, pointers The first two functions are pretty straightforward so we will focus on the third. Many of the functions in the `TypeSystem` interface will look familiar if you have worked with the -visualizer scripts. These functions underpin `SBType` the `SBValue` functions with matching names. +visualizer scripts. +These functions underpin `SBType` the `SBValue` functions with matching names. For example, `TypeSystem::GetFormat` returns the default format for the type if no custom formatter has been applied to it. -Of particular note are `GetIndexOfChildWithName` and `GetNumChildren`. The `TypeSystem` versions of -these functions operate on a *type*, not a value like the `SBValue` versions. The values returned +Of particular note are `GetIndexOfChildWithName` and `GetNumChildren`. +The `TypeSystem` versions of +these functions operate on a *type*, not a value like the `SBValue` versions. +The values returned from the `TypeSystem` functions dictate what parts of the struct can be interacted with *at all* by -the rest of LLDB. If a field is ommitted, that field effectively no longer exists to LLDB. +the rest of LLDB. +If a field is ommitted, that field effectively no longer exists to LLDB. Additionally, since they do not work with objects, there is no underlying memory to inspect or -interpret. Essentially, this means these functions do not have the same purpose as their equivalent -`SyntheticProvider` functions. There is no way to determine how many elements a `Vec` has or what -address those elements live at. It is also not possible to determine the value of the discriminant -of a sum-type. +interpret. +Essentially, this means these functions do not have the same purpose as their equivalent +`SyntheticProvider` functions. +There is no way to determine how many elements a `Vec` has or what address those elements live at. +It is also not possible to determine the value of the discriminant of a sum-type. Ideally, the `TypeSystem` should expose types as they appear in the debug info with as few -alterations as possible. LLDB's synthetics and frontend can handle making the type pretty. If some +alterations as possible. +LLDB's synthetics and frontend can handle making the type pretty. +If some piece of information is useless, the Rust compiler should be altered to not output that debug info in the first place. ## Expression parsing -The `TypeSystem` is typically written to have a counterpart that can handle expression parsing. It -requires implementing a few extra functions in the `TypeSystem` interface. The bulk of the -expression parsing code should live in [lldb/source/Plugins/ExpressionParser][expr]. +The `TypeSystem` is typically written to have a counterpart that can handle expression parsing. +It requires implementing a few extra functions in the `TypeSystem` interface. +The bulk of the expression parsing code should live in [lldb/source/Plugins/ExpressionParser][expr]. [expr]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/ExpressionParser -There isn't too much of note about the parser. It requires implementing a simple interpreter that -can handle (possibly simplified) Rust syntax. They operate on `lldb::ValueObject`s, which are the -objects that underpin `SBValue`. +There isn't too much of note about the parser. +It requires implementing a simple interpreter that can handle (possibly simplified) Rust syntax. +They operate on `lldb::ValueObject`s, which are the objects that underpin `SBValue`. ## Language -The [`Language` plugins][lang_plugin] are the C++ equivalent to the Python visualizer scripts. They +The [`Language` plugins][lang_plugin] are the C++ equivalent to the Python visualizer scripts. +They operate on `SBValue` objects for the same purpose: creating synthetic children and pretty-printing. The [CPlusPlusLanguage's implementations][cpp_lang] for the LibCxx types are great resources to learn how visualizers should be written. @@ -200,7 +228,8 @@ their python equivalent. While debug node parsing, type systems, and expression parsing are all closely tied to eachother, the `Language` plugin is encapsulated more and thus can be written "standalone" for any language -that an existing type system supports. Due to the lower barrier of entry, a `RustLanguage` plugin +that an existing type system supports. +Due to the lower barrier of entry, a `RustLanguage` plugin may be a good stepping stone towards full language support in LLDB. ## Visualizers From 225b77c53dcd927cbd4b0d55732d09fc49e55b70 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 09:53:35 +0200 Subject: [PATCH 60/77] reflow --- .../src/debuginfo/lldb-internals.md | 70 +++++++++---------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md index eaa7a022762e5..98eb1da6e77eb 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/lldb-internals.md @@ -24,21 +24,21 @@ underlyng lexing, parsing, function calling, etc. should still offer valuable in ## Rust support and TypeSystemClang As mentioned in the debug info overview, LLDB has partial Rust support. -To further clarify, Rust -uses the plugin-pipeline that was built for C/C++ (though it contains some helpers for Rust enum -types), which relies directly on the `clang` compiler's representation of types. -This imposes heavy -restrictions on how much we can change when LLDB's output doesn't match what we want. -Some -workarounds can help, but at the end of the day Rust's needs are secondary compared to making sure +To further clarify, +Rust uses the plugin-pipeline that was built for C/C++ +(though it contains some helpers for Rust enum types), +which relies directly on the `clang` compiler's representation of types. +This imposes heavy restrictions on how much we can change +when LLDB's output doesn't match what we want. +Some workarounds can help, but at the end of the day, +Rust's needs are secondary compared to making sure C and C++ compilation and debugging work correctly. LLDB is receptive to adding a `TypeSystemRust`, but it is a massive undertaking. -This section serves -to not only document how we currently interact with [`TypeSystemClang`][ts_clang], but also as light -guidance on implementing a `TypeSystemRust` in the future. +This section serves to not only document how we currently interact with [`TypeSystemClang`], +but also as light guidance on implementing a `TypeSystemRust` in the future. -[ts_clang]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/TypeSystem/Clang +[`TypeSystemClang`]: https://github.com/llvm/llvm-project/tree/main/lldb/source/Plugins/TypeSystem/Clang It is worth noting that a `TypeSystem` directly interacting with the target language's compiler is the intention, but it is not a requirement. @@ -74,9 +74,8 @@ from scratch using publicly available information about the PDB format. The first step is to process the raw debug nodes into something usable. This primarily occurs in the [`DWARFASTParser`][dwarf_ast] and [`PdbAstBuilder`][pdb_ast] classes. -These classes are fed a -deserialized form of the debug info generated from [`SymbolFileDWARF`][sf_dwarf] and -[`SymbolFileNativePDB`][sf_pdb] respectively. +These classes are fed a deserialized form of the debug info +generated from [`SymbolFileDWARF`][sf_dwarf] and [`SymbolFileNativePDB`][sf_pdb] respectively. The `SymbolFile` implementers make almost no transformations to the underlying debug info before passing it to the parsers. For both PDB and DWARF, the debug info is read using LLVM's debug info handlers. @@ -87,9 +86,8 @@ For both PDB and DWARF, the debug info is read using LLVM's debug info handlers. [sf_pdb]: https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h The parsers translate the nodes into more convenient formats for LLDB's purposes. -For `clang`, these -formats are `clang::QualType`, `clang::Decl`, and `clang::DeclContext`, which are the types `clang` -uses internally when compiling C and C++. +For `clang`, these formats are `clang::QualType`, `clang::Decl`, and `clang::DeclContext`, +which are the types `clang` uses internally when compiling C and C++. Again, using the compiler's representation of types is not a requirement, but the plugin system was built with it as a possibility. @@ -111,13 +109,13 @@ struct, the value that a static or const is initialized with, etc. `DeclContext` more or less represents a scope. `DeclContext`s typically contain `Decl`s and other `DeclContexts`, though the relationship isn't that straight forward. -For example, a function can be -both a `Decl` (because function signatures are types), **and** a `DeclContext` (because functions -contain variable declarations, nested functions declarations, etc.). +For example, a function can be both a `Decl` (because function signatures are types), +**and** a `DeclContext` +(because functions contain variable declarations, nested functions declarations, etc.). The translation process can be quite verbose, but is usually straightforward. -Much of the work here -is dependant on the exact information needed to fill out `LangType`, `Decl`, and `DeclContext`. +Much of the work here is dependant on the exact information needed to fill out `LangType`, +`Decl`, and `DeclContext`. Once a node is translated, a pointer to it is type-erased (`void*`) and wrapped in `CompilerType`, `CompilerDecl`, or `CompilerDeclContext`. @@ -161,11 +159,11 @@ The [`TypeSystem` interface][ts_interface] has 3 major purposes: 1. Act as the "sole authority" of a language's types. This allows the type system to be added to LLDB's "pool" of type systems. -When an executable is loaded, the target language is determined, and -the pool is queried to find a `TypeSystem` that claims it can handle the language. -One can also use -the `TypeSystem` to retrieve the backing `SymbolFile`, search for types, and synthesize basic types -that might not exist in the debug info (e.g. primitives, arrays-of-`T`, pointers-to-`T`). + When an executable is loaded, the target language is determined, and + the pool is queried to find a `TypeSystem` that claims it can handle the language. + One can also use the `TypeSystem` to retrieve the backing `SymbolFile`, + search for types, and synthesize basic types + that might not exist in the debug info (e.g. primitives, arrays-of-`T`, pointers-to-`T`). 2. Manage the lifetimes of the `LangType`, `Decl`, and `DeclContext` objects 3. Customize the "defaults" of how those types appear and how they can be interacted with. @@ -178,11 +176,10 @@ For example, `TypeSystem::GetFormat` returns the default format for the type if has been applied to it. Of particular note are `GetIndexOfChildWithName` and `GetNumChildren`. -The `TypeSystem` versions of -these functions operate on a *type*, not a value like the `SBValue` versions. -The values returned -from the `TypeSystem` functions dictate what parts of the struct can be interacted with *at all* by -the rest of LLDB. +The `TypeSystem` versions of these functions operate on a *type*, +not a value like the `SBValue` versions. +The values returned from the `TypeSystem` functions +dictate what parts of the struct can be interacted with *at all* by the rest of LLDB. If a field is ommitted, that field effectively no longer exists to LLDB. Additionally, since they do not work with objects, there is no underlying memory to inspect or @@ -195,9 +192,8 @@ It is also not possible to determine the value of the discriminant of a sum-type Ideally, the `TypeSystem` should expose types as they appear in the debug info with as few alterations as possible. LLDB's synthetics and frontend can handle making the type pretty. -If some -piece of information is useless, the Rust compiler should be altered to not output that debug info -in the first place. +If some piece of information is useless, +the Rust compiler should be altered to not output that debug info in the first place. ## Expression parsing @@ -214,8 +210,8 @@ They operate on `lldb::ValueObject`s, which are the objects that underpin `SBVal ## Language The [`Language` plugins][lang_plugin] are the C++ equivalent to the Python visualizer scripts. -They -operate on `SBValue` objects for the same purpose: creating synthetic children and pretty-printing. +They operate on `SBValue` objects for the same purpose: +creating synthetic children and pretty-printing. The [CPlusPlusLanguage's implementations][cpp_lang] for the LibCxx types are great resources to learn how visualizers should be written. From 7b106868bf1dca0079156530fccd06a631b06683 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 09:54:35 +0200 Subject: [PATCH 61/77] sembr src/debuginfo/debugger-visualizers.md --- .../src/debuginfo/debugger-visualizers.md | 86 ++++++++++++------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md index e3b82b1d4a421..ce4835728df99 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -3,40 +3,47 @@ These are typically the last step before the debugger displays the information, but the results may be piped through a debug adapter such as an IDE's debugger API. -The term "Visualizer" is a bit of a misnomer. The real goal isn't just to prettify the output, but -to provide an interface for the user to interact with that is as useful as possible. In many cases +The term "Visualizer" is a bit of a misnomer. +The real goal isn't just to prettify the output, but +to provide an interface for the user to interact with that is as useful as possible. +In many cases this means reconstructing the original type as closely as possible to its Rust representation, but not always. The visualizer interface allows generating "synthetic children" - fields that don't exist in the -debug info, but can be derived from invariants about the language and the type itself. A simple +debug info, but can be derived from invariants about the language and the type itself. +A simple example is allowing one to interact with the elements of a `Vec` instead of just it's `*mut u8` heap pointer, length, and capacity. ## `rust-lldb`, `rust-gdb`, and `rust-windbg.cmd` -These support scripts are distributed with Rust toolchains. They locate the appropriate debugger and +These support scripts are distributed with Rust toolchains. +They locate the appropriate debugger and the toolchain's visualizer scripts, then launch the debugger with the appropriate arguments to load the visualizer scripts before a debugee is launched/attached to. ## `#![debugger_visualizer]` [This attribute][dbg_vis_attr] allows Rust library authors to include pretty printers for their -types within the library itself. These pretty printers are of the same format as typical -visualizers, but are embedded directly into the compiled binary. These scripts are loaded -automatically by the debugger, allowing a seamless experience for users. This attribute currently -works for GDB and natvis scripts. +types within the library itself. +These pretty printers are of the same format as typical +visualizers, but are embedded directly into the compiled binary. +These scripts are loaded automatically by the debugger, allowing a seamless experience for users. +This attribute currently works for GDB and natvis scripts. [dbg_vis_attr]: https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute -GDB python scripts are embedded in the `.debug_gdb_scripts` section of the binary. More information -can be found [here](https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html). Rustc accomplishes this in [`rustc_codegen_llvm/src/debuginfo/gdb.rs`][gdb_rs] +GDB python scripts are embedded in the `.debug_gdb_scripts` section of the binary. +More information +can be found [here](https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html). +Rustc accomplishes this in [`rustc_codegen_llvm/src/debuginfo/gdb.rs`][gdb_rs] [gdb_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs Natvis files can be embedded in the PDB debug info using the [`/NATVIS` linker option][linker_opt], -and have the [highest priority][priority] when a type is resolving which visualizer to use. The -files specified by the attribute are collected into +and have the [highest priority][priority] when a type is resolving which visualizer to use. +The files specified by the attribute are collected into [`CrateInfo::natvis_debugger_visualizers`][natvis] which are then added as linker arguments in [`rustc_codegen_ssa/src/back/linker.rs`][linker_rs] @@ -46,17 +53,22 @@ files specified by the attribute are collected into [linker_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_ssa/src/back/linker.rs#L1106 LLDB is not currently supported, but there are a few methods that could potentially allow support in -the future. Officially, the intended method is via a [formatter bytecode][bytecode]. This was +the future. +Officially, the intended method is via a [formatter bytecode][bytecode]. +This was created to offer a comparable experience to GDB's, but without the safety concerns associated with -embedding an entire python script. The opcodes are limited, but it works with `SBValue` and `SBType` -in roughly the same way as python visualizer scripts. Implementing this would require writing some -sort of DSL/mini compiler. +embedding an entire python script. +The opcodes are limited, but it works with `SBValue` and `SBType` +in roughly the same way as python visualizer scripts. +Implementing this would require writing some sort of DSL/mini compiler. [bytecode]: https://lldb.llvm.org/resources/formatterbytecode.html Alternatively, it might be possible to copy GDB's strategy entirely: create a bespoke section in the -binary and embed a python script in it. LLDB will not load it automatically, but the python API does -allow one to access the [raw sections of the debug info][SBSection]. With this, it may be possible +binary and embed a python script in it. +LLDB will not load it automatically, but the python API does +allow one to access the [raw sections of the debug info][SBSection]. +With this, it may be possible to extract the python script from our bespoke section and then load it in during the startup of Rust's visualizer scripts. @@ -65,8 +77,10 @@ Rust's visualizer scripts. ## Performance Before tackling the visualizers themselves, it's important to note that these are part of a -performance-sensitive system. Please excuse the break in formality, but: if I have to spend -significant time debugging, I'm annoyed. If I have to *wait on my debugger*, I'm pissed. +performance-sensitive system. +Please excuse the break in formality, but: if I have to spend +significant time debugging, I'm annoyed. +If I have to *wait on my debugger*, I'm pissed. Every millisecond spent in these visualizers is a millisecond longer for the user to see output. This can be especially painful for large stackframes that contain many/large container types. @@ -75,15 +89,19 @@ delays of tens of seconds (or even minutes) before being able to interact with a frame. There is a tendancy to balk at the idea of optimizing Python code, but it really can have a -substantial impact. Remember, there is no compiler to help keep the code fast. Even simple -transformations are not done for you. It can be difficult to find Python performance tips through +substantial impact. +Remember, there is no compiler to help keep the code fast. +Even simple transformations are not done for you. +It can be difficult to find Python performance tips through all the noise of people suggesting you don't bother optimizing Python, so here are some things to keep in mind that are relevant to these scripts: * Everything allocates, even `int` -* Use tuples when possible. `list` is effectively `Vec>`, whereas tuples are equivalent -to `Box<[Any]>`. They have one less layer of indirection, don't carry extra capacity and can't -grow/shrink which can be advantageous in many cases. An additional benefit is that Python caches and +* Use tuples when possible. + `list` is effectively `Vec>`, whereas tuples are equivalent to `Box<[Any]>`. +They have one less layer of indirection, don't carry extra capacity and can't +grow/shrink which can be advantageous in many cases. +An additional benefit is that Python caches and recycles the underlying allocations of all tuples up to size 20. * Regexes are slow and should be avoided when simple string manipulation will do * Strings are immutable, thus many string operations implictly copy the contents. @@ -91,21 +109,25 @@ recycles the underlying allocations of all tuples up to size 20. way to do it. * f-strings are generally the fastest way to do small, simple string transformations such as surrounding a string with parentheses. -* The act of calling a function is somewhat slow (even if the function is completely empty). If the -code section is very hot, consider inlining the function manually. +* The act of calling a function is somewhat slow (even if the function is completely empty). + If the code section is very hot, consider inlining the function manually. * Local variable access is significantly faster than global and built-in function access * Member/method access via the `.` operator is also slow, consider reassigning deeply nested values to local variables to avoid this cost (e.g. `h = a.b.c.d.e.f.g.h`). * Accessing inherited methods and fields is about 2x slower than base-class methods and fields. Avoid inheritance whenever possible. -* Use [`__slots__`](https://wiki.python.org/moin/UsingSlots) wherever possible. `__slots__` is a way +* Use [`__slots__`](https://wiki.python.org/moin/UsingSlots) wherever possible. + `__slots__` is a way to indicate to Python that your class's fields won't change and speeds up field access by a -noticable amount. This does require you to name your fields in advance and initialize them in +noticable amount. +This does require you to name your fields in advance and initialize them in `__init__`, but it's a small price to pay for the benefits. -* Match statements/if..elif..else are not optimized in any way. The conditions are checked in order, +* Match statements/if..elif..else are not optimized in any way. + The conditions are checked in order, 1 by 1. If possible, use an alternative such as dictionary dispatch or a table of values * Compute lazily when possible * List comprehensions are typically faster than loops, generator comprehensions are a bit slower -than list comprehensions, but use less memory. You can think of comprehensions as equivalent to -Rust's `iter.map()`. List comprehensions effectively call `collect::>` at the end, whereas +than list comprehensions, but use less memory. +You can think of comprehensions as equivalent to Rust's `iter.map()`. +List comprehensions effectively call `collect::>` at the end, whereas generator comprehensions do not. From 7000c2a858b3e75e178d9764b61fe24ceeb38ec7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 10:19:53 +0200 Subject: [PATCH 62/77] reflow --- .../src/debuginfo/debugger-visualizers.md | 66 +++++++++---------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md index ce4835728df99..10167bf69cedc 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/debugger-visualizers.md @@ -6,15 +6,14 @@ be piped through a debug adapter such as an IDE's debugger API. The term "Visualizer" is a bit of a misnomer. The real goal isn't just to prettify the output, but to provide an interface for the user to interact with that is as useful as possible. -In many cases -this means reconstructing the original type as closely as possible to its Rust representation, but -not always. +In many cases, +this means reconstructing the original type as closely as possible to its Rust representation, +but not always. The visualizer interface allows generating "synthetic children" - fields that don't exist in the debug info, but can be derived from invariants about the language and the type itself. -A simple -example is allowing one to interact with the elements of a `Vec` instead of just it's `*mut u8` -heap pointer, length, and capacity. +A simple example is allowing one to interact with the elements of a `Vec` +instead of just it's `*mut u8` heap pointer, length, and capacity. ## `rust-lldb`, `rust-gdb`, and `rust-windbg.cmd` @@ -34,11 +33,10 @@ This attribute currently works for GDB and natvis scripts. [dbg_vis_attr]: https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute -GDB python scripts are embedded in the `.debug_gdb_scripts` section of the binary. -More information -can be found [here](https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html). -Rustc accomplishes this in [`rustc_codegen_llvm/src/debuginfo/gdb.rs`][gdb_rs] +GDB python scripts are embedded in the `.debug_gdb_scripts` section of the binary ([more info]). +Rustc accomplishes this in [`rustc_codegen_llvm/src/debuginfo/gdb.rs`][gdb_rs]. +[more info]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/dotdebug_005fgdb_005fscripts-section.html [gdb_rs]: https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs Natvis files can be embedded in the PDB debug info using the [`/NATVIS` linker option][linker_opt], @@ -55,22 +53,20 @@ The files specified by the attribute are collected into LLDB is not currently supported, but there are a few methods that could potentially allow support in the future. Officially, the intended method is via a [formatter bytecode][bytecode]. -This was -created to offer a comparable experience to GDB's, but without the safety concerns associated with -embedding an entire python script. +This was created to offer a comparable experience to GDB's, +but without the safety concerns associated with embedding an entire Python script. The opcodes are limited, but it works with `SBValue` and `SBType` -in roughly the same way as python visualizer scripts. +in roughly the same way as Python visualizer scripts. Implementing this would require writing some sort of DSL/mini compiler. [bytecode]: https://lldb.llvm.org/resources/formatterbytecode.html Alternatively, it might be possible to copy GDB's strategy entirely: create a bespoke section in the binary and embed a python script in it. -LLDB will not load it automatically, but the python API does +LLDB will not load it automatically, but the Python API does allow one to access the [raw sections of the debug info][SBSection]. -With this, it may be possible -to extract the python script from our bespoke section and then load it in during the startup of -Rust's visualizer scripts. +With this, it may be possible to extract the Python script from our bespoke section +and then load it in during the startup of Rust's visualizer scripts. [SBSection]: https://lldb.llvm.org/python_api/lldb.SBSection.html#sbsection @@ -99,35 +95,35 @@ keep in mind that are relevant to these scripts: * Everything allocates, even `int` * Use tuples when possible. `list` is effectively `Vec>`, whereas tuples are equivalent to `Box<[Any]>`. -They have one less layer of indirection, don't carry extra capacity and can't -grow/shrink which can be advantageous in many cases. -An additional benefit is that Python caches and -recycles the underlying allocations of all tuples up to size 20. + They have one less layer of indirection, don't carry extra capacity and can't grow/shrink, + which can be advantageous in many cases. + An additional benefit is that Python caches and + recycles the underlying allocations of all tuples up to size 20. * Regexes are slow and should be avoided when simple string manipulation will do * Strings are immutable, thus many string operations implictly copy the contents. * When concatenating large lists of strings, `"".join(iterable_of_strings)` is typically the fastest -way to do it. + way to do it. * f-strings are generally the fastest way to do small, simple string transformations such as surrounding a string with parentheses. * The act of calling a function is somewhat slow (even if the function is completely empty). If the code section is very hot, consider inlining the function manually. * Local variable access is significantly faster than global and built-in function access * Member/method access via the `.` operator is also slow, consider reassigning deeply nested values -to local variables to avoid this cost (e.g. `h = a.b.c.d.e.f.g.h`). + to local variables to avoid this cost (e.g. `h = a.b.c.d.e.f.g.h`). * Accessing inherited methods and fields is about 2x slower than base-class methods and fields. -Avoid inheritance whenever possible. + Avoid inheritance whenever possible. * Use [`__slots__`](https://wiki.python.org/moin/UsingSlots) wherever possible. `__slots__` is a way -to indicate to Python that your class's fields won't change and speeds up field access by a -noticable amount. -This does require you to name your fields in advance and initialize them in -`__init__`, but it's a small price to pay for the benefits. + to indicate to Python that your class's fields won't change and speeds up field access by a + noticable amount. + This does require you to name your fields in advance and initialize them in + `__init__`, but it's a small price to pay for the benefits. * Match statements/if..elif..else are not optimized in any way. - The conditions are checked in order, -1 by 1. If possible, use an alternative such as dictionary dispatch or a table of values + The conditions are checked in order, 1 by 1. + If possible, use an alternative such as dictionary dispatch or a table of values * Compute lazily when possible * List comprehensions are typically faster than loops, generator comprehensions are a bit slower -than list comprehensions, but use less memory. -You can think of comprehensions as equivalent to Rust's `iter.map()`. -List comprehensions effectively call `collect::>` at the end, whereas -generator comprehensions do not. + than list comprehensions, but use less memory. + You can think of comprehensions as equivalent to Rust's `iter.map()`. + List comprehensions effectively call `collect::>` at the end, whereas + generator comprehensions do not. From b0f5d97555138dbfa11d7622c59e503272a2cf85 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 10:20:30 +0200 Subject: [PATCH 63/77] sembr src/debuginfo/gdb-internals.md --- src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md index 8959f5d719c4e..2b80521f4519e 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/gdb-internals.md @@ -1,4 +1,4 @@ # GDB internals -GDB's Rust support lives at `gdb/rust-lang.h` and `gdb/rust-lang.c`. The expression parsing support -can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` +GDB's Rust support lives at `gdb/rust-lang.h` and `gdb/rust-lang.c`. +The expression parsing support can be found in `gdb/rust-exp.h` and `gdb/rust-parse.c` From ca59dd78d7a5172e02c315c1d90f115656bd446d Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 10:21:15 +0200 Subject: [PATCH 64/77] sembr src/debuginfo/llvm-codegen.md --- src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md index 3b6bd454b29f2..4f5bdaa1e6795 100644 --- a/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md +++ b/src/doc/rustc-dev-guide/src/debuginfo/llvm-codegen.md @@ -1,7 +1,8 @@ # LLVM codegen When Rust calls an LLVM `DIBuilder` function, LLVM translates the given information to a -["debug record"][dbg_record] that is format-agnostic. These records can be inspected in the LLVM-IR. +["debug record"][dbg_record] that is format-agnostic. +These records can be inspected in the LLVM-IR. [dbg_record]: https://llvm.org/docs/SourceLevelDebugging.html#debug-records From 1bb944b293b3c35557e1a58c42a5b0727040c909 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 23 Jul 2026 08:28:05 +0000 Subject: [PATCH 65/77] Prepare for merging from rust-lang/rust This updates the rust-version file to 390279b302ca98ae270f434100ae3730531d1246. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index a48a44e5d15fb..25a5238f538ee 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -9e71b3bc704eea68d39bd0f6a46703c7d22f5d3b +390279b302ca98ae270f434100ae3730531d1246 From e948729d7220df1f384b714705b18a543805e9ad Mon Sep 17 00:00:00 2001 From: Yukang Date: Thu, 23 Jul 2026 17:49:19 +0800 Subject: [PATCH 66/77] the fixme is outdated as we eagerly normalize outside of the trait solver --- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9a1b1f8300957..1014ce1b5d31a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -142,8 +142,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// version (resolve_vars_if_possible), this version will /// also select obligations if it seems useful, in an effort /// to get more type information. - // FIXME(-Znext-solver): A lot of the calls to this method should - // probably be `resolve_vars_with_obligations` or `structurally_resolve_type` instead. #[instrument(skip(self), level = "debug", ret)] pub(crate) fn resolve_vars_with_obligations>>( &self, From 7490d8ef3ac20a37a761c199aa358ee693021f3d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 17 Jul 2026 19:19:31 +0200 Subject: [PATCH 67/77] add `difference` method to `range_set` --- .../rustc_data_structures/src/range_set.rs | 40 +++++ tests/assembly-llvm/cmse-clear-padding.rs | 157 ++++++++++++++++-- 2 files changed, 179 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_data_structures/src/range_set.rs b/compiler/rustc_data_structures/src/range_set.rs index 514946a0fb2de..bd18728e20da5 100644 --- a/compiler/rustc_data_structures/src/range_set.rs +++ b/compiler/rustc_data_structures/src/range_set.rs @@ -56,4 +56,44 @@ where v.insert(idx, (offset, size)); } } + + /// The ranges from `self` with any intersection with `other` removed. + pub fn difference(&self, other: &Self) -> Self { + let (a, b) = (self, other); + let mut out = Vec::new(); + + let mut j = 0; + for &(a_offset, a_size) in a.0.iter() { + let mut cursor = a_offset; + let a_end = a_offset + a_size; + + // Skip ranges of `b` that end before this range of `a` begins. + // both sequences are sorted they cannot overlap any later range of `a` either. + while let Some(&(b_offset, b_size)) = b.0.get(j) + && b_offset + b_size <= cursor + { + j += 1; + } + + // Carve out each range of `b` that overlaps this range of `a`. A range of `b` may extend + // past `a_end` and overlap the next range of `a`, so leave `j` pointing at it. + let mut k = j; + while let Some(&(b_offset, b_size)) = b.0.get(k) + && b_offset < a_end + { + if b_offset > cursor { + out.push((cursor, b_offset)); + } + cursor = Ord::max(cursor, b_offset + b_size); + k += 1; + } + + // Keep the remainder of the `a`'s range. + if cursor < a_end { + out.push((cursor, a_end)); + } + } + + Self(out) + } } diff --git a/tests/assembly-llvm/cmse-clear-padding.rs b/tests/assembly-llvm/cmse-clear-padding.rs index b092bf304dcca..7c2757c77dbad 100644 --- a/tests/assembly-llvm/cmse-clear-padding.rs +++ b/tests/assembly-llvm/cmse-clear-padding.rs @@ -123,6 +123,8 @@ struct WideU8 { a: u8, } +// `extern "C"` does not clear the padding. +// // CHECK-LABEL: c_ret_with_wide_u8: // CHECK: mov r7, sp // CHECK-NEXT: orr.w r0, r0, r1, lsl #16 @@ -131,6 +133,8 @@ extern "C" fn c_ret_with_wide_u8(a: u8, b: u8) -> [WideU8; 2] { [WideU8 { a }, WideU8 { a: b }] } +// Upper bits are cleared by uxtb. +// // CHECK-LABEL: cmse_ret_with_wide_u8: // CHECK: mov r7, sp // CHECK-NEXT: uxtb r1, r1 @@ -141,6 +145,36 @@ extern "cmse-nonsecure-entry" fn cmse_ret_with_wide_u8(a: u8, b: u8) -> [WideU8; [WideU8 { a }, WideU8 { a: b }] } +// Same idea, the padding is recognized even through the MaybeUninit. +// +// CHECK-LABEL: cmse_ret_with_wide_u8_uninit: +// CHECK: mov r7, sp +// CHECK-NEXT: uxtb r0, r0 +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 +// CHECK-NEXT: bic r0, r0, #-16711936 +#[no_mangle] +extern "cmse-nonsecure-entry" fn cmse_ret_with_wide_u8_uninit( + a: u16, + b: u16, +) -> [MaybeUninit; 2] { + unsafe { [mem::transmute(a), mem::transmute(b)] } +} + +// Same idea, the padding is recognized even through the MaybeUninit. +// +// CHECK-LABEL: cmse_ret_with_wide_u8_uninit_tuple: +// CHECK: mov r7, sp +// CHECK-NEXT: uxtb r0, r0 +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 +// CHECK-NEXT: bic r0, r0, #-16711936 +#[no_mangle] +extern "cmse-nonsecure-entry" fn cmse_ret_with_wide_u8_uninit_tuple( + a: u16, + b: u16, +) -> (MaybeUninit, MaybeUninit) { + unsafe { (mem::transmute(a), mem::transmute(b)) } +} + // CHECK-LABEL: c_call_with_inner_wide_u8: // CHECK: push {r7, lr} // CHECK-NEXT: .setfp r7, sp @@ -177,28 +211,115 @@ extern "C" fn cmse_call_with_inner_wide_u8( unsafe { f(x) } } -// CHECK-LABEL: cmse_ret_with_wide_u8_uninit: +/// No variant-dependent padding. +#[repr(C)] +enum VariantsSameSize { + A(u16), + B(u16), +} +impl Copy for VariantsSameSize {} + +// CHECK-LABEL: variants_same_size: // CHECK: mov r7, sp -// CHECK-NEXT: uxtb r0, r0 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] // CHECK-NEXT: orr.w r0, r0, r1, lsl #16 -// CHECK-NEXT: bic r0, r0, #-16711936 #[no_mangle] -extern "cmse-nonsecure-entry" fn cmse_ret_with_wide_u8_uninit( - a: u16, - b: u16, -) -> [MaybeUninit; 2] { - unsafe { [mem::transmute(a), mem::transmute(b)] } +extern "cmse-nonsecure-entry" fn variants_same_size(v: &VariantsSameSize) -> VariantsSameSize { + *v } -// CHECK-LABEL: cmse_ret_with_wide_u8_uninit_tuple: -// CHECK: mov r7, sp -// CHECK-NEXT: uxtb r0, r0 -// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 -// CHECK-NEXT: bic r0, r0, #-16711936 +/// One byte of variant-dependent padding. +#[repr(C)] +enum VariantsDifferentSize { + A(u8), + B(u16), +} +impl Copy for VariantsDifferentSize {} + #[no_mangle] -extern "cmse-nonsecure-entry" fn cmse_ret_with_wide_u8_uninit_tuple( - a: u16, - b: u16, -) -> (MaybeUninit, MaybeUninit) { - unsafe { (mem::transmute(a), mem::transmute(b)) } +extern "cmse-nonsecure-entry" fn variants_different_size( + v: &VariantsDifferentSize, +) -> VariantsDifferentSize { + *v +} + +enum Void {} +impl Copy for Void {} + +#[repr(C)] +enum UninhabitedVariant { + A(Void), + B(u16), +} +impl Copy for UninhabitedVariant {} + +#[no_mangle] +extern "cmse-nonsecure-entry" fn uninhabited_variant(v: &UninhabitedVariant) -> UninhabitedVariant { + *v +} + +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "cmse-nonsecure-entry" fn variants_same_size_array( + v: &[VariantsSameSize; 1], +) -> [VariantsSameSize; 1] { + *v +} + +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "cmse-nonsecure-entry" fn variants_different_size_array( + v: &[VariantsDifferentSize; 1], +) -> [VariantsDifferentSize; 1] { + *v +} + +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "cmse-nonsecure-entry" fn variants_same_size_tuple( + v: &(VariantsSameSize,), +) -> (VariantsSameSize,) { + *v +} + +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "cmse-nonsecure-entry" fn variants_different_size_tuple( + v: &(VariantsDifferentSize,), +) -> (VariantsDifferentSize,) { + *v +} + +/// Three variants of different sizes. +#[repr(C)] +enum ThreeVariants { + A(u8), + B(u16), + C(u32), +} + +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "C" fn cmse_call_three_variants( + f: unsafe extern "cmse-nonsecure-call" fn(ThreeVariants), + x: ThreeVariants, +) { + unsafe { f(x) } +} + +/// The tag is stored in the niche of the `bool`. +#[repr(C)] +struct BoolU32 { + flag: bool, + val: u32, +} + +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "C" fn cmse_call_niche( + f: unsafe extern "cmse-nonsecure-call" fn(Option), + x: Option, +) { + unsafe { f(x) } } From 0d2986aaa0d66b69259d40684f1deef0f3c3f1cc Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 17 Jul 2026 19:27:33 +0200 Subject: [PATCH 68/77] add LLVM baseline test --- tests/assembly-llvm/cmse-clear-padding.rs | 39 +++++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/tests/assembly-llvm/cmse-clear-padding.rs b/tests/assembly-llvm/cmse-clear-padding.rs index 7c2757c77dbad..95f3d6fe8de8c 100644 --- a/tests/assembly-llvm/cmse-clear-padding.rs +++ b/tests/assembly-llvm/cmse-clear-padding.rs @@ -221,9 +221,8 @@ impl Copy for VariantsSameSize {} // CHECK-LABEL: variants_same_size: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r1, [r0, #2] -// CHECK-NEXT: ldrb r0, [r0] -// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] extern "cmse-nonsecure-entry" fn variants_same_size(v: &VariantsSameSize) -> VariantsSameSize { *v @@ -237,6 +236,10 @@ enum VariantsDifferentSize { } impl Copy for VariantsDifferentSize {} +// CHECK-LABEL: variants_different_size: +// CHECK: mov r7, sp +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] extern "cmse-nonsecure-entry" fn variants_different_size( v: &VariantsDifferentSize, @@ -254,11 +257,19 @@ enum UninhabitedVariant { } impl Copy for UninhabitedVariant {} +// CHECK-LABEL: uninhabited_variant: +// CHECK: mov r7, sp +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] extern "cmse-nonsecure-entry" fn uninhabited_variant(v: &UninhabitedVariant) -> UninhabitedVariant { *v } +// CHECK-LABEL: variants_same_size_array: +// CHECK: mov r7, sp +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_same_size_array( @@ -267,6 +278,10 @@ extern "cmse-nonsecure-entry" fn variants_same_size_array( *v } +// CHECK-LABEL: variants_different_size_array: +// CHECK: mov r7, sp +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_different_size_array( @@ -275,6 +290,10 @@ extern "cmse-nonsecure-entry" fn variants_different_size_array( *v } +// CHECK-LABEL: variants_same_size_tuple: +// CHECK: mov r7, sp +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_same_size_tuple( @@ -283,6 +302,10 @@ extern "cmse-nonsecure-entry" fn variants_same_size_tuple( *v } +// CHECK-LABEL: variants_different_size_tuple: +// CHECK: mov r7, sp +// CHECK-NEXT: ldrh r0, [r0, #2] +// CHECK-NEXT: lsls r0, r0, #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_different_size_tuple( @@ -299,6 +322,11 @@ enum ThreeVariants { C(u32), } +// CHECK-LABEL: cmse_call_three_variants: +// CHECK: mov r7, sp +// CHECK-NEXT: mov r1, r2 +// CHECK-NEXT: mov r2, r0 +// CHECK-NEXT: movs r0, #0 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "C" fn cmse_call_three_variants( @@ -315,6 +343,11 @@ struct BoolU32 { val: u32, } +// CHECK-LABEL: cmse_call_niche: +// CHECK: mov r7, sp +// CHECK-NEXT: mov r3, r0 +// CHECK-NEXT: uxtb r0, r1 +// CHECK-NEXT: mov r1, r2 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "C" fn cmse_call_niche( From ff3b1814d6f080d98b1c2315cb78d28f8f9c7281 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 17 Jul 2026 20:04:22 +0200 Subject: [PATCH 69/77] the tag is not padding --- compiler/rustc_abi/src/layout/ty.rs | 11 +++++++ tests/assembly-llvm/cmse-clear-padding.rs | 35 ++++++++++++----------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 9ca4aa2254547..c606319cf2a7f 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -361,6 +361,17 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { } }, Variants::Multiple { variants, .. } => { + // The variants do not contain e.g. the discriminant or coroutine upvars. + let FieldsShape::Arbitrary { offsets, in_memory_order: _ } = &self.fields else { + unreachable!("a multi-variant layout should have `Arbitrary` fields") + }; + + // So add them explicitly. + for (field, &offset) in offsets.iter_enumerated() { + let field = self.field(cx, field.as_usize()); + field.add_data_ranges(cx, base_offset + offset, out); + } + for variant in variants.indices() { let variant = self.for_variant(cx, variant); variant.add_data_ranges(cx, base_offset, out); diff --git a/tests/assembly-llvm/cmse-clear-padding.rs b/tests/assembly-llvm/cmse-clear-padding.rs index 95f3d6fe8de8c..91188c75fe01f 100644 --- a/tests/assembly-llvm/cmse-clear-padding.rs +++ b/tests/assembly-llvm/cmse-clear-padding.rs @@ -221,8 +221,9 @@ impl Copy for VariantsSameSize {} // CHECK-LABEL: variants_same_size: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 #[no_mangle] extern "cmse-nonsecure-entry" fn variants_same_size(v: &VariantsSameSize) -> VariantsSameSize { *v @@ -238,8 +239,8 @@ impl Copy for VariantsDifferentSize {} // CHECK-LABEL: variants_different_size: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldr r0, [r0] +// CHECK-NEXT: bic r0, r0, #65280 #[no_mangle] extern "cmse-nonsecure-entry" fn variants_different_size( v: &VariantsDifferentSize, @@ -259,8 +260,9 @@ impl Copy for UninhabitedVariant {} // CHECK-LABEL: uninhabited_variant: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 #[no_mangle] extern "cmse-nonsecure-entry" fn uninhabited_variant(v: &UninhabitedVariant) -> UninhabitedVariant { *v @@ -268,8 +270,8 @@ extern "cmse-nonsecure-entry" fn uninhabited_variant(v: &UninhabitedVariant) -> // CHECK-LABEL: variants_same_size_array: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldr r0, [r0] +// CHECK-NEXT: bic r0, r0, #65280 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_same_size_array( @@ -280,8 +282,8 @@ extern "cmse-nonsecure-entry" fn variants_same_size_array( // CHECK-LABEL: variants_different_size_array: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldr r0, [r0] +// CHECK-NEXT: bic r0, r0, #65280 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_different_size_array( @@ -292,8 +294,9 @@ extern "cmse-nonsecure-entry" fn variants_different_size_array( // CHECK-LABEL: variants_same_size_tuple: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_same_size_tuple( @@ -304,8 +307,8 @@ extern "cmse-nonsecure-entry" fn variants_same_size_tuple( // CHECK-LABEL: variants_different_size_tuple: // CHECK: mov r7, sp -// CHECK-NEXT: ldrh r0, [r0, #2] -// CHECK-NEXT: lsls r0, r0, #16 +// CHECK-NEXT: ldr r0, [r0] +// CHECK-NEXT: bic r0, r0, #65280 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_different_size_tuple( @@ -324,9 +327,9 @@ enum ThreeVariants { // CHECK-LABEL: cmse_call_three_variants: // CHECK: mov r7, sp +// CHECK-NEXT: mov r3, r0 +// CHECK-NEXT: uxtb r0, r1 // CHECK-NEXT: mov r1, r2 -// CHECK-NEXT: mov r2, r0 -// CHECK-NEXT: movs r0, #0 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "C" fn cmse_call_three_variants( From 91fe3785d31254bb1dd8b8ad1ae8623d9c916dca Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 17 Jul 2026 20:30:18 +0200 Subject: [PATCH 70/77] refactor --- compiler/rustc_abi/src/layout/ty.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index c606319cf2a7f..2689410ad735d 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -291,7 +291,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// This is the "guaranteed" padding. There may be more bytes that are padding for some /// but not all variants of this type; those are not included. /// (E.g. `Option` has no guaranteed padding so the empty range set is returned, but its `None` value still has padding). - pub fn padding_ranges(&self, cx: &C) -> Vec> + pub fn variant_independent_padding_ranges(&self, cx: &C) -> Vec> where Ty: TyAbiInterface<'a, C> + Copy, { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 99075536d04a8..36e259b62fae3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -11,7 +11,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::lang_items::LangItem; use rustc_lint_defs::builtin::TAIL_CALL_TRACK_CALLER; use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; @@ -610,8 +610,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // // Returning a value with value-dependent padding will instead trigger a lint. let ret_layout = self.fn_abi.ret.layout; - let uninit_ranges = ret_layout.padding_ranges(bx.cx()); - self.zero_byte_ranges(bx, llslot, ret_layout.size, &uninit_ranges); + self.clear_cmse_padding(bx, llslot, ret_layout.size, ret_layout); } load_cast(bx, cast_ty, llslot, self.fn_abi.ret.layout.align.abi) @@ -1730,6 +1729,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } + fn clear_cmse_padding( + &mut self, + bx: &mut Bx, + base_ptr: Bx::Value, + limit: Size, + layout: TyAndLayout<'tcx>, + ) { + // First clear variant-independent padding, a series of memsets. + let variant_independent = layout.variant_independent_padding_ranges(self.cx); + self.zero_byte_ranges(bx, base_ptr, limit, &variant_independent); + } + fn zero_byte_ranges( &mut self, bx: &mut Bx, @@ -1887,11 +1898,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // // Passing an argument with value-dependent padding will instead trigger a lint. if conv == CanonAbi::Arm(ArmCall::CCmseNonSecureCall) { - self.zero_byte_ranges( + self.clear_cmse_padding( bx, llscratch, Size::from_bytes(copy_bytes), - &arg.layout.padding_ranges(bx.cx()), + arg.layout, ); } From 7460074ff25cd1853c16f26bac51b89134e63976 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 17 Jul 2026 22:16:31 +0200 Subject: [PATCH 71/77] clear the variant-dependent padding --- compiler/rustc_abi/src/layout/ty.rs | 126 ++++++++++----- compiler/rustc_codegen_ssa/src/mir/block.rs | 163 +++++++++++++++++--- tests/assembly-llvm/cmse-clear-padding.rs | 99 ++++++++++-- 3 files changed, 321 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 2689410ad735d..c5d8d758c4733 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -284,6 +284,27 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { found } + /// Whether this type/layout has any padding that is dependent on a variant, i.e. has bytes that + /// are padding for some, but not all, valid values of this type. + pub fn has_variant_dependent_padding(&self, cx: &C) -> bool + where + Ty: TyAbiInterface<'a, C> + Copy, + { + match self.variants { + Variants::Multiple { .. } => true, + Variants::Empty => false, + Variants::Single { .. } => match &self.fields { + FieldsShape::Primitive | FieldsShape::Union(_) => false, + FieldsShape::Array { count, .. } => { + *count > 0 && self.field(cx, 0).has_variant_dependent_padding(cx) + } + FieldsShape::Arbitrary { offsets, .. } => { + (0..offsets.len()).any(|i| self.field(cx, i).has_variant_dependent_padding(cx)) + } + }, + } + } + /// The ranges of bytes that are always ignored by the representation relation of this type. /// /// In other words, for any sequence of bytes, if we reset the these padding bytes to uninit, @@ -316,6 +337,45 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { uninit_ranges } + /// The ranges of bytes that are ignored by the representation relation of this variant. + /// + /// The result does not include variant-independent padding. + pub fn variant_dependent_padding_ranges( + &self, + cx: &C, + variant_index: VariantIdx, + ) -> Vec> + where + Ty: TyAbiInterface<'a, C> + Copy, + { + let Variants::Multiple { .. } = self.variants else { + return Vec::new(); + }; + + // Bytes that are data in some variant. + let mut any = RangeSet::new(); + self.add_data_ranges(cx, Size::ZERO, &mut any); + + // Bytes that are data in this variant. + let mut this = RangeSet::new(); + + // The variants do not contain e.g. the discriminant or coroutine upvars. + let FieldsShape::Arbitrary { offsets, in_memory_order: _ } = &self.fields else { + unreachable!("a multi-variant layout should have `Arbitrary` fields") + }; + + // So add them explicitly. + for (field, &offset) in offsets.iter_enumerated() { + let field = self.field(cx, field.as_usize()); + field.add_data_ranges(cx, offset, &mut this); + } + + self.for_variant(cx, variant_index).add_data_ranges(cx, Size::ZERO, &mut this); + + // Padding specific to this variant: data in some variant, but not in this one. + any.difference(&this).0.iter().map(|&(offset, size)| offset..offset + size).collect() + } + /// Extend `out` with all ranges of bytes that *may* carry relevant data for values of this type. /// For enums and unions there are offsets that are initialized for some /// variants but not for others; those offset *will* get added to `out`. @@ -327,51 +387,43 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { return; } - match &self.variants { - Variants::Empty => { /* done */ } - Variants::Single { index: _ } => match &self.fields { - FieldsShape::Primitive => { - out.add_range(base_offset, self.size); - } - &FieldsShape::Union(field_count) => { - for field in 0..field_count.get() { - let field = self.field(cx, field); - field.add_data_ranges(cx, base_offset, out); - } - } - &FieldsShape::Array { stride, count } => { - let elem = self.field(cx, 0); - - // For scalars we know there is no padding between the elements, - // so the entire array is a single big data range. - if elem.backend_repr.is_scalar() { - out.add_range(base_offset, elem.size * count); - } else { - // FIXME: this is really inefficient for large arrays. - for idx in 0..count { - elem.add_data_ranges(cx, base_offset + idx * stride, out); - } - } + // Visit the fields of this value. For enum values the fields include the discriminant. + match &self.fields { + FieldsShape::Primitive => { + out.add_range(base_offset, self.size); + } + &FieldsShape::Union(field_count) => { + for field in 0..field_count.get() { + let field = self.field(cx, field); + field.add_data_ranges(cx, base_offset, out); } - FieldsShape::Arbitrary { offsets, in_memory_order: _ } => { - for (field, &offset) in offsets.iter_enumerated() { - let field = self.field(cx, field.as_usize()); - field.add_data_ranges(cx, base_offset + offset, out); + } + &FieldsShape::Array { stride, count } => { + let elem = self.field(cx, 0); + + // For scalars we know there is no padding between the elements, + // so the entire array is a single big data range. + if elem.backend_repr.is_scalar() { + out.add_range(base_offset, elem.size * count); + } else { + // FIXME: this is really inefficient for large arrays. + for idx in 0..count { + elem.add_data_ranges(cx, base_offset + idx * stride, out); } } - }, - Variants::Multiple { variants, .. } => { - // The variants do not contain e.g. the discriminant or coroutine upvars. - let FieldsShape::Arbitrary { offsets, in_memory_order: _ } = &self.fields else { - unreachable!("a multi-variant layout should have `Arbitrary` fields") - }; - - // So add them explicitly. + } + FieldsShape::Arbitrary { offsets, in_memory_order: _ } => { for (field, &offset) in offsets.iter_enumerated() { let field = self.field(cx, field.as_usize()); field.add_data_ranges(cx, base_offset + offset, out); } + } + } + // Visit the fields of each variant. + match &self.variants { + Variants::Empty | Variants::Single { index: _ } => { /* done */ } + Variants::Multiple { variants, .. } => { for variant in variants.indices() { let variant = self.for_variant(cx, variant); variant.add_data_ranges(cx, base_offset, out); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 36e259b62fae3..6170f93b2451c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -2,7 +2,8 @@ use std::cmp; use std::ops::Range; use rustc_abi::{ - Align, ArmCall, BackendRepr, CanonAbi, ExternAbi, HasDataLayout, Reg, Size, WrappingRange, + Align, ArmCall, BackendRepr, CanonAbi, ExternAbi, FieldsShape, HasDataLayout, Reg, Size, + VariantIdx, Variants, WrappingRange, }; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; @@ -603,14 +604,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if self.fn_abi.conv == CanonAbi::Arm(ArmCall::CCmseNonSecureEntry) { // The return value of an `extern "cmse-nonsecure-entry"` function crosses the - // secure boundary. Zero padding bytes so information does not leak. - // - // This only zeroes "guaranteed" padding. There may be more bytes that are - // padding for some but not all variants of this type; those are not zeroed. - // - // Returning a value with value-dependent padding will instead trigger a lint. + // secure boundary. Clear any padding bytes so information does not leak. let ret_layout = self.fn_abi.ret.layout; - self.clear_cmse_padding(bx, llslot, ret_layout.size, ret_layout); + self.clear_padding_cmse(bx, llslot, ret_layout.size, ret_layout); } load_cast(bx, cast_ty, llslot, self.fn_abi.ret.layout.align.abi) @@ -1729,7 +1725,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn clear_cmse_padding( + /// When using CMSE, values that cross the secure boundary from secure to non-secure mode can + /// contain stale secure data in their padding bytes. This function clears that data. This is + /// required when a value is: + /// + /// - passed to an `extern "cmse-nonsecure-call"` function + /// - returned from an `extern "cmse-nonsecure-entry"` function + /// + /// This function clears both: + /// + /// - variant-independent padding, bytes that are padding for all valid values of the type + /// - variant-dependent padding, bytes that are padding for some but not all values of the type + /// + /// Clearing variant-dependent padding requires looking at the data at runtime to determine what + /// bytes to clear. + fn clear_padding_cmse( &mut self, bx: &mut Bx, base_ptr: Bx::Value, @@ -1738,25 +1748,143 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ) { // First clear variant-independent padding, a series of memsets. let variant_independent = layout.variant_independent_padding_ranges(self.cx); - self.zero_byte_ranges(bx, base_ptr, limit, &variant_independent); + self.zero_byte_ranges(bx, base_ptr, Size::ZERO, limit, &variant_independent); + + // Then clear the extra padding of the active variant of any (nested) enum. + self.clear_variant_dependent_padding(bx, base_ptr, Size::ZERO, limit, layout); + } + + fn clear_variant_dependent_padding( + &mut self, + bx: &mut Bx, + base_ptr: Bx::Value, + base_offset: Size, + limit: Size, + layout: TyAndLayout<'tcx>, + ) { + let cx = self.cx; + + if !layout.has_variant_dependent_padding(cx) { + return; + } + + // Recurse into aggregate fields/elements to reach any nested enums. + match layout.fields { + FieldsShape::Array { stride, count } => { + let elem = layout.field(cx, 0); + if elem.has_variant_dependent_padding(cx) { + for idx in 0..count { + let off = base_offset + idx * stride; + self.clear_variant_dependent_padding(bx, base_ptr, off, limit, elem); + } + } + } + FieldsShape::Arbitrary { .. } => { + for i in 0..layout.fields.count() { + let field = layout.field(cx, i); + if field.has_variant_dependent_padding(cx) { + let off = base_offset + layout.fields.offset(i); + self.clear_variant_dependent_padding(bx, base_ptr, off, limit, field); + } + } + } + FieldsShape::Primitive | FieldsShape::Union(_) => { /* nothing to visit */ } + } + + // If this is not a multi-variant enum, we're done. + let Variants::Multiple { ref variants, .. } = layout.variants else { + return; + }; + + // Collect variants that will need padding cleared. + let mut work = Vec::with_capacity(variants.len()); + for i in 0..variants.len() { + let idx = VariantIdx::from_usize(i); + let variant = layout.for_variant(cx, idx); + + // Don't consider uninhabited variants. + if variant.is_uninhabited() { + continue; + } + + let variant_dependent = layout.variant_dependent_padding_ranges(cx, idx); + let has_nested_variant_dependent = (0..variant.fields.count()) + .any(|i| variant.field(cx, i).has_variant_dependent_padding(cx)); + + if !variant_dependent.is_empty() || has_nested_variant_dependent { + work.push((idx, variant, variant_dependent)); + } + } + + if work.is_empty() { + return; + } + + // Build the switch and clear the appropriate padding for each variant. + let root_block = bx.llbb(); + let join_block = bx.append_sibling_block("cmse_pad_join"); + let mut cases = Vec::with_capacity(work.len()); + + for (idx, variant, variant_dependent) in work.into_iter() { + let Some(discr) = layout.ty.discriminant_for_variant(bx.tcx(), idx) else { + bug!("multi-variant layout on a type without discriminants"); + }; + + let variant_block = bx.append_sibling_block("cmse_pad_variant"); + bx.switch_to_block(variant_block); + + // Clear the padding of this variant. + self.zero_byte_ranges(bx, base_ptr, base_offset, limit, &variant_dependent); + + // Recurse into the fields. + for i in 0..variant.fields.count() { + let field = variant.field(cx, i); + let off = base_offset + variant.fields.offset(i); + self.clear_variant_dependent_padding(bx, base_ptr, off, limit, field); + } + + bx.br(join_block); + cases.push((discr.val, variant_block)); + } + + // Construct the dispatch. + bx.switch_to_block(root_block); + + let discr_ty = layout.ty.discriminant_ty(bx.tcx()); + let enum_ptr = bx.inbounds_ptradd(base_ptr, bx.const_usize(base_offset.bytes())); + let operand = OperandRef { + val: OperandValue::Ref(PlaceValue::new_sized(enum_ptr, layout.align.abi)), + layout, + move_annotation: None, + }; + let discr = operand.codegen_get_discr(self, bx, discr_ty); + + // Default to the join block (for variants without variant-dependent padding). + bx.switch(discr, join_block, cases.into_iter()); + + bx.switch_to_block(join_block); } fn zero_byte_ranges( &mut self, bx: &mut Bx, ptr: Bx::Value, + offset: Size, limit: Size, ranges: &[Range], ) { let zero = bx.const_u8(0); for range in ranges { - let end = cmp::min(range.end, limit); + let start = range.start + offset; + let end = range.end + offset; + + let end = cmp::min(end, limit); if range.start >= end { continue; } - let offset = bx.const_usize(range.start.bytes()); - let len = bx.const_usize((end - range.start).bytes()); + let offset = bx.const_usize(start.bytes()); + let len = bx.const_usize((end - start).bytes()); let ptr = bx.inbounds_ptradd(ptr, offset); bx.memset(ptr, zero, len, Align::ONE, MemFlags::empty()); } @@ -1891,14 +2019,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); // The arguments of an `extern "cmse-nonsecure-call"` function cross the secure - // boundary. Zero padding bytes so information does not leak. - // - // This only zeroes "guaranteed" padding. There may be more bytes that are - // padding for some but not all variants of this type; those are not zeroed. - // - // Passing an argument with value-dependent padding will instead trigger a lint. + // boundary. Clear any padding bytes so information does not leak. if conv == CanonAbi::Arm(ArmCall::CCmseNonSecureCall) { - self.clear_cmse_padding( + self.clear_padding_cmse( bx, llscratch, Size::from_bytes(copy_bytes), diff --git a/tests/assembly-llvm/cmse-clear-padding.rs b/tests/assembly-llvm/cmse-clear-padding.rs index 91188c75fe01f..93b10845ea511 100644 --- a/tests/assembly-llvm/cmse-clear-padding.rs +++ b/tests/assembly-llvm/cmse-clear-padding.rs @@ -237,10 +237,16 @@ enum VariantsDifferentSize { } impl Copy for VariantsDifferentSize {} +// A uxtbeq conditionally clears the padding only for variant A. +// // CHECK-LABEL: variants_different_size: // CHECK: mov r7, sp -// CHECK-NEXT: ldr r0, [r0] -// CHECK-NEXT: bic r0, r0, #65280 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] +// CHECK-NEXT: lsls r2, r0, #31 +// CHECK-NEXT: it eq +// CHECK-NEXT: uxtbeq r1, r1 +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 #[no_mangle] extern "cmse-nonsecure-entry" fn variants_different_size( v: &VariantsDifferentSize, @@ -258,6 +264,8 @@ enum UninhabitedVariant { } impl Copy for UninhabitedVariant {} +// Only `B` is inhabited, so reading the tag is not needed. +// // CHECK-LABEL: uninhabited_variant: // CHECK: mov r7, sp // CHECK-NEXT: ldrh r1, [r0, #2] @@ -268,6 +276,7 @@ extern "cmse-nonsecure-entry" fn uninhabited_variant(v: &UninhabitedVariant) -> *v } +// The single guaranteed-padding byte is cleared with a `bic` mask over the whole loaded word. // CHECK-LABEL: variants_same_size_array: // CHECK: mov r7, sp // CHECK-NEXT: ldr r0, [r0] @@ -282,8 +291,12 @@ extern "cmse-nonsecure-entry" fn variants_same_size_array( // CHECK-LABEL: variants_different_size_array: // CHECK: mov r7, sp -// CHECK-NEXT: ldr r0, [r0] -// CHECK-NEXT: bic r0, r0, #65280 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] +// CHECK-NEXT: lsls r2, r0, #31 +// CHECK-NEXT: it eq +// CHECK-NEXT: uxtbeq r1, r1 +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_different_size_array( @@ -307,8 +320,12 @@ extern "cmse-nonsecure-entry" fn variants_same_size_tuple( // CHECK-LABEL: variants_different_size_tuple: // CHECK: mov r7, sp -// CHECK-NEXT: ldr r0, [r0] -// CHECK-NEXT: bic r0, r0, #65280 +// CHECK-NEXT: ldrh r1, [r0, #2] +// CHECK-NEXT: ldrb r0, [r0] +// CHECK-NEXT: lsls r2, r0, #31 +// CHECK-NEXT: it eq +// CHECK-NEXT: uxtbeq r1, r1 +// CHECK-NEXT: orr.w r0, r0, r1, lsl #16 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "cmse-nonsecure-entry" fn variants_different_size_tuple( @@ -326,10 +343,21 @@ enum ThreeVariants { } // CHECK-LABEL: cmse_call_three_variants: -// CHECK: mov r7, sp -// CHECK-NEXT: mov r3, r0 +// CHECK: mov r3, r0 +// +// Clears padding in the extend the discriminant. // CHECK-NEXT: uxtb r0, r1 -// CHECK-NEXT: mov r1, r2 +// +// Uses uxtb for the A variant, uxtheq for the B variant, +// and nothing for the C variant. +// +// CHECK-NEXT: cbz r0, .LBB{{[0-9_]+}} +// CHECK-NEXT: cmp r0, #1 +// CHECK-NEXT: it eq +// CHECK-NEXT: uxtheq r2, r2 +// CHECK-NEXT: b .LBB{{[0-9_]+}} +// CHECK-NEXT: .LBB{{[0-9_]+}}: +// CHECK-NEXT: uxtb r2, r2 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "C" fn cmse_call_three_variants( @@ -339,6 +367,51 @@ extern "C" fn cmse_call_three_variants( unsafe { f(x) } } +/// Three variants of different sizes, with a nested enum. +#[repr(C)] +enum ThreeVariantsNested { + A(u8), + B(Option), + C(u32), +} + +// CHECK-LABEL: cmse_call_three_variants_nested: +// CHECK: mov r3, r0 +// +// Clears padding in the extend the discriminant. +// CHECK-NEXT: uxtb r0, r1 +// +// Match on the discriminant, jump to A block +// +// CHECK-NEXT: cbz r0, .LBB{{[0-9_]+}} +// +// Match on the discriminant, do nothing for C. +// +// CHECK-NEXT: cmp r0, #1 +// CHECK-NEXT: bne .LBB{{[0-9_]+}} +// +// The B variant conditionally clears the Option payload. +// +// CHECK-NEXT: lsls r1, r2, #31 +// CHECK-NEXT: movw r1, #65535 +// CHECK-NEXT: it eq +// CHECK-NEXT: moveq r1, #254 +// CHECK-NEXT: ands r2, r1 +// CHECK-NEXT: b .LBB{{[0-9_]+}} +// +// The A variant uses uxtb. +// +// CHECK-NEXT: .LBB{{[0-9_]+}}: +// CHECK-NEXT: uxtb r2, r2 +#[no_mangle] +#[expect(improper_ctypes_definitions)] +extern "C" fn cmse_call_three_variants_nested( + f: unsafe extern "cmse-nonsecure-call" fn(ThreeVariantsNested), + x: ThreeVariantsNested, +) { + unsafe { f(x) } +} + /// The tag is stored in the niche of the `bool`. #[repr(C)] struct BoolU32 { @@ -346,11 +419,17 @@ struct BoolU32 { val: u32, } +// Bit 0b0010 is used to encode the tag, so `r0 - 2 == 0` checks the tag value. +// Zero-extension clears padding in the tag 32-bit word, the `val` is either 0 +// (stored in r1) when None or the actual value r2 when Some. +// // CHECK-LABEL: cmse_call_niche: // CHECK: mov r7, sp // CHECK-NEXT: mov r3, r0 // CHECK-NEXT: uxtb r0, r1 -// CHECK-NEXT: mov r1, r2 +// CHECK-NEXT: subs r1, r0, #2 +// CHECK-NEXT: it ne +// CHECK-NEXT: movne r1, r2 #[no_mangle] #[expect(improper_ctypes_definitions)] extern "C" fn cmse_call_niche( From 6574ec298072073283185186f31ed966386eed79 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 27 Jun 2026 08:25:16 +0000 Subject: [PATCH 72/77] Add test for two cases 1. const argument expression 2. const argument with static value namespace --- .../ui/const-generics/mgca/static-const-arg.rs | 18 ++++++++++++++++++ .../mgca/static-const-arg.stderr | 14 ++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/ui/const-generics/mgca/static-const-arg.rs create mode 100644 tests/ui/const-generics/mgca/static-const-arg.stderr diff --git a/tests/ui/const-generics/mgca/static-const-arg.rs b/tests/ui/const-generics/mgca/static-const-arg.rs new file mode 100644 index 0000000000000..9ad248de3cb0f --- /dev/null +++ b/tests/ui/const-generics/mgca/static-const-arg.rs @@ -0,0 +1,18 @@ +// Regression test for #132986. +// FIXME(min_generic_const_args): using statics as direct const arguments should error instead of +// ICEing until const eval can evaluate statics to valtrees for const generics. + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +static A: u32 = 0; + +struct Foo; + +const _: Foo<{ A }> = Foo; +//~^ ERROR static items cannot be used as const arguments + +const _: Foo = Foo; +//~^ ERROR static items cannot be used as const arguments + +fn main() {} diff --git a/tests/ui/const-generics/mgca/static-const-arg.stderr b/tests/ui/const-generics/mgca/static-const-arg.stderr new file mode 100644 index 0000000000000..9c5473f94d2cc --- /dev/null +++ b/tests/ui/const-generics/mgca/static-const-arg.stderr @@ -0,0 +1,14 @@ +error: static items cannot be used as const arguments + --> $DIR/static-const-arg.rs:12:16 + | +LL | const _: Foo<{ A }> = Foo; + | ^ + +error: static items cannot be used as const arguments + --> $DIR/static-const-arg.rs:15:14 + | +LL | const _: Foo = Foo; + | ^ + +error: aborting due to 2 previous errors + From 899387f14f3726784d5ee8a0c99c0129b0e7dc53 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 11 Jul 2026 03:44:34 +0000 Subject: [PATCH 73/77] make sure to emit error during hir_lowering for const statics --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b59bed76eadd7..f5b4cee8dedf2 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2933,7 +2933,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .unwrap_or_else(|guar| Const::new_error(tcx, guar)) } Res::Def(DefKind::Static { .. }, _) => { - span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported") + let guar = self + .dcx() + .span_err(path.span, "static items cannot be used as const arguments"); + return Const::new_error(tcx, guar); } // FIXME(const_generics): create real const to allow fn items as const paths Res::Def(DefKind::Fn | DefKind::AssocFn, did) => { From b4c60f04e7c9071e5840279eb0cebfd5328d00ea Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 23 Jul 2026 11:30:04 +0000 Subject: [PATCH 74/77] add macroless_generic_const_args as feature --- tests/ui/const-generics/mgca/static-const-arg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/const-generics/mgca/static-const-arg.rs b/tests/ui/const-generics/mgca/static-const-arg.rs index 9ad248de3cb0f..716c8bb6dc4de 100644 --- a/tests/ui/const-generics/mgca/static-const-arg.rs +++ b/tests/ui/const-generics/mgca/static-const-arg.rs @@ -2,7 +2,7 @@ // FIXME(min_generic_const_args): using statics as direct const arguments should error instead of // ICEing until const eval can evaluate statics to valtrees for const generics. -#![feature(min_generic_const_args)] +#![feature(min_generic_const_args, macroless_generic_const_args)] #![allow(incomplete_features)] static A: u32 = 0; From baffab0f9a83556063b939689cb76b1ed67cd50f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 22 Jul 2026 14:58:16 -0400 Subject: [PATCH 75/77] rustfmt fix: ignore file not found errors for external mods with custom outer attributes It's possible that at least one of the attributes is a custom proc macro that takes the module tokens as an input. It's hard to know for sure since rustfmt only operates on the AST pre-expansion. In this case we'll be overly permissive and just ignore the file not found error so rustfmt can still try formatting the input. Fixes rustfmt issue 6959 --- src/tools/rustfmt/src/lib.rs | 1 + src/tools/rustfmt/src/modules.rs | 12 +++++++++++- src/tools/rustfmt/src/utils.rs | 8 ++++++++ src/tools/rustfmt/tests/target/issue_6959.rs | 2 ++ 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/tools/rustfmt/tests/target/issue_6959.rs diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index 5f49bbf0c7e31..65c83a612bf9f 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -11,6 +11,7 @@ extern crate rustc_ast_pretty; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_expand; +extern crate rustc_feature; extern crate rustc_parse; extern crate rustc_session; extern crate rustc_span; diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs index 099a644282102..baa1a86ad25c8 100644 --- a/src/tools/rustfmt/src/modules.rs +++ b/src/tools/rustfmt/src/modules.rs @@ -16,7 +16,7 @@ use crate::parse::parser::{ Directory, DirectoryOwnership, ModError, ModulePathSuccess, Parser, ParserError, }; use crate::parse::session::ParseSess; -use crate::utils::{contains_skip, mk_sp}; +use crate::utils::{contains_custom_attributes, contains_skip, mk_sp}; mod visitor; @@ -472,6 +472,16 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { } Err(e) => match e { ModError::FileNotFound(_, default_path, _secondary_path) => { + if contains_custom_attributes(attrs) { + // It's possible that at least one of the attributes is a custom proc macro + // that takes the module tokens as an input. It's hard to know for sure + // since rustfmt only operates on the AST pre-expansion. In this case we'll + // be overly permissive and just ignore the file not found error so rustfmt + // can still try formatting the input. + tracing::warn!("Couldn't find file for mod {};`", mod_name.to_string()); + return Ok(None); + } + Err(ModuleResolutionError { module: mod_name.to_string(), kind: ModuleResolutionErrorKind::NotFound { file: default_path }, diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index 15a4fce93482a..131455fc0ff12 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -6,6 +6,7 @@ use rustc_ast::ast::{ NodeId, Path, RestrictionKind, Visibility, VisibilityKind, }; use rustc_ast_pretty::pprust; +use rustc_feature::is_builtin_attr_name; use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol}; use unicode_width::UnicodeWidthStr; @@ -327,6 +328,13 @@ pub(crate) fn contains_skip(attrs: &[Attribute]) -> bool { .any(|a| a.meta().map_or(false, |a| is_skip(&a))) } +#[inline] +pub(crate) fn contains_custom_attributes(attrs: &[Attribute]) -> bool { + attrs + .iter() + .any(|a| a.name().is_some_and(|name| !is_builtin_attr_name(name))) +} + #[inline] pub(crate) fn semicolon_for_expr(context: &RewriteContext<'_>, expr: &ast::Expr) -> bool { // Never try to insert semicolons on expressions when we're inside diff --git a/src/tools/rustfmt/tests/target/issue_6959.rs b/src/tools/rustfmt/tests/target/issue_6959.rs new file mode 100644 index 0000000000000..2194ba3285353 --- /dev/null +++ b/src/tools/rustfmt/tests/target/issue_6959.rs @@ -0,0 +1,2 @@ +#[my_macro] +mod foo; From 5ad773b6d7cd8d47c84d47aa666b85a0c571e5bf Mon Sep 17 00:00:00 2001 From: Ian Miller Date: Thu, 23 Jul 2026 16:51:20 +0100 Subject: [PATCH 76/77] fix(lld): route version mismatch warnings to linker_info on macOS Broaden `is_macos_ld` to `is_macos_linker` by matching `Darwin(..)` instead of `Darwin(_, Lld::No)`, so the linker output filtering also runs when lld is used. Add lld-specific version mismatch pattern to `deployment_mismatch` closure, routing these warnings to `linker_info` (default Allow) instead of `linker_messages` (default Warn). Add a real-lld sub-test to `macos-deployment-target-warning` that exercises the `ld64.lld` path via `-fuse-ld=`, verifying lld warnings are normalized and routed to `linker_info`. Signed-off-by: Ian Miller --- compiler/rustc_codegen_ssa/src/back/link.rs | 10 +++++---- .../macos-deployment-target-warning/rmake.rs | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 105093e37b237..0a9af492b1f45 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -884,9 +884,9 @@ fn is_msvc_link_exe(sess: &Session) -> bool { && linker_path.to_str() == Some("link.exe") } -fn is_macos_ld(sess: &Session) -> bool { +fn is_macos_linker(sess: &Session) -> bool { let (_, flavor) = linker_and_flavor(sess); - sess.target.is_like_darwin && matches!(flavor, LinkerFlavor::Darwin(_, Lld::No)) + sess.target.is_like_darwin && matches!(flavor, LinkerFlavor::Darwin(..)) } fn is_windows_gnu_ld(sess: &Session) -> bool { @@ -953,8 +953,8 @@ fn report_linker_output( *output += "\r\n" } }); - } else if is_macos_ld(sess) { - info!("inferred macOS LD"); + } else if is_macos_linker(sess) { + info!("inferred macOS linker"); // FIXME: Tracked by https://github.com/rust-lang/rust/issues/136113 let deployment_mismatch = |line: &str| { @@ -967,6 +967,8 @@ fn report_linker_output( && line.contains("building for") && line.contains("but linking with") && line.contains("which was built for newer version")) + // lld (ld64.lld / rust-lld): + || line.contains("which is newer than target minimum of") }; // FIXME: This is a real warning we would like to show, but it hits too many crates // to want to turn it on immediately. diff --git a/tests/run-make/macos-deployment-target-warning/rmake.rs b/tests/run-make/macos-deployment-target-warning/rmake.rs index 6aab525a7c8a4..47f9cd1cf5f2c 100644 --- a/tests/run-make/macos-deployment-target-warning/rmake.rs +++ b/tests/run-make/macos-deployment-target-warning/rmake.rs @@ -13,6 +13,7 @@ fn main() { let ld_prime_obj = r"ld: warning: object file \(.*\) was built for newer '.+' version \(\d+\.\d+\) than being linked \(\d+\.\d+\)"; let ld64_dylib = r"ld: warning: dylib \(.*\) was built for newer .+ version \(\d+\.\d+\) than being linked \(\d+\.\d+\)"; let ld_prime_dylib = r"ld: warning: building for [^ ,]+, but linking with dylib '[^']*' which was built for newer version [0-9.]+"; + let lld_obj = r"ld64\.lld: warning: .+ has version \d+\.\d+(\.\d+)?, which is newer than target minimum of \d+\.\d+(\.\d+)?"; // Test 1: static archive (object file mismatch) cc().arg("-c").arg("-mmacosx-version-min=15.5").output("foo.o").input("foo.c").run(); @@ -54,4 +55,24 @@ fn main() { .normalize(ld64_dylib, "NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING") .normalize(ld_prime_dylib, "NORMALIZED_DYLIB_DEPLOYMENT_MISMATCH_LINKER_WARNING") .run(); + + // Test 3: static archive with lld (object file mismatch) + let lld_path = std::path::PathBuf::from(std::env::var("LLVM_BIN_DIR").unwrap()).join("lld"); + let ld64_lld = std::env::current_dir().unwrap().join("ld64.lld"); + std::os::unix::fs::symlink(&lld_path, &ld64_lld).expect("failed to create ld64.lld symlink"); + + let lld_warnings = rustc() + .arg("-lstatic=foo") + .link_arg("-mmacosx-version-min=11.2") + .link_arg(&format!("-fuse-ld={}", ld64_lld.display())) + .input("main.rs") + .crate_type("bin") + .run() + .stderr_utf8(); + + diff() + .expected_file("warnings.txt") + .actual_text("(rustc -W linker-info with lld)", &lld_warnings) + .normalize(lld_obj, "NORMALIZED_OBJECT_DEPLOYMENT_MISMATCH_LINKER_WARNING") + .run(); } From cd9fd520d995c70dd7b06c89f6b86fbfecbb6741 Mon Sep 17 00:00:00 2001 From: zedddie Date: Thu, 16 Jul 2026 23:51:26 +0200 Subject: [PATCH 77/77] bless batch --- .../associated-types/cache/poison-copy-via-projection.rs | 4 ++++ .../cache/poison-copy-via-projection.stderr | 2 +- .../coherence/coherence-overlap-downstream-fundamental.rs | 7 +++++++ .../coherence-overlap-downstream-fundamental.stderr | 2 +- tests/ui/lowering/expr-metavar-in-let-pattern.rs | 4 ++++ tests/ui/lowering/expr-metavar-in-let-pattern.stderr | 4 ++-- tests/ui/macros/attr-path-metavar-generic-args.rs | 3 +++ tests/ui/macros/attr-path-metavar-generic-args.stderr | 2 +- tests/ui/pattern/type-alias-as-variant-pattern.rs | 3 +++ tests/ui/pattern/type-alias-as-variant-pattern.stderr | 2 +- tests/ui/std/instant-add-duration-overflow.rs | 3 +++ tests/ui/std/instant-sub-duration-overflow.rs | 2 ++ tests/ui/std/system-time-add-duration-overflow.rs | 2 ++ tests/ui/std/system-time-sub-duration-overflow.rs | 2 ++ tests/ui/traits/coerce-diverging-through-from.rs | 2 ++ 15 files changed, 38 insertions(+), 6 deletions(-) diff --git a/tests/ui/associated-types/cache/poison-copy-via-projection.rs b/tests/ui/associated-types/cache/poison-copy-via-projection.rs index 5e83a1cd67785..6afaccf89693d 100644 --- a/tests/ui/associated-types/cache/poison-copy-via-projection.rs +++ b/tests/ui/associated-types/cache/poison-copy-via-projection.rs @@ -1,3 +1,7 @@ +//! Regression test for . +//! Where clause implying trait assoc type is `Copy`, poisoned cache to +//! believe `String: Copy`, which exposed UB. + pub trait Mirror { type Image; } diff --git a/tests/ui/associated-types/cache/poison-copy-via-projection.stderr b/tests/ui/associated-types/cache/poison-copy-via-projection.stderr index 0e7ce9e98c4d7..5fd2bbd1439a2 100644 --- a/tests/ui/associated-types/cache/poison-copy-via-projection.stderr +++ b/tests/ui/associated-types/cache/poison-copy-via-projection.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `s` - --> $DIR/issue-42796.rs:18:20 + --> $DIR/poison-copy-via-projection.rs:22:20 | LL | let s = "Hello!".to_owned(); | - move occurs because `s` has type `String`, which does not implement the `Copy` trait diff --git a/tests/ui/coherence/coherence-overlap-downstream-fundamental.rs b/tests/ui/coherence/coherence-overlap-downstream-fundamental.rs index 597472b4f48f0..23482621c2f15 100644 --- a/tests/ui/coherence/coherence-overlap-downstream-fundamental.rs +++ b/tests/ui/coherence/coherence-overlap-downstream-fundamental.rs @@ -1,3 +1,10 @@ +//! Regression test for . +//! Test trait relationship defined as `Trait1 for T where T: Trait2` +//! rejects implementations of `Trait1` with generics over `#[fundamental]` +//! types, as a downstream crate can implement dependent `Trait2` for the same +//! type with the same generics, causing coherence breakage. +//! +//! This used to ICE if downstream crate tried to `impl Trait2> for A`. //@ dont-require-annotations: NOTE pub trait Trait1 { diff --git a/tests/ui/coherence/coherence-overlap-downstream-fundamental.stderr b/tests/ui/coherence/coherence-overlap-downstream-fundamental.stderr index 5a089cb3d8bbb..c96148f07b8d3 100644 --- a/tests/ui/coherence/coherence-overlap-downstream-fundamental.stderr +++ b/tests/ui/coherence/coherence-overlap-downstream-fundamental.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait1>` for type `A` - --> $DIR/issue-43355.rs:15:1 + --> $DIR/coherence-overlap-downstream-fundamental.rs:22:1 | LL | impl Trait1 for T where T: Trait2 { | --------------------------------------------- first implementation here diff --git a/tests/ui/lowering/expr-metavar-in-let-pattern.rs b/tests/ui/lowering/expr-metavar-in-let-pattern.rs index 24d70d2964bb2..3f10576e31010 100644 --- a/tests/ui/lowering/expr-metavar-in-let-pattern.rs +++ b/tests/ui/lowering/expr-metavar-in-let-pattern.rs @@ -1,3 +1,7 @@ +//! Regression test for . +//! Test expr metavars aren't allowed in places where pattern is expected, +//! and their use doesn't cause ICE. + fn main() { let mut y; const C: u32 = 0; diff --git a/tests/ui/lowering/expr-metavar-in-let-pattern.stderr b/tests/ui/lowering/expr-metavar-in-let-pattern.stderr index e74342b85adb3..6161a7ed50e05 100644 --- a/tests/ui/lowering/expr-metavar-in-let-pattern.stderr +++ b/tests/ui/lowering/expr-metavar-in-let-pattern.stderr @@ -1,5 +1,5 @@ error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-43250.rs:9:8 + --> $DIR/expr-metavar-in-let-pattern.rs:13:8 | LL | m!(y); | ^ @@ -7,7 +7,7 @@ LL | m!(y); = note: the `expr` fragment specifier forces the metavariable's content to be an expression error: arbitrary expressions aren't allowed in patterns - --> $DIR/issue-43250.rs:11:8 + --> $DIR/expr-metavar-in-let-pattern.rs:15:8 | LL | m!(C); | ^ diff --git a/tests/ui/macros/attr-path-metavar-generic-args.rs b/tests/ui/macros/attr-path-metavar-generic-args.rs index b3f76d8b04992..389d37f07c437 100644 --- a/tests/ui/macros/attr-path-metavar-generic-args.rs +++ b/tests/ui/macros/attr-path-metavar-generic-args.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test generics in attribute paths are rejected. + #![allow(unused)] macro_rules! m { diff --git a/tests/ui/macros/attr-path-metavar-generic-args.stderr b/tests/ui/macros/attr-path-metavar-generic-args.stderr index 64a3c2a3d8d06..ac60ec0cafa5b 100644 --- a/tests/ui/macros/attr-path-metavar-generic-args.stderr +++ b/tests/ui/macros/attr-path-metavar-generic-args.stderr @@ -1,5 +1,5 @@ error: unexpected generic arguments in path - --> $DIR/issue-43424.rs:10:10 + --> $DIR/attr-path-metavar-generic-args.rs:13:10 | LL | m!(inline); | ^^^^ diff --git a/tests/ui/pattern/type-alias-as-variant-pattern.rs b/tests/ui/pattern/type-alias-as-variant-pattern.rs index 36d15fc35b48a..092357d0ceb96 100644 --- a/tests/ui/pattern/type-alias-as-variant-pattern.rs +++ b/tests/ui/pattern/type-alias-as-variant-pattern.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Test type-based paths in variant patterns don't cause ICE. + type Value = String; fn main() { diff --git a/tests/ui/pattern/type-alias-as-variant-pattern.stderr b/tests/ui/pattern/type-alias-as-variant-pattern.stderr index 8743b1cfdef77..9ecff58c41c0d 100644 --- a/tests/ui/pattern/type-alias-as-variant-pattern.stderr +++ b/tests/ui/pattern/type-alias-as-variant-pattern.stderr @@ -1,5 +1,5 @@ error[E0599]: no associated function or constant named `String` found for struct `String` in the current scope - --> $DIR/issue-42880.rs:4:22 + --> $DIR/type-alias-as-variant-pattern.rs:7:22 | LL | let f = |&Value::String(_)| (); | ^^^^^^ associated function or constant not found in `String` diff --git a/tests/ui/std/instant-add-duration-overflow.rs b/tests/ui/std/instant-add-duration-overflow.rs index ca2c52b99a82a..519dbcac69c0f 100644 --- a/tests/ui/std/instant-add-duration-overflow.rs +++ b/tests/ui/std/instant-add-duration-overflow.rs @@ -1,5 +1,8 @@ +//! Regression test for . +//! Test overflowing `Instant` panics. //@ run-fail //@ error-pattern:overflow +//@ needs-subprocess use std::time::{Duration, Instant}; diff --git a/tests/ui/std/instant-sub-duration-overflow.rs b/tests/ui/std/instant-sub-duration-overflow.rs index 19cd12e685fd1..0009b2800040b 100644 --- a/tests/ui/std/instant-sub-duration-overflow.rs +++ b/tests/ui/std/instant-sub-duration-overflow.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test overflowing `Instant` panics. //@ run-fail //@ error-pattern:overflow //@ needs-subprocess diff --git a/tests/ui/std/system-time-add-duration-overflow.rs b/tests/ui/std/system-time-add-duration-overflow.rs index 3838d28e33d1b..a920afa5ed799 100644 --- a/tests/ui/std/system-time-add-duration-overflow.rs +++ b/tests/ui/std/system-time-add-duration-overflow.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test overflowing `SystemTime` panics. //@ run-fail //@ error-pattern:overflow //@ needs-subprocess diff --git a/tests/ui/std/system-time-sub-duration-overflow.rs b/tests/ui/std/system-time-sub-duration-overflow.rs index bd4f66f3e161b..64d88b527028f 100644 --- a/tests/ui/std/system-time-sub-duration-overflow.rs +++ b/tests/ui/std/system-time-sub-duration-overflow.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test overflowing `SystemTime` panics. //@ run-fail //@ error-pattern:overflow //@ needs-subprocess diff --git a/tests/ui/traits/coerce-diverging-through-from.rs b/tests/ui/traits/coerce-diverging-through-from.rs index ed07314531c3d..024d21daec264 100644 --- a/tests/ui/traits/coerce-diverging-through-from.rs +++ b/tests/ui/traits/coerce-diverging-through-from.rs @@ -1,3 +1,5 @@ +//! Regression test for . +//! Test using `From::from(f())` on a diverging `f()` doesn't ICE. //@ run-pass //@ needs-unwind