Change:
The types and do not have the same ABI, as demonstrated by this testcase: The first is The second is RISC-V had , so the fix will likely . I couldn't find an O-loongarch label. Cc'ing the people listed on
The loongarch ABI seems to be pretty much exactly like the RISC-V ABI, so I wonder if it would make sense to share some of that code so that bugs like this only have to be fixed once.
Thanks for the report! The LoongArch ABI is indeed closely modeled after that of RISC-V, so yeah the fix should look similar. should be able to follow up tomorrow.
WG-prioritization assigning priority (). label -I-prioritize +P-medium
I don't think you meant to tag me. Don't know much about rust.
Doh, the correct Rust/LoongArch person is who happens to have another handle of "hev". Sorry for the noise!
Thanks for your pointing out. I don't think the types and would have the same ABI on LoongArch64. The key point of the problem is that is a , which is different from a : For types and , they are same ABI: The first is: The second is: And it seems that the current ABI of is the same as that of C language on LoongArch64: The first is: The second is:
I haven't studied the LoongArch psABI as closely, but from a Rust semantics perspective: is "a -sized area that may or may not hold an initialized ", so and really should behave the same when that's the case -- implying the two must have the same ABI. So this is something to look into and fix after all...
It's a Rust union, but it doesn't have , so whatever applies to C unions is completely irrelevant. For instance, many ABIs (e.g. x86) treat structs different from integers, and still has the same ABI as -- that's because is not a struct, so its ABI doesn't have to match that of a C struct. We promise that has the same ABI as for all on all targets, so this is really not optional. Your C example, when translated to Rust, needs on all types. The ABI of those types obviously needs to match the C types. But that's completely compatible with also treating types differently.
Thank you for your explanation. Hmm, I'm not familiar with Rust ABI, and it seems to have less relevance to psABI. OK, I will follow the RISC-V patches to fix LoongArch.
It's the same problem we have on all targets: there is a target ABI that is defined in terms of C types, and now every other language has to figure out how to map their types to C types to then compute the ABI from that. Unfortunately the Rust compiler has no central infrastructure for that (there's no function to "give me the C type that describes the ABI of a given Rust type"), and so each target has to implement that mapping itself, and they are all making similar mistakes...
label +O-loongarch

Discussion:
} FieldsShape::Union(_) => { if !arg_layout.is_zst() { <ins> if arg_layout.is_transparent() { let non_1zst_elem = arg_layout.non_1zst_field(cx).expect("not exactly one non-1-ZST field in non-ZST repr(transparent) union").1; return should_use_fp_conv_helper( cx, &non_1zst_elem, xlen, flen, field1_kind, field2_kind, ); } </ins> return Err(CannotUseFpConv); } }

// Hence there are `cfg` throughout this test to disable parts of it on those targets. // sparc64: https://github.com/rust-lang/rust/issues/115336 // mips64: https://github.com/rust-lang/rust/issues/115404 <del> // loongarch64: https://github.com/rust-lang/rust/issues/115509 </del> macro_rules! assert_abi_compatible { ($name:ident, $t1:ty, $t2:ty) => {

test_abi_compatible!(wrap1, $t, Wrapper1<$t>); test_abi_compatible!(wrap2, $t, Wrapper2<$t>); test_abi_compatible!(wrap3, $t, Wrapper3<$t>); <del> #[cfg(not(target_arch = "loongarch64"))] </del> test_abi_compatible!(wrap4, $t, WrapperUnion<$t>); } };