Skip to content

Carry the b_offset inside BackendRepr::ScalarPair#158666

Open
scottmcm wants to merge 3 commits into
rust-lang:mainfrom
scottmcm:scalar-but-packed
Open

Carry the b_offset inside BackendRepr::ScalarPair#158666
scottmcm wants to merge 3 commits into
rust-lang:mainfrom
scottmcm:scalar-but-packed

Conversation

@scottmcm

@scottmcm scottmcm commented Jul 1, 2026

Copy link
Copy Markdown
Member

View all comments

Inspired by rust-lang/compiler-team#1007 but doesn't actually change any of the layout rules just yet.

This turned out to be a nice change even if we didn't use the extra flexibility, IMHO, because it allowed so many things like

@@ -222,12 +224,12 @@ fn from_const_alloc<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
                 let val = read_scalar(offset, size, s, bx.immediate_backend_type(layout));
                 OperandRef { val: OperandValue::Immediate(val), layout, move_annotation: None }
             }
-            BackendRepr::ScalarPair(
-                a @ abi::Scalar::Initialized { .. },
-                b @ abi::Scalar::Initialized { .. },
-            ) => {
+            BackendRepr::ScalarPair {
+                a: a @ abi::Scalar::Initialized { .. },
+                b: b @ abi::Scalar::Initialized { .. },
+                b_offset,
+            } => {
                 let (a_size, b_size) = (a.size(bx), b.size(bx));
-                let b_offset = (offset + a_size).align_to(b.default_align(bx).abi);
                 assert!(b_offset.bytes() > 0);
                 let a_val = read_scalar(
                     offset,

as oh my was that little magic incantation copy-pasted all over the place.

Apologies for the pretty-giant PR. I tried to make it as direct a change as I could: if it was (..) before it's { .. } now, if it was (_, _) before it's { a: _, b: _, b_offset: _ } now. I kept the names the same so the code lines were unchanged even if normally I might have just renamed things, etc. I'll add some inline notes for places of particular interest.

r? @workingjubilee

@rustbot

rustbot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

rustc_codegen_cranelift is developed in its own repository. If possible, consider making this change to rust-lang/rustc_codegen_cranelift instead.

cc @bjorn3

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

rustc_codegen_gcc is developed in its own repository. If possible, consider making this change to rust-lang/rustc_codegen_gcc instead.

cc @antoyo, @GuillaumeGomez

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a, @makai410

Some changes occurred in compiler/rustc_codegen_llvm/src/builder/autodiff.rs

cc @ZuseZ4

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. F-autodiff `#![feature(autodiff)]` S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 1, 2026
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jul 1, 2026
@rustbot

rustbot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

workingjubilee is currently at their maximum review capacity.
They may take a while to respond.

) => {
l1.primitive() == r1.primitive()
&& l2.primitive() == r2.primitive()
&& l_offset == r_offset

@scottmcm scottmcm Jul 1, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: since this is an eq-like method, I also check that the offsets are the same here. (They always will be right now, but it makes sense to check it regardless IMHO.)

View changes since the review

abi::BackendRepr::ScalarPair { a: out_a, b: out_b, b_offset: out_offset },
) if in_a.size(cx) == out_a.size(cx)
&& in_b.size(cx) == out_b.size(cx)
&& in_offset == out_offset =>

@scottmcm scottmcm Jul 1, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: when transmuting we only want to transmute the immediates individually when the second one is at the same offset in the source and destination.

(It'll probably be UB if they're not, but not necessarily since the out_b might allow uninit, so it's not worth trying to do something smart for those cases. They can fall through to the via-alloca implementation.)

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh cool, so the code is now more correct also! neat.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was correct before as well because same scalars implied same offset, but it's clearer that it's correct now, and definitely more resiliently correct to subtle changes.

}
(
Immediate::ScalarPair(a_val, b_val),
BackendRepr::ScalarPair { a: _, b: _, b_offset },

@scottmcm scottmcm Jul 1, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: by not needing to recompute the offset the two scalars actually ended up unused here.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol

a1.size(&self.ecx) == a2.size(&self.ecx)
&& b1.size(&self.ecx) == b2.size(&self.ecx)
// The alignment of the second component determines its offset, so that also needs to match.
&& b1.default_align(&self.ecx) == b2.default_align(&self.ecx)

@scottmcm scottmcm Jul 1, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: like the other spot this is thinking about transmutes, so now we can check the offset directly instead of indirectly via the default alignment.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat side effect!

@rust-log-analyzer

This comment has been minimized.

"`ScalarPair` second field at bad offset in {inner:#?}",
);
assert_eq!(
b_offset, field2_offset,

@scottmcm scottmcm Jul 1, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: for this PR I kept all the existing checks here, since it's not actually changing any layouts. (That's wanting on the MCP FCP.) Just added this new one that the offset stored in the variant matches the expected field offset.

View changes since the review

@scottmcm scottmcm force-pushed the scalar-but-packed branch from 455c80c to ede96e9 Compare July 1, 2026 17:14
@rustbot

rustbot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

clippy is developed in its own repository. If possible, consider making this change to rust-lang/rust-clippy instead.

cc @rust-lang/clippy

@rustbot rustbot added the T-clippy Relevant to the Clippy team. label Jul 1, 2026
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    Checking miri v0.1.0 (/checkout/src/tools/miri)
error[E0164]: expected tuple struct or tuple variant, found struct variant `rustc_abi::BackendRepr::ScalarPair`
   --> src/tools/miri/src/shims/native_lib/mod.rs:316:33
    |
316 | ...                   let rustc_abi::BackendRepr::ScalarPair(a, b) = imm.layout.backend_repr
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
    |
help: the struct variant's fields are being ignored
    |
316 -                             let rustc_abi::BackendRepr::ScalarPair(a, b) = imm.layout.backend_repr
316 +                             let rustc_abi::BackendRepr::ScalarPair { a: _, b: _, b_offset: _ } = imm.layout.backend_repr
    |

For more information about this error, try `rustc --explain E0164`.
[RUSTC-TIMING] miri test:false 4.341
error: could not compile `miri` (lib) due to 1 previous error

@rustbot

rustbot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

miri is developed in its own repository. If possible, consider making this change to rust-lang/miri instead.

cc @rust-lang/miri

@workingjubilee workingjubilee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added some incantations to the PR since the code is now a bit short on them. :^)

a couple minor wording nitpicks, because you wrote r? workingjubilee and I'd hate to disappoint. I will give it another scan once you're done fighting CI and r+ then, but it seems good! my eyes have indeed confirmed "this sure is a lot of whitespace changes thanks to rustfmt".

oh, the callconv code does need a further scan, I'll get to that about then but I don't expect it to need any changes.

View changes since this review

Comment thread compiler/rustc_abi/src/lib.rs
Immediate::from(if offset.bytes() == 0 {
a_val
} else {
assert_eq!(offset, a.size(cx).align_to(b.default_align(cx).abi));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by the shades of the Seraphim!

Comment on lines +968 to -965
let BackendRepr::ScalarPair { a: _, b: _, b_offset } = dest.layout.backend_repr
else {
bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout);
};
let b_offset = a_scalar.size(bx).align_to(b_scalar.default_align(bx).abi);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by the hoary hosts of Hoggoth!

assert_eq!(field.size, a.size(bx.cx()));
(Some(a), a_llval)
} else {
assert_eq!(offset, a.size(bx.cx()).align_to(b.default_align(bx.cx()).abi));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by the crimson bands of Cyttorak!

a1.size(&self.ecx) == a2.size(&self.ecx)
&& b1.size(&self.ecx) == b2.size(&self.ecx)
// The alignment of the second component determines its offset, so that also needs to match.
&& b1.default_align(&self.ecx) == b2.default_align(&self.ecx)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat side effect!

Comment on lines 398 to +401
BackendRepr::Scalar(scalar) => PassMode::Direct(scalar_attrs(scalar, Size::ZERO)),
BackendRepr::ScalarPair(a, b) => PassMode::Pair(
scalar_attrs(a, Size::ZERO),
scalar_attrs(b, a.size(cx).align_to(b.default_align(cx).abi)),
),
BackendRepr::ScalarPair { a, b, b_offset } => {
PassMode::Pair(scalar_attrs(a, Size::ZERO), scalar_attrs(b, b_offset))
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chintap ...I need to look more closely at the surrounding code here because this is actually something that makes me wonder how correct it is.

Or was, for that matter.

Comment on lines 913 to +916
// We have padding if the sizes don't add up to the total.
// (No need to check the offset because it's only possible for the scalar sizes
// to add up to the total size if the b_offset equals the `left_size`, but that's
// not a sufficient check because there needs to be no padding after right either.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be stated more concisely like so, I think?

Suggested change
// We have padding if the sizes don't add up to the total.
// (No need to check the offset because it's only possible for the scalar sizes
// to add up to the total size if the b_offset equals the `left_size`, but that's
// not a sufficient check because there needs to be no padding after right either.)
// We have padding if the sizes don't add up to the total
// without respect to b_offset, which indicates padding only if the total is higher.

abi::BackendRepr::ScalarPair { a: out_a, b: out_b, b_offset: out_offset },
) if in_a.size(cx) == out_a.size(cx)
&& in_b.size(cx) == out_b.size(cx)
&& in_offset == out_offset =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh cool, so the code is now more correct also! neat.

/// The two scalars are listed in *memory* order, so the first is at offset zero
/// and the second at a non-zero offset.
/// The two scalars are listed in *memory* order, so `a` is at offset zero
/// and `b` is at non-size offset `b_offset`.

@fbstj fbstj Jul 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does non-size offset mean? especially since b_offset: Size

View changes since the review

@workingjubilee workingjubilee Jul 1, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I left the same review comment. :^) #158666 (comment) resolving it so there's only one instance of this conversation.

I think this happened because of psychically tripping up over "non-zero offset" and "btw b_offset doesn't have to just be a's Size-rounded-up-to-some-Align-again".

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

93                    ),
94                },
-            ),
+                b_offset: Size(4 bytes),
+            },
96            fields: Arbitrary {
97                offsets: [
98                    Size(0 bytes),

---

140                                ),
141                            },
-                        ),
+                            b_offset: Size(4 bytes),
+                        },
143                        field_offsets: [
144                            Size(4 bytes),
145                        ],

