Change:
On aarch64-unknown-linux-gnu (a tier 1 target), consider this testcase: passes its argument as uses IOW, uses float registers and uses int registers. This violates our promise that types are ABI-compatible. I think this might indicate a bug in the function? At least I don't see anything in the aarch64 adjustment that would be obviously wrong.
This also affects arm32 targets like arm-unknown-linux-gnueabihf.
Yes, that is definitely the issue -- that is heterogeneous.
Should be fixed by

Discussion:
/// only a single type (e.g., `(u32, u32)`). Such aggregates are often /// special-cased in ABIs. /// <del> /// Note: We generally ignore fields of zero-sized type when computing /// this value (see #56877). </del> <ins> /// Note: We generally ignore 1-ZST fields when computing this value (see #56877). </ins> /// /// This is public so that it can be used in unit tests, but /// should generally only be relevant to the ABI details of

let mut total = start; for i in 0..layout.fields.count() { <ins> let field = layout.field(cx, i); if field.is_1zst() { // No data here and no impact on layout, can be ignored. // (We might be able to also ignore all aligned ZST but that's less clear.) continue; } </ins> if !is_union && total != layout.fields.offset(i) { <ins> // This field isn't just after the previous one we considered, abort. </ins> return Err(Heterogeneous); } <del> let field = layout.field(cx, i); </del> result = result.merge(field.homogeneous_aggregate(cx)?)?; // Keep track of the offset (without padding).

test_transparent!(unit, ()); test_transparent!(pair, (i32, f32)); // mixing in some floats since they often get special treatment test_transparent!(triple, (i8, i16, f32)); // chosen to fit into 64bit <ins> test_transparent!(triple_f32, (f32, f32, f32)); // homogeneous case test_transparent!(triple_f64, (f64, f64, f64)); </ins> test_transparent!(tuple, (i32, f32, i64, f64)); test_transparent!(empty_array, [u32; 0]); test_transparent!(empty_1zst_array, [u8; 0]);

test_transparent!(large_array, [i32; 16]); test_transparent!(enum_, Option<i32>); test_transparent!(enum_niched, Option<&'static i32>); <del> // Pure-float types that are not ScalarPair seem to be tricky. // FIXME: <https://github.com/rust-lang/rust/issues/115664> #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] mod tricky { use super::*; test_transparent!(triple_f32, (f32, f32, f32)); test_transparent!(triple_f64, (f64, f64, f64)); } </del> // RFC 3391 <https://rust-lang.github.io/rfcs/3391-result_ffi_guarantees.html>. macro_rules! test_nonnull {

<ins> #![feature(rustc_attrs)] #![feature(transparent_unions)] use std::marker::PhantomData; // Regression test for #115664. We want to ensure that `repr(transparent)` wrappers do not affect // the result of `homogeneous_aggregate`. type Tuple = (f32, f32, f32); struct Zst; #[repr(transparent)] struct Wrapper1<T>(T); #[repr(transparent)] struct Wrapper2<T>((), Zst, T); #[repr(transparent)] struct Wrapper3<T>(T, [u8; 0], PhantomData<u64>); #[repr(transparent)] union WrapperUnion<T: Copy> { nothing: (), something: T, } #[rustc_layout(homogeneous_aggregate)] pub type Test0 = Tuple; //~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test1 = Wrapper1<Tuple>; //~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test2 = Wrapper2<Tuple>; //~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test3 = Wrapper3<Tuple>; //~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test4 = WrapperUnion<Tuple>; //~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) fn main() {} </ins>

<ins> error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-transparent.rs:25:1 | LL | pub type Test0 = Tuple; | ^^^^^^^^^^^^^^ error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-transparent.rs:29:1 | LL | pub type Test1 = Wrapper1<Tuple>; | ^^^^^^^^^^^^^^ error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-transparent.rs:33:1 | LL | pub type Test2 = Wrapper2<Tuple>; | ^^^^^^^^^^^^^^ error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-transparent.rs:37:1 | LL | pub type Test3 = Wrapper3<Tuple>; | ^^^^^^^^^^^^^^ error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-transparent.rs:41:1 | LL | pub type Test4 = WrapperUnion<Tuple>; | ^^^^^^^^^^^^^^ error: aborting due to 5 previous errors </ins>