Description
The following code:
pub fn bad() -> Result<u64, core::ptr::NonNull<()>> {
Ok(0)
}
#[allow(improper_ctypes_definitions)]
pub extern "C" fn good() -> Result<u64, core::ptr::NonNull<()>> {
Ok(0)
}
Both functions should be identical, returning the 128-bit value in RAX and RDX per the sysv-64 ABI, which is the default for the environment godbolt uses by default.
Instead, when returning the value without specifying any ABI, the compiler chooses to return the value using an out pointer argument.
Note: This affects Result<usize, std::io::Error>
, which is a particularly useful type and affects a significant portion of std::io
, such as Read
and Write
Meta
This has improved and regressed since 1.43.0, the first version I could find which would use 128 bits for the type.
All versions tested used the expected code generation for the extern "C"
function.
All tests done using https://godbolt.org and no target overrides, which in practice is a x86_64 linux machine using the sysv-64 ABI.
..= 1.42.0: niche not used, cannot be compared
1.43.0 ..= 1.47.0: codegen like today, uses out ptr for return
1.48.0 ..= 1.60.0: returns using an LLVM i128
, which produces the most desirable code on sysv-64
1.61.0 .. (current 2022-05-28 nightly): poor codegen that uses an out ptr for return
@rustbot label +regression-from-stable-to-stable +A-codegen