---

166                                ),
167                            },
-                        ),
+                            b_offset: Size(4 bytes),
+                        },
169                        field_offsets: [
170                            Size(4 bytes),
171                        ],


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args repr/repr-c-dead-variants.rs`

error in revision `aarch64-unknown-linux-gnu`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/repr/repr-c-dead-variants.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--cfg" "aarch64_unknown_linux_gnu" "--check-cfg" "cfg(test,FALSE,aarch64_unknown_linux_gnu,i686_pc_windows_msvc,x86_64_unknown_linux_gnu,armebv7r_none_eabi)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Cpanic=abort" "-Cforce-unwind-tables=yes" "--target" "aarch64-unknown-linux-gnu" "--extern" "minicore=/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu/libminicore.rlib"
stdout: none
--- stderr -------------------------------
error: layout_of(Univariant) = Layout {
           size: Size(4 bytes),
           align: AbiAlign {
---
           randomization_seed: 15956128936533895400,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:44:1
   |
LL | enum Univariant { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^

error: layout_of(TwoVariants) = Layout {
           size: Size(8 bytes),
           align: AbiAlign {
---
                       I8,
                       false,
                   ),
               },
               b_offset: Size(4 bytes),
           },
           fields: Arbitrary {
               offsets: [
                   Size(0 bytes),
               ],
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(4 bytes),
                       },
                       field_offsets: [
                           Size(4 bytes),
                       ],
                       fields_in_memory_order: [
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(4 bytes),
                       },
                       field_offsets: [
                           Size(4 bytes),
                       ],
                       fields_in_memory_order: [
---
           randomization_seed: 2841470775817841315,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:51:1
   |
LL | enum TwoVariants { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^

error: layout_of(DeadBranchHasOtherField) = Layout {
           size: Size(16 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Memory {
               sized: true,
           },
           fields: Arbitrary {
---
           randomization_seed: 8023648819463119270,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:63:1
   |
LL | enum DeadBranchHasOtherField { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
------------------------------------------

---

93                    ),
94                },
-            ),
+                b_offset: Size(1 bytes),
+            },
96            fields: Arbitrary {
97                offsets: [
98                    Size(0 bytes),

---

140                                ),
141                            },
-                        ),
+                            b_offset: Size(1 bytes),
+                        },
143                        field_offsets: [
144                            Size(1 bytes),
145                        ],

---

166                                ),
167                            },
-                        ),
+                            b_offset: Size(1 bytes),
+                        },
169                        field_offsets: [
170                            Size(1 bytes),
171                        ],


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args repr/repr-c-dead-variants.rs`

