From 68cfe93c112699e0651eb54e4a4de4b3a14cb5cc Mon Sep 17 00:00:00 2001 From: Zachary S Date: Mon, 15 Jun 2026 00:47:48 -0500 Subject: [PATCH 01/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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/68] 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 4f1921c367350d7f328667bcb79468173a56aee7 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 16 Jul 2026 18:01:35 +0200 Subject: [PATCH 13/68] 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 14/68] 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 15/68] 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 377748d2835bfa5413baa2e52bd8e42fc2358b5d Mon Sep 17 00:00:00 2001 From: zedddie Date: Sat, 18 Jul 2026 01:14:40 +0200 Subject: [PATCH 16/68] 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 17/68] 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 18/68] 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 19/68] 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 20/68] 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 2851cef01a6a8cc8afc5770eba31362b944cc4e2 Mon Sep 17 00:00:00 2001 From: zedddie Date: Mon, 20 Jul 2026 01:59:03 +0200 Subject: [PATCH 21/68] 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 7726456e92260a1f3080a0a4a0cd0714684e8048 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 15:47:03 +0200 Subject: [PATCH 22/68] 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 23/68] 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 a9d6ac19ce56eaf9be0ffbf9b69f333bf13daca0 Mon Sep 17 00:00:00 2001 From: dianqk Date: Mon, 20 Jul 2026 21:28:09 +0800 Subject: [PATCH 24/68] Add test cases for a hoisting miscompilation --- ...dont_hoist_deref.EarlyOtherwiseBranch.diff | 49 +++++++++++++++++++ tests/mir-opt/early_otherwise_branch.rs | 42 ++++++++++++++++ tests/ui/mir/hoist_deref_early_else.rs | 37 ++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff create mode 100644 tests/ui/mir/hoist_deref_early_else.rs diff --git a/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff new file mode 100644 index 0000000000000..b449b7e28dd2e --- /dev/null +++ b/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff @@ -0,0 +1,49 @@ +- // MIR for `dont_hoist_deref` before EarlyOtherwiseBranch ++ // MIR for `dont_hoist_deref` after EarlyOtherwiseBranch + + fn dont_hoist_deref(_1: u64, _2: *const u64) -> u64 { + let mut _0: u64; ++ let mut _3: bool; + + bb0: { +- switchInt(copy _1) -> [1: bb1, 2: bb2, otherwise: bb5]; ++ _3 = Ne(copy _1, copy (*_2)); ++ switchInt(move _3) -> [0: bb5, otherwise: bb3]; + } + + bb1: { +- switchInt(copy (*_2)) -> [1: bb3, otherwise: bb5]; ++ _0 = const 100_u64; ++ goto -> bb4; + } + + bb2: { +- switchInt(copy (*_2)) -> [2: bb4, otherwise: bb5]; ++ _0 = const 200_u64; ++ goto -> bb4; + } + + bb3: { +- _0 = const 100_u64; +- goto -> bb6; ++ _0 = const 999_u64; ++ goto -> bb4; + } + + bb4: { +- _0 = const 200_u64; +- goto -> bb6; ++ return; + } + + bb5: { +- _0 = const 999_u64; +- goto -> bb6; +- } +- +- bb6: { +- return; ++ switchInt(copy _1) -> [1: bb1, 2: bb2, otherwise: bb3]; + } + } + diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs index 19a5d25de2dfb..99bd0d65cf470 100644 --- a/tests/mir-opt/early_otherwise_branch.rs +++ b/tests/mir-opt/early_otherwise_branch.rs @@ -156,6 +156,47 @@ fn target_self(val: i32) { } } +// EMIT_MIR early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff +#[custom_mir(dialect = "runtime")] +fn dont_hoist_deref(q: u64, p: *const u64) -> u64 { + mir! { + { + match q { + 1 => bb1, + 2 => bb2, + _ => bb5, + } + } + bb1 = { + match *p { + 1 => bb3, + _ => bb5, + } + } + bb2 = { + match *p { + 2 => bb4, + _ => bb5, + } + } + bb3 = { + RET = 100; + Goto(bb6) + } + bb4 = { + RET = 200; + Goto(bb6) + } + bb5 = { + RET = 999; + Goto(bb6) + } + bb6 = { + Return() + } + } +} + fn main() { opt1(None, Some(0)); opt2(None, Some(0)); @@ -164,4 +205,5 @@ fn main() { opt5(0, 0); opt5_failed(0, 0); target_self(1); + dont_hoist_deref(3, std::ptr::null()); } diff --git a/tests/ui/mir/hoist_deref_early_else.rs b/tests/ui/mir/hoist_deref_early_else.rs new file mode 100644 index 0000000000000..06e31bcb0b3ad --- /dev/null +++ b/tests/ui/mir/hoist_deref_early_else.rs @@ -0,0 +1,37 @@ +//! Regression test for issue . +//! The null pointer `p` should never be dereferenced. +//@[noopt] run-pass +//@[opt] run-crash +//@ revisions: noopt opt +//@ check-run-results +//@[noopt] compile-flags: -C opt-level=0 +//@[opt] compile-flags: -C opt-level=3 + +use std::hint::black_box; + +#[inline(never)] +fn foo(q: u64, p: *const u64) -> u64 { + unsafe { + 'a: { + match q { + 1 => match *p { + 1 => break 'a 100, + _ => {} + }, + 2 => match *p { + 2 => break 'a 200, + _ => {} + }, + _ => {} + } + 999 + } + } +} + +fn main() { + let q: u64 = black_box(3); + let p: *const u64 = black_box(std::ptr::null()); + let r = foo(q, p); + assert_eq!(999, black_box(r)); +} From a22fed77686db50c1185e4267743924ac50f584a Mon Sep 17 00:00:00 2001 From: dianqk Date: Mon, 20 Jul 2026 22:41:37 +0800 Subject: [PATCH 25/68] early_otherwise: Don't hoist dereferences when the otherwise branch is reachable --- .../src/early_otherwise_branch.rs | 97 ++++++++++++------- ...dont_hoist_deref.EarlyOtherwiseBranch.diff | 37 +++---- tests/mir-opt/early_otherwise_branch.rs | 9 ++ tests/ui/mir/hoist_deref_early_else.rs | 3 +- 4 files changed, 83 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index 2b786b7e9e1a2..7adeebd235384 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -243,7 +243,7 @@ fn evaluate_candidate<'tcx>( return None; } - // We only handle: + // For now, we only handle: // ``` // bb4: { // _8 = discriminant((_3.1: Enum1)); @@ -262,41 +262,8 @@ fn evaluate_candidate<'tcx>( // When thie BB has exactly one statement, this statement should be discriminant. let need_hoist_discriminant = bbs[child].statements.len() == 1; + let otherwise_is_empty_unreachable = bbs[targets.otherwise()].is_empty_unreachable(); let child_place = if need_hoist_discriminant { - if !bbs[targets.otherwise()].is_empty_unreachable() { - // Someone could write code like this: - // ```rust - // let Q = val; - // if discriminant(P) == otherwise { - // let ptr = &mut Q as *mut _ as *mut u8; - // // It may be difficult for us to effectively determine whether values are valid. - // // Invalid values can come from all sorts of corners. - // unsafe { *ptr = 10; } - // } - // - // match P { - // A => match Q { - // A => { - // // code - // } - // _ => { - // // don't use Q - // } - // } - // _ => { - // // don't use Q - // } - // }; - // ``` - // - // Hoisting the `discriminant(Q)` out of the `A` arm causes us to compute the discriminant of an - // invalid value, which is UB. - // In order to fix this, **we would either need to show that the discriminant computation of - // `place` is computed in all branches**. - // FIXME(#95162) For the moment, we adopt a conservative approach and - // consider only the `otherwise` branch has no statements and an unreachable terminator. - return None; - } // Handle: // ``` // bb4: { @@ -325,8 +292,7 @@ fn evaluate_candidate<'tcx>( }; *child_place }; - let destination = if need_hoist_discriminant || bbs[targets.otherwise()].is_empty_unreachable() - { + let destination = if otherwise_is_empty_unreachable { child_targets.otherwise() } else { targets.otherwise() @@ -340,6 +306,7 @@ fn evaluate_candidate<'tcx>( child_place, destination, need_hoist_discriminant, + otherwise_is_empty_unreachable, ) { return None; } @@ -359,11 +326,67 @@ fn verify_candidate_branch<'tcx>( place: Place<'tcx>, destination: BasicBlock, need_hoist_discriminant: bool, + otherwise_is_empty_unreachable: bool, ) -> bool { // In order for the optimization to be correct, the terminator must be a `SwitchInt`. let TerminatorKind::SwitchInt { discr: switch_op, targets } = &branch.terminator().kind else { return false; }; + if !otherwise_is_empty_unreachable { + // Someone could write code like this: + // ```rust + // let Q = val; + // if discriminant(P) == otherwise { + // let ptr = &mut Q as *mut _ as *mut u8; + // // It may be difficult for us to effectively determine whether values are valid. + // // Invalid values can come from all sorts of corners. + // unsafe { *ptr = 10; } + // } + // + // match P { + // A => match Q { + // A => { + // // code + // } + // _ => { + // // don't use Q + // } + // } + // _ => { + // // don't use Q + // } + // }; + // ``` + // + // Hoisting the `discriminant(Q)` out of the `A` arm causes us to compute the discriminant of an + // invalid value, which is UB. + // In order to fix this, **we would either need to show that the discriminant computation of + // `place` is computed in all branches**. + // For , we adopt a conservative approach and + // consider only the `otherwise` branch has no statements and an unreachable terminator. + if need_hoist_discriminant { + return false; + } + // For : + // ``` + // bb0: { + // switchInt(copy _1) -> [1: bb1, 2: bb2, otherwise: bb5]; + // } + // bb1: { + // switchInt(copy (*_2)) -> [1: bb3, otherwise: bb5]; + // } + // bb2: { + // switchInt(copy (*_2)) -> [2: bb4, otherwise: bb5]; + // } + // ``` + // We cannot hoist the dereference of `_2` to `bb0`, + // because execution can reach `bb5` without dereferencing `_2`. + if let Some(place) = switch_op.place() + && !place.is_stable_offset() + { + return false; + } + } if need_hoist_discriminant { // If we need hoist discriminant, the branch must have exactly one statement. let [statement] = branch.statements.as_slice() else { diff --git a/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff index b449b7e28dd2e..66891f818a6cf 100644 --- a/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff @@ -3,47 +3,36 @@ fn dont_hoist_deref(_1: u64, _2: *const u64) -> u64 { let mut _0: u64; -+ let mut _3: bool; bb0: { -- switchInt(copy _1) -> [1: bb1, 2: bb2, otherwise: bb5]; -+ _3 = Ne(copy _1, copy (*_2)); -+ switchInt(move _3) -> [0: bb5, otherwise: bb3]; + switchInt(copy _1) -> [1: bb1, 2: bb2, otherwise: bb5]; } bb1: { -- switchInt(copy (*_2)) -> [1: bb3, otherwise: bb5]; -+ _0 = const 100_u64; -+ goto -> bb4; + switchInt(copy (*_2)) -> [1: bb3, otherwise: bb5]; } bb2: { -- switchInt(copy (*_2)) -> [2: bb4, otherwise: bb5]; -+ _0 = const 200_u64; -+ goto -> bb4; + switchInt(copy (*_2)) -> [2: bb4, otherwise: bb5]; } bb3: { -- _0 = const 100_u64; -- goto -> bb6; -+ _0 = const 999_u64; -+ goto -> bb4; + _0 = const 100_u64; + goto -> bb6; } bb4: { -- _0 = const 200_u64; -- goto -> bb6; -+ return; + _0 = const 200_u64; + goto -> bb6; } bb5: { -- _0 = const 999_u64; -- goto -> bb6; -- } -- -- bb6: { -- return; -+ switchInt(copy _1) -> [1: bb1, 2: bb2, otherwise: bb3]; + _0 = const 999_u64; + goto -> bb6; + } + + bb6: { + return; } } diff --git a/tests/mir-opt/early_otherwise_branch.rs b/tests/mir-opt/early_otherwise_branch.rs index 99bd0d65cf470..54406f41f8fc1 100644 --- a/tests/mir-opt/early_otherwise_branch.rs +++ b/tests/mir-opt/early_otherwise_branch.rs @@ -159,6 +159,15 @@ fn target_self(val: i32) { // EMIT_MIR early_otherwise_branch.dont_hoist_deref.EarlyOtherwiseBranch.diff #[custom_mir(dialect = "runtime")] fn dont_hoist_deref(q: u64, p: *const u64) -> u64 { + // The dereference of `p` cannot be hoisted because the `otherwise` branch + // can be taken without dereferencing `p`. + // Hoisting the dereference could therefore cause UB when `p` is null. + // Hoisting a dereference also requires proving that the dereference is safe to reorder. + // CHECK-LABEL: fn dont_hoist_deref( + // CHECK: bb0: { + // CHECK-NEXT: switchInt(copy _1) + // CHECK: switchInt(copy (*_2)) + // CHECK: switchInt(copy (*_2)) mir! { { match q { diff --git a/tests/ui/mir/hoist_deref_early_else.rs b/tests/ui/mir/hoist_deref_early_else.rs index 06e31bcb0b3ad..fb749e96d7c08 100644 --- a/tests/ui/mir/hoist_deref_early_else.rs +++ b/tests/ui/mir/hoist_deref_early_else.rs @@ -1,7 +1,6 @@ //! Regression test for issue . //! The null pointer `p` should never be dereferenced. -//@[noopt] run-pass -//@[opt] run-crash +//@ run-pass //@ revisions: noopt opt //@ check-run-results //@[noopt] compile-flags: -C opt-level=0 From 6c5df713317b31612051b9f741d7d8b236a2aab6 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 20 Jul 2026 18:47:13 +0200 Subject: [PATCH 26/68] 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 27/68] 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 28/68] 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 29/68] 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 30/68] 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 31/68] 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 32/68] 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 33/68] 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 34/68] 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 35/68] 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 36/68] 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 37/68] 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 38/68] 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 39/68] 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 40/68] 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 41/68] 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 fe9408070ec51de32a609fbd1245b062a12509f4 Mon Sep 17 00:00:00 2001 From: Senthilnathan Date: Wed, 22 Jul 2026 19:04:22 +0530 Subject: [PATCH 42/68] 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 d5482401250fef44346e03ab35df9e1fac005016 Mon Sep 17 00:00:00 2001 From: Senthilnathan Date: Thu, 23 Jul 2026 11:03:10 +0530 Subject: [PATCH 43/68] 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 f46856816629ab21354fd766225e9dea9540c388 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 09:38:06 +0200 Subject: [PATCH 44/68] 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 45/68] 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 46/68] 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 47/68] 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 48/68] 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 49/68] 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 50/68] 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 51/68] 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 e9ad00c5af1c7c57e2d84c96a5b255485a0a83c7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 Dec 2025 20:25:58 +0000 Subject: [PATCH 52/68] Remove 'static requirement on try_as_dyn --- .../src/const_eval/eval_queries.rs | 1 + .../rustc_const_eval/src/interpret/util.rs | 5 +- compiler/rustc_const_eval/src/lib.rs | 1 + compiler/rustc_hir_analysis/src/collect.rs | 6 ++ .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 + compiler/rustc_hir_typeck/src/opaque_types.rs | 1 + compiler/rustc_infer/src/infer/mod.rs | 3 + .../rustc_infer/src/infer/opaque_types/mod.rs | 3 +- .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 6 ++ compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_middle/src/queries.rs | 9 ++ .../src/ty/context/impl_interner.rs | 4 + compiler/rustc_middle/src/ty/generics.rs | 76 +++++++++++++++- compiler/rustc_middle/src/ty/mod.rs | 64 +++++++++++++- .../rustc_mir_transform/src/elaborate_drop.rs | 1 + .../src/solve/assembly/mod.rs | 2 + .../src/solve/eval_ctxt/mod.rs | 54 +++++++----- .../src/solve/normalizes_to.rs | 1 + .../src/solve/project_goals/opaque_types.rs | 4 +- .../src/solve/search_graph.rs | 1 + .../src/solve/trait_goals.rs | 11 ++- .../src/solve/delegate.rs | 1 + .../src/solve/fulfill.rs | 1 + .../src/traits/fulfill.rs | 1 + .../src/traits/normalize.rs | 4 +- .../src/traits/project.rs | 1 + .../src/traits/query/normalize.rs | 2 +- .../src/traits/select/mod.rs | 43 +++++++-- compiler/rustc_ty_utils/src/instance.rs | 1 + compiler/rustc_ty_utils/src/layout.rs | 2 + compiler/rustc_type_ir/src/infer_ctxt.rs | 29 ++++++ compiler/rustc_type_ir/src/interner.rs | 2 + .../rustc_type_ir/src/region_constraint.rs | 1 + compiler/rustc_type_ir/src/relate/combine.rs | 1 + library/core/src/any.rs | 20 ++--- library/coretests/tests/mem/trait_info_of.rs | 1 + tests/ui/any/non_static.rs | 88 +++++++++++++++++++ tests/ui/any/static_method_bound.rs | 34 +++++++ 39 files changed, 436 insertions(+), 52 deletions(-) create mode 100644 tests/ui/any/non_static.rs create mode 100644 tests/ui/any/static_method_bound.rs diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 57ccbb8ff10ea..b2c6663e41085 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -44,6 +44,7 @@ fn retry_codegen_mode_with_postanalysis<'tcx, K: TypeVisitable>, V> | ty::TypingMode::Typeck { .. } | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } + | ty::TypingMode::Reflection | ty::TypingMode::PostAnalysis => {} } diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index cbef1de487c43..1b23432c8c57a 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -29,7 +29,10 @@ pub(crate) fn type_implements_dyn_trait<'tcx, M: Machine<'tcx>>( ); }; - let (infcx, param_env) = ecx.tcx.infer_ctxt().build_with_typing_env(ecx.typing_env); + let (infcx, param_env) = ecx.tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::new( + ecx.typing_env.param_env, + ty::TypingMode::Reflection, + )); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| { diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 5b63379edd332..7fe32b4e75ffb 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -33,6 +33,7 @@ fn assert_typing_mode(typing_mode: ty::TypingMode<'_>) { // `InterpCx::new` for more details. ty::TypingMode::Coherence | ty::TypingMode::Typeck { .. } + | ty::TypingMode::Reflection | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } => bug!( "Const eval should always happens in PostAnalysis or Codegen mode. See the comment on `assert_typing_mode` for more details." diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b520ea106dfa0..605b6e3751ef3 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -85,6 +85,7 @@ pub(crate) fn provide(providers: &mut Providers) { adt_def, fn_sig, impl_trait_header, + impl_is_fully_generic_for_reflection, coroutine_kind, coroutine_for_closure, opaque_ty_origin, @@ -1395,6 +1396,11 @@ pub fn suggest_impl_trait<'tcx>( None } +fn impl_is_fully_generic_for_reflection(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + tcx.impl_trait_header(def_id).is_fully_generic_for_reflection() + && tcx.explicit_predicates_of(def_id).is_fully_generic_for_reflection() +} + fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader<'_> { let icx = ItemCtxt::new(tcx, def_id); let item = tcx.hir_expect_item(def_id); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9a1b1f8300957..137351dfcdd5b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -696,6 +696,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { defining_opaque_types_and_generators } ty::TypingMode::Coherence + | ty::TypingMode::Reflection | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } | ty::TypingMode::PostAnalysis diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 797077d97c133..17e193d7f44ab 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -103,6 +103,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { defining_opaque_types_and_generators } ty::TypingMode::Coherence + | ty::TypingMode::Reflection | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } | ty::TypingMode::PostAnalysis diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index af1f5de717a60..72820a31a95b9 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -354,6 +354,7 @@ impl<'tcx> Drop for InferCtxt<'tcx> { TypingMode::Coherence | TypingMode::Typeck { .. } | TypingMode::PostBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => {} // In erased mode, the opaque type storage is always empty @@ -1171,6 +1172,7 @@ impl<'tcx> InferCtxt<'tcx> { // and post-borrowck analysis mode. We may need to modify its uses // to support PostBorrowck in the old solver as well. TypingMode::Coherence + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen => false, @@ -1505,6 +1507,7 @@ impl<'tcx> InferCtxt<'tcx> { mode @ (ty::TypingMode::Coherence | ty::TypingMode::PostBorrowck { .. } | ty::TypingMode::PostAnalysis + | ty::TypingMode::Reflection | ty::TypingMode::Codegen) => mode, ty::TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(), }; diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 2d05e33e44891..08c7c49417124 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -285,7 +285,8 @@ impl<'tcx> InferCtxt<'tcx> { } mode @ (ty::TypingMode::PostBorrowck { .. } | ty::TypingMode::PostAnalysis - | ty::TypingMode::Codegen) => { + | ty::TypingMode::Codegen + | ty::TypingMode::Reflection) => { bug!("insert hidden type in {mode:?}") } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 2a138154f7020..9acebc1a4822f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -241,6 +241,7 @@ provide! { tcx, def_id, other, cdata, fn_sig => { table } codegen_fn_attrs => { table } impl_trait_header => { table } + impl_is_fully_generic_for_reflection => { table_direct } const_param_default => { table } object_lifetime_default => { table } thir_abstract_const => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 8fa0c1b2dcdd8..602c5ee0201dd 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2197,6 +2197,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let header = tcx.impl_trait_header(def_id); record!(self.tables.impl_trait_header[def_id] <- header); + let impl_is_fully_generic_for_reflection = + tcx.impl_is_fully_generic_for_reflection(def_id); + self.tables + .impl_is_fully_generic_for_reflection + .set(def_id.index, impl_is_fully_generic_for_reflection); + self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id)); let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4847ddda90fd1..237672878bb4c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -413,6 +413,7 @@ define_tables! { constness: Table, safety: Table, defaultness: Table, + impl_is_fully_generic_for_reflection: Table, - optional: attributes: Table>, diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index cbd54ec959c6a..387bf3f6f8c1f 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -1098,6 +1098,15 @@ rustc_queries! { separate_provide_extern } + /// Whether all generic parameters of the type are unique unconstrained generic parameters + /// of the impl. `Bar<'static>` or `Foo<'a, 'a>` or outlives bounds on the lifetimes cause + /// this boolean to be false and `try_as_dyn` to return `None`. + query impl_is_fully_generic_for_reflection(impl_id: DefId) -> bool { + desc { "computing trait implemented by `{}`", tcx.def_path_str(impl_id) } + cache_on_disk + separate_provide_extern + } + /// Given an `impl_def_id`, return true if the self type is guaranteed to be unsized due /// to either being one of the built-in unsized types (str/slice/dyn) or to be a struct /// whose tail is one of those types. diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 052a937cf5017..222a70753311a 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -703,6 +703,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.impl_polarity(impl_def_id) } + fn is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool { + self.impl_is_fully_generic_for_reflection(impl_def_id) + } + fn trait_is_auto(self, trait_def_id: DefId) -> bool { self.trait_is_auto(trait_def_id) } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 02ac0586c33ae..9a6b3dbea1ef3 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -1,14 +1,16 @@ +use std::ops::ControlFlow; + use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_macros::{StableHash, TyDecodable, TyEncodable}; use rustc_span::{Span, Symbol, kw}; +use rustc_type_ir::{TypeSuperVisitable as _, TypeVisitable, TypeVisitor}; use tracing::instrument; use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt, Unnormalized}; -use crate::ty; use crate::ty::region::RegionExt; -use crate::ty::{EarlyBinder, GenericArgsRef}; +use crate::ty::{self, ClauseKind, EarlyBinder, GenericArgsRef, Region, RegionKind, TyKind}; #[derive(Clone, Debug, TyEncodable, TyDecodable, StableHash)] pub enum GenericParamDefKind { @@ -456,6 +458,76 @@ impl<'tcx> GenericPredicates<'tcx> { instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| Unnormalized::new(*p))); instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); } + + /// Allow simple where bounds like `T: Debug`, but prevent any kind of + /// outlives bounds or uses of generic parameters on the right hand side. + /// + /// We allow simple bounds because when the `T` actually gets substituted with a concrete type + /// during monomorphization, we will be checking its `Debug` impl for fully_generic_for_reflection. + /// + /// Constants (associated or generic) are irrelevant for this analysis, as their value is neither + /// affected by lifetimes, nor do they affect lifetimes. + pub fn is_fully_generic_for_reflection(self) -> bool { + struct ParamChecker; + impl<'tcx> TypeVisitor> for ParamChecker { + type Result = ControlFlow<()>; + fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result { + match r.kind() { + RegionKind::ReEarlyParam(_) | RegionKind::ReStatic | RegionKind::ReError(_) => { + ControlFlow::Break(()) + } + RegionKind::ReVar(_) + | RegionKind::RePlaceholder(_) + | RegionKind::ReErased + | RegionKind::ReLateParam(_) => { + bug!("unexpected lifetime in impl: {r:?}") + } + RegionKind::ReBound(..) => ControlFlow::Continue(()), + } + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + match t.kind() { + TyKind::Param(_p) => { + // Reject using parameters used in the type in where bounds + return ControlFlow::Break(()); + } + TyKind::Alias(..) => return ControlFlow::Break(()), + _ => (), + } + t.super_visit_with(self) + } + } + + // Pessimistic: if any of the parameters have where bounds + // don't allow this impl to be used. + self.predicates.iter().all(|(clause, _)| { + match clause.kind().skip_binder() { + ClauseKind::Trait(trait_predicate) => { + // In a `T: Trait`, if the rhs bound does not contain any generic params + // or 'static lifetimes, then it cannot transitively cause such requirements, + // considering we apply the fully-generic-for-reflection rules to any impls for + // that trait, too. + if matches!(trait_predicate.self_ty().kind(), ty::Param(_)) + && trait_predicate.trait_ref.args[1..] + .iter() + .all(|arg| arg.visit_with(&mut ParamChecker).is_continue()) + { + return true; + } + } + ClauseKind::RegionOutlives(_) + | ClauseKind::TypeOutlives(_) + | ClauseKind::Projection(_) + | ClauseKind::ConstArgHasType(_, _) + | ClauseKind::WellFormed(_) + | ClauseKind::ConstEvaluatable(_) + | ClauseKind::HostEffect(_) + | ClauseKind::UnstableFeature(_) => {} + } + clause.visit_with(&mut ParamChecker).is_continue() + }) + } } /// `[const]` bounds for a given item. This is represented using a struct much like diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9b582eeb2c520..379df48fc899f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -16,6 +16,7 @@ use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use std::num::NonZero; +use std::ops::ControlFlow; use std::ptr::NonNull; use std::{assert_matches, fmt, iter, str}; @@ -30,7 +31,7 @@ use rustc_abi::{ use rustc_ast::node_id::NodeMap; use rustc_ast::{self as ast, NodeId}; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; use rustc_data_structures::steal::Steal; @@ -309,6 +310,65 @@ pub struct ImplTraitHeader<'tcx> { pub constness: hir::Constness, } +impl<'tcx> ImplTraitHeader<'tcx> { + /// For trait impls, checks whether + /// * the type and trait only use generic lifetime arguments (and no concrete ones like `'static`), and + /// * uses each generic param (lifetime or type) only once. + /// Pessimistic analysis, so it will reject alias types + /// and other types that may be actually ok. We can allow more in the future. + /// + /// Constants (associated or generic) are irrelevant for this analysis, as their value is neither + /// affected by lifetimes, nor do they affect lifetimes. + pub fn is_fully_generic_for_reflection(self) -> bool { + #[derive(Default)] + struct ParamFinder { + seen: FxHashSet, + } + + impl<'tcx> TypeVisitor> for ParamFinder { + type Result = ControlFlow<()>; + fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result { + match r.kind() { + RegionKind::ReEarlyParam(param) => { + if self.seen.insert(param.index) { + ControlFlow::Continue(()) + } else { + ControlFlow::Break(()) + } + } + RegionKind::ReBound(..) | RegionKind::ReLateParam(_) => { + ControlFlow::Continue(()) + } + RegionKind::ReStatic + | RegionKind::ReVar(_) + | RegionKind::RePlaceholder(_) + | RegionKind::ReErased + | RegionKind::ReError(_) => ControlFlow::Break(()), + } + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + match t.kind() { + TyKind::Param(p) => { + // Reject using a parameter twice (e.g. in `Foo`) + if !self.seen.insert(p.index) { + return ControlFlow::Break(()); + } + } + TyKind::Alias(..) => return ControlFlow::Break(()), + _ => (), + } + t.super_visit_with(self) + } + } + self.trait_ref + .instantiate_identity() + .skip_norm_wip() + .visit_with(&mut ParamFinder::default()) + .is_continue() + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, StableHash, Debug)] #[derive(TypeFoldable, TypeVisitable, Default)] pub enum Asyncness { @@ -1178,6 +1238,7 @@ impl<'tcx> TypingEnv<'tcx> { let TypingEnv { typing_mode, param_env } = self; match typing_mode.0.assert_not_erased() { TypingMode::Coherence + | TypingMode::Reflection | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => {} @@ -1194,6 +1255,7 @@ impl<'tcx> TypingEnv<'tcx> { let TypingEnv { typing_mode, param_env } = self; match typing_mode.0.assert_not_erased() { TypingMode::Coherence + | TypingMode::Reflection | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 8b21e8284476b..c2c702dbf2470 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -802,6 +802,7 @@ where match self.elaborator.typing_env().typing_mode().assert_not_erased() { ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => {} ty::TypingMode::Coherence + | ty::TypingMode::Reflection | ty::TypingMode::Typeck { .. } | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } => { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 6d111ff44d415..290e49c8a33a4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -483,6 +483,7 @@ where TypingMode::Coherence => true, TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen @@ -1066,6 +1067,7 @@ where | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis + | TypingMode::Reflection | TypingMode::Codegen => vec![], TypingMode::ErasedNotCoherence(MayBeErased) => { self.opaque_accesses diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index c3ccb46069063..16f8f3496d9e7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -566,28 +566,34 @@ where .entered(); let (result, orig_values, canonical_goal, succeeded_in_erased) = 'retry_canonicalize: { - let skip_erased_attempt = if typing_mode.is_coherence() { - true - } else { - let mut skip = false; - if opaque_types.iter().any(|(_, ty)| ty.is_ty_var()) - && let PredicateKind::Clause(ClauseKind::Trait(..)) = + let skip_erased_attempt = match typing_mode { + TypingMode::Reflection | TypingMode::Coherence => true, + TypingMode::Typeck { .. } + | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::PostBorrowck { .. } + | TypingMode::Codegen + | TypingMode::PostAnalysis + | TypingMode::ErasedNotCoherence(_) => { + let mut skip = false; + if opaque_types.iter().any(|(_, ty)| ty.is_ty_var()) + && let PredicateKind::Clause(ClauseKind::Trait(..)) = + goal.predicate.kind().skip_binder() + { + skip = true; + } + + if let PredicateKind::Clause(ClauseKind::Trait(tr)) = goal.predicate.kind().skip_binder() - { - skip = true; - } + && tr.self_ty().has_coroutines() + && self.cx().trait_is_auto(tr.trait_ref.def_id) + { + // FIXME(#155443): this doesn't make a difference now, but with eager normalization + // it likely will. + // skip_erased_attempt = true; + } - if let PredicateKind::Clause(ClauseKind::Trait(tr)) = - goal.predicate.kind().skip_binder() - && tr.self_ty().has_coroutines() - && self.cx().trait_is_auto(tr.trait_ref.def_id) - { - // FIXME(#155443): this doesn't make a difference now, but with eager normalization - // it likely will. - // skip_erased_attempt = true; + skip } - - skip }; if skip_erased_attempt { @@ -1649,9 +1655,10 @@ fn should_rerun_after_erased_canonicalization( // ============================= (RerunCondition::Always, _) => RerunDecision::Yes, // ============================= - (RerunCondition::OpaqueInStorage(..), TypingMode::PostAnalysis | TypingMode::Codegen) => { - RerunDecision::Yes - } + ( + RerunCondition::OpaqueInStorage(..), + TypingMode::PostAnalysis | TypingMode::Codegen | TypingMode::Reflection, + ) => RerunDecision::Yes, ( RerunCondition::OpaqueInStorage(defids), TypingMode::PostBorrowck { defined_opaque_types: opaques } @@ -1667,12 +1674,13 @@ fn should_rerun_after_erased_canonicalization( TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen + | TypingMode::Reflection | TypingMode::PostTypeckUntilBorrowck { .. }, ) => RerunDecision::No, // ============================= ( RerunCondition::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(_), - TypingMode::PostAnalysis | TypingMode::Codegen, + TypingMode::PostAnalysis | TypingMode::Codegen | TypingMode::Reflection, ) => RerunDecision::Yes, ( RerunCondition::OpaqueInStorageOrAnyOpaqueHasInferAsHidden(defids), diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 582cd122c8ecf..fd5f1a3f82b86 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -348,6 +348,7 @@ where | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } | ty::TypingMode::PostAnalysis + | ty::TypingMode::Reflection | ty::TypingMode::Codegen => { ecx.instantiate_normalizes_to_as_rigid(goal)?; return ecx.evaluate_added_goals_and_make_canonical_response( diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs index 7524b2021c015..3387c8599b911 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/opaque_types.rs @@ -106,6 +106,7 @@ where TypingMode::Coherence | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis + | TypingMode::Reflection | TypingMode::Codegen => unreachable!(), } } @@ -149,7 +150,8 @@ where self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) .map_err(Into::into) } - TypingMode::PostAnalysis | TypingMode::Codegen => { + // FIXME(try_as_dyn): probably want to treat opaques opaquely and rigid + TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => { // FIXME: Add an assertion that opaque type storage is empty. let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args); let actual = self.normalize(GoalSource::Misc, goal.param_env, actual)?; diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index 778826ba60aee..4918258350bf3 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -70,6 +70,7 @@ where } TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 2ebea5d3eb188..50ccfa84a70be 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -87,7 +87,15 @@ where // Impl matches polarity (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive) - | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => Certainty::Yes, + | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => { + if ecx.typing_mode().is_reflection() + && !cx.is_fully_generic_for_reflection(impl_def_id) + { + return Err(NoSolution.into()); + } else { + Certainty::Yes + } + } // Impl doesn't match polarity (ty::ImplPolarity::Positive, ty::PredicatePolarity::Negative) @@ -1607,6 +1615,7 @@ where } TypingMode::Coherence | TypingMode::PostAnalysis + | TypingMode::Reflection | TypingMode::Codegen | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } => {} diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 605f4d6758a5a..f5a30d2b26563 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -384,6 +384,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< TypingMode::Coherence | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } => false, TypingMode::PostAnalysis | TypingMode::Codegen => { let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 8d5d8f26f9dce..a61c679c9870f 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -340,6 +340,7 @@ where TypingMode::Coherence | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } + | TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => return Default::default(), }; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 95f0c3dc9881d..4ec21b9f8a4cd 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -178,6 +178,7 @@ where TypingMode::Coherence | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } + | TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => return Default::default(), }; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 9364482a87cb8..b822c713bfabb 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -144,7 +144,7 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), - TypingMode::PostAnalysis | TypingMode::Codegen => {} + TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => {} } value.has_type_flags(flags) @@ -433,7 +433,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => ty.super_fold_with(self), - TypingMode::PostAnalysis | TypingMode::Codegen => { + TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e0edc76682a3b..79b531afbe2ae 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -991,6 +991,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( TypingMode::Coherence | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } => { debug!( assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index ac6100747970e..fb15ed8a74c07 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -220,7 +220,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } => ty.try_super_fold_with(self)?, - TypingMode::PostAnalysis | TypingMode::Codegen => { + TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => { let args = data.args.try_fold_with(self)?; let recursion_limit = self.cx().recursion_limit(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7c9ae9246c96b..f94aa9bcb754c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -17,7 +17,7 @@ use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::relate::TypeRelation; -use rustc_infer::traits::{PredicateObligations, TraitObligation}; +use rustc_infer::traits::{ImplSource, PredicateObligations, TraitObligation}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::bug; use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; @@ -282,6 +282,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(SelectionError::Overflow(OverflowError::Canonical)) } Err(e) => Err(e), + Ok(ImplSource::Builtin(..)) if self.typing_mode().is_reflection() => { + // Builtin impls regularly don't satisfy the try_as_dyn requirements, so + // we just reject all of them. + Err(SelectionError::Unimplemented) + } Ok(candidate) => Ok(Some(candidate)), } } @@ -1299,6 +1304,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match this.confirm_candidate(stack.obligation, candidate.clone()) { Ok(selection) => { debug!(?selection); + if let ImplSource::Builtin(..) = selection + && this.typing_mode().is_reflection() + { + return Ok(EvaluatedToErr); + } this.evaluate_predicates_recursively( stack.list(), selection.nested_obligations().into_iter(), @@ -1485,6 +1495,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { TypingMode::Coherence => {} TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen => return Ok(()), @@ -1536,6 +1547,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { defining_opaque_types.is_empty() || (!pred.has_opaque_types() && !pred.has_coroutines()) } + // Impls that are not fully generic are completely ignored as "nonexistent" + // in this mode, so the results wildly differ from normal trait solving. + TypingMode::Reflection => false, // The hidden types of `defined_opaque_types` is not local to the current // inference context, so we can freely move this to the global cache. TypingMode::PostBorrowck { .. } => true, @@ -2569,11 +2583,27 @@ impl<'tcx> SelectionContext<'_, 'tcx> { })?; nested_obligations.extend(obligations); - if impl_trait_header.polarity == ty::ImplPolarity::Reservation - && !self.typing_mode().is_coherence() - { - debug!("reservation impls only apply in intercrate mode"); - return Err(()); + match self.typing_mode() { + TypingMode::Coherence => {} + TypingMode::Reflection + if !self.tcx().impl_is_fully_generic_for_reflection(impl_def_id) => + { + debug!("reflection mode only allows fully generic impls"); + return Err(()); + } + + TypingMode::Typeck { .. } + | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::PostBorrowck { .. } + | TypingMode::Codegen + | TypingMode::ErasedNotCoherence(_) + | TypingMode::Reflection + | TypingMode::PostAnalysis => { + if impl_trait_header.polarity == ty::ImplPolarity::Reservation { + debug!("reservation impls only apply in intercrate mode"); + return Err(()); + } + } } Ok(Normalized { value: impl_args, obligations: nested_obligations }) @@ -2916,6 +2946,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } TypingMode::Coherence | TypingMode::PostAnalysis + | TypingMode::Reflection | TypingMode::Codegen | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ } | TypingMode::PostBorrowck { defined_opaque_types: _ } => false, diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index d9069ac127729..b5a82793dcc97 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -167,6 +167,7 @@ fn resolve_associated_item<'tcx>( ty::TypingMode::Coherence | ty::TypingMode::Typeck { .. } | ty::TypingMode::PostTypeckUntilBorrowck { .. } + | ty::TypingMode::Reflection | ty::TypingMode::PostBorrowck { .. } => false, ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => { !trait_ref.still_further_specializable() diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index abec1850502b6..7a53fe1e0cfc8 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -87,6 +87,7 @@ fn layout_of<'tcx>( | ty::TypingMode::Typeck { .. } | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } + | ty::TypingMode::Reflection | ty::TypingMode::ErasedNotCoherence(_) | ty::TypingMode::PostAnalysis => {} } @@ -552,6 +553,7 @@ fn layout_of_uncached<'tcx>( | ty::TypingMode::Typeck { .. } | ty::TypingMode::PostTypeckUntilBorrowck { .. } | ty::TypingMode::PostBorrowck { .. } + | ty::TypingMode::Reflection | ty::TypingMode::ErasedNotCoherence(_) | ty::TypingMode::PostAnalysis => { return Err(error(cx, LayoutError::TooGeneric(ty))); diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 75f906e498eda..c652119957dd4 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -123,6 +123,10 @@ pub enum TypingMode { /// This is currently only used by the new solver, but should be implemented in /// the old solver as well. PostBorrowck { defined_opaque_types: I::LocalDefIds }, + /// During the evaluation of reflection logic that ignores lifetimes, we can only + /// handle impls that are fully generic over all lifetimes without constraints on + /// those lifetimes (other than implied bounds). + Reflection, /// After analysis, mostly during MIR optimizations, we're able to /// reveal all opaque types. As the hidden type should *never* be observable /// directly by the user, this should not be used by checks which may expose @@ -173,6 +177,7 @@ impl PartialEq for TypingModeEqWrapper { fn eq(&self, other: &Self) -> bool { match (self.0, other.0) { (TypingMode::Coherence, TypingMode::Coherence) => true, + (TypingMode::Reflection, TypingMode::Reflection) => true, ( TypingMode::Typeck { defining_opaque_types_and_generators: l }, TypingMode::Typeck { defining_opaque_types_and_generators: r }, @@ -193,6 +198,7 @@ impl PartialEq for TypingModeEqWrapper { ) => true, ( TypingMode::Coherence + | TypingMode::Reflection | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } @@ -218,6 +224,25 @@ impl TypingMode { TypingMode::Coherence => true, TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection + | TypingMode::PostBorrowck { .. } + | TypingMode::PostAnalysis + | TypingMode::Codegen + | TypingMode::ErasedNotCoherence(_) => false, + } + } + + /// There are a bunch of places in the compiler where we single out `Reflection`, + /// and alter behavior. We'd like to *always* match on `TypingMode` exhaustively, + /// but not having this method leads to a bunch of noisy code. + /// + /// See also the documentation on [`TypingMode`] about exhaustive matching. + pub fn is_reflection(&self) -> bool { + match self { + TypingMode::Reflection => true, + TypingMode::Typeck { .. } + | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Coherence | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen @@ -236,6 +261,7 @@ impl TypingMode { TypingMode::Coherence | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis | TypingMode::Codegen => false, @@ -262,6 +288,7 @@ impl TypingMode { } TypingMode::PostAnalysis => TypingMode::PostAnalysis, TypingMode::Codegen => TypingMode::Codegen, + TypingMode::Reflection => TypingMode::Reflection, TypingMode::ErasedNotCoherence(MayBeErased) => panic!( "Called `assert_not_erased` from a place that can be called by the trait solver in `TypingMode::ErasedNotCoherence`. `TypingMode` is `ErasedNotCoherence` in a place where that should be impossible" ), @@ -327,6 +354,7 @@ impl From> for TypingMode TypingMode::PostAnalysis, TypingMode::Codegen => TypingMode::Codegen, + TypingMode::Reflection => TypingMode::Reflection, } } } @@ -563,6 +591,7 @@ where TypingMode::Coherence | TypingMode::Typeck { .. } | TypingMode::PostTypeckUntilBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis => infcx.cx().features().feature_bound_holds_in_crate(symbol), TypingMode::Codegen => true, diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 565414fdd58e3..bfa1c982bd0b7 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -423,6 +423,8 @@ pub trait Interner: fn impl_polarity(self, impl_def_id: Self::ImplId) -> ty::ImplPolarity; + fn is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool; + fn trait_is_auto(self, trait_def_id: Self::TraitId) -> bool; fn trait_is_coinductive(self, trait_def_id: Self::TraitId) -> bool; diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index b4ec6dbf5126d..e42e96901b74d 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -914,6 +914,7 @@ fn rewrite_type_outlives_constraints_in_universe_for_eager_placeholder_handling< | TypingMode::ErasedNotCoherence { .. } | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } + | TypingMode::Reflection | TypingMode::PostAnalysis | TypingMode::Codegen => (), }; diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 9ac4cd2dddc81..66eb27074ee30 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -180,6 +180,7 @@ where Ok(a) } TypingMode::Typeck { .. } + | TypingMode::Reflection | TypingMode::PostTypeckUntilBorrowck { .. } | TypingMode::PostBorrowck { .. } | TypingMode::PostAnalysis diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 6c8cb114b9ef1..f518ec810b572 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -86,7 +86,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::intrinsics::{self, type_id_vtable}; +use crate::intrinsics::{self, type_id, type_id_vtable}; use crate::mem::transmute; use crate::mem::type_info::{TraitImpl, TypeKind}; use crate::{fmt, hash, ptr}; @@ -786,12 +786,12 @@ impl TypeId { #[unstable(feature = "type_info", issue = "146922")] #[rustc_const_unstable(feature = "type_info", issue = "146922")] #[rustc_comptime] - pub fn trait_info_of> + ?Sized + 'static>( + pub fn trait_info_of> + ?Sized>( self, ) -> Option> { // SAFETY: The vtable was obtained for `T`, so it is guaranteed to be `DynMetadata`. // The intrinsic can't infer this because it is designed to work with arbitrary TypeIds. - unsafe { transmute(self.trait_info_of_trait_type_id(const { TypeId::of::() })) } + unsafe { transmute(self.trait_info_of_trait_type_id(const { type_id::() })) } } /// Checks if the [TypeId] implements the trait of `trait_represented_by_type_id`. If it does it returns [TraitImpl] which can be used to build a fat pointer. @@ -983,17 +983,14 @@ pub const fn type_name_of_val(_val: &T) -> &'static str { /// ``` #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] -pub const fn try_as_dyn< - T: Any + ?Sized + 'static, - U: ptr::Pointee> + ?Sized + 'static, ->( +pub const fn try_as_dyn> + ?Sized>( t: &T, ) -> Option<&U> { // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is // only supported for sized types). The function therefore unconditionally // returns `None` in that case. let vtable: Option> = - const { TypeId::of::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; + const { type_id::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; match vtable { Some(dyn_metadata) => { let pointer = ptr::from_raw_parts(t as *const T as *const (), dyn_metadata); @@ -1042,17 +1039,14 @@ pub const fn try_as_dyn< /// ``` #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] -pub const fn try_as_dyn_mut< - T: Any + ?Sized + 'static, - U: ptr::Pointee> + ?Sized + 'static, ->( +pub const fn try_as_dyn_mut> + ?Sized>( t: &mut T, ) -> Option<&mut U> { // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is // only supported for sized types). The function therefore unconditionally // returns `None` in that case. let vtable: Option> = - const { TypeId::of::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; + const { type_id::().trait_info_of::().as_ref().map(TraitImpl::get_vtable) }; match vtable { Some(dyn_metadata) => { let pointer = ptr::from_raw_parts_mut(t as *mut T as *mut (), dyn_metadata); diff --git a/library/coretests/tests/mem/trait_info_of.rs b/library/coretests/tests/mem/trait_info_of.rs index c723a96095815..4fd4a013693d9 100644 --- a/library/coretests/tests/mem/trait_info_of.rs +++ b/library/coretests/tests/mem/trait_info_of.rs @@ -10,6 +10,7 @@ impl Blah for Garlic { self.0 * 21 } } +unsafe impl Send for Garlic {} #[test] fn test_implements_trait() { diff --git a/tests/ui/any/non_static.rs b/tests/ui/any/non_static.rs new file mode 100644 index 0000000000000..ad04b7f475e0b --- /dev/null +++ b/tests/ui/any/non_static.rs @@ -0,0 +1,88 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@check-pass +#![feature(try_as_dyn)] + +trait Trait {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&&42_i32).is_none()); +}; + +impl<'a> Trait for &'a [(); 1] {} +const _: () = { + let x = (); + assert!(std::any::try_as_dyn::<_, dyn Trait>(&&[x]).is_some()); +}; + +type Foo = &'static [(); 2]; + +// Ensure type aliases don't skip these checks +impl Trait for Foo {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&&[(), ()]).is_none()); +}; + +impl Trait for &() {} +const _: () = { + let x = (); + assert!(std::any::try_as_dyn::<_, dyn Trait>(&&x).is_some()); +}; + +impl Trait for () {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&()).is_some()); +}; + +// Not fully generic impl -> returns None even tho +// implemented for *some* lifetimes +impl<'a> Trait for (&'a (), &'a ()) {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&(&(), &())).is_none()); +}; + +// Not fully generic impl -> returns None even tho +// implemented for *some* lifetimes +impl<'a, 'b: 'a> Trait for (&'a (), &'b (), ()) {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&(&(), &(), ())).is_none()); +}; + +// Only valid for 'static lifetimes -> returns None +// even though we are actually using a `'static` lifetime. +// We can't know what lifetimes are there during codegen, so +// we pessimistically assume it could be a shorter one +impl Trait for &'static u32 {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&&42_u32).is_none()); +}; + +trait Trait2 {} + +struct Struct(T); + +// While this is the impl for `Trait`, in `Reflection` solver mode +// we reject the impl for `Trait2` below, and thus this impl also +// doesn't match. +impl Trait for Struct {} + +impl Trait2 for &'static u32 {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait>(&Struct(&42_u32)).is_none()); +}; + +const _: () = { + trait Homo {} + impl Homo for (T, T) {} + + // Let's pick `T = &'_ i32`. + assert!(std::any::try_as_dyn::<_, dyn Homo>(&(&42_i32, &27_i32)).is_none()); +}; + +trait Trait3<'a> {} + +impl Trait3<'static> for () {} +const _: () = { + assert!(std::any::try_as_dyn::<_, dyn Trait3<'_>>(&()).is_none()); +}; + +fn main() {} diff --git a/tests/ui/any/static_method_bound.rs b/tests/ui/any/static_method_bound.rs new file mode 100644 index 0000000000000..aaab8623868f1 --- /dev/null +++ b/tests/ui/any/static_method_bound.rs @@ -0,0 +1,34 @@ +//@run-fail +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +type Payload = Box; + +trait Trait { + fn as_static(&self) -> &'static Payload + where + Self: 'static; +} + +impl<'a> Trait for &'a Payload { + fn as_static(&self) -> &'static Payload + where + Self: 'static, + { + *self + } +} + +fn main() { + let storage: Box = Box::new(Box::new(1i32)); + let wrong: &'static Payload = extend(&*storage); + drop(storage); + println!("{wrong}"); +} + +fn extend(a: &Payload) -> &'static Payload { + // TODO: should panic at the `unwrap` here + let b: &(dyn Trait + 'static) = try_as_dyn::<&Payload, dyn Trait + 'static>(&a).unwrap(); + b.as_static() +} From b111aec99d1ca1ce4cce79406173ff76f0481754 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 13 Jan 2026 13:43:04 +0000 Subject: [PATCH 53/68] Add helper trait that restricts lifetimes and extra predicates to ensure soundness --- compiler/rustc_hir/src/lang_items.rs | 2 + compiler/rustc_middle/src/traits/select.rs | 2 + .../src/ty/context/impl_interner.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 15 ++- .../src/solve/assembly/mod.rs | 24 ++++ .../src/solve/effect_goals.rs | 7 ++ .../src/solve/normalizes_to.rs | 7 ++ .../src/solve/trait_goals.rs | 49 ++++++++- compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/select/candidate_assembly.rs | 34 +++++- .../src/traits/select/confirmation.rs | 33 ++++++ .../src/traits/select/mod.rs | 1 + compiler/rustc_type_ir/src/lang_items.rs | 1 + library/core/src/any.rs | 104 +++++++++++------- .../src/library-features/try-as-dyn.md | 90 +++++++++++++++ tests/ui/any/any_static.next.stderr | 16 +++ tests/ui/any/any_static.old.stderr | 16 +++ tests/ui/any/any_static.rs | 22 ++++ tests/ui/any/builtin_bound.rs | 23 ++++ tests/ui/any/hrtb.next.stderr | 9 ++ tests/ui/any/hrtb.old.stderr | 9 ++ tests/ui/any/hrtb.rs | 19 ++++ tests/ui/any/hrtb2.next.stderr | 9 ++ tests/ui/any/hrtb2.old.stderr | 9 ++ tests/ui/any/hrtb2.rs | 19 ++++ tests/ui/any/non_static.rs | 1 + tests/ui/any/reject_manual_impl.rs | 29 +++++ tests/ui/any/reject_manual_impl.stderr | 46 ++++++++ tests/ui/any/static_method_bound.rs | 3 +- tests/ui/any/static_method_bound.stderr | 16 +++ tests/ui/any/trait_info_of.next.stderr | 14 +++ tests/ui/any/trait_info_of.old.stderr | 14 +++ tests/ui/any/trait_info_of.rs | 45 ++++++++ tests/ui/any/try_as_dyn.rs | 7 +- tests/ui/any/try_as_dyn_assoc_ty_lifetime.rs | 27 +++++ tests/ui/any/try_as_dyn_builtin_impl.rs | 48 ++++++++ tests/ui/any/try_as_dyn_elaborated_bounds.rs | 29 +++++ tests/ui/any/try_as_dyn_generic_impl.rs | 40 +++++++ .../any/try_as_dyn_generic_trait.next.stderr | 9 ++ .../any/try_as_dyn_generic_trait.old.stderr | 9 ++ tests/ui/any/try_as_dyn_generic_trait.rs | 26 +++++ tests/ui/any/try_as_dyn_mut.rs | 5 +- tests/ui/any/try_as_dyn_soundness_test1.rs | 15 +-- tests/ui/any/try_as_dyn_soundness_test2.rs | 11 +- .../vtable-try-as-dyn.full-debuginfo.stderr | 6 +- .../vtable-try-as-dyn.no-debuginfo.stderr | 6 +- .../reflection/trait_info_of_too_big.stderr | 2 +- 47 files changed, 853 insertions(+), 77 deletions(-) create mode 100644 src/doc/unstable-book/src/library-features/try-as-dyn.md create mode 100644 tests/ui/any/any_static.next.stderr create mode 100644 tests/ui/any/any_static.old.stderr create mode 100644 tests/ui/any/any_static.rs create mode 100644 tests/ui/any/builtin_bound.rs create mode 100644 tests/ui/any/hrtb.next.stderr create mode 100644 tests/ui/any/hrtb.old.stderr create mode 100644 tests/ui/any/hrtb.rs create mode 100644 tests/ui/any/hrtb2.next.stderr create mode 100644 tests/ui/any/hrtb2.old.stderr create mode 100644 tests/ui/any/hrtb2.rs create mode 100644 tests/ui/any/reject_manual_impl.rs create mode 100644 tests/ui/any/reject_manual_impl.stderr create mode 100644 tests/ui/any/static_method_bound.stderr create mode 100644 tests/ui/any/trait_info_of.next.stderr create mode 100644 tests/ui/any/trait_info_of.old.stderr create mode 100644 tests/ui/any/trait_info_of.rs create mode 100644 tests/ui/any/try_as_dyn_assoc_ty_lifetime.rs create mode 100644 tests/ui/any/try_as_dyn_builtin_impl.rs create mode 100644 tests/ui/any/try_as_dyn_elaborated_bounds.rs create mode 100644 tests/ui/any/try_as_dyn_generic_impl.rs create mode 100644 tests/ui/any/try_as_dyn_generic_trait.next.stderr create mode 100644 tests/ui/any/try_as_dyn_generic_trait.old.stderr create mode 100644 tests/ui/any/try_as_dyn_generic_trait.rs diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 1592dfdde4e6f..92f48cda10f9f 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -194,6 +194,8 @@ language_item_table! { CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1); DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1); + TryAsDyn, sym::try_as_dyn, try_as_dyn, Target::Trait, GenericRequirement::Exact(1); + // lang items relating to transmutability TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0); TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(2); diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 92f7ed0cb19f6..a2eecebcc3501 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -180,6 +180,8 @@ pub enum SelectionCandidate<'tcx> { BuiltinUnsizeCandidate, BikeshedGuaranteedNoDropCandidate, + + TryAsDynCandidate, } /// The result of trait evaluation. The order is important diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 222a70753311a..0f5ec3e04ddce 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -938,6 +938,7 @@ bidirectional_lang_item_map! { Sized, TransmuteTrait, TrivialClone, + TryAsDyn, Tuple, Unpin, Unsize, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 379df48fc899f..151ca10b85ef6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -313,8 +313,9 @@ pub struct ImplTraitHeader<'tcx> { impl<'tcx> ImplTraitHeader<'tcx> { /// For trait impls, checks whether /// * the type and trait only use generic lifetime arguments (and no concrete ones like `'static`), and - /// * uses each generic param (lifetime or type) only once. - /// Pessimistic analysis, so it will reject alias types + /// * uses any generic param (lifetime or type) only once. + /// + /// This is a pessimistic analysis, so it will reject alias types /// and other types that may be actually ok. We can allow more in the future. /// /// Constants (associated or generic) are irrelevant for this analysis, as their value is neither @@ -336,14 +337,12 @@ impl<'tcx> ImplTraitHeader<'tcx> { ControlFlow::Break(()) } } - RegionKind::ReBound(..) | RegionKind::ReLateParam(_) => { - ControlFlow::Continue(()) - } - RegionKind::ReStatic - | RegionKind::ReVar(_) + RegionKind::ReBound(..) => ControlFlow::Continue(()), + RegionKind::ReStatic | RegionKind::ReError(_) => ControlFlow::Break(()), + RegionKind::ReVar(_) | RegionKind::RePlaceholder(_) | RegionKind::ReErased - | RegionKind::ReError(_) => ControlFlow::Break(()), + | RegionKind::ReLateParam(_) => bug!("unexpected lifetime in impl: {r:?}"), } } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 290e49c8a33a4..040f98de7bcfd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -365,6 +365,11 @@ where goal: Goal, ) -> Result, NoSolutionOrRerunNonErased>; + fn consider_builtin_try_as_dyn_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolutionOrRerunNonErased>; + /// Consider (possibly several) candidates to upcast or unsize a type to another /// type, excluding the coercion of a sized type into a `dyn Trait`. /// @@ -569,6 +574,14 @@ where let cx = self.cx(); let trait_def_id = goal.predicate.trait_def_id(cx); + // Builtin impls regularly are not `is_fully_generic_for_reflection`, so instead + // of trying to handle these manually, we just reject all builtin impls in reflection + // mode. We can probably lift this restriction for specific cases, but this is safer. + // See `try_as_dyn_builtin_impl` for how just allowing all builtin impls is unsound. + if self.typing_mode().is_reflection() { + return Ok(()); + } + // N.B. When assembling built-in candidates for lang items that are also // `auto` traits, then the auto trait candidate that is assembled in // `consider_auto_trait_candidate` MUST be disqualified to remain sound. @@ -661,6 +674,9 @@ where Some(SolverTraitLangItem::BikeshedGuaranteedNoDrop) => { G::consider_builtin_bikeshed_guaranteed_no_drop_candidate(self, goal) } + Some(SolverTraitLangItem::TryAsDyn) => { + G::consider_builtin_try_as_dyn_candidate(self, goal) + } Some(SolverTraitLangItem::Field) => G::consider_builtin_field_candidate(self, goal), _ => Err(NoSolution.into()), } @@ -873,6 +889,14 @@ where return; } + // Builtin impls regularly are not `is_fully_generic_for_reflection`, so instead + // of trying to handle these manually, we just reject all builtin impls in reflection + // mode. We can probably lift this restriction for specific cases, but this is safer. + // See `try_as_dyn_builtin_impl` for how just allowing all builtin impls is unsound. + if self.typing_mode().is_reflection() { + return; + } + let self_ty = goal.predicate.self_ty(); let bounds = match self_ty.kind() { ty::Bool diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 1c53bc7711ed8..df9758d5d2ab7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -451,6 +451,13 @@ where unreachable!("BikeshedGuaranteedNoDrop is not const"); } + fn consider_builtin_try_as_dyn_candidate( + _ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolutionOrRerunNonErased> { + unreachable!("`TryAsDynCompat` is not const: {:?}", goal) + } + fn consider_structural_builtin_unsize_candidates( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index fd5f1a3f82b86..069102f3db50b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -1077,6 +1077,13 @@ where ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } + + fn consider_builtin_try_as_dyn_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolutionOrRerunNonErased> { + unreachable!("try_as_dyn helper trait doesn't have assoc types") + } } impl EvalCtxt<'_, D> diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 50ccfa84a70be..f29df578cd97b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -10,9 +10,9 @@ use rustc_type_ir::solve::{ RerunReason, RerunResultExt, SizedTraitKind, }; use rustc_type_ir::{ - self as ty, FieldInfo, Interner, MayBeErased, Movability, PredicatePolarity, Region, - TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _, - elaborate, + self as ty, ExistentialPredicate, FieldInfo, Interner, MayBeErased, Movability, + PredicatePolarity, Region, TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode, + Unnormalized, Upcast as _, elaborate, }; use tracing::{debug, instrument, trace, warn}; @@ -873,6 +873,49 @@ where } } + fn consider_builtin_try_as_dyn_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolutionOrRerunNonErased> { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { + return Err(NoSolution.into()); + } + let cx = ecx.cx(); + + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { + let self_ty = goal.predicate.self_ty(); + let ty_lifetime = goal.predicate.trait_ref.args.region_at(1); + match self_ty.kind() { + ty::Dynamic(bounds, lifetime) => { + for bound in bounds.iter() { + match bound.skip_binder() { + ExistentialPredicate::Trait(_) => {} + // FIXME(try_as_dyn): check what kind of projections we can allow + ExistentialPredicate::Projection(_) => return Err(NoSolution.into()), + // Auto traits do not affect lifetimes outside of specialization, + // which is disabled in reflection. + ExistentialPredicate::AutoTrait(_) => {} + } + } + ecx.add_goal( + GoalSource::Misc, + goal.with(cx, ty::OutlivesPredicate(ty_lifetime, lifetime)), + )?; + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + + ty::Bound(..) + | ty::Infer( + ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_), + ) => { + panic!("unexpected type `{self_ty:?}`") + } + + _ => Err(NoSolution.into()), + } + }) + } + fn consider_builtin_field_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7917478cc2c60..95421ba8cfdab 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2139,6 +2139,7 @@ symbols! { truncf32, truncf64, truncf128, + try_as_dyn, try_blocks, try_blocks_heterogeneous, try_capture, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index a4f751e23d799..d4027fcf388b1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -15,7 +15,8 @@ use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind}; use rustc_infer::traits::{Obligation, PolyTraitObligation, PredicateObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ - self, FieldInfo, SizedTraitKind, TraitRef, Ty, TypeVisitableExt, elaborate, + self, ExistentialPredicate, FieldInfo, SizedTraitKind, TraitRef, Ty, TypeVisitableExt, + elaborate, }; use rustc_middle::{bug, span_bug}; use rustc_span::DUMMY_SP; @@ -132,6 +133,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut candidates, ); } + Some(LangItem::TryAsDyn) => { + self.assemble_candidates_for_try_as_dyn(obligation, &mut candidates); + } Some(LangItem::Field) => { self.assemble_candidates_for_field_trait(obligation, &mut candidates); } @@ -1457,6 +1461,34 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + fn assemble_candidates_for_try_as_dyn( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + match *obligation.predicate.self_ty().skip_binder().kind() { + ty::Dynamic(bounds, _lifetime) => { + for bound in bounds { + match bound.skip_binder() { + ExistentialPredicate::Trait(_) => {} + // FIXME(try_as_dyn): check what kind of projections we can allow + ExistentialPredicate::Projection(_) => return, + // Auto traits do not affect lifetimes outside of specialization, + // which is disabled in reflection. + ExistentialPredicate::AutoTrait(_) => {} + } + } + candidates.vec.push(TryAsDynCandidate); + } + + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + candidates.ambiguous = true; + } + + _ => {} + } + } + fn assemble_candidates_for_field_trait( &mut self, obligation: &PolyTraitObligation<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a7c84e71a68c5..49c277b39289b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -138,6 +138,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { BikeshedGuaranteedNoDropCandidate => { self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation) } + + TryAsDynCandidate => self.confirm_try_as_dyn_candidate(obligation), }) } @@ -1315,4 +1317,35 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::Builtin(BuiltinImplSource::Misc, obligations) } + + fn confirm_try_as_dyn_candidate( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + ) -> ImplSource<'tcx, PredicateObligation<'tcx>> { + let tcx = self.tcx(); + + let mut obligations = PredicateObligations::new(); + + let self_ty = obligation.predicate.self_ty(); + let ty_lifetime = obligation.predicate.map_bound(|p| p.trait_ref.args.region_at(1)); + + match *self_ty.skip_binder().kind() { + ty::Dynamic(_bounds, lifetime) => { + obligations.push( + obligation.with( + tcx, + ty_lifetime + .map_bound(|ty_lifetime| ty::OutlivesPredicate(ty_lifetime, lifetime)), + ), + ); + } + + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + panic!("unexpected type `{self_ty:?}`") + } + + _ => {} + } + ImplSource::Builtin(BuiltinImplSource::Misc, obligations) + } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f94aa9bcb754c..58f2d0c7f33ac 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2073,6 +2073,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | TraitUpcastingUnsizeCandidate(_) | BuiltinObjectCandidate | BuiltinUnsizeCandidate + | TryAsDynCandidate | BikeshedGuaranteedNoDropCandidate => false, // Non-global param candidates have already been handled, global // where-bounds get ignored. diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 05f9bb382dc38..1671128e67a3a 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -54,6 +54,7 @@ pub enum SolverTraitLangItem { Sized, TransmuteTrait, TrivialClone, + TryAsDyn, Tuple, Unpin, Unsize, diff --git a/library/core/src/any.rs b/library/core/src/any.rs index f518ec810b572..85ff2fe1dd6ee 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -786,9 +786,7 @@ impl TypeId { #[unstable(feature = "type_info", issue = "146922")] #[rustc_const_unstable(feature = "type_info", issue = "146922")] #[rustc_comptime] - pub fn trait_info_of> + ?Sized>( - self, - ) -> Option> { + pub fn trait_info_of<'a, T: TryAsDynCompatible<'a> + ?Sized>(self) -> Option> { // SAFETY: The vtable was obtained for `T`, so it is guaranteed to be `DynMetadata`. // The intrinsic can't infer this because it is designed to work with arbitrary TypeIds. unsafe { transmute(self.trait_info_of_trait_type_id(const { type_id::() })) } @@ -948,12 +946,72 @@ pub const fn type_name_of_val(_val: &T) -> &'static str { type_name::() } -/// Returns `Some(&U)` if `T` can be coerced to the trait object type `U`. Otherwise, it returns `None`. +/// Trait that is automatically implemented for all `dyn Trait<'b, C> + 'a` without assoc type bounds. +/// The lifetime parameter should be the same that is used to constrain generic type parameters +/// that are turned into the dyn trait constrained by `TryAsDynCompatible`. +/// +/// This is required for `try_as_dyn` to be able to soundly convert non-static +/// types to `dyn Trait`. +/// +/// Note: these requirements are sufficient for soundness, but it is unclear +/// if they are all necessary. We may be able to lift some requirements in favor +/// of more precise ones. +/// +#[unstable(feature = "try_as_dyn", issue = "144361")] +#[lang = "try_as_dyn"] +#[rustc_deny_explicit_impl] +pub trait TryAsDynCompatible<'a>: ptr::Pointee> {} + +/// Returns `Some(&U)` if `T` can be coerced to the dyn trait type `U`. Otherwise, it returns `None`. +/// +/// # Run-time failures +/// +/// There are multiple ways to get a `None`, and you need to manually analyze which one it is, as the +/// compiler does not provide any help here. +/// +/// * `T` does not implement `Trait` at all, +/// * `T`'s impl for `Trait` is not fully generic, +/// * `T`'s impl for `Trait` is a builtin impl (e.g. `dyn Debug` implements `Debug`) +/// +/// There is some detailed documentation about this feature at +/// +/// But the gist is summarized below: +/// +/// ## Lifetime-independent impls +/// +/// `try_as_dyn` does not have access to lifetime information, thus it cannot differentiate between +/// `'static`, other lifetimes, and can't reason about outlives bounds on impls. Thus we can only accept +/// impls that do not have `'static` lifetimes, or outlives bounds of any kind. You can have simple +/// trait bounds, and the compiler will transitively only use impls of those simple trait bounds that satisfy +/// the same rules as the main trait you're converting to. +/// +/// An example of a legal impl is: +/// +/// ```rust +/// # trait Trait<'a, T> {} +/// # struct Type<'b, U>(&'b U); +/// # use std::fmt::{Debug, Display}; +/// impl<'a, 'b, T: Debug, U: Display> Trait<'a, T> for Type<'b, U> {} +/// ``` +/// +/// Impls without generic parameters at all are also legal, as long as they contain no `'static` lifetimes. +/// +/// ## Builtin impls +/// +/// Builtin impls (like `impl Debug for dyn Debug`) have various obscure rules and often are not fully generic. +/// To simplify reasoning about what is allowed and what not, all builtin impls are rejected and will neither +/// directly nor indirectly contribute to a `Some` result. /// /// # Compile-time failures -/// Determining whether `T` can be coerced to the trait object type `U` requires compiler trait resolution. +/// Determining whether `T` can be coerced to the dyn trait type `U` requires compiler trait resolution. /// In some cases, that resolution can exceed the recursion limit, /// and compilation will fail instead of this function returning `None`. +/// +/// The input type `T` must outlive the lifetime `'a` on the `dyn Trait + 'a`. +/// This is basically the same rule that forbids `let x: &dyn Trait + 'static = &&some_local_variable;` +/// So if you see borrow check errors around `try_as_dyn`, think about whether a normal unsizing +/// coercion would be possible at all if you were using concrete types or had bounds on the input type. +/// /// # Examples /// /// ```rust @@ -983,7 +1041,7 @@ pub const fn type_name_of_val(_val: &T) -> &'static str { /// ``` #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] -pub const fn try_as_dyn> + ?Sized>( +pub const fn try_as_dyn<'a, T: ?Sized + 'a, U: TryAsDynCompatible<'a> + ?Sized>( t: &T, ) -> Option<&U> { // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is @@ -1006,40 +1064,10 @@ pub const fn try_as_dyn &'static str; -/// } -/// -/// struct Dog; -/// impl Animal for Dog { -/// fn speak(&self) -> &'static str { "woof" } -/// } -/// -/// struct Rock; // does not implement Animal -/// -/// let mut dog = Dog; -/// let mut rock = Rock; -/// -/// let as_animal: Option<&mut dyn Animal> = try_as_dyn_mut::(&mut dog); -/// assert_eq!(as_animal.unwrap().speak(), "woof"); -/// -/// let not_an_animal: Option<&mut dyn Animal> = try_as_dyn_mut::(&mut rock); -/// assert!(not_an_animal.is_none()); -/// ``` +/// See documentation of [try_as_dyn] for details about the behaviour and limitations. #[must_use] #[unstable(feature = "try_as_dyn", issue = "144361")] -pub const fn try_as_dyn_mut> + ?Sized>( +pub const fn try_as_dyn_mut<'a, T: ?Sized + 'a, U: TryAsDynCompatible<'a> + ?Sized>( t: &mut T, ) -> Option<&mut U> { // For unsized `T`, `trait_info_of` always returns `None` (vtable lookup is diff --git a/src/doc/unstable-book/src/library-features/try-as-dyn.md b/src/doc/unstable-book/src/library-features/try-as-dyn.md new file mode 100644 index 0000000000000..81abde709c6dc --- /dev/null +++ b/src/doc/unstable-book/src/library-features/try-as-dyn.md @@ -0,0 +1,90 @@ +# `try_as_dyn` + +The tracking issue for this feature is: [#144361] + +[#144361]: https://github.com/rust-lang/rust/issues/144361 + +------------------------ + +The `try_as_dyn` feature allows going from a generic `T` with no bounds +to a `dyn Trait`, if `T: Trait` and various conditions are upheld. It is +very related to specialization, as it allows you to specialize within +function bodies, but in a more general manner than `Any::downcast`. + +```rust +#![feature(try_as_dyn)] + +fn downcast_debug_format(t: &T) -> String { + match std::any::try_as_dyn::<_, dyn std::fmt::Debug>(t) { + Some(d) => format!("{d:?}"), + None => "default".to_string() + } +} +``` + + +## Rules and reasons for them + +> [!IMPORTANT] +> The main problem of **`try_as_dyn` and specialization is the compiler's inability, while trait-checking, to distinguish/_discriminate_ between any two given lifetimes**[^1]. + +[^1]: the compiler cannot _branch_ on whether "`'a : 'b` holds": for soundness, it can either choose not to know the answer, or _assume_ that it holds and produce an obligation for the borrow-checker which shall "assert this" (making compilation fail in a fatal manner if not). Most usages of Rust lie in the latter category (typical `where` clauses anywhere), whilst specialization/`try_as_dyn()` wants to support fallibility of the operation (_i.e._, being queried on a type not fulfilling the predicate without causing a compilation error). This rules out the latter, resulting in the need for the former, _i.e._, for the `try_as_dyn()` attempt to unconditionally "fail" with `None`. + +### `'static` is not mentioned anywhere in the `impl` block header. + +The most obvious one: if you have `impl IsStatic for &'static str`, then determining whether `&'? str : IsStatic` does hold amounts to discriminating `'? : 'static`. + +### Each outlives `where` bound (`Type: 'a` and `'a: 'b`) does not mention lifetime-infected parameters. + +Parameters are considered lifetime-infected if they are defined in an `impl` block's generic parameter list. +Const generics are excempt, as they can't affect lifetimes. +`for<'a>` lifetimes (and in the future types) are not lifetime-infected. + +We can create lifetime discrimination this way. For instance, given `impl<'a, 'b> Outlives<'a> for &'b str where 'b : 'a {}`, `Outlives<'static>` amounts to `IsStatic` from previous bullet. + +### Each lifetime-infected parameter is mentioned at most once in the `Self` type and the implemented trait's generic parameters, combined. + +Repetition of a parameter entails equality of those two use-sites; in lifetime-terms, this would be a double `'a : 'b` / `'b : 'a` clause, for instance. +Follow-up from the previous example: `impl<'a> Uses<'a> for &'a str {}`, and check whether `&'? str : Uses<'static>`. + +### Each individual trait where bound (`Type: Trait`) mentions each lifetime-infected parameter at most once. + +Mentioning a lifetime-infected parameter in multiple `where` bounds is allowed. + +Looking at the previous rules, which focuses on `Self : …`, this is just observing that shifting the requirements to other parameters within `where` clauses \[ought to\] boil down to the same set of issues. + +This is _unnecessarily restrictive_: we should be able to loosen it up somehow. Repetition only in `where` clauses seems fine. + + +### The `impl` block is a handwritten impl + +as opposed to a type implementing a trait automatically by the compiler (such as auto-traits, `dyn Bounds… : Bounds…`, and closures) + + +The reason for this is that some such auto-generated impls _come with hidden bounds or whatnot_, which run afoul of the previous rules, whilst also being _extremely challenging for the current compiler logic to know of such bounds_. +IIUC, this restriction could be lifted in the future should the compiler logic be better at spotting these hidden bounds, when present. + +One contrived such example being the case of `dyn 'u + for<'a> Outlives<'a>`, where the compiler-generated `impl` for it of `Outlives` is: `impl<'b, 'u> Outlives<'b> for dyn 'u + for<'a> Outlives<'a> where 'b : 'u {}` which violates the "`'a: 'b` not to mention lt-infected params" rule, whilst also being hard to detect in current compiler logic. + +### Associated type projections (`::Assoc`) are not mentioned anywhere in the `impl` block header. + +Associated-type equality bounds can very much amount to lifetime-infected parameter equality constraints, +which are problematic as per the "at most one mention of each lifetime-infected parameter in header" rule. +To illustrate, with the following definitions, `&'? str: Trait<'static>` discriminates `'?` against `'static`: +```rust +trait Trait<'x> {} +impl<'a, 'b> Trait<'b> for &'a str +where + // &'a str = &'b str, + Option<&'a str>: IntoIterator, +{} +``` + +```rust +trait Trait<'x> {} +impl<'a> Trait<'a> for &'a str {} +``` + +### Each trait `where` bound with an associated type equality (`Type: Trait`) does not mention lifetime-infected parameters. + +Checking whether `Option<&'? str>: IntoIterator` holds discriminates `'?` against `'static`. diff --git a/tests/ui/any/any_static.next.stderr b/tests/ui/any/any_static.next.stderr new file mode 100644 index 0000000000000..e57d544140980 --- /dev/null +++ b/tests/ui/any/any_static.next.stderr @@ -0,0 +1,16 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/any_static.rs:18:35 + | +LL | fn extend(a: &Payload) -> &'static Payload { + | - - let's call the lifetime of this reference `'1` + | | + | `a` is a reference that is only valid in the function body +LL | let b: &(dyn Any + 'static) = try_as_dyn::<&Payload, dyn Any + 'static>(&a).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `a` escapes the function body here + | argument requires that `'1` must outlive `'static` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/any/any_static.old.stderr b/tests/ui/any/any_static.old.stderr new file mode 100644 index 0000000000000..e57d544140980 --- /dev/null +++ b/tests/ui/any/any_static.old.stderr @@ -0,0 +1,16 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/any_static.rs:18:35 + | +LL | fn extend(a: &Payload) -> &'static Payload { + | - - let's call the lifetime of this reference `'1` + | | + | `a` is a reference that is only valid in the function body +LL | let b: &(dyn Any + 'static) = try_as_dyn::<&Payload, dyn Any + 'static>(&a).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `a` escapes the function body here + | argument requires that `'1` must outlive `'static` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/any/any_static.rs b/tests/ui/any/any_static.rs new file mode 100644 index 0000000000000..7305cabfa8c16 --- /dev/null +++ b/tests/ui/any/any_static.rs @@ -0,0 +1,22 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +#![feature(try_as_dyn)] + +use std::any::{Any, try_as_dyn}; + +type Payload = Box; + +fn main() { + let storage: Box = Box::new(Box::new(1i32)); + let wrong: &'static Payload = extend(&*storage); + drop(storage); + println!("{wrong}"); +} + +fn extend(a: &Payload) -> &'static Payload { + let b: &(dyn Any + 'static) = try_as_dyn::<&Payload, dyn Any + 'static>(&a).unwrap(); + //~^ ERROR: borrowed data escapes outside of function + let c: &&'static Payload = b.downcast_ref::<&'static Payload>().unwrap(); + *c +} diff --git a/tests/ui/any/builtin_bound.rs b/tests/ui/any/builtin_bound.rs new file mode 100644 index 0000000000000..8c4bcf7ad2e3f --- /dev/null +++ b/tests/ui/any/builtin_bound.rs @@ -0,0 +1,23 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass +#![feature(try_as_dyn)] + +trait Trait {} + +// In contrast to `T: Sized`, `Struct: Sized` does not go +// through a fast path, and is thus rejected by the builtin impl +// check that rejects all builtin impls in reflection mode. +// FIXME(try_as_dyn): should probably allow builtin impls that +// are never lifetime dependent (like Sized). +impl Trait for Struct where Struct: Sized {} + +struct Struct(T); + +const _: () = { + let x = Struct(42); + assert!(std::any::try_as_dyn::<_, dyn Trait>(&x).is_none()); +}; + +fn main() {} diff --git a/tests/ui/any/hrtb.next.stderr b/tests/ui/any/hrtb.next.stderr new file mode 100644 index 0000000000000..385b3c3cf2212 --- /dev/null +++ b/tests/ui/any/hrtb.next.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value + --> $DIR/hrtb.rs:15:25 + | +LL | let _dy: &dyn Bar = try_as_dyn(&x).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/any/hrtb.old.stderr b/tests/ui/any/hrtb.old.stderr new file mode 100644 index 0000000000000..385b3c3cf2212 --- /dev/null +++ b/tests/ui/any/hrtb.old.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value + --> $DIR/hrtb.rs:15:25 + | +LL | let _dy: &dyn Bar = try_as_dyn(&x).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/any/hrtb.rs b/tests/ui/any/hrtb.rs new file mode 100644 index 0000000000000..ab31529a0d207 --- /dev/null +++ b/tests/ui/any/hrtb.rs @@ -0,0 +1,19 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait Foo<'a, 'b> {} + +trait Bar {} +impl Foo<'a, 'b> + ?Sized> Bar for Option<*const T> {} + +const _: () = { + let x: Option<*const dyn for<'a> Foo<'a, 'a>> = None; + let _dy: &dyn Bar = try_as_dyn(&x).unwrap(); + //~^ ERROR: `Option::unwrap()` on a `None` value +}; + +fn main() {} diff --git a/tests/ui/any/hrtb2.next.stderr b/tests/ui/any/hrtb2.next.stderr new file mode 100644 index 0000000000000..dfe000dc503a8 --- /dev/null +++ b/tests/ui/any/hrtb2.next.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value + --> $DIR/hrtb2.rs:15:25 + | +LL | let _dy: &dyn Bar = try_as_dyn(&x).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/any/hrtb2.old.stderr b/tests/ui/any/hrtb2.old.stderr new file mode 100644 index 0000000000000..dfe000dc503a8 --- /dev/null +++ b/tests/ui/any/hrtb2.old.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value + --> $DIR/hrtb2.rs:15:25 + | +LL | let _dy: &dyn Bar = try_as_dyn(&x).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/any/hrtb2.rs b/tests/ui/any/hrtb2.rs new file mode 100644 index 0000000000000..ee1bd7cde8982 --- /dev/null +++ b/tests/ui/any/hrtb2.rs @@ -0,0 +1,19 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait Foo<'a> {} + +trait Bar {} +impl Bar for Option<*const T> where T: for<'a> Foo<'a> {} + +const _: () = { + let x: Option<*const dyn Foo<'_>> = None; + let _dy: &dyn Bar = try_as_dyn(&x).unwrap(); + //~^ ERROR: `Option::unwrap()` on a `None` value +}; + +fn main() {} diff --git a/tests/ui/any/non_static.rs b/tests/ui/any/non_static.rs index ad04b7f475e0b..40d7bb7bf5469 100644 --- a/tests/ui/any/non_static.rs +++ b/tests/ui/any/non_static.rs @@ -1,5 +1,6 @@ //@ revisions: next old //@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@check-pass #![feature(try_as_dyn)] diff --git a/tests/ui/any/reject_manual_impl.rs b/tests/ui/any/reject_manual_impl.rs new file mode 100644 index 0000000000000..590cebd48950f --- /dev/null +++ b/tests/ui/any/reject_manual_impl.rs @@ -0,0 +1,29 @@ +#![feature(try_as_dyn)] + +use std::any::TryAsDynCompatible; + +struct Foo(dyn Iterator); + +impl TryAsDynCompatible<'static> for Foo {} +//~^ ERROR: explicit impls for the `TryAsDynCompatible` trait are not permitted + +struct Bar(dyn Iterator); + +impl<'a> TryAsDynCompatible<'a> for Bar {} +//~^ ERROR: explicit impls for the `TryAsDynCompatible` trait are not permitted + +struct Baz; + +impl<'a> TryAsDynCompatible<'a> for Baz {} +//~^ ERROR: explicit impls for the `TryAsDynCompatible` trait are not permitted + +trait Trait {} + +impl<'a> TryAsDynCompatible<'a> for dyn Trait {} +//~^ ERROR: explicit impls for the `TryAsDynCompatible` trait are not permitted + +impl TryAsDynCompatible<'static> for dyn Iterator {} +//~^ ERROR: explicit impls for the `TryAsDynCompatible` trait are not permitted +//~| ERROR: only traits defined in the current crate can be implemented for arbitrary types + +fn main() {} diff --git a/tests/ui/any/reject_manual_impl.stderr b/tests/ui/any/reject_manual_impl.stderr new file mode 100644 index 0000000000000..37be37c47ea79 --- /dev/null +++ b/tests/ui/any/reject_manual_impl.stderr @@ -0,0 +1,46 @@ +error[E0322]: explicit impls for the `TryAsDynCompatible` trait are not permitted + --> $DIR/reject_manual_impl.rs:7:1 + | +LL | impl TryAsDynCompatible<'static> for Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `TryAsDynCompatible` not allowed + +error[E0322]: explicit impls for the `TryAsDynCompatible` trait are not permitted + --> $DIR/reject_manual_impl.rs:12:1 + | +LL | impl<'a> TryAsDynCompatible<'a> for Bar {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `TryAsDynCompatible` not allowed + +error[E0322]: explicit impls for the `TryAsDynCompatible` trait are not permitted + --> $DIR/reject_manual_impl.rs:17:1 + | +LL | impl<'a> TryAsDynCompatible<'a> for Baz {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `TryAsDynCompatible` not allowed + +error[E0322]: explicit impls for the `TryAsDynCompatible` trait are not permitted + --> $DIR/reject_manual_impl.rs:22:1 + | +LL | impl<'a> TryAsDynCompatible<'a> for dyn Trait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `TryAsDynCompatible` not allowed + +error[E0322]: explicit impls for the `TryAsDynCompatible` trait are not permitted + --> $DIR/reject_manual_impl.rs:25:1 + | +LL | impl TryAsDynCompatible<'static> for dyn Iterator {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `TryAsDynCompatible` not allowed + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/reject_manual_impl.rs:25:1 + | +LL | impl TryAsDynCompatible<'static> for dyn Iterator {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------ + | | + | `dyn Iterator` is not defined in the current crate + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0117, E0322. +For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/any/static_method_bound.rs b/tests/ui/any/static_method_bound.rs index aaab8623868f1..b2cc77e4d9cfe 100644 --- a/tests/ui/any/static_method_bound.rs +++ b/tests/ui/any/static_method_bound.rs @@ -1,4 +1,3 @@ -//@run-fail #![feature(try_as_dyn)] use std::any::try_as_dyn; @@ -28,7 +27,7 @@ fn main() { } fn extend(a: &Payload) -> &'static Payload { - // TODO: should panic at the `unwrap` here let b: &(dyn Trait + 'static) = try_as_dyn::<&Payload, dyn Trait + 'static>(&a).unwrap(); + //~^ ERROR: borrowed data escapes outside of function b.as_static() } diff --git a/tests/ui/any/static_method_bound.stderr b/tests/ui/any/static_method_bound.stderr new file mode 100644 index 0000000000000..152672d024ab1 --- /dev/null +++ b/tests/ui/any/static_method_bound.stderr @@ -0,0 +1,16 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/static_method_bound.rs:30:37 + | +LL | fn extend(a: &Payload) -> &'static Payload { + | - - let's call the lifetime of this reference `'1` + | | + | `a` is a reference that is only valid in the function body +LL | let b: &(dyn Trait + 'static) = try_as_dyn::<&Payload, dyn Trait + 'static>(&a).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `a` escapes the function body here + | argument requires that `'1` must outlive `'static` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/any/trait_info_of.next.stderr b/tests/ui/any/trait_info_of.next.stderr new file mode 100644 index 0000000000000..45bbbe4892937 --- /dev/null +++ b/tests/ui/any/trait_info_of.next.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `dyn Trait>: TryAsDynCompatible<'_>` is not satisfied + --> $DIR/trait_info_of.rs:30:30 + | +LL | .trait_info_of::>() + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `TryAsDynCompatible<'_>` is not implemented for `dyn Trait>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `TypeId::trait_info_of` + --> $SRC_DIR/core/src/any.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/any/trait_info_of.old.stderr b/tests/ui/any/trait_info_of.old.stderr new file mode 100644 index 0000000000000..45bbbe4892937 --- /dev/null +++ b/tests/ui/any/trait_info_of.old.stderr @@ -0,0 +1,14 @@ +error[E0277]: the trait bound `dyn Trait>: TryAsDynCompatible<'_>` is not satisfied + --> $DIR/trait_info_of.rs:30:30 + | +LL | .trait_info_of::>() + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `TryAsDynCompatible<'_>` is not implemented for `dyn Trait>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `TypeId::trait_info_of` + --> $SRC_DIR/core/src/any.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/any/trait_info_of.rs b/tests/ui/any/trait_info_of.rs new file mode 100644 index 0000000000000..5eb6742be506e --- /dev/null +++ b/tests/ui/any/trait_info_of.rs @@ -0,0 +1,45 @@ +//! Check that we can't use `TypeId::trait_info_of` to unsoundly skip +//! the try_as_dyn checks. + +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +#![feature(type_info, ptr_metadata, arbitrary_self_types_pointers)] + +use std::any::TypeId; +use std::ptr::{self, DynMetadata}; + +type Payload = Box; + +trait Trait { + type Assoc; + fn method(self: *const Self, value: Self::Assoc) -> &'static Payload; +} +struct Thing; +impl Trait for Thing { + type Assoc = &'static Payload; + fn method(self: *const Self, value: Self::Assoc) -> &'static Payload { + value + } +} + +fn extend<'a>(payload: &'a Payload) -> &'static Payload { + let metadata: DynMetadata> = const { + TypeId::of::() + .trait_info_of::>() + //~^ ERROR `dyn Trait>: TryAsDynCompatible<'_>` is not satisfied + .unwrap() + .get_vtable() + }; + let ptr: *const dyn Trait = + ptr::from_raw_parts(std::ptr::null::<()>(), metadata); + ptr.method(payload) +} + +fn main() { + let payload: Box = Box::new(Box::new(1i32)); + let wrong: &'static Payload = extend(&*payload); + drop(payload); + println!("{wrong}"); +} diff --git a/tests/ui/any/try_as_dyn.rs b/tests/ui/any/try_as_dyn.rs index ee220f797ced9..cf9ca7bd885da 100644 --- a/tests/ui/any/try_as_dyn.rs +++ b/tests/ui/any/try_as_dyn.rs @@ -1,3 +1,6 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ run-pass #![feature(try_as_dyn)] @@ -7,7 +10,7 @@ use std::fmt::Debug; fn debug_format_with_try_as_dyn(t: &T) -> String { match std::any::try_as_dyn::<_, dyn Debug>(t) { Some(d) => format!("{d:?}"), - None => "default".to_string() + None => "default".to_string(), } } @@ -16,7 +19,7 @@ fn main() { #[allow(dead_code)] #[derive(Debug)] struct A { - index: usize + index: usize, } let a = A { index: 42 }; let result = debug_format_with_try_as_dyn(&a); diff --git a/tests/ui/any/try_as_dyn_assoc_ty_lifetime.rs b/tests/ui/any/try_as_dyn_assoc_ty_lifetime.rs new file mode 100644 index 0000000000000..aa2056a7fc42c --- /dev/null +++ b/tests/ui/any/try_as_dyn_assoc_ty_lifetime.rs @@ -0,0 +1,27 @@ +//@check-pass +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait HasAssoc<'a> { + type Assoc; +} +struct Dummy; +impl<'a> HasAssoc<'a> for Dummy { + // Changing this to &'a i64 makes try_as_dyn succeed + type Assoc = &'static i64; +} + +trait Trait {} +impl Trait for i32 where for<'a> Dummy: HasAssoc<'a, Assoc = &'a i64> {} + +const _: () = { + let x = 1i32; + assert!(try_as_dyn::<_, dyn Trait>(&x).is_none()); +}; + +fn main() {} diff --git a/tests/ui/any/try_as_dyn_builtin_impl.rs b/tests/ui/any/try_as_dyn_builtin_impl.rs new file mode 100644 index 0000000000000..4ed06a78c2e36 --- /dev/null +++ b/tests/ui/any/try_as_dyn_builtin_impl.rs @@ -0,0 +1,48 @@ +#![feature(try_as_dyn)] +//@ run-fail +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +use std::any::{Any, try_as_dyn}; + +type Payload = Box; + +trait Outlives<'b>: 'b {} + +trait WithLt { + type Ref; +} +impl<'a> WithLt for dyn for<'b> Outlives<'b> + 'a { + type Ref = &'a Payload; +} + +struct Thing(T::Ref); + +trait Trait { + fn get(&self) -> &'static Payload; +} +impl Trait for Thing +where + T: WithLt + for<'b> Outlives<'b> + ?Sized, +{ + fn get(&self) -> &'static Payload { + let x: &::Ref = &self.0; + let y: &(dyn Any + 'static) = x; + let z: &&'static Payload = y.downcast_ref().unwrap(); + *z + } +} + +fn extend<'a>(payload: &'a Payload) -> &'static Payload { + let thing: Thing Outlives<'b> + 'a> = Thing(payload); + let dy: &dyn Trait = try_as_dyn(&thing).unwrap(); + dy.get() +} + +fn main() { + let payload: Box = Box::new(Box::new(1)); + let wrong: &'static Payload = extend(&*payload); + drop(payload); + println!("{wrong}"); +} diff --git a/tests/ui/any/try_as_dyn_elaborated_bounds.rs b/tests/ui/any/try_as_dyn_elaborated_bounds.rs new file mode 100644 index 0000000000000..b0357e4fcca2c --- /dev/null +++ b/tests/ui/any/try_as_dyn_elaborated_bounds.rs @@ -0,0 +1,29 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@check-pass + +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait Trait: 'static {} +trait Other {} +struct Foo(T); + +impl Trait for () {} +impl Trait for &'static () {} + +// This impl has an implied `T: 'static` bound, but that's +// not an issue, as we just ignore all `Trait` impls where +// that would be a relevant distinguisher. +impl Other for Foo {} + +const _: () = { + let foo = Foo(()); + assert!(try_as_dyn::, dyn Other>(&foo).is_some()); + let foo = Foo(&()); + assert!(try_as_dyn::, dyn Other>(&foo).is_none()); +}; + +fn main() {} diff --git a/tests/ui/any/try_as_dyn_generic_impl.rs b/tests/ui/any/try_as_dyn_generic_impl.rs new file mode 100644 index 0000000000000..21033312fe277 --- /dev/null +++ b/tests/ui/any/try_as_dyn_generic_impl.rs @@ -0,0 +1,40 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +#![feature(try_as_dyn)] +//@ check-pass + +use std::any::try_as_dyn; + +struct Thing(T); +trait Trait {} +impl Trait for Thing {} + +const _: () = { + let thing = Thing(1); + assert!(try_as_dyn::<_, dyn Trait>(&thing).is_some()); +}; + +struct Thing2(T); +impl Trait for Thing2 {} +struct NoDebug; + +const _: () = { + let thing = Thing2(1); + assert!(try_as_dyn::<_, dyn Trait>(&thing).is_some()); + let thing = Thing2(NoDebug); + assert!(try_as_dyn::<_, dyn Trait>(&thing).is_none()); +}; + +trait Trait2 {} +impl<'a, 'b> Trait2 for &'a &'b () {} + +struct Thing3(T); +impl Trait for Thing3 {} + +const _: () = { + let thing = Thing3(&&()); + assert!(try_as_dyn::<_, dyn Trait2>(&thing).is_none()); +}; + +fn main() {} diff --git a/tests/ui/any/try_as_dyn_generic_trait.next.stderr b/tests/ui/any/try_as_dyn_generic_trait.next.stderr new file mode 100644 index 0000000000000..99382f9a4032c --- /dev/null +++ b/tests/ui/any/try_as_dyn_generic_trait.next.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value + --> $DIR/try_as_dyn_generic_trait.rs:22:51 + | +LL | let convert: &dyn Convert<&'static Payload> = try_as_dyn(&payload).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/any/try_as_dyn_generic_trait.old.stderr b/tests/ui/any/try_as_dyn_generic_trait.old.stderr new file mode 100644 index 0000000000000..99382f9a4032c --- /dev/null +++ b/tests/ui/any/try_as_dyn_generic_trait.old.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation panicked: called `Option::unwrap()` on a `None` value + --> $DIR/try_as_dyn_generic_trait.rs:22:51 + | +LL | let convert: &dyn Convert<&'static Payload> = try_as_dyn(&payload).unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/any/try_as_dyn_generic_trait.rs b/tests/ui/any/try_as_dyn_generic_trait.rs new file mode 100644 index 0000000000000..630c071218fc8 --- /dev/null +++ b/tests/ui/any/try_as_dyn_generic_trait.rs @@ -0,0 +1,26 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +type Payload = *const i32; + +trait Convert { + fn convert(&self) -> &T; +} + +impl Convert for T { + fn convert(&self) -> &T { + self + } +} + +const _: () = { + let payload: Payload = std::ptr::null(); + let convert: &dyn Convert<&'static Payload> = try_as_dyn(&payload).unwrap(); + //~^ ERROR: `Option::unwrap()` on a `None` value +}; + +fn main() {} diff --git a/tests/ui/any/try_as_dyn_mut.rs b/tests/ui/any/try_as_dyn_mut.rs index ff7baa32ea874..a4fadb72d2823 100644 --- a/tests/ui/any/try_as_dyn_mut.rs +++ b/tests/ui/any/try_as_dyn_mut.rs @@ -1,3 +1,6 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ run-pass #![feature(try_as_dyn)] @@ -7,7 +10,7 @@ use std::fmt::{Error, Write}; fn try_as_dyn_mut_write(t: &mut T, s: &str) -> Result<(), Error> { match std::any::try_as_dyn_mut::<_, dyn Write>(t) { Some(w) => w.write_str(s), - None => Ok(()) + None => Ok(()), } } diff --git a/tests/ui/any/try_as_dyn_soundness_test1.rs b/tests/ui/any/try_as_dyn_soundness_test1.rs index 0772e9a2d77ee..4dfb5492e3a59 100644 --- a/tests/ui/any/try_as_dyn_soundness_test1.rs +++ b/tests/ui/any/try_as_dyn_soundness_test1.rs @@ -1,19 +1,16 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ run-pass #![feature(try_as_dyn)] use std::any::try_as_dyn; -trait Trait { +trait Trait {} -} - -impl Trait for for<'a> fn(&'a Box) { - -} - -fn store(_: &'static Box) { +impl Trait for for<'a> fn(&'a Box) {} -} +fn store(_: &'static Box) {} fn main() { let fn_ptr: fn(&'static Box) = store; diff --git a/tests/ui/any/try_as_dyn_soundness_test2.rs b/tests/ui/any/try_as_dyn_soundness_test2.rs index c16b50d0261ed..a9985384cd1e6 100644 --- a/tests/ui/any/try_as_dyn_soundness_test2.rs +++ b/tests/ui/any/try_as_dyn_soundness_test2.rs @@ -1,14 +1,13 @@ +//@ revisions: next old +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) //@ run-pass #![feature(try_as_dyn)] use std::any::try_as_dyn; -trait Trait { +trait Trait {} -} - -impl Trait fn(&'a Box)> for () { - -} +impl Trait fn(&'a Box)> for () {} fn main() { let dt = try_as_dyn::<_, dyn Trait)>>(&()); diff --git a/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr b/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr index c9c15e2d62c9f..c6a53d4face4f 100644 --- a/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr +++ b/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr @@ -1,15 +1,15 @@ error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture --> $SRC_DIR/core/src/any.rs:LL:COL | - = note: evaluation of `std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>::{constant#0}` failed inside this call -note: inside `TypeId::trait_info_of::` + = note: evaluation of `std::any::try_as_dyn::<'_, [u8; usize::MAX], dyn Trait>::{constant#0}` failed inside this call +note: inside `TypeId::trait_info_of::<'_, dyn Trait>` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `type_info::::size` --> $SRC_DIR/core/src/mem/type_info.rs:LL:COL -note: the above error was encountered while instantiating `fn try_as_dyn::<[u8; usize::MAX], dyn Trait>` +note: the above error was encountered while instantiating `fn try_as_dyn::<'_, [u8; usize::MAX], dyn Trait>` --> $DIR/vtable-try-as-dyn.rs:14:13 | LL | let _ = std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>(x); diff --git a/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr b/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr index c9c15e2d62c9f..c6a53d4face4f 100644 --- a/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr +++ b/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr @@ -1,15 +1,15 @@ error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target architecture --> $SRC_DIR/core/src/any.rs:LL:COL | - = note: evaluation of `std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>::{constant#0}` failed inside this call -note: inside `TypeId::trait_info_of::` + = note: evaluation of `std::any::try_as_dyn::<'_, [u8; usize::MAX], dyn Trait>::{constant#0}` failed inside this call +note: inside `TypeId::trait_info_of::<'_, dyn Trait>` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `type_info::::size` --> $SRC_DIR/core/src/mem/type_info.rs:LL:COL -note: the above error was encountered while instantiating `fn try_as_dyn::<[u8; usize::MAX], dyn Trait>` +note: the above error was encountered while instantiating `fn try_as_dyn::<'_, [u8; usize::MAX], dyn Trait>` --> $DIR/vtable-try-as-dyn.rs:14:13 | LL | let _ = std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>(x); diff --git a/tests/ui/reflection/trait_info_of_too_big.stderr b/tests/ui/reflection/trait_info_of_too_big.stderr index b5dc1d3cdb44a..8d8557670e816 100644 --- a/tests/ui/reflection/trait_info_of_too_big.stderr +++ b/tests/ui/reflection/trait_info_of_too_big.stderr @@ -15,7 +15,7 @@ error[E0080]: values of the type `[u8; usize::MAX]` are too big for the target a LL | TypeId::of::<[u8; usize::MAX]>().trait_info_of::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_::{constant#0}` failed inside this call | -note: inside `TypeId::trait_info_of::` +note: inside `TypeId::trait_info_of::<'_, dyn Trait>` --> $SRC_DIR/core/src/any.rs:LL:COL note: inside `TypeId::trait_info_of_trait_type_id` --> $SRC_DIR/core/src/any.rs:LL:COL From e948729d7220df1f384b714705b18a543805e9ad Mon Sep 17 00:00:00 2001 From: Yukang Date: Thu, 23 Jul 2026 17:49:19 +0800 Subject: [PATCH 54/68] 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 afb2e9cb0e58a8b46030dcd4d856e607afec7813 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 23 Jul 2026 12:13:38 +0200 Subject: [PATCH 55/68] use `minicore::simd::Simd` more --- .../preserve-vec-element-types.rs | 6 +- tests/codegen-llvm/regparm-inreg.rs | 11 +- tests/codegen-llvm/s390x-simd.rs | 26 +- tests/ui/abi/arm-unadjusted-intrinsic.rs | 10 +- tests/ui/abi/simd-abi-checks-empty-list.rs | 13 +- .../ui/abi/simd-abi-checks-empty-list.stderr | 8 +- tests/ui/abi/simd-abi-checks-s390x.rs | 16 +- tests/ui/abi/simd-abi-checks-s390x.z10.stderr | 40 +-- ...simd-abi-checks-s390x.z13_no_vector.stderr | 40 +-- ...imd-abi-checks-s390x.z13_soft_float.stderr | 40 +-- tests/ui/abi/simd-abi-checks-sse.rs | 11 +- tests/ui/abi/simd-abi-checks-sse.stderr | 8 +- tests/ui/asm/powerpc/bad-reg.aix64.stderr | 228 ++++++++-------- tests/ui/asm/powerpc/bad-reg.powerpc.stderr | 258 +++++++++--------- tests/ui/asm/powerpc/bad-reg.powerpc64.stderr | 254 ++++++++--------- .../ui/asm/powerpc/bad-reg.powerpc64le.stderr | 228 ++++++++-------- .../ui/asm/powerpc/bad-reg.powerpcspe.stderr | 256 ++++++++--------- tests/ui/asm/powerpc/bad-reg.rs | 16 +- tests/ui/asm/s390x/bad-reg.rs | 10 +- tests/ui/asm/s390x/bad-reg.s390x.stderr | 108 ++++---- .../ui/asm/s390x/bad-reg.s390x_vector.stderr | 94 +++---- tests/ui/codegen/deprecated-llvm-intrinsic.rs | 6 +- .../codegen/deprecated-llvm-intrinsic.stderr | 4 +- 23 files changed, 817 insertions(+), 874 deletions(-) diff --git a/tests/codegen-llvm/preserve-vec-element-types.rs b/tests/codegen-llvm/preserve-vec-element-types.rs index 50e560412e817..b3908b1c24cc2 100644 --- a/tests/codegen-llvm/preserve-vec-element-types.rs +++ b/tests/codegen-llvm/preserve-vec-element-types.rs @@ -2,7 +2,7 @@ //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled --target=aarch64-unknown-linux-gnu //@ needs-llvm-components: aarch64 //@ add-minicore -#![feature(no_core, repr_simd, f16, f128)] +#![feature(no_core, f16, f128)] #![crate_type = "lib"] #![no_std] #![no_core] @@ -12,11 +12,9 @@ // useful for optimization. It prevents additional bitcasts that make LLVM patterns fail. extern crate minicore; +use minicore::simd::Simd; use minicore::*; -#[repr(simd)] -pub struct Simd([T; N]); - #[repr(C)] struct Pair(T, T); diff --git a/tests/codegen-llvm/regparm-inreg.rs b/tests/codegen-llvm/regparm-inreg.rs index ef70f7f8be0bd..77d4c206071e7 100644 --- a/tests/codegen-llvm/regparm-inreg.rs +++ b/tests/codegen-llvm/regparm-inreg.rs @@ -14,12 +14,13 @@ #![crate_type = "lib"] #![no_core] -#![feature(no_core, lang_items, repr_simd)] +#![feature(no_core, lang_items)] extern crate minicore; -use minicore::*; pub mod tests { + use minicore::simd::Simd; + // regparm doesn't work for "fastcall" calling conv (only 2 inregs) // CHECK: @f1(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3) #[no_mangle] @@ -98,8 +99,7 @@ pub mod tests { pub extern "C" fn f10(_: f32, _: f64, _: bool, _: i16) {} #[allow(non_camel_case_types)] - #[repr(simd)] - pub struct __m128([f32; 4]); + type __m128 = Simd; // regparm0: @f11(i32 noundef %_1, <4 x float> %_2, i32 noundef %_3, i32 noundef %_4) // regparm1: @f11(i32 inreg noundef %_1, <4 x float> %_2, i32 noundef %_3, i32 noundef %_4) @@ -111,8 +111,7 @@ pub mod tests { pub extern "C" fn f11(_: i32, _: __m128, _: i32, _: i32) {} #[allow(non_camel_case_types)] - #[repr(simd)] - pub struct __m256([f32; 8]); + type __m256 = Simd; // regparm0: @f12(i32 noundef %_1, <8 x float> %_2, i32 noundef %_3, i32 noundef %_4) // regparm1: @f12(i32 inreg noundef %_1, <8 x float> %_2, i32 noundef %_3, i32 noundef %_4) diff --git a/tests/codegen-llvm/s390x-simd.rs b/tests/codegen-llvm/s390x-simd.rs index 8439e79716746..f223f6edad3df 100644 --- a/tests/codegen-llvm/s390x-simd.rs +++ b/tests/codegen-llvm/s390x-simd.rs @@ -6,35 +6,13 @@ #![crate_type = "rlib"] #![feature(no_core, asm_experimental_arch)] -#![feature(simd_ffi, intrinsics, repr_simd)] +#![feature(simd_ffi, intrinsics)] #![no_core] extern crate minicore; +use minicore::simd::*; use minicore::*; -#[repr(simd)] -struct i8x16([i8; 16]); - -#[repr(simd)] -struct i16x8([i16; 8]); - -#[repr(simd)] -struct i32x4([i32; 4]); - -#[repr(simd)] -struct i64x2([i64; 2]); - -#[repr(simd)] -struct f32x4([f32; 4]); - -#[repr(simd)] -struct f64x2([f64; 2]); - -impl Copy for i8x16 {} -impl Copy for i16x8 {} -impl Copy for i32x4 {} -impl Copy for i64x2 {} - #[rustc_intrinsic] unsafe fn simd_ge(x: T, y: T) -> U; diff --git a/tests/ui/abi/arm-unadjusted-intrinsic.rs b/tests/ui/abi/arm-unadjusted-intrinsic.rs index 1f386308c878f..788c5e67904ab 100644 --- a/tests/ui/abi/arm-unadjusted-intrinsic.rs +++ b/tests/ui/abi/arm-unadjusted-intrinsic.rs @@ -7,23 +7,19 @@ //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu //@[aarch64] needs-llvm-components: aarch64 //@ ignore-backends: gcc -#![feature( - no_core, lang_items, link_llvm_intrinsics, - abi_unadjusted, repr_simd, arm_target_feature, -)] +#![feature(no_core, lang_items, link_llvm_intrinsics, abi_unadjusted, arm_target_feature)] #![no_std] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] extern crate minicore; +use minicore::simd::Simd; use minicore::*; // Regression test for https://github.com/rust-lang/rust/issues/118124. -#[repr(simd)] -pub struct int8x16_t(pub(crate) [i8; 16]); -impl Copy for int8x16_t {} +pub type int8x16_t = Simd; #[repr(C)] pub struct int8x16x4_t(pub int8x16_t, pub int8x16_t, pub int8x16_t, pub int8x16_t); diff --git a/tests/ui/abi/simd-abi-checks-empty-list.rs b/tests/ui/abi/simd-abi-checks-empty-list.rs index 8907a2c391db6..52e588b028bd2 100644 --- a/tests/ui/abi/simd-abi-checks-empty-list.rs +++ b/tests/ui/abi/simd-abi-checks-empty-list.rs @@ -6,14 +6,11 @@ //@ build-fail //@ ignore-backends: gcc #![no_core] -#![feature(no_core, repr_simd)] -#![allow(improper_ctypes_definitions)] +#![feature(no_core)] extern crate minicore; -use minicore::*; +use minicore::simd::Simd; -#[repr(simd)] -pub struct SimdVec([i32; 4]); - -pub extern "C" fn pass_by_vec(_: SimdVec) {} -//~^ ERROR: this function definition uses SIMD vector type `SimdVec` which is not currently supported with the chosen ABI +#[expect(improper_ctypes_definitions)] +pub extern "C" fn pass_by_vec(_: Simd) {} +//~^ ERROR: this function definition uses SIMD vector type `Simd` which is not currently supported with the chosen ABI diff --git a/tests/ui/abi/simd-abi-checks-empty-list.stderr b/tests/ui/abi/simd-abi-checks-empty-list.stderr index 603f5daeb2a10..e19c775eee750 100644 --- a/tests/ui/abi/simd-abi-checks-empty-list.stderr +++ b/tests/ui/abi/simd-abi-checks-empty-list.stderr @@ -1,8 +1,8 @@ -error: this function definition uses SIMD vector type `SimdVec` which is not currently supported with the chosen ABI - --> $DIR/simd-abi-checks-empty-list.rs:18:1 +error: this function definition uses SIMD vector type `Simd` which is not currently supported with the chosen ABI + --> $DIR/simd-abi-checks-empty-list.rs:15:1 | -LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here +LL | pub extern "C" fn pass_by_vec(_: Simd) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here error: aborting due to 1 previous error diff --git a/tests/ui/abi/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs index c8f4483650ccd..8ca3d2f457899 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.rs +++ b/tests/ui/abi/simd-abi-checks-s390x.rs @@ -12,29 +12,21 @@ //[z13_soft_float]~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly //[z13_soft_float]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature` -#![feature(no_core, repr_simd)] +#![feature(no_core)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types, improper_ctypes_definitions)] extern crate minicore; +use minicore::simd::*; use minicore::*; -#[repr(simd)] -pub struct i8x8([i8; 8]); -#[repr(simd)] -pub struct i8x16([i8; 16]); -#[repr(simd)] -pub struct i8x32([i8; 32]); #[repr(C)] pub struct Wrapper(T); +impl Copy for Wrapper {} + #[repr(transparent)] pub struct TransparentWrapper(T); - -impl Copy for i8x8 {} -impl Copy for i8x16 {} -impl Copy for i8x32 {} -impl Copy for Wrapper {} impl Copy for TransparentWrapper {} #[no_mangle] diff --git a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr index 0a40658fa66bf..c401da52ba878 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr @@ -1,21 +1,21 @@ -error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:41:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:33:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:38:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:92:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:84:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -24,8 +24,8 @@ LL | | ) -> TransparentWrapper { | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:91:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -34,48 +34,48 @@ LL | | ) -> TransparentWrapper { | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:114:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:106:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:119:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:111:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:130:1 +error: this function definition uses SIMD vector type `Wrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:135:1 +error: this function definition uses SIMD vector type `Wrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:127:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:146:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:138:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:151:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:143:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr index 0a40658fa66bf..c401da52ba878 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr @@ -1,21 +1,21 @@ -error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:41:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:33:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:38:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:92:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:84:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -24,8 +24,8 @@ LL | | ) -> TransparentWrapper { | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:91:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -34,48 +34,48 @@ LL | | ) -> TransparentWrapper { | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:114:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:106:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:119:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:111:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:130:1 +error: this function definition uses SIMD vector type `Wrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:135:1 +error: this function definition uses SIMD vector type `Wrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:127:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:146:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:138:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:151:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:143:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index cda51a211324e..59697d6af254a 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -8,24 +8,24 @@ warning: target feature `soft-float` must be disabled to ensure that the ABI of = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 -error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:41:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:33:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:38:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:92:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:84:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -34,8 +34,8 @@ LL | | ) -> TransparentWrapper { | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:91:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -44,48 +44,48 @@ LL | | ) -> TransparentWrapper { | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:114:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:106:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:119:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:111:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:130:1 +error: this function definition uses SIMD vector type `Wrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:135:1 +error: this function definition uses SIMD vector type `Wrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:127:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:146:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:138:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) -error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:151:1 +error: this function definition uses SIMD vector type `TransparentWrapper>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled + --> $DIR/simd-abi-checks-s390x.rs:143:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-sse.rs b/tests/ui/abi/simd-abi-checks-sse.rs index b9c1c10757d14..736f32afcd464 100644 --- a/tests/ui/abi/simd-abi-checks-sse.rs +++ b/tests/ui/abi/simd-abi-checks-sse.rs @@ -6,17 +6,14 @@ //@ build-fail //@ needs-llvm-components: x86 //@ ignore-backends: gcc -#![feature(no_core, repr_simd)] +#![feature(no_core)] #![no_core] #![allow(improper_ctypes_definitions)] extern crate minicore; -use minicore::*; - -#[repr(simd)] -pub struct SseVector([i64; 2]); +use minicore::simd::Simd; #[no_mangle] -pub unsafe extern "C" fn f(_: SseVector) { - //~^ ERROR: this function definition uses SIMD vector type `SseVector` which (with the chosen ABI) requires the `sse` target feature, which is not enabled +pub unsafe extern "C" fn f(_: Simd) { + //~^ ERROR: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `sse` target feature, which is not enabled } diff --git a/tests/ui/abi/simd-abi-checks-sse.stderr b/tests/ui/abi/simd-abi-checks-sse.stderr index 018d8b687d513..1a6583a511e0c 100644 --- a/tests/ui/abi/simd-abi-checks-sse.stderr +++ b/tests/ui/abi/simd-abi-checks-sse.stderr @@ -1,8 +1,8 @@ -error: this function definition uses SIMD vector type `SseVector` which (with the chosen ABI) requires the `sse` target feature, which is not enabled - --> $DIR/simd-abi-checks-sse.rs:20:1 +error: this function definition uses SIMD vector type `Simd` which (with the chosen ABI) requires the `sse` target feature, which is not enabled + --> $DIR/simd-abi-checks-sse.rs:17:1 | -LL | pub unsafe extern "C" fn f(_: SseVector) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here +LL | pub unsafe extern "C" fn f(_: Simd) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here | = help: consider enabling it globally (`-C target-feature=+sse`) or locally (`#[target_feature(enable="sse")]`) diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index c7373780e382c..d6317e32bd8fb 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:139:18 + --> $DIR/bad-reg.rs:131:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:142:18 + --> $DIR/bad-reg.rs:134:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:145:26 + --> $DIR/bad-reg.rs:137:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:148:26 + --> $DIR/bad-reg.rs:140:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:152:18 + --> $DIR/bad-reg.rs:144:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:155:18 + --> $DIR/bad-reg.rs:147:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:158:26 + --> $DIR/bad-reg.rs:150:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:161:26 + --> $DIR/bad-reg.rs:153:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:165:18 + --> $DIR/bad-reg.rs:157:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:168:18 + --> $DIR/bad-reg.rs:160:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:171:26 + --> $DIR/bad-reg.rs:163:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:174:26 + --> $DIR/bad-reg.rs:166:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:178:18 + --> $DIR/bad-reg.rs:170:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:181:18 + --> $DIR/bad-reg.rs:173:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:184:26 + --> $DIR/bad-reg.rs:176:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:187:26 + --> $DIR/bad-reg.rs:179:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:183:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:185:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:187:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:189:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:205:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:206:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:226:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:220:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:222:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:224:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:226:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:270:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:264:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:266:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:268:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:270:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,7 +693,7 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:334:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` @@ -701,19 +701,19 @@ LL | asm!("", out("vs63") _, out("v31") _); | register `vs63` error: register class `spe_acc` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:340:26 + --> $DIR/bad-reg.rs:332:26 | LL | asm!("/* {} */", out(spe_acc) _); | ^^^^^^^^^^^^^^ error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:65:27 + --> $DIR/bad-reg.rs:58:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -721,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:68:28 + --> $DIR/bad-reg.rs:61:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -729,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:76:35 + --> $DIR/bad-reg.rs:69:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -737,7 +737,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:106:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -745,7 +745,7 @@ LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:109:29 + --> $DIR/bad-reg.rs:101:29 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -753,7 +753,7 @@ LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:116:36 + --> $DIR/bad-reg.rs:108:36 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^ @@ -761,7 +761,7 @@ LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is ava = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:139:27 + --> $DIR/bad-reg.rs:131:27 | LL | asm!("", in("cr") x); | ^ @@ -769,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:142:28 + --> $DIR/bad-reg.rs:134:28 | LL | asm!("", out("cr") x); | ^ @@ -777,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:145:33 + --> $DIR/bad-reg.rs:137:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -785,7 +785,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:152:28 + --> $DIR/bad-reg.rs:144:28 | LL | asm!("", in("ctr") x); | ^ @@ -793,7 +793,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:155:29 + --> $DIR/bad-reg.rs:147:29 | LL | asm!("", out("ctr") x); | ^ @@ -801,7 +801,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:158:34 + --> $DIR/bad-reg.rs:150:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -809,7 +809,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:165:27 + --> $DIR/bad-reg.rs:157:27 | LL | asm!("", in("lr") x); | ^ @@ -817,7 +817,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:168:28 + --> $DIR/bad-reg.rs:160:28 | LL | asm!("", out("lr") x); | ^ @@ -825,7 +825,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:171:33 + --> $DIR/bad-reg.rs:163:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -833,7 +833,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:178:28 + --> $DIR/bad-reg.rs:170:28 | LL | asm!("", in("xer") x); | ^ @@ -841,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:181:29 + --> $DIR/bad-reg.rs:173:29 | LL | asm!("", out("xer") x); | ^ @@ -849,7 +849,7 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:184:34 + --> $DIR/bad-reg.rs:176:34 | LL | asm!("/* {} */", in(xer) x); | ^ @@ -857,7 +857,7 @@ LL | asm!("/* {} */", in(xer) x); = note: register class `xer` supports these types: error: cannot use register `spe_acc`: spe_acc is only available on spe targets - --> $DIR/bad-reg.rs:338:18 + --> $DIR/bad-reg.rs:330:18 | LL | asm!("", out("spe_acc") _); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr index 5c4cd71c2d1ad..88a8cecf40550 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:139:18 + --> $DIR/bad-reg.rs:131:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:142:18 + --> $DIR/bad-reg.rs:134:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:145:26 + --> $DIR/bad-reg.rs:137:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:148:26 + --> $DIR/bad-reg.rs:140:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:152:18 + --> $DIR/bad-reg.rs:144:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:155:18 + --> $DIR/bad-reg.rs:147:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:158:26 + --> $DIR/bad-reg.rs:150:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:161:26 + --> $DIR/bad-reg.rs:153:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:165:18 + --> $DIR/bad-reg.rs:157:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:168:18 + --> $DIR/bad-reg.rs:160:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:171:26 + --> $DIR/bad-reg.rs:163:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:174:26 + --> $DIR/bad-reg.rs:166:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:178:18 + --> $DIR/bad-reg.rs:170:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:181:18 + --> $DIR/bad-reg.rs:173:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:184:26 + --> $DIR/bad-reg.rs:176:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:187:26 + --> $DIR/bad-reg.rs:179:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:183:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:185:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:187:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:189:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:205:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:206:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:226:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:220:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:222:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:224:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:226:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:270:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:264:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:266:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:268:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:270:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,7 +693,7 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:334:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` @@ -701,145 +701,145 @@ LL | asm!("", out("vs63") _, out("v31") _); | register `vs63` error: register class `spe_acc` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:340:26 + --> $DIR/bad-reg.rs:332:26 | LL | asm!("/* {} */", out(spe_acc) _); | ^^^^^^^^^^^^^^ error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", in("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:62:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:68:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:71:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:66:26 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:76:26 + --> $DIR/bad-reg.rs:69:26 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:79:26 + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", out(vreg) _); // requires altivec | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:90:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:92:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:96:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:106:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:109:18 + --> $DIR/bad-reg.rs:101:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:106:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:116:26 + --> $DIR/bad-reg.rs:108:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:111:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:139:27 + --> $DIR/bad-reg.rs:131:27 | LL | asm!("", in("cr") x); | ^ @@ -847,7 +847,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:142:28 + --> $DIR/bad-reg.rs:134:28 | LL | asm!("", out("cr") x); | ^ @@ -855,7 +855,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:145:33 + --> $DIR/bad-reg.rs:137:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -863,7 +863,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:152:28 + --> $DIR/bad-reg.rs:144:28 | LL | asm!("", in("ctr") x); | ^ @@ -871,7 +871,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:155:29 + --> $DIR/bad-reg.rs:147:29 | LL | asm!("", out("ctr") x); | ^ @@ -879,7 +879,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:158:34 + --> $DIR/bad-reg.rs:150:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -887,7 +887,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:165:27 + --> $DIR/bad-reg.rs:157:27 | LL | asm!("", in("lr") x); | ^ @@ -895,7 +895,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:168:28 + --> $DIR/bad-reg.rs:160:28 | LL | asm!("", out("lr") x); | ^ @@ -903,7 +903,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:171:33 + --> $DIR/bad-reg.rs:163:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -911,7 +911,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:178:28 + --> $DIR/bad-reg.rs:170:28 | LL | asm!("", in("xer") x); | ^ @@ -919,7 +919,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:181:29 + --> $DIR/bad-reg.rs:173:29 | LL | asm!("", out("xer") x); | ^ @@ -927,7 +927,7 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:184:34 + --> $DIR/bad-reg.rs:176:34 | LL | asm!("/* {} */", in(xer) x); | ^ @@ -935,7 +935,7 @@ LL | asm!("/* {} */", in(xer) x); = note: register class `xer` supports these types: error: cannot use register `spe_acc`: spe_acc is only available on spe targets - --> $DIR/bad-reg.rs:338:18 + --> $DIR/bad-reg.rs:330:18 | LL | asm!("", out("spe_acc") _); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index 151bb5682e03b..6a438798840ef 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:139:18 + --> $DIR/bad-reg.rs:131:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:142:18 + --> $DIR/bad-reg.rs:134:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:145:26 + --> $DIR/bad-reg.rs:137:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:148:26 + --> $DIR/bad-reg.rs:140:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:152:18 + --> $DIR/bad-reg.rs:144:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:155:18 + --> $DIR/bad-reg.rs:147:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:158:26 + --> $DIR/bad-reg.rs:150:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:161:26 + --> $DIR/bad-reg.rs:153:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:165:18 + --> $DIR/bad-reg.rs:157:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:168:18 + --> $DIR/bad-reg.rs:160:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:171:26 + --> $DIR/bad-reg.rs:163:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:174:26 + --> $DIR/bad-reg.rs:166:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:178:18 + --> $DIR/bad-reg.rs:170:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:181:18 + --> $DIR/bad-reg.rs:173:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:184:26 + --> $DIR/bad-reg.rs:176:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:187:26 + --> $DIR/bad-reg.rs:179:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:183:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:185:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:187:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:189:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:205:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:206:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:226:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:220:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:222:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:224:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:226:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:270:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:264:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:266:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:268:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:270:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,7 +693,7 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:334:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` @@ -701,35 +701,35 @@ LL | asm!("", out("vs63") _, out("v31") _); | register `vs63` error: register class `spe_acc` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:340:26 + --> $DIR/bad-reg.rs:332:26 | LL | asm!("/* {} */", out(spe_acc) _); | ^^^^^^^^^^^^^^ error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:59:27 + --> $DIR/bad-reg.rs:52:27 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^ | - = note: this is required to use type `i64x2` with register class `vreg` + = note: this is required to use type `Simd` with register class `vreg` error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:62:28 + --> $DIR/bad-reg.rs:55:28 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^ | - = note: this is required to use type `i64x2` with register class `vreg` + = note: this is required to use type `Simd` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:65:27 + --> $DIR/bad-reg.rs:58:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -737,7 +737,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:68:28 + --> $DIR/bad-reg.rs:61:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -745,15 +745,15 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:73:35 + --> $DIR/bad-reg.rs:66:35 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^ | - = note: this is required to use type `i64x2` with register class `vreg` + = note: this is required to use type `Simd` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:76:35 + --> $DIR/bad-reg.rs:69:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -761,67 +761,67 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:90:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:92:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:96:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:106:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:109:18 + --> $DIR/bad-reg.rs:101:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:106:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:116:26 + --> $DIR/bad-reg.rs:108:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:111:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:139:27 + --> $DIR/bad-reg.rs:131:27 | LL | asm!("", in("cr") x); | ^ @@ -829,7 +829,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:142:28 + --> $DIR/bad-reg.rs:134:28 | LL | asm!("", out("cr") x); | ^ @@ -837,7 +837,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:145:33 + --> $DIR/bad-reg.rs:137:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -845,7 +845,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:152:28 + --> $DIR/bad-reg.rs:144:28 | LL | asm!("", in("ctr") x); | ^ @@ -853,7 +853,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:155:29 + --> $DIR/bad-reg.rs:147:29 | LL | asm!("", out("ctr") x); | ^ @@ -861,7 +861,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:158:34 + --> $DIR/bad-reg.rs:150:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -869,7 +869,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:165:27 + --> $DIR/bad-reg.rs:157:27 | LL | asm!("", in("lr") x); | ^ @@ -877,7 +877,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:168:28 + --> $DIR/bad-reg.rs:160:28 | LL | asm!("", out("lr") x); | ^ @@ -885,7 +885,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:171:33 + --> $DIR/bad-reg.rs:163:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -893,7 +893,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:178:28 + --> $DIR/bad-reg.rs:170:28 | LL | asm!("", in("xer") x); | ^ @@ -901,7 +901,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:181:29 + --> $DIR/bad-reg.rs:173:29 | LL | asm!("", out("xer") x); | ^ @@ -909,7 +909,7 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:184:34 + --> $DIR/bad-reg.rs:176:34 | LL | asm!("/* {} */", in(xer) x); | ^ @@ -917,7 +917,7 @@ LL | asm!("/* {} */", in(xer) x); = note: register class `xer` supports these types: error: cannot use register `spe_acc`: spe_acc is only available on spe targets - --> $DIR/bad-reg.rs:338:18 + --> $DIR/bad-reg.rs:330:18 | LL | asm!("", out("spe_acc") _); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index c7373780e382c..d6317e32bd8fb 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:139:18 + --> $DIR/bad-reg.rs:131:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:142:18 + --> $DIR/bad-reg.rs:134:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:145:26 + --> $DIR/bad-reg.rs:137:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:148:26 + --> $DIR/bad-reg.rs:140:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:152:18 + --> $DIR/bad-reg.rs:144:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:155:18 + --> $DIR/bad-reg.rs:147:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:158:26 + --> $DIR/bad-reg.rs:150:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:161:26 + --> $DIR/bad-reg.rs:153:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:165:18 + --> $DIR/bad-reg.rs:157:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:168:18 + --> $DIR/bad-reg.rs:160:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:171:26 + --> $DIR/bad-reg.rs:163:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:174:26 + --> $DIR/bad-reg.rs:166:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:178:18 + --> $DIR/bad-reg.rs:170:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:181:18 + --> $DIR/bad-reg.rs:173:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:184:26 + --> $DIR/bad-reg.rs:176:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:187:26 + --> $DIR/bad-reg.rs:179:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:183:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:185:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:187:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:189:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:205:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:206:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:226:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:220:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:222:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:224:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:226:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:270:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:264:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:266:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:268:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:270:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,7 +693,7 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:334:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` @@ -701,19 +701,19 @@ LL | asm!("", out("vs63") _, out("v31") _); | register `vs63` error: register class `spe_acc` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:340:26 + --> $DIR/bad-reg.rs:332:26 | LL | asm!("/* {} */", out(spe_acc) _); | ^^^^^^^^^^^^^^ error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:65:27 + --> $DIR/bad-reg.rs:58:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -721,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:68:28 + --> $DIR/bad-reg.rs:61:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -729,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:76:35 + --> $DIR/bad-reg.rs:69:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -737,7 +737,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:106:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -745,7 +745,7 @@ LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:109:29 + --> $DIR/bad-reg.rs:101:29 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -753,7 +753,7 @@ LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:116:36 + --> $DIR/bad-reg.rs:108:36 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^ @@ -761,7 +761,7 @@ LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is ava = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:139:27 + --> $DIR/bad-reg.rs:131:27 | LL | asm!("", in("cr") x); | ^ @@ -769,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:142:28 + --> $DIR/bad-reg.rs:134:28 | LL | asm!("", out("cr") x); | ^ @@ -777,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:145:33 + --> $DIR/bad-reg.rs:137:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -785,7 +785,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:152:28 + --> $DIR/bad-reg.rs:144:28 | LL | asm!("", in("ctr") x); | ^ @@ -793,7 +793,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:155:29 + --> $DIR/bad-reg.rs:147:29 | LL | asm!("", out("ctr") x); | ^ @@ -801,7 +801,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:158:34 + --> $DIR/bad-reg.rs:150:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -809,7 +809,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:165:27 + --> $DIR/bad-reg.rs:157:27 | LL | asm!("", in("lr") x); | ^ @@ -817,7 +817,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:168:28 + --> $DIR/bad-reg.rs:160:28 | LL | asm!("", out("lr") x); | ^ @@ -825,7 +825,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:171:33 + --> $DIR/bad-reg.rs:163:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -833,7 +833,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:178:28 + --> $DIR/bad-reg.rs:170:28 | LL | asm!("", in("xer") x); | ^ @@ -841,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:181:29 + --> $DIR/bad-reg.rs:173:29 | LL | asm!("", out("xer") x); | ^ @@ -849,7 +849,7 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:184:34 + --> $DIR/bad-reg.rs:176:34 | LL | asm!("/* {} */", in(xer) x); | ^ @@ -857,7 +857,7 @@ LL | asm!("/* {} */", in(xer) x); = note: register class `xer` supports these types: error: cannot use register `spe_acc`: spe_acc is only available on spe targets - --> $DIR/bad-reg.rs:338:18 + --> $DIR/bad-reg.rs:330:18 | LL | asm!("", out("spe_acc") _); | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr b/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr index 2b4657bf358e5..86ea5eed9385d 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:139:18 + --> $DIR/bad-reg.rs:131:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:142:18 + --> $DIR/bad-reg.rs:134:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:145:26 + --> $DIR/bad-reg.rs:137:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:148:26 + --> $DIR/bad-reg.rs:140:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:152:18 + --> $DIR/bad-reg.rs:144:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:155:18 + --> $DIR/bad-reg.rs:147:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:158:26 + --> $DIR/bad-reg.rs:150:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:161:26 + --> $DIR/bad-reg.rs:153:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:165:18 + --> $DIR/bad-reg.rs:157:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:168:18 + --> $DIR/bad-reg.rs:160:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:171:26 + --> $DIR/bad-reg.rs:163:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:174:26 + --> $DIR/bad-reg.rs:166:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:178:18 + --> $DIR/bad-reg.rs:170:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:181:18 + --> $DIR/bad-reg.rs:173:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:184:26 + --> $DIR/bad-reg.rs:176:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:187:26 + --> $DIR/bad-reg.rs:179:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:183:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:185:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:187:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:189:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:205:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:206:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:226:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:220:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:222:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:224:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:226:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:270:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:264:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:266:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:268:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:270:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,7 +693,7 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:334:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` @@ -701,145 +701,145 @@ LL | asm!("", out("vs63") _, out("v31") _); | register `vs63` error: register class `spe_acc` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:340:26 + --> $DIR/bad-reg.rs:332:26 | LL | asm!("/* {} */", out(spe_acc) _); | ^^^^^^^^^^^^^^ error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", in("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:62:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:68:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:71:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:66:26 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:76:26 + --> $DIR/bad-reg.rs:69:26 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:79:26 + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", out(vreg) _); // requires altivec | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:90:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:92:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:96:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:106:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:109:18 + --> $DIR/bad-reg.rs:101:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:106:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:116:26 + --> $DIR/bad-reg.rs:108:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:111:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:139:27 + --> $DIR/bad-reg.rs:131:27 | LL | asm!("", in("cr") x); | ^ @@ -847,7 +847,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:142:28 + --> $DIR/bad-reg.rs:134:28 | LL | asm!("", out("cr") x); | ^ @@ -855,7 +855,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:145:33 + --> $DIR/bad-reg.rs:137:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -863,7 +863,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:152:28 + --> $DIR/bad-reg.rs:144:28 | LL | asm!("", in("ctr") x); | ^ @@ -871,7 +871,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:155:29 + --> $DIR/bad-reg.rs:147:29 | LL | asm!("", out("ctr") x); | ^ @@ -879,7 +879,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:158:34 + --> $DIR/bad-reg.rs:150:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -887,7 +887,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:165:27 + --> $DIR/bad-reg.rs:157:27 | LL | asm!("", in("lr") x); | ^ @@ -895,7 +895,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:168:28 + --> $DIR/bad-reg.rs:160:28 | LL | asm!("", out("lr") x); | ^ @@ -903,7 +903,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:171:33 + --> $DIR/bad-reg.rs:163:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -911,7 +911,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:178:28 + --> $DIR/bad-reg.rs:170:28 | LL | asm!("", in("xer") x); | ^ @@ -919,7 +919,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:181:29 + --> $DIR/bad-reg.rs:173:29 | LL | asm!("", out("xer") x); | ^ @@ -927,7 +927,7 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:184:34 + --> $DIR/bad-reg.rs:176:34 | LL | asm!("/* {} */", in(xer) x); | ^ diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs index 20a2b65e2f50d..88c78859e8326 100644 --- a/tests/ui/asm/powerpc/bad-reg.rs +++ b/tests/ui/asm/powerpc/bad-reg.rs @@ -14,25 +14,18 @@ // ignore-tidy-file-linelength #![crate_type = "rlib"] -#![feature(no_core, repr_simd, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch)] #![no_core] #![allow(non_camel_case_types)] extern crate minicore; +use minicore::simd::{i32x4, i64x2}; use minicore::*; -#[repr(simd)] -pub struct i32x4([i32; 4]); -#[repr(simd)] -pub struct i64x2([i64; 2]); - -impl Copy for i32x4 {} -impl Copy for i64x2 {} - fn f() { let mut x = 0; - let mut v32x4 = i32x4([0; 4]); - let mut v64x2 = i64x2([0; 2]); + let mut v32x4 = i32x4::from_array([0; 4]); + let mut v64x2 = i64x2::from_array([0; 2]); unsafe { // Unsupported registers asm!("", out("sp") _); @@ -92,7 +85,6 @@ fn f() { asm!("", out("v30") _); asm!("", out("v31") _); - // vsreg asm!("", out("vs0") _); // always ok asm!("", in("vs0") v32x4); // requires vsx diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs index 05128f8defd32..a6b2b869a851e 100644 --- a/tests/ui/asm/s390x/bad-reg.rs +++ b/tests/ui/asm/s390x/bad-reg.rs @@ -7,22 +7,18 @@ //@ ignore-backends: gcc #![crate_type = "rlib"] -#![feature(no_core, repr_simd)] +#![feature(no_core)] #![no_core] #![allow(non_camel_case_types)] extern crate minicore; +use minicore::simd::i64x2; use minicore::*; -#[repr(simd)] -pub struct i64x2([i64; 2]); - -impl Copy for i64x2 {} - fn f() { let mut x = 0; let mut b = 0u8; - let mut v = i64x2([0; 2]); + let mut v = i64x2::from_array([0; 2]); unsafe { // Unsupported registers asm!("", out("r11") _); diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr index 7a9887a4b7cf7..cccf715a860a7 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr @@ -1,149 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:24:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:26:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:28:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:30:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:54:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:56:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:58:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:62:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:64:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:101:18 + --> $DIR/bad-reg.rs:97:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:100:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:107:26 + --> $DIR/bad-reg.rs:103:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:112:31 + --> $DIR/bad-reg.rs:108:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:114:31 + --> $DIR/bad-reg.rs:110:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:116:31 + --> $DIR/bad-reg.rs:112:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:118:31 + --> $DIR/bad-reg.rs:114:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:120:31 + --> $DIR/bad-reg.rs:116:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:122:31 + --> $DIR/bad-reg.rs:118:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:124:31 + --> $DIR/bad-reg.rs:120:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:126:31 + --> $DIR/bad-reg.rs:122:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:128:31 + --> $DIR/bad-reg.rs:124:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:130:31 + --> $DIR/bad-reg.rs:126:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:132:32 + --> $DIR/bad-reg.rs:128:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:134:32 + --> $DIR/bad-reg.rs:130:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:136:32 + --> $DIR/bad-reg.rs:132:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:138:32 + --> $DIR/bad-reg.rs:134:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:140:32 + --> $DIR/bad-reg.rs:136:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:142:32 + --> $DIR/bad-reg.rs:138:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,73 +271,73 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:145:32 + --> $DIR/bad-reg.rs:141:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:71:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", in("v0") v); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:73:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("v0") v); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:75:18 + --> $DIR/bad-reg.rs:71:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:77:18 + --> $DIR/bad-reg.rs:73:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:79:18 + --> $DIR/bad-reg.rs:75:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:78:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:85:26 + --> $DIR/bad-reg.rs:81:26 | LL | asm!("/* {} */", in(vreg) v); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:87:26 + --> $DIR/bad-reg.rs:83:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:89:26 + --> $DIR/bad-reg.rs:85:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:92:26 + --> $DIR/bad-reg.rs:88:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:98:27 + --> $DIR/bad-reg.rs:94:27 | LL | asm!("", in("a2") x); | ^ @@ -345,7 +345,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:101:28 + --> $DIR/bad-reg.rs:97:28 | LL | asm!("", out("a2") x); | ^ @@ -353,7 +353,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:104:35 + --> $DIR/bad-reg.rs:100:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 4b02af95768a1..f590cb0dfc4f0 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -1,149 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:24:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:26:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:28:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:30:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:54:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:56:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:58:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:62:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:64:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:101:18 + --> $DIR/bad-reg.rs:97:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:100:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:107:26 + --> $DIR/bad-reg.rs:103:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:112:31 + --> $DIR/bad-reg.rs:108:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:114:31 + --> $DIR/bad-reg.rs:110:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:116:31 + --> $DIR/bad-reg.rs:112:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:118:31 + --> $DIR/bad-reg.rs:114:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:120:31 + --> $DIR/bad-reg.rs:116:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:122:31 + --> $DIR/bad-reg.rs:118:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:124:31 + --> $DIR/bad-reg.rs:120:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:126:31 + --> $DIR/bad-reg.rs:122:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:128:31 + --> $DIR/bad-reg.rs:124:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:130:31 + --> $DIR/bad-reg.rs:126:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:132:32 + --> $DIR/bad-reg.rs:128:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:134:32 + --> $DIR/bad-reg.rs:130:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:136:32 + --> $DIR/bad-reg.rs:132:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:138:32 + --> $DIR/bad-reg.rs:134:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:140:32 + --> $DIR/bad-reg.rs:136:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:142:32 + --> $DIR/bad-reg.rs:138:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,13 +271,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:145:32 + --> $DIR/bad-reg.rs:141:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:79:27 + --> $DIR/bad-reg.rs:75:27 | LL | asm!("", in("v0") b); | ^ @@ -285,7 +285,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:82:28 + --> $DIR/bad-reg.rs:78:28 | LL | asm!("", out("v0") b); | ^ @@ -293,7 +293,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:89:35 + --> $DIR/bad-reg.rs:85:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -301,7 +301,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:98:27 + --> $DIR/bad-reg.rs:94:27 | LL | asm!("", in("a2") x); | ^ @@ -309,7 +309,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:101:28 + --> $DIR/bad-reg.rs:97:28 | LL | asm!("", out("a2") x); | ^ @@ -317,7 +317,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:104:35 + --> $DIR/bad-reg.rs:100:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/codegen/deprecated-llvm-intrinsic.rs b/tests/ui/codegen/deprecated-llvm-intrinsic.rs index 33bc5f419151a..ffa1ffc541684 100644 --- a/tests/ui/codegen/deprecated-llvm-intrinsic.rs +++ b/tests/ui/codegen/deprecated-llvm-intrinsic.rs @@ -3,18 +3,16 @@ //@ compile-flags: --target aarch64-unknown-linux-gnu //@ needs-llvm-components: aarch64 //@ ignore-backends: gcc -#![feature(no_core, lang_items, link_llvm_intrinsics, abi_unadjusted, repr_simd, simd_ffi)] +#![feature(no_core, lang_items, link_llvm_intrinsics, abi_unadjusted, simd_ffi)] #![no_std] #![no_core] #![allow(internal_features, non_camel_case_types, improper_ctypes)] #![crate_type = "lib"] extern crate minicore; +use minicore::simd::i8x8; use minicore::*; -#[repr(simd)] -pub struct i8x8([i8; 8]); - extern "unadjusted" { #[deny(deprecated_llvm_intrinsic)] #[link_name = "llvm.aarch64.neon.rbit.v8i8"] diff --git a/tests/ui/codegen/deprecated-llvm-intrinsic.stderr b/tests/ui/codegen/deprecated-llvm-intrinsic.stderr index 40e4684a8ea4f..dc490deab1b61 100644 --- a/tests/ui/codegen/deprecated-llvm-intrinsic.stderr +++ b/tests/ui/codegen/deprecated-llvm-intrinsic.stderr @@ -1,11 +1,11 @@ error: using deprecated intrinsic `llvm.aarch64.neon.rbit.v8i8`, `llvm.bitreverse.v8i8` can be used instead - --> $DIR/deprecated-llvm-intrinsic.rs:21:5 + --> $DIR/deprecated-llvm-intrinsic.rs:19:5 | LL | fn foo(a: i8x8) -> i8x8; | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/deprecated-llvm-intrinsic.rs:19:12 + --> $DIR/deprecated-llvm-intrinsic.rs:17:12 | LL | #[deny(deprecated_llvm_intrinsic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ From 7490d8ef3ac20a37a761c199aa358ee693021f3d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 17 Jul 2026 19:19:31 +0200 Subject: [PATCH 56/68] 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 57/68] 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 58/68] 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 59/68] 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 60/68] 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 61/68] 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 62/68] 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 63/68] 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 a6d0a76a5bc869b4bc32673e46230419588a5d44 Mon Sep 17 00:00:00 2001 From: panstromek Date: Thu, 23 Jul 2026 14:57:39 +0200 Subject: [PATCH 64/68] Remove deref outdated workaround for `P` type P is long gone, so this workaround is no longer necessary --- compiler/rustc_expand/src/expand.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 8b897aa3c5f96..48a0cc575fbeb 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1336,8 +1336,6 @@ impl InvocationCollectorNode for Box { return Ok(walk_flat_map(node, collector)); } - // Work around borrow checker not seeing through `P`'s deref. - let (span, mut attrs) = (node.span, mem::take(&mut node.attrs)); let ItemKind::Mod(_, ident, ref mut mod_kind) = node.kind else { unreachable!() }; let ecx = &mut collector.cx; let (file_path, dir_path, dir_ownership) = match mod_kind { @@ -1346,7 +1344,7 @@ impl InvocationCollectorNode for Box { let (dir_path, dir_ownership) = mod_dir_path( ecx.sess, ident, - &attrs, + &node.attrs, &ecx.current_expansion.module, ecx.current_expansion.dir_ownership, *inline, @@ -1355,14 +1353,13 @@ impl InvocationCollectorNode for Box { // This lets `parse_external_mod` catch cycles if it's self-referential. let file_path = match inline { Inline::Yes => None, - Inline::No { .. } => mod_file_path_from_attr(ecx.sess, &attrs, &dir_path), + Inline::No { .. } => mod_file_path_from_attr(ecx.sess, &node.attrs, &dir_path), }; - node.attrs = attrs; (file_path, dir_path, dir_ownership) } ModKind::Unloaded => { // We have an outline `mod foo;` so we need to parse the file. - let old_attrs_len = attrs.len(); + let old_attrs_len = node.attrs.len(); let ParsedExternalMod { items, spans, @@ -1373,10 +1370,10 @@ impl InvocationCollectorNode for Box { } = parse_external_mod( ecx.sess, ident, - span, + node.span, &ecx.current_expansion.module, ecx.current_expansion.dir_ownership, - &mut attrs, + &mut node.attrs, ); if let Some(lint_store) = ecx.lint_store { @@ -1385,14 +1382,13 @@ impl InvocationCollectorNode for Box { ecx.ecfg.features, ecx.resolver.registered_tools(), ecx.current_expansion.lint_node_id, - &attrs, + &node.attrs, &items, ident.name, ); } *mod_kind = ModKind::Loaded(items, Inline::No { had_parse_error }, spans); - node.attrs = attrs; if node.attrs.len() > old_attrs_len { // If we loaded an out-of-line module and added some inner attributes, // then we need to re-configure it and re-collect attributes for From baffab0f9a83556063b939689cb76b1ed67cd50f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 22 Jul 2026 14:58:16 -0400 Subject: [PATCH 65/68] 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 bdd6ca864badb2240a768d174e082a3351252854 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 23 Jul 2026 17:51:17 +0200 Subject: [PATCH 66/68] use lowest edition the test accepts --- tests/ui/delegation/hir-crate-items-before-lowering-ices.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs index aaf84514eb784..3dda014001421 100644 --- a/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs +++ b/tests/ui/delegation/hir-crate-items-before-lowering-ices.rs @@ -1,5 +1,5 @@ //@ revisions: ice_155125 ice_155127 ice_155128 ice_155164 ice_155202 -//@[ice_155202] edition: 2024 +//@[ice_155202] edition: 2018.. #![feature(min_generic_const_args, fn_delegation)] From cd9fd520d995c70dd7b06c89f6b86fbfecbb6741 Mon Sep 17 00:00:00 2001 From: zedddie Date: Thu, 16 Jul 2026 23:51:26 +0200 Subject: [PATCH 67/68] 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 From d1c358202631e37120461a5c14e6fab1a2eed3a7 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Thu, 23 Jul 2026 12:12:56 -0700 Subject: [PATCH 68/68] handle bound vars in rpit method chain suggestion --- .../src/error_reporting/traits/suggestions.rs | 142 +++++++++--------- .../ui/iterators/rpit-method-chain-no-ice.rs | 14 ++ .../iterators/rpit-method-chain-no-ice.stderr | 22 +++ 3 files changed, 108 insertions(+), 70 deletions(-) create mode 100644 tests/ui/iterators/rpit-method-chain-no-ice.rs create mode 100644 tests/ui/iterators/rpit-method-chain-no-ice.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 2a1f0e7935ea0..b4f55e27048e2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -5487,81 +5487,83 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if !matches!(tcx.def_kind(body_def_id), DefKind::Fn | DefKind::AssocFn) { return; } - let output = - tcx.fn_sig(body_def_id).instantiate_identity().skip_norm_wip().output().skip_binder(); - let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: opaque_def_id }, args, .. }) = - output.kind() - else { - return; - }; - - // The predicate that reaches here has been rewritten through the impls it was - // derived from (e.g. `Iterator for Map` turns `Iterator::Item` requirements - // into requirements on `F`'s return type), so the associated types the user wrote - // in the signature are recovered from the opaque's bounds instead. - let mut probe_diffs = vec![]; - for clause in tcx.item_bounds(opaque_def_id).instantiate(tcx, args).skip_norm_wip() { - let Some(proj) = clause.as_projection_clause() else { continue }; - let proj = self.instantiate_binder_with_fresh_vars( - expr.span, - BoundRegionConversionTime::FnCall, - proj, - ); - let Some(expected_term) = proj.term.as_type() else { continue }; - // Only the projection (for its `DefId`) is used when probing the chain; the - // bound's own term is carried in `found` for the divergence check below and - // is replaced with the probed type afterwards. - probe_diffs.push(TypeError::Sorts(ty::error::ExpectedFound { - expected: proj.projection_term.expect_ty().to_ty(tcx, ty::IsRigid::No), - found: expected_term, - })); - } - if probe_diffs.is_empty() { - return; - } - - // If the returned expression is a binding, walk the chain that created it instead. - let expr = if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind - && let hir::Path { res: Res::Local(hir_id), .. } = path - && let hir::Node::Pat(binding) = tcx.hir_node(*hir_id) - && let hir::Node::LetStmt(local) = tcx.parent_hir_node(binding.hir_id) - && let Some(binding_expr) = local.init - { - binding_expr - } else { - expr - }; - // Resolve what each bound associated type actually is for the returned expression, - // and keep only the ones that diverged from the signature. - let expr_ty = self.resolve_vars_if_possible( - typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)), - ); - let assocs = self.probe_assoc_types_at_expr( - &probe_diffs, - expr.span, - expr_ty, - expr.hir_id, - param_env, - ); - let mut type_diffs = vec![]; - for (probe_diff, assoc) in iter::zip(probe_diffs, assocs) { - let TypeError::Sorts(ty::error::ExpectedFound { expected, found: expected_term }) = - probe_diff + let binder = tcx.fn_sig(body_def_id).instantiate_identity().skip_norm_wip().output(); + self.enter_forall(binder, |output| { + let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: opaque_def_id }, args, .. }) = + output.kind() else { - continue; + return; }; - let Some((_, (_, actual_ty))) = assoc else { continue }; - if !self.can_eq(param_env, expected_term, actual_ty) { - type_diffs.push(TypeError::Sorts(ty::error::ExpectedFound { - expected, - found: actual_ty, + + // The predicate that reaches here has been rewritten through the impls it was + // derived from (e.g. `Iterator for Map` turns `Iterator::Item` requirements + // into requirements on `F`'s return type), so the associated types the user wrote + // in the signature are recovered from the opaque's bounds instead. + let mut probe_diffs = vec![]; + for clause in tcx.item_bounds(opaque_def_id).instantiate(tcx, args).skip_norm_wip() { + let Some(proj) = clause.as_projection_clause() else { continue }; + let proj = self.instantiate_binder_with_fresh_vars( + expr.span, + BoundRegionConversionTime::FnCall, + proj, + ); + let Some(expected_term) = proj.term.as_type() else { continue }; + // Only the projection (for its `DefId`) is used when probing the chain; the + // bound's own term is carried in `found` for the divergence check below and + // is replaced with the probed type afterwards. + probe_diffs.push(TypeError::Sorts(ty::error::ExpectedFound { + expected: proj.projection_term.expect_ty().to_ty(tcx, ty::IsRigid::No), + found: expected_term, })); } - } - if !type_diffs.is_empty() { - self.point_at_chain(expr, typeck_results, type_diffs, param_env, err); - } + if probe_diffs.is_empty() { + return; + } + + // If the returned expression is a binding, walk the chain that created it instead. + let expr = if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind + && let hir::Path { res: Res::Local(hir_id), .. } = path + && let hir::Node::Pat(binding) = tcx.hir_node(*hir_id) + && let hir::Node::LetStmt(local) = tcx.parent_hir_node(binding.hir_id) + && let Some(binding_expr) = local.init + { + binding_expr + } else { + expr + }; + + // Resolve what each bound associated type actually is for the returned expression, + // and keep only the ones that diverged from the signature. + let expr_ty = self.resolve_vars_if_possible( + typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(tcx)), + ); + let assocs = self.probe_assoc_types_at_expr( + &probe_diffs, + expr.span, + expr_ty, + expr.hir_id, + param_env, + ); + let mut type_diffs = vec![]; + for (probe_diff, assoc) in iter::zip(probe_diffs, assocs) { + let TypeError::Sorts(ty::error::ExpectedFound { expected, found: expected_term }) = + probe_diff + else { + continue; + }; + let Some((_, (_, actual_ty))) = assoc else { continue }; + if !self.can_eq(param_env, expected_term, actual_ty) { + type_diffs.push(TypeError::Sorts(ty::error::ExpectedFound { + expected, + found: actual_ty, + })); + } + } + if !type_diffs.is_empty() { + self.point_at_chain(expr, typeck_results, type_diffs, param_env, err); + } + }); } /// If the type that failed selection is an array or a reference to an array, diff --git a/tests/ui/iterators/rpit-method-chain-no-ice.rs b/tests/ui/iterators/rpit-method-chain-no-ice.rs new file mode 100644 index 0000000000000..170653f0eeaf3 --- /dev/null +++ b/tests/ui/iterators/rpit-method-chain-no-ice.rs @@ -0,0 +1,14 @@ +//! Regression test for #159685 + +struct EntriesBuffer(Box<[u8]>); + +impl EntriesBuffer { + fn has_lifetime(&self) -> impl Iterator { + //~^ ERROR expected `IterMut<'_, u8>` to be an iterator that yields `&mut str`, but it yields `&mut u8` + self.0.iter_mut() + } +} + +fn main() { + EntriesBuffer(vec![0u8].into_boxed_slice()).has_lifetime(); +} diff --git a/tests/ui/iterators/rpit-method-chain-no-ice.stderr b/tests/ui/iterators/rpit-method-chain-no-ice.stderr new file mode 100644 index 0000000000000..74e33cecf3523 --- /dev/null +++ b/tests/ui/iterators/rpit-method-chain-no-ice.stderr @@ -0,0 +1,22 @@ +error[E0271]: expected `IterMut<'_, u8>` to be an iterator that yields `&mut str`, but it yields `&mut u8` + --> $DIR/rpit-method-chain-no-ice.rs:6:31 + | +LL | fn has_lifetime(&self) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&mut str`, found `&mut u8` +LL | +LL | self.0.iter_mut() + | ----------------- return type was inferred to be `std::slice::IterMut<'_, u8>` here + | + = note: expected mutable reference `&mut str` + found mutable reference `&mut u8` +note: the method call chain might not have had the expected associated types + --> $DIR/rpit-method-chain-no-ice.rs:8:16 + | +LL | self.0.iter_mut() + | ------ ^^^^^^^^^^ `Iterator::Item` is `&mut u8` here + | | + | this expression has type `Box<[u8]>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`.