For
pub struct Moo((u128, ()));
pub fn moo(a: Moo, b: Moo) -> Moo {
Moo(((a.0).0 + (b.0).0, ()))
}
pub struct Baa(u128, ());
pub fn baa(a: Baa, b: Baa) -> Baa {
Baa(a.0 + b.0, ())
}
cargo asm gives
try::moo:
mov rcx, qword, ptr, [rdx]
add rcx, qword, ptr, [rsi]
mov rdx, qword, ptr, [rdx, +, 8]
adc rdx, qword, ptr, [rsi, +, 8]
mov rax, rdi
mov qword, ptr, [rdi, +, 8], rdx
mov qword, ptr, [rdi], rcx
ret
and
try::baa:
mov rax, rdi
add rax, rdx
adc rsi, rcx
mov rdx, rsi
ret
Notably this effects the type (u128, ()) as well.
pub type Oink = (u128, ());
pub fn oink(a: Oink, b: Oink) -> Oink {
(a.0 + b.0, ())
}
ASM:
.set playground::oink, playground::moo
(I couldn't think of a farm animal sound that rhymes with "baz")
(I couldn't think of a farm animal sound that rhymes with "baz")
Moo, moo, brown cow, have you milk for me?
Baa, baa, black sheep, have you any wool?
Buzz, buzz, busy bee, is your honey sweet?
Web repro: https://rust.godbolt.org/z/3lLlZF
This looks like a Rust ABI thing -- Moo makes a type but Baa becomes transparent:
%Moo = type { [0 x i64], { [0 x i64], i128, [0 x i8], {}, [0 x i8] }, [0 x i64] }
define void @_ZN7example3moo17hef8326368864ce30E(%Moo* noalias nocapture sret dereferenceable(16), %Moo* noalias nocapture readonly dereferenceable(16) %a, %Moo* noalias nocapture readonly dereferenceable(16) %b) unnamed_addr #0 {
define i128 @_ZN7example3baa17h7849d3e5f09843b9E(i128 %a, i128 %b) unnamed_addr #1 {
The ASM differences are uninteresting -- they're just from the parameters (and return value) being passed as pointers vs being passed by value.
Would it be possible for the Rust ABI to make tuples behave as repr transparent? As it is, a tuple with an element and a ZST marker would not be zero-cost.
Most helpful comment
Moo, moo, brown cow, have you milk for me?
Baa, baa, black sheep, have you any wool?
Buzz, buzz, busy bee, is your honey sweet?