error in revision `armebv7r-none-eabi`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/repr/repr-c-dead-variants.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--cfg" "armebv7r_none_eabi" "--check-cfg" "cfg(test,FALSE,aarch64_unknown_linux_gnu,i686_pc_windows_msvc,x86_64_unknown_linux_gnu,armebv7r_none_eabi)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.armebv7r-none-eabi" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Cpanic=abort" "-Cforce-unwind-tables=yes" "--target" "armebv7r-none-eabi" "--extern" "minicore=/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.armebv7r-none-eabi/libminicore.rlib"
stdout: none
--- stderr -------------------------------
error: layout_of(Univariant) = Layout {
           size: Size(1 bytes),
           align: AbiAlign {
---
           randomization_seed: 15956128936533895400,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:44:1
   |
LL | enum Univariant { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^

error: layout_of(TwoVariants) = Layout {
           size: Size(2 bytes),
           align: AbiAlign {
---
                       I8,
                       false,
                   ),
               },
               b_offset: Size(1 bytes),
           },
           fields: Arbitrary {
               offsets: [
                   Size(0 bytes),
               ],
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(1 bytes),
                       },
                       field_offsets: [
                           Size(1 bytes),
                       ],
                       fields_in_memory_order: [
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(1 bytes),
                       },
                       field_offsets: [
                           Size(1 bytes),
                       ],
                       fields_in_memory_order: [
---
           randomization_seed: 2841470775817841315,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:51:1
   |
LL | enum TwoVariants { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^

error: layout_of(DeadBranchHasOtherField) = Layout {
           size: Size(16 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Memory {
               sized: true,
           },
           fields: Arbitrary {
---
           randomization_seed: 8023648819463119270,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:63:1
   |
LL | enum DeadBranchHasOtherField { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
------------------------------------------

---

93                    ),
94                },
-            ),
+                b_offset: Size(1 bytes),
+            },
96            fields: Arbitrary {
97                offsets: [
98                    Size(0 bytes),

---

140                                ),
141                            },
-                        ),
+                            b_offset: Size(1 bytes),
+                        },
143                        field_offsets: [
144                            Size(1 bytes),
145                        ],

---

166                                ),
167                            },
-                        ),
+                            b_offset: Size(1 bytes),
+                        },
169                        field_offsets: [
170                            Size(1 bytes),
171                        ],


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args repr/repr-c-int-dead-variants.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/repr/repr-c-int-dead-variants.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-int-dead-variants" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error: layout_of(UnivariantU8) = Layout {
           size: Size(1 bytes),
           align: AbiAlign {
               abi: Align(1 bytes),
           },
           backend_repr: Scalar(
               Initialized {
                   value: Int(
                       I8,
---
           randomization_seed: 9339210691079068372,
       }
  --> /checkout/tests/ui/repr/repr-c-int-dead-variants.rs:15:1
   |
LL | enum UnivariantU8 { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^

error: layout_of(TwoVariantsU8) = Layout {
           size: Size(2 bytes),
           align: AbiAlign {
               abi: Align(1 bytes),
           },
           backend_repr: ScalarPair {
               a: Initialized {
                   value: Int(
                       I8,
---
                       I8,
                       false,
                   ),
               },
               b_offset: Size(1 bytes),
           },
           fields: Arbitrary {
               offsets: [
                   Size(0 bytes),
               ],
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(1 bytes),
                       },
                       field_offsets: [
                           Size(1 bytes),
                       ],
                       fields_in_memory_order: [
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(1 bytes),
                       },
                       field_offsets: [
                           Size(1 bytes),
                       ],
                       fields_in_memory_order: [
---
           randomization_seed: 8867768348692815593,
       }
  --> /checkout/tests/ui/repr/repr-c-int-dead-variants.rs:22:1
   |
LL | enum TwoVariantsU8 { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^^

error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
           size: Size(16 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Memory {
               sized: true,
           },
           fields: Arbitrary {
---
           randomization_seed: 17619836599796372240,
       }
  --> /checkout/tests/ui/repr/repr-c-int-dead-variants.rs:34:1
   |
LL | enum DeadBranchHasOtherFieldU8 { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
------------------------------------------

---- [ui] tests/ui/repr/repr-c-int-dead-variants.rs stdout end ----
---- [ui] tests/ui/repr/repr-c-dead-variants.rs#i686-pc-windows-msvc stdout ----
Saved the actual stderr to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc/repr-c-dead-variants.i686-pc-windows-msvc.stderr`
diff of stderr:

78            align: AbiAlign {
79                abi: Align(4 bytes),
80            },
---

93                    ),
94                },
-            ),
+                b_offset: Size(4 bytes),
+            },
96            fields: Arbitrary {
97                offsets: [
98                    Size(0 bytes),

---

140                                ),
141                            },
-                        ),
+                            b_offset: Size(4 bytes),
+                        },
143                        field_offsets: [
144                            Size(4 bytes),
145                        ],

---

166                                ),
167                            },
-                        ),
+                            b_offset: Size(4 bytes),
+                        },
169                        field_offsets: [
170                            Size(4 bytes),
171                        ],


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args repr/repr-c-dead-variants.rs`

error in revision `i686-pc-windows-msvc`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/repr/repr-c-dead-variants.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--cfg" "i686_pc_windows_msvc" "--check-cfg" "cfg(test,FALSE,aarch64_unknown_linux_gnu,i686_pc_windows_msvc,x86_64_unknown_linux_gnu,armebv7r_none_eabi)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Cpanic=abort" "-Cforce-unwind-tables=yes" "--target" "i686-pc-windows-gnu" "--extern" "minicore=/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc/libminicore.rlib"
stdout: none
--- stderr -------------------------------
error: layout_of(Univariant) = Layout {
           size: Size(4 bytes),
           align: AbiAlign {
---
           randomization_seed: 15956128936533895400,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:44:1
   |
LL | enum Univariant { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^

error: layout_of(TwoVariants) = Layout {
           size: Size(8 bytes),
           align: AbiAlign {
---
                       I8,
                       false,
                   ),
               },
               b_offset: Size(4 bytes),
           },
           fields: Arbitrary {
               offsets: [
                   Size(0 bytes),
               ],
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(4 bytes),
                       },
                       field_offsets: [
                           Size(4 bytes),
                       ],
                       fields_in_memory_order: [
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(4 bytes),
                       },
                       field_offsets: [
                           Size(4 bytes),
                       ],
                       fields_in_memory_order: [
---
           randomization_seed: 2841470775817841315,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:51:1
   |
LL | enum TwoVariants { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^

error: layout_of(DeadBranchHasOtherField) = Layout {
           size: Size(16 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Memory {
               sized: true,
           },
           fields: Arbitrary {
---
           randomization_seed: 8023648819463119270,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:63:1
   |
LL | enum DeadBranchHasOtherField { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
------------------------------------------

---

93                    ),
94                },
-            ),
+                b_offset: Size(4 bytes),
+            },
96            fields: Arbitrary {
97                offsets: [
98                    Size(0 bytes),

---

140                                ),
141                            },
-                        ),
+                            b_offset: Size(4 bytes),
+                        },
143                        field_offsets: [
144                            Size(4 bytes),
145                        ],

---

166                                ),
167                            },
-                        ),
+                            b_offset: Size(4 bytes),
+                        },
169                        field_offsets: [
170                            Size(4 bytes),
171                        ],


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args repr/repr-c-dead-variants.rs`

error in revision `x86_64-unknown-linux-gnu`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/repr/repr-c-dead-variants.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--cfg" "x86_64_unknown_linux_gnu" "--check-cfg" "cfg(test,FALSE,aarch64_unknown_linux_gnu,i686_pc_windows_msvc,x86_64_unknown_linux_gnu,armebv7r_none_eabi)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Cpanic=abort" "-Cforce-unwind-tables=yes" "--target" "x86_64-unknown-linux-gnu" "--extern" "minicore=/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu/libminicore.rlib"
stdout: none
--- stderr -------------------------------
error: layout_of(Univariant) = Layout {
           size: Size(4 bytes),
           align: AbiAlign {
---
           randomization_seed: 15956128936533895400,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:44:1
   |
LL | enum Univariant { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^

error: layout_of(TwoVariants) = Layout {
           size: Size(8 bytes),
           align: AbiAlign {
---
                       I8,
                       false,
                   ),
               },
               b_offset: Size(4 bytes),
           },
           fields: Arbitrary {
               offsets: [
                   Size(0 bytes),
               ],
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(4 bytes),
                       },
                       field_offsets: [
                           Size(4 bytes),
                       ],
                       fields_in_memory_order: [
---
                                   I8,
                                   false,
                               ),
                           },
                           b_offset: Size(4 bytes),
                       },
                       field_offsets: [
                           Size(4 bytes),
                       ],
                       fields_in_memory_order: [
---
           randomization_seed: 2841470775817841315,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:51:1
   |
LL | enum TwoVariants { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^

error: layout_of(DeadBranchHasOtherField) = Layout {
           size: Size(16 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Memory {
               sized: true,
           },
           fields: Arbitrary {
---
           randomization_seed: 8023648819463119270,
       }
  --> /checkout/tests/ui/repr/repr-c-dead-variants.rs:63:1
   |
LL | enum DeadBranchHasOtherField { //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors
------------------------------------------

---
159                    ),
160                    valid_range: 0..=18446744073709551615,
161                },
-            ),
+                b_offset: Size(8 bytes),
+            },
163            fields: Arbitrary {
164                offsets: [
165                    Size(0 bytes),


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args type/pattern_types/non_null.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/type/pattern_types/non_null.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/type/pattern_types/non_null" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error: layout_of((*const T) is !null) = Layout {
           size: Size(8 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Scalar(
               Initialized {
                   value: Pointer(
                       AddressSpace(
---
           randomization_seed: 17179869191,
       }
  --> /checkout/tests/ui/type/pattern_types/non_null.rs:11:1
   |
LL | type NonNull<T> = pattern_type!(*const T is !null); //~ ERROR layout_of
   | ^^^^^^^^^^^^^^^

error: layout_of(Option<(*const ()) is !null>) = Layout {
           size: Size(8 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: Scalar(
               Initialized {
                   value: Pointer(
                       AddressSpace(
---
           randomization_seed: 12057720629248040856,
       }
  --> /checkout/tests/ui/type/pattern_types/non_null.rs:14:1
   |
LL | type Test = Option<NonNull<()>>; //~ ERROR layout_of
   | ^^^^^^^^^

error: layout_of((*const [u8]) is !null) = Layout {
           size: Size(16 bytes),
           align: AbiAlign {
               abi: Align(8 bytes),
           },
           backend_repr: ScalarPair {
               a: Initialized {
                   value: Pointer(
                       AddressSpace(
---
                       false,
                   ),
                   valid_range: 0..=18446744073709551615,
               },
               b_offset: Size(8 bytes),
           },
           fields: Arbitrary {
               offsets: [
                   Size(0 bytes),
               ],
---
           randomization_seed: 16,
       }
  --> /checkout/tests/ui/type/pattern_types/non_null.rs:17:1
   |
LL | type Wide = pattern_type!(*const [u8] is !null); //~ ERROR layout_of
   | ^^^^^^^^^

error: aborting due to 3 previous errors
------------------------------------------

@oli-obk

oli-obk commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

@bors try @rust-timer queue

@rust-timer

Copy link
Copy Markdown
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rust-bors

rust-bors Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

⌛ Trying commit 22e7592 with merge e1ccfbf

To cancel the try build, run the command @bors try cancel.

Workflow: https://github.com/rust-lang/rust/actions/runs/28539007014

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 1, 2026
rust-bors Bot pushed a commit that referenced this pull request Jul 1, 2026
Carry the `b_offset` inside `BackendRepr::ScalarPair`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. F-autodiff `#![feature(autodiff)]` S-waiting-on-perf Status: Waiting on a perf run to be completed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants