Distinguish repr(C) ZSTs from others in ABI compatibility rules#157973
Distinguish repr(C) ZSTs from others in ABI compatibility rules#157973Jules-Bertholet wants to merge 2 commits into
repr(C) ZSTs from others in ABI compatibility rules#157973Conversation
|
rustbot has assigned @Mark-Simulacrum. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| /// - Alignment 1 | ||
| /// - Not `repr(C)` | ||
| /// - Not a `repr(transparent)` wrapper around a type that fails to satisfy these conditions | ||
| /// - Not an array whose element type fails to satisfy these conditions |
There was a problem hiding this comment.
We exempt arrays for 2 reasons:
- A future version of C, or some other language we would like to do FFI with, might allow passing arrays to functions directly by value, in a way that would conflict with these guarantees
- It would be nice to also use "trivial ABI" in the specification of
repr(C), and we need this clause for that. See discussion at repr(ordered_fields) rfcs#3845 (comment)
We could also simplify this clause by saying merely:
| /// - Not an array whose element type fails to satisfy these conditions | |
| /// - Not an array |
The downside would be a larger breaking change.
Note that repr(transparent) will need to be adjusted to account for this change (by rejecting non-trivial arrays as "additional" fields).
There was a problem hiding this comment.
Some C ABIs pass and return ZSTs by pointer. But () should never be returned by pointer, as it must match void. To account for this, we have to weaken the present guarantee of "any two types with size 0 and alignment 1 are ABI-compatible" to exclude repr(C).
I think the implication here is that () is repr(C)? Am I reading that right? Where do we make that guarantee? Or is the thinking that the language here would make () and #[repr(C)] struct Foo; not ABI compatible?
One callout is that ZSTs aren't (I think?) standardized -- C and C++ without extensions both require types to be non-ZST if I remember right (e.g., see https://stackoverflow.com/a/2632075). Maybe that has changed since then though?
It seems like at minimum, it would be nice to avoid weakening this guarantee for Rust ABI even if we do so for C ABIs as a result of the weird platforms.
There was a problem hiding this comment.
Or is the thinking that the language here would make
()and#[repr(C)] struct Foo;not ABI compatible?
Yes, this.
(Split out from compiler implementation in #156112)
Some C ABIs pass and return ZSTs by pointer. But
()should never be returned by pointer, as it must matchvoid. To account for this, we have to weaken the present guarantee of "any two types with size 0 and alignment 1 are ABI-compatible" to excluderepr(C).Fixes rust-lang/unsafe-code-guidelines#552; see also #78586, #155299.
@rustbot label T-lang A-ABI needs-fcp