From 5065a91d7fc4c7528a310bdb865b5a567e31e737 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Sat, 21 Dec 2024 16:36:18 +0100 Subject: [PATCH 01/13] Improve prose around `as_slice` example of IterMut I've removed the cryptic message about not being able to call `&mut self` methods while retaining a shared borrow of the iterator, such as `as_slice` produces. This is just normal borrowing rules and does not seem especially relevant here. I can whip up a replacement if someone thinks it has value. --- library/core/src/slice/iter.rs | 42 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index d2842f69008e2..a687ed7129dc8 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -49,7 +49,7 @@ impl<'a, T> IntoIterator for &'a mut [T] { /// // First, we need a slice to call the `iter` method on: /// let slice = &[1, 2, 3]; /// -/// // Then we call `iter` on the slice to get the `Iter` struct, +/// // Then we call `iter` on the slice to get the `Iter` iterator, /// // and iterate over it: /// for element in slice.iter() { /// println!("{element}"); @@ -107,24 +107,20 @@ impl<'a, T> Iter<'a, T> { /// Views the underlying data as a subslice of the original data. /// - /// This has the same lifetime as the original slice, and so the - /// iterator can continue to be used while this exists. - /// /// # Examples /// /// Basic usage: /// /// ``` /// // First, we need a slice to call the `iter` method on: - /// // struct (`&[usize]` here): /// let slice = &[1, 2, 3]; /// - /// // Then we call `iter` on the slice to get the `Iter` struct: + /// // Then we call `iter` on the slice to get the `Iter` iterator: /// let mut iter = slice.iter(); /// // Here `as_slice` still returns the whole slice, so this prints "[1, 2, 3]": /// println!("{:?}", iter.as_slice()); /// - /// // Now, we call the `next` method to remove the first element of the iterator: + /// // Now, we call the `next` method to remove the first element from the iterator: /// iter.next(); /// // Here the iterator does not contain the first element of the slice any more, /// // so `as_slice` only returns the last two elements of the slice, @@ -181,7 +177,7 @@ impl AsRef<[T]> for Iter<'_, T> { /// // First, we need a slice to call the `iter_mut` method on: /// let slice = &mut [1, 2, 3]; /// -/// // Then we call `iter_mut` on the slice to get the `IterMut` struct, +/// // Then we call `iter_mut` on the slice to get the `IterMut` iterator, /// // iterate over it and increment each element value: /// for element in slice.iter_mut() { /// *element += 1; @@ -286,25 +282,30 @@ impl<'a, T> IterMut<'a, T> { /// Views the underlying data as a subslice of the original data. /// - /// To avoid creating `&mut [T]` references that alias, the returned slice - /// borrows its lifetime from the iterator the method is applied on. - /// /// # Examples /// /// Basic usage: /// /// ``` - /// let mut slice: &mut [usize] = &mut [1, 2, 3]; + /// // First, we need a slice to call the `iter_mut` method on: + /// let slice = &mut [1, 2, 3]; /// - /// // First, we get the iterator: + /// // Then we call `iter_mut` on the slice to get the `IterMut` iterator: /// let mut iter = slice.iter_mut(); - /// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]": - /// assert_eq!(iter.as_slice(), &[1, 2, 3]); + /// // Here `as_slice` still returns the whole slice, so this prints "[1, 2, 3]": + /// println!("{:?}", iter.as_slice()); /// - /// // Next, we move to the second element of the slice: - /// iter.next(); - /// // Now `as_slice` returns "[2, 3]": - /// assert_eq!(iter.as_slice(), &[2, 3]); + /// // Now, we call the `next` method to remove the first element from the iterator + /// // and increment its value: + /// *iter.next().unwrap() += 1; + /// // Here the iterator does not contain the first element of the slice any more, + /// // so `as_slice` only returns the last two elements of the slice, + /// // and so this prints "[2, 3]": + /// println!("{:?}", iter.as_slice()); + /// + /// // The underlying slice still contains three elements, but its first element + /// // was increased by 1, so this prints "[2, 2, 3]": + /// println!("{:?}", slice); /// ``` #[must_use] #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")] @@ -315,9 +316,6 @@ impl<'a, T> IterMut<'a, T> { /// Views the underlying data as a mutable subslice of the original data. /// - /// To avoid creating `&mut [T]` references that alias, the returned slice - /// borrows its lifetime from the iterator the method is applied on. - /// /// # Examples /// /// Basic usage: From 5966ba0424e75accc4be35c2e334791a98c23aaf Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Dec 2024 00:26:47 +0100 Subject: [PATCH 02/13] Fix ptr::from_ref documentation example comment The comment says that the expression involves no function call, but that was only true for the example above, the example here _does_ contain a function call. --- library/core/src/ptr/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index e6e13eaff7b0f..d2b60f06e4559 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -777,7 +777,7 @@ pub fn with_exposed_provenance_mut(addr: usize) -> *mut T { /// # type T = i32; /// # fn foo() -> T { 42 } /// // The temporary holding the return value of `foo` does *not* have its lifetime extended, -/// // because the surrounding expression involves no function call. +/// // because the surrounding expression involves a function call. /// let p = ptr::from_ref(&foo()); /// unsafe { p.read() }; // UB! Reading from a dangling pointer ⚠️ /// ``` @@ -828,7 +828,7 @@ pub const fn from_ref(r: &T) -> *const T { /// # type T = i32; /// # fn foo() -> T { 42 } /// // The temporary holding the return value of `foo` does *not* have its lifetime extended, -/// // because the surrounding expression involves no function call. +/// // because the surrounding expression involves a function call. /// let p = ptr::from_mut(&mut foo()); /// unsafe { p.write(T::default()) }; // UB! Writing to a dangling pointer ⚠️ /// ``` From 326fedf3097e1e2974491318c0266f9c11577b21 Mon Sep 17 00:00:00 2001 From: Noa Date: Wed, 8 Jan 2025 22:43:09 -0600 Subject: [PATCH 03/13] Add Pin::as_deref_mut to relnotes --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index 7c2c2406e9062..13102734a8c1f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -60,6 +60,7 @@ Stabilized APIs - [`core::ptr::without_provenance_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.without_provenance_mut.html) - [`core::ptr::dangling`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling.html) - [`core::ptr::dangling_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling_mut.html) +- [`Pin::as_deref_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.as_deref_mut) These APIs are now stable in const contexts From 00448ab45ab952749d4d4d14894cee8ff3231cd3 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 9 Jan 2025 17:32:29 +0000 Subject: [PATCH 04/13] Make bare-fn test less dependent on path width --- .../fn-pointer/bare-fn-no-impl-fn-ptr-99875.rs | 2 ++ .../fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.rs b/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.rs index cf73fd8d31fbb..f776a6ce4c12f 100644 --- a/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.rs +++ b/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.rs @@ -1,3 +1,5 @@ +// Sets some arbitrarily large width for more consistent output (see #135288). +//@ compile-flags: --diagnostic-width=120 struct Argument; struct Return; diff --git a/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr b/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr index 5b89158b0dba2..ba0af763975d4 100644 --- a/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr +++ b/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied - --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:12:11 + --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11 | LL | takes(function); | ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}` @@ -7,7 +7,7 @@ LL | takes(function); | required by a bound introduced by this call | note: required by a bound in `takes` - --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:9:18 + --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:11:18 | LL | fn takes(_: impl Trait) {} | ^^^^^ required by this bound in `takes` @@ -16,18 +16,18 @@ help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return`, LL | takes(function as fn(Argument) -> Return); | +++++++++++++++++++++++++ -error[E0277]: the trait bound `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11: 14:34}: Trait` is not satisfied - --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11 +error[E0277]: the trait bound `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:16:11: 16:34}: Trait` is not satisfied + --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:16:11 | LL | takes(|_: Argument| -> Return { todo!() }); | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound | | | required by a bound introduced by this call | - = help: the trait `Trait` is not implemented for closure `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11: 14:34}` + = help: the trait `Trait` is not implemented for closure `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:16:11: 16:34}` = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return` note: required by a bound in `takes` - --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:9:18 + --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:11:18 | LL | fn takes(_: impl Trait) {} | ^^^^^ required by this bound in `takes` From 5e505189cd2b5355eb4b24bdce7aca7ca4e65189 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 9 Jan 2025 21:25:59 +0100 Subject: [PATCH 05/13] Add tests cases from review of #132289 --- .../auxiliary/pr_review_132289_2_lib.rs | 37 +++++++++++++ .../auxiliary/pr_review_132289_3_lib.rs | 12 +++++ tests/ui/coherence/pr-review-132289-1.rs | 52 +++++++++++++++++++ tests/ui/coherence/pr-review-132289-2.rs | 26 ++++++++++ tests/ui/coherence/pr-review-132289-3.rs | 50 ++++++++++++++++++ .../coherence/pr-review-132289-3.run.stdout | 1 + 6 files changed, 178 insertions(+) create mode 100644 tests/ui/coherence/auxiliary/pr_review_132289_2_lib.rs create mode 100644 tests/ui/coherence/auxiliary/pr_review_132289_3_lib.rs create mode 100644 tests/ui/coherence/pr-review-132289-1.rs create mode 100644 tests/ui/coherence/pr-review-132289-2.rs create mode 100644 tests/ui/coherence/pr-review-132289-3.rs create mode 100644 tests/ui/coherence/pr-review-132289-3.run.stdout diff --git a/tests/ui/coherence/auxiliary/pr_review_132289_2_lib.rs b/tests/ui/coherence/auxiliary/pr_review_132289_2_lib.rs new file mode 100644 index 0000000000000..4b79147dce109 --- /dev/null +++ b/tests/ui/coherence/auxiliary/pr_review_132289_2_lib.rs @@ -0,0 +1,37 @@ +pub type A = &'static [usize; 1]; +pub type B = &'static [usize; 100]; + +pub trait Trait

{ + type Assoc; +} + +pub type Dyn

= dyn Trait; + +pub trait LocallyUnimplemented

{} + +impl Trait

for T +where + T: LocallyUnimplemented

, +{ + type Assoc = B; +} + +trait MakeArray { + fn make() -> &'static Arr; +} +impl MakeArray<[usize; N]> for () { + fn make() -> &'static [usize; N] { + &[1337; N] + } +} + +// it would be sound for this return type to be interpreted as being +// either of A or B, if that's what a soundness fix for overlap of +// dyn Trait's impls would entail + +// In this test, we check at the call-site that the interpretation +// is consistent across crates in this specific scenario. +pub fn function

() -> ( as Trait

>::Assoc, usize) { + let val = <() as MakeArray<_>>::make(); + (val, val.len()) +} diff --git a/tests/ui/coherence/auxiliary/pr_review_132289_3_lib.rs b/tests/ui/coherence/auxiliary/pr_review_132289_3_lib.rs new file mode 100644 index 0000000000000..f90be3b2487e5 --- /dev/null +++ b/tests/ui/coherence/auxiliary/pr_review_132289_3_lib.rs @@ -0,0 +1,12 @@ +use std::ops::Index; + +pub trait Trait { + fn f(&self) + where + dyn Index<(), Output = ()>: Index<()>; + // rustc (correctly) determines ^^^^^^^^ this bound to be true +} + +pub fn call(x: &dyn Trait) { + x.f(); // so we can call `f` +} diff --git a/tests/ui/coherence/pr-review-132289-1.rs b/tests/ui/coherence/pr-review-132289-1.rs new file mode 100644 index 0000000000000..ab3ed9655e071 --- /dev/null +++ b/tests/ui/coherence/pr-review-132289-1.rs @@ -0,0 +1,52 @@ +// This is a regression test for issues that came up during review of the (closed) +// PR #132289; this single-crate test case is +// the first example from @steffahn during review. +// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564492153 + +//@ check-pass + +type A = &'static [usize; 1]; +type B = &'static [usize; 100]; + +type DynSomething = dyn Something; + +trait Super { + type Assoc; +} +impl Super for Foo { + type Assoc = A; +} + +trait IsDynSomething {} +impl IsDynSomething for DynSomething {} + +impl Super for T +where + T: IsDynSomething, +{ + type Assoc = B; +} + +trait Something: Super { + fn method(&self) -> Self::Assoc; +} + +struct Foo; +impl Something for Foo { + fn method(&self) -> Self::Assoc { + &[1337] + } +} + +fn main() { + let x = &Foo; + let y: &DynSomething = x; + + // no surprises here + let _arr1: A = x.method(); + + // this (`_arr2`) can't ever become B either, soundly + let _arr2: A = y.method(); + // there aren't any other arrays being defined anywhere in this + // test case, besides the length-1 one containing [1337] +} diff --git a/tests/ui/coherence/pr-review-132289-2.rs b/tests/ui/coherence/pr-review-132289-2.rs new file mode 100644 index 0000000000000..95ad86c61ff19 --- /dev/null +++ b/tests/ui/coherence/pr-review-132289-2.rs @@ -0,0 +1,26 @@ +// This is a regression test for issues that came up during review of the (closed) +// PR #132289; this 2-crate test case is adapted from +// the second example from @steffahn during review. +// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564587796 + +//@ run-pass +//@ aux-build: pr_review_132289_2_lib.rs + +extern crate pr_review_132289_2_lib; + +use pr_review_132289_2_lib::{function, Dyn, LocallyUnimplemented}; + +struct Param; + +impl LocallyUnimplemented for Dyn {} + +// it would be sound for `function::`'s return type to be +// either of A or B, if that's what a soundness fix for overlap of +// dyn Trait's impls would entail + +// In this test, we check at this call-site that the interpretation +// is consistent with the function definition's body. +fn main() { + let (arr, len) = function::(); + assert_eq!(arr.len(), len); +} diff --git a/tests/ui/coherence/pr-review-132289-3.rs b/tests/ui/coherence/pr-review-132289-3.rs new file mode 100644 index 0000000000000..7e597baa6ec29 --- /dev/null +++ b/tests/ui/coherence/pr-review-132289-3.rs @@ -0,0 +1,50 @@ +// This is a regression test for issues that came up during review of the (closed) +// PR #132289; this 3-ish-crate (including std) test case is adapted from +// the third example from @steffahn during review. +// https://github.com/rust-lang/rust/pull/132289#issuecomment-2564599221 + +//@ run-pass +//@ check-run-results +//@ aux-build: pr_review_132289_3_lib.rs + +extern crate pr_review_132289_3_lib; + +use std::ops::Index; + +use pr_review_132289_3_lib::{call, Trait}; + +trait SubIndex: Index {} + +struct Param; + +trait Project { + type Ty: ?Sized; +} +impl Project for () { + type Ty = dyn SubIndex; +} + +impl Index for <() as Project>::Ty { + type Output = (); + + fn index(&self, _: Param) -> &() { + &() + } +} + +struct Struct; + +impl Trait for Struct { + fn f(&self) + where + // higher-ranked to allow potentially-false bounds + for<'a> dyn Index<(), Output = ()>: Index<()>, + // after #132289 rustc used to believe this bound false + { + println!("hello!"); + } +} + +fn main() { + call(&Struct); // <- would segfault if the method `f` wasn't part of the vtable +} diff --git a/tests/ui/coherence/pr-review-132289-3.run.stdout b/tests/ui/coherence/pr-review-132289-3.run.stdout new file mode 100644 index 0000000000000..4effa19f4f75f --- /dev/null +++ b/tests/ui/coherence/pr-review-132289-3.run.stdout @@ -0,0 +1 @@ +hello! From 13e8876ed43454b7104596264cd415032ff5b145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 28 Dec 2024 17:45:17 +0000 Subject: [PATCH 06/13] Add `default_field_values` entry to unstable book --- .../language-features/default-field-values.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/doc/unstable-book/src/language-features/default-field-values.md diff --git a/src/doc/unstable-book/src/language-features/default-field-values.md b/src/doc/unstable-book/src/language-features/default-field-values.md new file mode 100644 index 0000000000000..3143b2d7cae3d --- /dev/null +++ b/src/doc/unstable-book/src/language-features/default-field-values.md @@ -0,0 +1,93 @@ +# `default_field_values` + +The tracking issue for this feature is: [#132162] + +[#132162]: https://github.com/rust-lang/rust/issues/132162 + +The RFC for this feature is: [#3681] + +[#3681]: https://github.com/rust-lang/rfcs/blob/master/text/3681-default-field-values.md + +------------------------ + +The `default_field_values` feature allows users to specify a const value for +individual fields in struct definitions, allowing those to be omitted from +initializers. + +## Examples + +```rust +#![feature(default_field_values)] + +#[derive(Default)] +struct Pet { + name: Option, // impl Default for Pet will use Default::default() for name + age: i128 = 42, // impl Default for Pet will use the literal 42 for age +} + +fn main() { + let a = Pet { name: Some(String::new()), .. }; // Pet { name: Some(""), age: 42 } + let b = Pet::default(); // Pet { name: None, age: 42 } + assert_eq!(a.age, b.age); + // The following would be a compilation error: `name` needs to be specified + // let _ = Pet { .. }; +} +``` + +## `#[derive(Default)]` + +When deriving Default, the provided values are then used. On enum variants, +the variant must still be marked with `#[default]` and have all its fields +with default values. + +```rust +#![feature(default_field_values)] + +#[derive(Default)] +enum A { + #[default] + B { + x: i32 = 0, + y: i32 = 0, + }, + C, +} +``` + +## Enum variants + +This feature also supports enum variants for both specifying default values +and `#[derive(Default)]`. + +## Interaction with `#[non_exhaustive]` + +A struct or enum variant marked with `#[non_exhaustive]` is not allowed to +have default field values. + +## Lints + +When manually implementing the `Default` trait for a type that has default +field values, if any of these are overriden in the impl the +`default_overrides_default_fields` lint will trigger. This lint is in place +to avoid surprising diverging behavior between `S { .. }` and +`S::default()`, where using the same type in both ways could result in +different values. The appropriate way to write a manual `Default` +implementation is to use the functional update syntax: + +```rust +#![feature(default_field_values)] + +struct Pet { + name: String, + age: i128 = 42, // impl Default for Pet will use the literal 42 for age +} + +impl Default for Pet { + fn default() -> Pet { + Pet { + name: "no-name".to_string(), + .. + } + } +} +``` From 9d2e1ed6bd86047f724c8bde4f79561024d13fb8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Jan 2025 22:16:51 +0000 Subject: [PATCH 07/13] Make sure to walk into nested const blocks in RegionResolutionVisitor --- compiler/rustc_hir_analysis/src/check/region.rs | 12 ++++++++---- tests/ui/inline-const/collect-scopes-in-pat.rs | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 tests/ui/inline-const/collect-scopes-in-pat.rs diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index e5f98bdfb7fed..daea2e98b03f8 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -420,10 +420,10 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h // properly, we can't miss any types. match expr.kind { - // Manually recurse over closures and inline consts, because they are the only - // case of nested bodies that share the parent environment. - hir::ExprKind::Closure(&hir::Closure { body, .. }) - | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => { + // Manually recurse over closures, because they are nested bodies + // that share the parent environment. We handle const blocks in + // `visit_inline_const`. + hir::ExprKind::Closure(&hir::Closure { body, .. }) => { let body = visitor.tcx.hir().body(body); visitor.visit_body(body); } @@ -906,6 +906,10 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) { resolve_local(self, Some(l.pat), l.init) } + fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) { + let body = self.tcx.hir().body(c.body); + self.visit_body(body); + } } /// Per-body `region::ScopeTree`. The `DefId` should be the owner `DefId` for the body; diff --git a/tests/ui/inline-const/collect-scopes-in-pat.rs b/tests/ui/inline-const/collect-scopes-in-pat.rs new file mode 100644 index 0000000000000..024fde537413f --- /dev/null +++ b/tests/ui/inline-const/collect-scopes-in-pat.rs @@ -0,0 +1,16 @@ +// @compile-flags: -Zlint-mir +//@ check-pass + +#![feature(inline_const_pat)] + +fn main() { + match 1 { + const { + || match 0 { + x => 0, + }; + 0 + } => (), + _ => (), + } +} From 9585f3667860b9ccfa3224d5a5e63661e6861d9d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Jan 2025 22:17:10 +0000 Subject: [PATCH 08/13] Rename RegionResolutionVisitor to ScopeResolutionVisitor --- .../rustc_hir_analysis/src/check/region.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index daea2e98b03f8..83c69dc2ef415 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -31,7 +31,7 @@ struct Context { parent: Option<(Scope, ScopeDepth)>, } -struct RegionResolutionVisitor<'tcx> { +struct ScopeResolutionVisitor<'tcx> { tcx: TyCtxt<'tcx>, // The number of expressions and patterns visited in the current body. @@ -71,7 +71,7 @@ struct RegionResolutionVisitor<'tcx> { } /// Records the lifetime of a local variable as `cx.var_parent` -fn record_var_lifetime(visitor: &mut RegionResolutionVisitor<'_>, var_id: hir::ItemLocalId) { +fn record_var_lifetime(visitor: &mut ScopeResolutionVisitor<'_>, var_id: hir::ItemLocalId) { match visitor.cx.var_parent { None => { // this can happen in extern fn declarations like @@ -82,7 +82,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor<'_>, var_id: hir::I } } -fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx hir::Block<'tcx>) { +fn resolve_block<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, blk: &'tcx hir::Block<'tcx>) { debug!("resolve_block(blk.hir_id={:?})", blk.hir_id); let prev_cx = visitor.cx; @@ -193,7 +193,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h visitor.cx = prev_cx; } -fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) { +fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) { fn has_let_expr(expr: &Expr<'_>) -> bool { match &expr.kind { hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), @@ -220,7 +220,7 @@ fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir visitor.cx = prev_cx; } -fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) { +fn resolve_pat<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, pat: &'tcx hir::Pat<'tcx>) { visitor.record_child_scope(Scope { local_id: pat.hir_id.local_id, data: ScopeData::Node }); // If this is a binding then record the lifetime of that binding. @@ -237,7 +237,7 @@ fn resolve_pat<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, pat: &'tcx hir debug!("resolve_pat - post-increment {} pat = {:?}", visitor.expr_and_pat_count, pat); } -fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) { +fn resolve_stmt<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, stmt: &'tcx hir::Stmt<'tcx>) { let stmt_id = stmt.hir_id.local_id; debug!("resolve_stmt(stmt.id={:?})", stmt_id); @@ -256,7 +256,7 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h visitor.cx.parent = prev_parent; } -fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) { +fn resolve_expr<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) { debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr); let prev_cx = visitor.cx; @@ -554,7 +554,7 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h } fn resolve_local<'tcx>( - visitor: &mut RegionResolutionVisitor<'tcx>, + visitor: &mut ScopeResolutionVisitor<'tcx>, pat: Option<&'tcx hir::Pat<'tcx>>, init: Option<&'tcx hir::Expr<'tcx>>, ) { @@ -725,7 +725,7 @@ fn resolve_local<'tcx>( /// | ( E& ) /// ``` fn record_rvalue_scope_if_borrow_expr<'tcx>( - visitor: &mut RegionResolutionVisitor<'tcx>, + visitor: &mut ScopeResolutionVisitor<'tcx>, expr: &hir::Expr<'_>, blk_id: Option, ) { @@ -782,7 +782,7 @@ fn resolve_local<'tcx>( } } -impl<'tcx> RegionResolutionVisitor<'tcx> { +impl<'tcx> ScopeResolutionVisitor<'tcx> { /// Records the current parent (if any) as the parent of `child_scope`. /// Returns the depth of `child_scope`. fn record_child_scope(&mut self, child_scope: Scope) -> ScopeDepth { @@ -838,7 +838,7 @@ impl<'tcx> RegionResolutionVisitor<'tcx> { } } -impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { +impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { fn visit_block(&mut self, b: &'tcx Block<'tcx>) { resolve_block(self, b); } @@ -926,7 +926,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { } let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { - let mut visitor = RegionResolutionVisitor { + let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(), expr_and_pat_count: 0, From a75617c223ca4476625c20565a3e1ff51d384102 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 16 Nov 2024 01:55:07 +0100 Subject: [PATCH 09/13] Foo != Foo under layout randomization previously field ordering was using the same seed for all instances of Foo, now we pass seed values through the layout tree so that not only the struct itself affects layout but also its fields --- compiler/rustc_abi/src/layout.rs | 37 ++++++++++++++++++++++-- compiler/rustc_abi/src/lib.rs | 39 ++++++++++++++++++++++++++ compiler/rustc_middle/src/ty/layout.rs | 1 + compiler/rustc_ty_utils/src/layout.rs | 10 +++++++ tests/ui/layout/randomize.rs | 29 +++++++++++++++++++ 5 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 tests/ui/layout/randomize.rs diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 226a46f605cc4..3b897c1cb3e51 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -119,6 +119,8 @@ impl LayoutCalculator { .chain(Niche::from_scalar(dl, Size::ZERO, a)) .max_by_key(|niche| niche.available(dl)); + let combined_seed = a.size(&self.cx).bytes().wrapping_add(b.size(&self.cx).bytes()); + LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { @@ -131,6 +133,7 @@ impl LayoutCalculator { size, max_repr_align: None, unadjusted_abi_align: align.abi, + randomization_seed: combined_seed, } } @@ -223,6 +226,7 @@ impl LayoutCalculator { size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, + randomization_seed: 0, } } @@ -385,6 +389,11 @@ impl LayoutCalculator { return Err(LayoutCalculatorError::EmptyUnion); }; + let combined_seed = only_variant + .iter() + .map(|v| v.randomization_seed) + .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); + Ok(LayoutData { variants: Variants::Single { index: only_variant_idx }, fields: FieldsShape::Union(union_field_count), @@ -394,6 +403,7 @@ impl LayoutCalculator { size: size.align_to(align.abi), max_repr_align, unadjusted_abi_align, + randomization_seed: combined_seed, }) } @@ -650,6 +660,11 @@ impl LayoutCalculator { BackendRepr::Memory { sized: true } }; + let combined_seed = variant_layouts + .iter() + .map(|v| v.randomization_seed) + .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); + let layout = LayoutData { variants: Variants::Multiple { tag: niche_scalar, @@ -671,6 +686,7 @@ impl LayoutCalculator { align, max_repr_align, unadjusted_abi_align, + randomization_seed: combined_seed, }; Some(TmpLayout { layout, variants: variant_layouts }) @@ -961,6 +977,11 @@ impl LayoutCalculator { let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag); + let combined_seed = layout_variants + .iter() + .map(|v| v.randomization_seed) + .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); + let tagged_layout = LayoutData { variants: Variants::Multiple { tag, @@ -978,6 +999,7 @@ impl LayoutCalculator { size, max_repr_align, unadjusted_abi_align, + randomization_seed: combined_seed, }; let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants }; @@ -1029,6 +1051,8 @@ impl LayoutCalculator { let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut max_repr_align = repr.align; let mut inverse_memory_index: IndexVec = fields.indices().collect(); + let field_seed = + fields.raw.iter().fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed)); let optimize_field_order = !repr.inhibit_struct_field_reordering(); if optimize_field_order && fields.len() > 1 { let end = @@ -1046,8 +1070,9 @@ impl LayoutCalculator { use rand::seq::SliceRandom; // `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field // ordering. - let mut rng = - rand_xoshiro::Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed); + let mut rng = rand_xoshiro::Xoshiro128StarStar::seed_from_u64( + field_seed.wrapping_add(repr.field_shuffle_seed), + ); // Shuffle the ordering of the fields. optimizing.shuffle(&mut rng); @@ -1344,6 +1369,13 @@ impl LayoutCalculator { unadjusted_abi_align }; + // a transparent struct only has a single field, so its seed should be the same as the one we pass forward + let seed = if repr.transparent() { + field_seed + } else { + field_seed.wrapping_add(repr.field_shuffle_seed) + }; + Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Arbitrary { offsets, memory_index }, @@ -1353,6 +1385,7 @@ impl LayoutCalculator { size, max_repr_align, unadjusted_abi_align, + randomization_seed: seed, }) } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 7fa869a509cc3..8ad33749f3473 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1719,6 +1719,18 @@ pub struct LayoutData { /// Only used on aarch64-linux, where the argument passing ABI ignores the requested alignment /// in some cases. pub unadjusted_abi_align: Align, + + /// The randomization seed based on this type's own repr and its fields. + /// + /// Since randomization is toggled on a per-crate basis even crates that do not have randomization + /// enabled should still calculate a seed so that downstream uses can use it to distinguish different + /// types. + /// + /// For every T and U for which we do not guarantee that a repr(Rust) `Foo` can be coerced or + /// transmuted to `Foo` we aim to create probalistically distinct seeds so that Foo can choose + /// to reorder its fields based on that information. The current implementation is a conservative + /// approximation of this goal. + pub randomization_seed: u64, } impl LayoutData { @@ -1739,6 +1751,30 @@ impl LayoutData { let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); let size = scalar.size(cx); let align = scalar.align(cx); + + let range = scalar.valid_range(cx); + + // All primitive types for which we don't have subtype coercions should get a distinct seed, + // so that types wrapping them can use randomization to arrive at distinct layouts. + // + // Some type information is already lost at this point, so as an approximation we derive + // the seed from what remains. For example on 64-bit targets usize and u64 can no longer + // be distinguished. + let randomization_seed = size + .bytes() + .wrapping_add( + match scalar.primitive() { + Primitive::Int(_, true) => 1, + Primitive::Int(_, false) => 2, + Primitive::Float(_) => 3, + Primitive::Pointer(_) => 4, + } << 32, + ) + // distinguishes references from pointers + .wrapping_add((range.start as u64).rotate_right(16)) + // distinguishes char from u32 and bool from u8 + .wrapping_add((range.end as u64).rotate_right(16)); + LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Primitive, @@ -1748,6 +1784,7 @@ impl LayoutData { align, max_repr_align: None, unadjusted_abi_align: align.abi, + randomization_seed, } } } @@ -1770,6 +1807,7 @@ where variants, max_repr_align, unadjusted_abi_align, + ref randomization_seed, } = self; f.debug_struct("Layout") .field("size", size) @@ -1780,6 +1818,7 @@ where .field("variants", variants) .field("max_repr_align", max_repr_align) .field("unadjusted_abi_align", unadjusted_abi_align) + .field("randomization_seed", randomization_seed) .finish() } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 6e6da6de749a1..8d4d127607d34 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -770,6 +770,7 @@ where size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: tcx.data_layout.i8_align.abi, + randomization_seed: 0, }) } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 9f138cf1275d2..fae787f9a40b3 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -347,6 +347,7 @@ fn layout_of_uncached<'tcx>( size, max_repr_align: None, unadjusted_abi_align: element.align.abi, + randomization_seed: element.randomization_seed.wrapping_add(count), }) } ty::Slice(element) => { @@ -360,6 +361,8 @@ fn layout_of_uncached<'tcx>( size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: element.align.abi, + // adding a randomly chosen value to distinguish slices + randomization_seed: element.randomization_seed.wrapping_add(0x2dcba99c39784102), }) } ty::Str => tcx.mk_layout(LayoutData { @@ -371,6 +374,8 @@ fn layout_of_uncached<'tcx>( size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, + // another random value + randomization_seed: 0xc1325f37d127be22, }), // Odd unit types. @@ -542,6 +547,7 @@ fn layout_of_uncached<'tcx>( align, max_repr_align: None, unadjusted_abi_align: align.abi, + randomization_seed: e_ly.randomization_seed.wrapping_add(e_len), }) } @@ -999,6 +1005,9 @@ fn coroutine_layout<'tcx>( BackendRepr::Memory { sized: true } }; + // this is similar to how ReprOptions populates its field_shuffle_seed + let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash().as_u64(); + let layout = tcx.mk_layout(LayoutData { variants: Variants::Multiple { tag, @@ -1019,6 +1028,7 @@ fn coroutine_layout<'tcx>( align, max_repr_align: None, unadjusted_abi_align: align.abi, + randomization_seed: def_hash, }); debug!("coroutine layout ({:?}): {:#?}", ty, layout); Ok(layout) diff --git a/tests/ui/layout/randomize.rs b/tests/ui/layout/randomize.rs new file mode 100644 index 0000000000000..be895252a1b23 --- /dev/null +++ b/tests/ui/layout/randomize.rs @@ -0,0 +1,29 @@ +//@ build-pass +//@ revisions: normal randomize-layout +//@ [randomize-layout]compile-flags: -Zrandomize-layout + +#![crate_type = "lib"] + +struct Foo(u32, T, u8); + +struct Wrapper(T); + +#[repr(transparent)] +struct TransparentWrapper(u16); + +const _: () = { + // behavior of the current implementation, not guaranteed + #[cfg(not(randomize_layout))] + assert!(std::mem::offset_of!(Foo::, 1) == std::mem::offset_of!(Foo::>, 1)); + + // under randomization Foo != Foo + #[cfg(randomize_layout)] + assert!(std::mem::offset_of!(Foo::, 1) != std::mem::offset_of!(Foo::>, 1)); + + // but repr(transparent) should make them the same again. + // maybe not strictly guaranteed? but UCG has been leaning in that direction at least + #[cfg(randomize_layout)] + assert!( + std::mem::offset_of!(Foo::, 1) == std::mem::offset_of!(Foo::, 1) + ); +}; From d7fb729d393e40919adfa0738a205c24c821808d Mon Sep 17 00:00:00 2001 From: The 8472 Date: Mon, 23 Dec 2024 23:17:02 +0100 Subject: [PATCH 10/13] adjust UI tests --- tests/ui/abi/c-zst.aarch64-darwin.stderr | 2 + tests/ui/abi/c-zst.powerpc-linux.stderr | 2 + tests/ui/abi/c-zst.s390x-linux.stderr | 2 + tests/ui/abi/c-zst.sparc64-linux.stderr | 2 + tests/ui/abi/c-zst.x86_64-linux.stderr | 2 + .../ui/abi/c-zst.x86_64-pc-windows-gnu.stderr | 2 + tests/ui/abi/debug.rs | 1 + tests/ui/abi/debug.stderr | 46 +++++++++++---- tests/ui/abi/sysv64-zst.stderr | 2 + tests/ui/abi/win64-zst.x86_64-linux.stderr | 2 + .../abi/win64-zst.x86_64-windows-gnu.stderr | 2 + .../abi/win64-zst.x86_64-windows-msvc.stderr | 2 + tests/ui/layout/debug.rs | 1 + tests/ui/layout/debug.stderr | 56 ++++++++++++------- tests/ui/layout/hexagon-enum.rs | 1 + tests/ui/layout/hexagon-enum.stderr | 20 +++++-- ...6158-scalarpair-payload-might-be-uninit.rs | 1 + ...-scalarpair-payload-might-be-uninit.stderr | 27 +++++++-- .../ui/layout/issue-96185-overaligned-enum.rs | 1 + .../issue-96185-overaligned-enum.stderr | 10 +++- tests/ui/layout/thumb-enum.rs | 1 + tests/ui/layout/thumb-enum.stderr | 20 +++++-- .../ui/layout/zero-sized-array-enum-niche.rs | 1 + .../layout/zero-sized-array-enum-niche.stderr | 21 +++++-- ...-variants.aarch64-unknown-linux-gnu.stderr | 14 ++++- ...-c-dead-variants.armebv7r-none-eabi.stderr | 14 ++++- ...-dead-variants.i686-pc-windows-msvc.stderr | 14 ++++- tests/ui/repr/repr-c-dead-variants.rs | 1 + ...d-variants.x86_64-unknown-linux-gnu.stderr | 14 ++++- tests/ui/repr/repr-c-int-dead-variants.rs | 1 + tests/ui/repr/repr-c-int-dead-variants.stderr | 14 ++++- tests/ui/type/pattern_types/range_patterns.rs | 1 + .../type/pattern_types/range_patterns.stderr | 19 +++++-- 33 files changed, 248 insertions(+), 71 deletions(-) diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 7d384bc875f98..d9742612bcfd2 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, @@ -49,6 +50,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 7980710bab676..0e98b5f806bc2 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Indirect { @@ -60,6 +61,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 7980710bab676..0e98b5f806bc2 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Indirect { @@ -60,6 +61,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 7980710bab676..0e98b5f806bc2 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Indirect { @@ -60,6 +61,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index 7d384bc875f98..d9742612bcfd2 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, @@ -49,6 +50,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 7980710bab676..0e98b5f806bc2 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Indirect { @@ -60,6 +61,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index 565743bf978ea..6dbc316146412 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -1,4 +1,5 @@ //@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ normalize-stderr: "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" //@ normalize-stderr: "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" //@ normalize-stderr: "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index aa51c42c58dc4..e550e5bfcf3c3 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -25,6 +25,7 @@ error: fn_abi_of(test) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -71,6 +72,7 @@ error: fn_abi_of(test) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -87,7 +89,7 @@ error: fn_abi_of(test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:15:1 + --> $DIR/debug.rs:16:1 | LL | fn test(_x: u8) -> bool { true } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -128,6 +130,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -165,6 +168,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -181,7 +185,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:18:1 + --> $DIR/debug.rs:19:1 | LL | type TestFnPtr = fn(bool) -> u8; | ^^^^^^^^^^^^^^ @@ -214,6 +218,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -248,6 +253,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -257,13 +263,13 @@ error: fn_abi_of(test_generic) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:21:1 + --> $DIR/debug.rs:22:1 | LL | fn test_generic(_x: *const T) { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:24:1 + --> $DIR/debug.rs:25:1 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -296,6 +302,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -330,6 +337,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -366,6 +374,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -400,6 +409,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -409,7 +419,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:40:1 + --> $DIR/debug.rs:41:1 | LL | type TestAbiNe = (fn(u8), fn(u32)); | ^^^^^^^^^^^^^^ @@ -439,6 +449,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Indirect { @@ -477,6 +488,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -510,6 +522,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Indirect { @@ -548,6 +561,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -557,7 +571,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:43:1 + --> $DIR/debug.rs:44:1 | LL | type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); | ^^^^^^^^^^^^^^^^^^^^ @@ -589,6 +603,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -623,6 +638,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -659,6 +675,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -693,6 +710,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -702,7 +720,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:46:1 + --> $DIR/debug.rs:47:1 | LL | type TestAbiNeFloat = (fn(f32), fn(u32)); | ^^^^^^^^^^^^^^^^^^^ @@ -735,6 +753,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -769,6 +788,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -805,6 +825,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -839,6 +860,7 @@ error: ABIs are not compatible }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -848,13 +870,13 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:50:1 + --> $DIR/debug.rs:51:1 | LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:53:46 + --> $DIR/debug.rs:54:46 | LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -863,7 +885,7 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = note: only the last element of a tuple may have a dynamically sized type error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:28:5 + --> $DIR/debug.rs:29:5 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -906,6 +928,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Direct( @@ -942,6 +965,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: $SEED, }, }, mode: Ignore, @@ -951,7 +975,7 @@ error: fn_abi_of(assoc_test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:33:5 + --> $DIR/debug.rs:34:5 | LL | fn assoc_test(&self) { } | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 8e1791e27d27c..781e9b2f4c9d5 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, @@ -49,6 +50,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/win64-zst.x86_64-linux.stderr b/tests/ui/abi/win64-zst.x86_64-linux.stderr index 76d90670eb1dd..a28a59fdd8d02 100644 --- a/tests/ui/abi/win64-zst.x86_64-linux.stderr +++ b/tests/ui/abi/win64-zst.x86_64-linux.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, @@ -49,6 +50,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr b/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr index 7ee90e2474413..cf0cc00c5ed07 100644 --- a/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr +++ b/tests/ui/abi/win64-zst.x86_64-windows-gnu.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Indirect { @@ -60,6 +61,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr b/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr index 76d90670eb1dd..a28a59fdd8d02 100644 --- a/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr +++ b/tests/ui/abi/win64-zst.x86_64-windows-msvc.stderr @@ -22,6 +22,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, @@ -49,6 +50,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, max_repr_align: None, unadjusted_abi_align: $SOME_ALIGN, + randomization_seed: 0, }, }, mode: Ignore, diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 5602c4e711f61..81dc72852543d 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -1,4 +1,5 @@ //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" #![feature(never_type, rustc_attrs, type_alias_impl_trait, repr_simd)] #![crate_type = "lib"] diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index bd31665dac1f7..1fc55511384f2 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -1,5 +1,5 @@ error: unions cannot have zero fields - --> $DIR/debug.rs:82:1 + --> $DIR/debug.rs:83:1 | LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^^^^ @@ -61,6 +61,7 @@ error: layout_of(E) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(12 bytes), @@ -87,13 +88,15 @@ error: layout_of(E) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:7:1 + --> $DIR/debug.rs:8:1 | LL | enum E { Foo, Bar(!, i32, i32) } | ^^^^^^ @@ -138,8 +141,9 @@ error: layout_of(S) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:10:1 + --> $DIR/debug.rs:11:1 | LL | struct S { f1: i32, f2: (), f3: i32 } | ^^^^^^^^ @@ -162,8 +166,9 @@ error: layout_of(U) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:13:1 + --> $DIR/debug.rs:14:1 | LL | union U { f1: (i32, i32), f3: i32 } | ^^^^^^^ @@ -255,6 +260,7 @@ error: layout_of(Result) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(8 bytes), @@ -292,13 +298,15 @@ error: layout_of(Result) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:16:1 + --> $DIR/debug.rs:17:1 | LL | type Test = Result; | ^^^^^^^^^ @@ -325,8 +333,9 @@ error: layout_of(i32) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:19:1 + --> $DIR/debug.rs:20:1 | LL | type T = impl std::fmt::Debug; | ^^^^^^ @@ -349,8 +358,9 @@ error: layout_of(V) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:25:1 + --> $DIR/debug.rs:26:1 | LL | pub union V { | ^^^^^^^^^^^ @@ -373,8 +383,9 @@ error: layout_of(W) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:31:1 + --> $DIR/debug.rs:32:1 | LL | pub union W { | ^^^^^^^^^^^ @@ -397,8 +408,9 @@ error: layout_of(Y) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:37:1 + --> $DIR/debug.rs:38:1 | LL | pub union Y { | ^^^^^^^^^^^ @@ -421,8 +433,9 @@ error: layout_of(P1) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:44:1 + --> $DIR/debug.rs:45:1 | LL | union P1 { x: u32 } | ^^^^^^^^ @@ -445,8 +458,9 @@ error: layout_of(P2) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:48:1 + --> $DIR/debug.rs:49:1 | LL | union P2 { x: (u32, u32) } | ^^^^^^^^ @@ -469,8 +483,9 @@ error: layout_of(P3) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:56:1 + --> $DIR/debug.rs:57:1 | LL | union P3 { x: F32x4 } | ^^^^^^^^ @@ -493,8 +508,9 @@ error: layout_of(P4) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:60:1 + --> $DIR/debug.rs:61:1 | LL | union P4 { x: E } | ^^^^^^^^ @@ -522,8 +538,9 @@ error: layout_of(P5) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:64:1 + --> $DIR/debug.rs:65:1 | LL | union P5 { zst: [u16; 0], byte: u8 } | ^^^^^^^^ @@ -551,20 +568,21 @@ error: layout_of(MaybeUninit) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/debug.rs:67:1 + --> $DIR/debug.rs:68:1 | LL | type X = std::mem::MaybeUninit; | ^^^^^^ error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:70:1 + --> $DIR/debug.rs:71:1 | LL | const C: () = (); | ^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:78:19 + --> $DIR/debug.rs:79:19 | LL | type Impossible = (str, str); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -573,13 +591,13 @@ LL | type Impossible = (str, str); = note: only the last element of a tuple may have a dynamically sized type error: the type `EmptyUnion` has an unknown layout - --> $DIR/debug.rs:82:1 + --> $DIR/debug.rs:83:1 | LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^ error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:74:5 + --> $DIR/debug.rs:75:5 | LL | const C: () = (); | ^^^^^^^^^^^ diff --git a/tests/ui/layout/hexagon-enum.rs b/tests/ui/layout/hexagon-enum.rs index e3a5c53671d40..5fa12e479e7db 100644 --- a/tests/ui/layout/hexagon-enum.rs +++ b/tests/ui/layout/hexagon-enum.rs @@ -1,4 +1,5 @@ //@ compile-flags: --target hexagon-unknown-linux-musl +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: hexagon // // Verify that the hexagon targets implement the repr(C) for enums correctly. diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 59fe667923f11..96f0a8c874086 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -61,13 +61,15 @@ error: layout_of(A) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:16:1 + --> $DIR/hexagon-enum.rs:17:1 | LL | enum A { Apple } | ^^^^^^ @@ -135,13 +137,15 @@ error: layout_of(B) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:20:1 + --> $DIR/hexagon-enum.rs:21:1 | LL | enum B { Banana = 255, } | ^^^^^^ @@ -209,13 +213,15 @@ error: layout_of(C) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:24:1 + --> $DIR/hexagon-enum.rs:25:1 | LL | enum C { Chaenomeles = 256, } | ^^^^^^ @@ -283,13 +289,15 @@ error: layout_of(P) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:28:1 + --> $DIR/hexagon-enum.rs:29:1 | LL | enum P { Peach = 0x1000_0000isize, } | ^^^^^^ @@ -357,13 +365,15 @@ error: layout_of(T) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:34:1 + --> $DIR/hexagon-enum.rs:35:1 | LL | enum T { Tangerine = TANGERINE as isize } | ^^^^^^ diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs index 328d204aa3cda..ab7e0897ce32c 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs @@ -1,4 +1,5 @@ //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index ca041fb539b93..cd9e4c0278150 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -83,6 +83,7 @@ error: layout_of(MissingPayloadField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(1 bytes), @@ -103,13 +104,15 @@ error: layout_of(MissingPayloadField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:16:1 + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:17:1 | LL | pub enum MissingPayloadField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -201,6 +204,7 @@ error: layout_of(CommonPayloadField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -238,13 +242,15 @@ error: layout_of(CommonPayloadField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:25:1 + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:26:1 | LL | pub enum CommonPayloadField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -334,6 +340,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -370,13 +377,15 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:33:1 + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:34:1 | LL | pub enum CommonPayloadFieldIsMaybeUninit { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -482,6 +491,7 @@ error: layout_of(NicheFirst) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(0 bytes), @@ -502,6 +512,7 @@ error: layout_of(NicheFirst) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(0 bytes), @@ -522,13 +533,15 @@ error: layout_of(NicheFirst) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:41:1 + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:42:1 | LL | pub enum NicheFirst { | ^^^^^^^^^^^^^^^^^^^ @@ -634,6 +647,7 @@ error: layout_of(NicheSecond) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(0 bytes), @@ -654,6 +668,7 @@ error: layout_of(NicheSecond) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(0 bytes), @@ -674,13 +689,15 @@ error: layout_of(NicheSecond) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:50:1 + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:51:1 | LL | pub enum NicheSecond { | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/layout/issue-96185-overaligned-enum.rs b/tests/ui/layout/issue-96185-overaligned-enum.rs index 341233a7890eb..19da169105cec 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.rs +++ b/tests/ui/layout/issue-96185-overaligned-enum.rs @@ -1,4 +1,5 @@ //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index bc40a2aa482ed..15a3f6004f50f 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -57,6 +57,7 @@ error: layout_of(Aligned1) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(8 bytes), @@ -79,6 +80,7 @@ error: layout_of(Aligned1) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, @@ -86,8 +88,9 @@ error: layout_of(Aligned1) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96185-overaligned-enum.rs:8:1 + --> $DIR/issue-96185-overaligned-enum.rs:9:1 | LL | pub enum Aligned1 { | ^^^^^^^^^^^^^^^^^ @@ -157,6 +160,7 @@ error: layout_of(Aligned2) = Layout { Align(1 bytes), ), unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(1 bytes), @@ -179,6 +183,7 @@ error: layout_of(Aligned2) = Layout { Align(1 bytes), ), unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, @@ -186,8 +191,9 @@ error: layout_of(Aligned2) = Layout { Align(1 bytes), ), unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/issue-96185-overaligned-enum.rs:16:1 + --> $DIR/issue-96185-overaligned-enum.rs:17:1 | LL | pub enum Aligned2 { | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/layout/thumb-enum.rs b/tests/ui/layout/thumb-enum.rs index 57a9a2d813709..2381d9d02926d 100644 --- a/tests/ui/layout/thumb-enum.rs +++ b/tests/ui/layout/thumb-enum.rs @@ -1,4 +1,5 @@ //@ compile-flags: --target thumbv8m.main-none-eabihf +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: arm // // Verify that thumb targets implement the repr(C) for enums correctly. diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index bf043af586b1c..120081d193c69 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -61,13 +61,15 @@ error: layout_of(A) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:16:1 + --> $DIR/thumb-enum.rs:17:1 | LL | enum A { Apple } | ^^^^^^ @@ -135,13 +137,15 @@ error: layout_of(B) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:20:1 + --> $DIR/thumb-enum.rs:21:1 | LL | enum B { Banana = 255, } | ^^^^^^ @@ -209,13 +213,15 @@ error: layout_of(C) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:24:1 + --> $DIR/thumb-enum.rs:25:1 | LL | enum C { Chaenomeles = 256, } | ^^^^^^ @@ -283,13 +289,15 @@ error: layout_of(P) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:28:1 + --> $DIR/thumb-enum.rs:29:1 | LL | enum P { Peach = 0x1000_0000isize, } | ^^^^^^ @@ -357,13 +365,15 @@ error: layout_of(T) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:34:1 + --> $DIR/thumb-enum.rs:35:1 | LL | enum T { Tangerine = TANGERINE as isize } | ^^^^^^ diff --git a/tests/ui/layout/zero-sized-array-enum-niche.rs b/tests/ui/layout/zero-sized-array-enum-niche.rs index 152f44bd86375..d3ff016d8aa23 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.rs +++ b/tests/ui/layout/zero-sized-array-enum-niche.rs @@ -1,4 +1,5 @@ //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index d61408098df7f..b6fcc14c063c5 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -59,6 +59,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -92,13 +93,15 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/zero-sized-array-enum-niche.rs:13:1 + --> $DIR/zero-sized-array-enum-niche.rs:14:1 | LL | type AlignedResult = Result<[u32; 0], bool>; | ^^^^^^^^^^^^^^^^^^ @@ -164,6 +167,7 @@ error: layout_of(MultipleAlignments) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), + randomization_seed: $SEED, }, Layout { size: Size(4 bytes), @@ -188,6 +192,7 @@ error: layout_of(MultipleAlignments) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -221,13 +226,15 @@ error: layout_of(MultipleAlignments) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/zero-sized-array-enum-niche.rs:21:1 + --> $DIR/zero-sized-array-enum-niche.rs:22:1 | LL | enum MultipleAlignments { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -293,6 +300,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(3 bytes), @@ -326,13 +334,15 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/zero-sized-array-enum-niche.rs:37:1 + --> $DIR/zero-sized-array-enum-niche.rs:38:1 | LL | type NicheLosesToTagged = Result<[u32; 0], Packed>>; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -402,6 +412,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -435,13 +446,15 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/zero-sized-array-enum-niche.rs:44:1 + --> $DIR/zero-sized-array-enum-niche.rs:45:1 | LL | type NicheWinsOverTagged = Result<[u32; 0], Packed>; | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 64a0cb7f31a14..8e8f1d159b740 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -55,13 +55,15 @@ error: layout_of(Univariant) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:38:1 + --> $DIR/repr-c-dead-variants.rs:39:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -137,6 +139,7 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(8 bytes), @@ -173,13 +176,15 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:45:1 + --> $DIR/repr-c-dead-variants.rs:46:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -247,6 +252,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, Layout { size: Size(16 bytes), @@ -271,6 +277,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, ], }, @@ -278,8 +285,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:57:1 + --> $DIR/repr-c-dead-variants.rs:58:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 5c4daa6d51977..2cd0960ce3eec 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -55,13 +55,15 @@ error: layout_of(Univariant) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:38:1 + --> $DIR/repr-c-dead-variants.rs:39:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -137,6 +139,7 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -173,13 +176,15 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:45:1 + --> $DIR/repr-c-dead-variants.rs:46:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -247,6 +252,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, Layout { size: Size(16 bytes), @@ -271,6 +277,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, ], }, @@ -278,8 +285,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:57:1 + --> $DIR/repr-c-dead-variants.rs:58:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 64a0cb7f31a14..8e8f1d159b740 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -55,13 +55,15 @@ error: layout_of(Univariant) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:38:1 + --> $DIR/repr-c-dead-variants.rs:39:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -137,6 +139,7 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(8 bytes), @@ -173,13 +176,15 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:45:1 + --> $DIR/repr-c-dead-variants.rs:46:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -247,6 +252,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, Layout { size: Size(16 bytes), @@ -271,6 +277,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, ], }, @@ -278,8 +285,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:57:1 + --> $DIR/repr-c-dead-variants.rs:58:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index 3e8ae3d096d86..99f20982a9960 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -7,6 +7,7 @@ // See also: repr-c-int-dead-variants.rs //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" // This test depends on the value of the `c_enum_min_bits` target option. // As there's no way to actually check it from UI test, we only run this test on a subset of archs. diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 64a0cb7f31a14..8e8f1d159b740 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -55,13 +55,15 @@ error: layout_of(Univariant) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:38:1 + --> $DIR/repr-c-dead-variants.rs:39:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -137,6 +139,7 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, Layout { size: Size(8 bytes), @@ -173,13 +176,15 @@ error: layout_of(TwoVariants) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:45:1 + --> $DIR/repr-c-dead-variants.rs:46:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -247,6 +252,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, Layout { size: Size(16 bytes), @@ -271,6 +277,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, ], }, @@ -278,8 +285,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:57:1 + --> $DIR/repr-c-dead-variants.rs:58:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-int-dead-variants.rs b/tests/ui/repr/repr-c-int-dead-variants.rs index 627569e080d4c..723e573024402 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.rs +++ b/tests/ui/repr/repr-c-int-dead-variants.rs @@ -4,6 +4,7 @@ // See also: repr-c-dead-variants.rs //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" // A simple uninhabited type. enum Void {} diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index 75005a64523a3..fa08b323dec2a 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -55,13 +55,15 @@ error: layout_of(UnivariantU8) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-int-dead-variants.rs:14:1 + --> $DIR/repr-c-int-dead-variants.rs:15:1 | LL | enum UnivariantU8 { | ^^^^^^^^^^^^^^^^^ @@ -137,6 +139,7 @@ error: layout_of(TwoVariantsU8) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(2 bytes), @@ -173,13 +176,15 @@ error: layout_of(TwoVariantsU8) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-int-dead-variants.rs:21:1 + --> $DIR/repr-c-int-dead-variants.rs:22:1 | LL | enum TwoVariantsU8 { | ^^^^^^^^^^^^^^^^^^ @@ -247,6 +252,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, Layout { size: Size(16 bytes), @@ -271,6 +277,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, }, ], }, @@ -278,8 +285,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, } - --> $DIR/repr-c-int-dead-variants.rs:33:1 + --> $DIR/repr-c-int-dead-variants.rs:34:1 | LL | enum DeadBranchHasOtherFieldU8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index ff87444b49e30..446a33195c8bd 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -3,6 +3,7 @@ #![allow(incomplete_features)] //@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 0eed7c2ce1ce8..7da8cfd4dbc2d 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -36,8 +36,9 @@ error: layout_of(NonZero) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/range_patterns.rs:10:1 + --> $DIR/range_patterns.rs:11:1 | LL | type X = std::num::NonZeroU32; | ^^^^^^ @@ -73,8 +74,9 @@ error: layout_of((u32) is 1..=) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/range_patterns.rs:12:1 + --> $DIR/range_patterns.rs:13:1 | LL | type Y = pattern_type!(u32 is 1..); | ^^^^^^ @@ -137,6 +139,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(4 bytes), @@ -176,13 +179,15 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/range_patterns.rs:14:1 + --> $DIR/range_patterns.rs:15:1 | LL | type Z = Option; | ^^^^^^ @@ -245,6 +250,7 @@ error: layout_of(Option>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, }, Layout { size: Size(4 bytes), @@ -284,13 +290,15 @@ error: layout_of(Option>) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, }, ], }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/range_patterns.rs:16:1 + --> $DIR/range_patterns.rs:17:1 | LL | type A = Option; | ^^^^^^ @@ -333,8 +341,9 @@ error: layout_of(NonZeroU32New) = Layout { }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), + randomization_seed: $SEED, } - --> $DIR/range_patterns.rs:18:1 + --> $DIR/range_patterns.rs:19:1 | LL | struct NonZeroU32New(pattern_type!(u32 is 1..)); | ^^^^^^^^^^^^^^^^^^^^ From 56889dd826f0e306fb08c1faa903b35daf59806a Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 16 Nov 2024 02:22:28 +0100 Subject: [PATCH 11/13] exclude unsizable tail from randomization seed calculation --- compiler/rustc_abi/src/layout.rs | 22 +++++++++------------- tests/ui/layout/randomize.rs | 7 ++++--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 3b897c1cb3e51..b8773f9ff38f6 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -1051,15 +1051,16 @@ impl LayoutCalculator { let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut max_repr_align = repr.align; let mut inverse_memory_index: IndexVec = fields.indices().collect(); - let field_seed = - fields.raw.iter().fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed)); let optimize_field_order = !repr.inhibit_struct_field_reordering(); - if optimize_field_order && fields.len() > 1 { - let end = - if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; - let optimizing = &mut inverse_memory_index.raw[..end]; - let fields_excluding_tail = &fields.raw[..end]; + let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; + let optimizing = &mut inverse_memory_index.raw[..end]; + let fields_excluding_tail = &fields.raw[..end]; + // unsizable tail fields are excluded so that we use the same seed for the sized and unsized layouts. + let field_seed = fields_excluding_tail + .iter() + .fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed)); + if optimize_field_order && fields.len() > 1 { // 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. @@ -1369,12 +1370,7 @@ impl LayoutCalculator { unadjusted_abi_align }; - // a transparent struct only has a single field, so its seed should be the same as the one we pass forward - let seed = if repr.transparent() { - field_seed - } else { - field_seed.wrapping_add(repr.field_shuffle_seed) - }; + let seed = field_seed.wrapping_add(repr.field_shuffle_seed); Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, diff --git a/tests/ui/layout/randomize.rs b/tests/ui/layout/randomize.rs index be895252a1b23..da8414bc3e2df 100644 --- a/tests/ui/layout/randomize.rs +++ b/tests/ui/layout/randomize.rs @@ -20,10 +20,11 @@ const _: () = { #[cfg(randomize_layout)] assert!(std::mem::offset_of!(Foo::, 1) != std::mem::offset_of!(Foo::>, 1)); - // but repr(transparent) should make them the same again. - // maybe not strictly guaranteed? but UCG has been leaning in that direction at least + // Even transparent wrapper inner types get a different layout since associated type + // pecialization could result in the outer type behaving differently depending on the exact + // inner type. #[cfg(randomize_layout)] assert!( - std::mem::offset_of!(Foo::, 1) == std::mem::offset_of!(Foo::, 1) + std::mem::offset_of!(Foo::, 1) != std::mem::offset_of!(Foo::, 1) ); }; From 8b1de1682fcfaa2f56d6e4b98e1f18eb1bfcee55 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 16 Nov 2024 02:49:03 +0100 Subject: [PATCH 12/13] also initialize Layout field in rust-analyzer --- src/tools/rust-analyzer/crates/hir-ty/src/layout.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 0c1f63880cd2a..108171586ea89 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -197,6 +197,7 @@ fn layout_of_simd_ty( align, max_repr_align: None, unadjusted_abi_align: align.abi, + randomization_seed: 0, })) } @@ -313,6 +314,7 @@ pub fn layout_of_ty_query( size, max_repr_align: None, unadjusted_abi_align: element.align.abi, + randomization_seed: 0, } } TyKind::Slice(element) => { @@ -326,6 +328,7 @@ pub fn layout_of_ty_query( size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: element.align.abi, + randomization_seed: 0, } } TyKind::Str => Layout { @@ -337,6 +340,7 @@ pub fn layout_of_ty_query( size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, + randomization_seed: 0, }, // Potentially-wide pointers. TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => { From d89b6d5ac6ceb7f735c8d2c7397fb6bb0e0e3020 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Thu, 9 Jan 2025 00:50:47 +0100 Subject: [PATCH 13/13] test that coercions still work under randomization --- tests/ui/layout/randomize.rs | 48 ++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/tests/ui/layout/randomize.rs b/tests/ui/layout/randomize.rs index da8414bc3e2df..27e99327a3196 100644 --- a/tests/ui/layout/randomize.rs +++ b/tests/ui/layout/randomize.rs @@ -1,18 +1,23 @@ -//@ build-pass +//@ run-pass //@ revisions: normal randomize-layout -//@ [randomize-layout]compile-flags: -Zrandomize-layout +//@ [randomize-layout]compile-flags: -Zrandomize-layout -Zlayout-seed=2 -#![crate_type = "lib"] +#![feature(offset_of_enum)] -struct Foo(u32, T, u8); +use std::ptr; -struct Wrapper(T); +// these types only have their field offsets taken, they're never constructed +#[allow(dead_code)] +pub struct Foo(u32, T, u8); +#[allow(dead_code)] +pub struct Wrapper(T); #[repr(transparent)] -struct TransparentWrapper(u16); +#[allow(dead_code)] +pub struct TransparentWrapper(u16); const _: () = { - // behavior of the current implementation, not guaranteed + // Behavior of the current non-randomized implementation, not guaranteed #[cfg(not(randomize_layout))] assert!(std::mem::offset_of!(Foo::, 1) == std::mem::offset_of!(Foo::>, 1)); @@ -21,10 +26,37 @@ const _: () = { assert!(std::mem::offset_of!(Foo::, 1) != std::mem::offset_of!(Foo::>, 1)); // Even transparent wrapper inner types get a different layout since associated type - // pecialization could result in the outer type behaving differently depending on the exact + // specialization could result in the outer type behaving differently depending on the exact // inner type. #[cfg(randomize_layout)] assert!( std::mem::offset_of!(Foo::, 1) != std::mem::offset_of!(Foo::, 1) ); + + // Currently all fn pointers are treated interchangably even with randomization. Not guaranteed. + // Associated type specialization could also break this. + assert!( + std::mem::offset_of!(Foo::, 1) == std::mem::offset_of!(Foo:: usize>, 1) + ); + + // But subtype coercions must always result in the same layout. + assert!( + std::mem::offset_of!(Foo::, 1) == std::mem::offset_of!(Foo::, 1) + ); + + // Randomization must uphold NPO guarantees + assert!(std::mem::offset_of!(Option::<&usize>, Some.0) == 0); + assert!(std::mem::offset_of!(Result::<&usize, ()>, Ok.0) == 0); }; + +#[allow(dead_code)] +struct Unsizable(usize, T); + +fn main() { + // offset_of doesn't let us probe the unsized field, check at runtime. + let x = &Unsizable::<[u32; 4]>(0, [0; 4]); + let y: &Unsizable::<[u32]> = x; + + // type coercion must not change the layout. + assert_eq!(ptr::from_ref(&x.1).addr(), ptr::from_ref(&y.1).addr()); +}