Skip to content

Distinguish repr(C) ZSTs from others in ABI compatibility rules#157973

Open
Jules-Bertholet wants to merge 2 commits into
rust-lang:mainfrom
Jules-Bertholet:distinguish-c-zst-docs
Open

Distinguish repr(C) ZSTs from others in ABI compatibility rules#157973
Jules-Bertholet wants to merge 2 commits into
rust-lang:mainfrom
Jules-Bertholet:distinguish-c-zst-docs

Conversation

@Jules-Bertholet

@Jules-Bertholet Jules-Bertholet commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

(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 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).

Fixes rust-lang/unsafe-code-guidelines#552; see also #78586, #155299.

@rustbot label T-lang A-ABI needs-fcp

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 16, 2026
@rustbot

rustbot commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 11 candidates
  • Random selection from 6 candidates

@rustbot rustbot added A-ABI Area: Concerning the application binary interface (ABI) needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. T-lang Relevant to the language team labels Jun 16, 2026
/// - 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

@Jules-Bertholet Jules-Bertholet Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Suggested change
/// - 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).

View changes since the review

@Mark-Simulacrum Mark-Simulacrum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably mostly an opsem question in my eyes, at least to figure out the right shape. I see there's already been some discussion but I think nailing the language is probably better delegated too.

r? opsem

View changes since this review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Jules-Bertholet Jules-Bertholet Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is the thinking that the language here would make () and #[repr(C)] struct Foo; not ABI compatible?

Yes, this.

@rustbot rustbot added the T-opsem Relevant to the opsem team label Jun 21, 2026
@rustbot rustbot assigned CAD97 and unassigned Mark-Simulacrum Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ABI Area: Concerning the application binary interface (ABI) needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team T-libs Relevant to the library team, which will review and decide on the PR/issue. T-opsem Relevant to the opsem team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Any two types with size 0 and alignment 1 are ABI-compatible" vs the Windows ABI

4 participants