Skip to content

Specify that "option-like" enums must be #[repr(Rust)] to be ABI-compatible with their non-1ZST field. #141947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions library/core/src/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,8 @@ mod prim_ref {}
/// - If `T` is guaranteed to be subject to the [null pointer
/// optimization](option/index.html#representation), and `E` is an enum satisfying the following
/// requirements, then `T` and `E` are ABI-compatible. Such an enum `E` is called "option-like".
/// - The enum `E` uses the [`Rust` representation], and is not modified by the `align` or
/// `packed` representation modifiers.
Comment on lines +1836 to +1837
Copy link
Member

Choose a reason for hiding this comment

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

Changing alignment of something can change its ABI, and both of these repr attributes, as modifiers, can do that. So I am okay with having the guarantee be conditional on any usage of the repr attributes. If T-lang wants us to guarantee that the attributes only invalidate the nullptr opt if they actually would result in a change in the alignment of the type, that may be doable, but it would require auditing the code involved and landing a number of tests, so I don't know that it should happen in this PR. Also, see my next comment.

/// - The enum `E` has exactly two variants.
/// - One variant has exactly one field, of type `T`.
/// - All fields of the other variant are zero-sized with 1-byte alignment.
Copy link
Member

Choose a reason for hiding this comment

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

Reviewing more closely, I feel guaranteeing e.g. repr(align(2)) won't change the layout if T is 2-aligned would be inconsistent with this clause.

We could potentially raise this alignment to whatever the alignment of T is, for example. I don't want to alter the guarantee around the 1ZST case, however, as it places a number of annoying requirements on the implementation. Being able to special-case specifically on 1ZSTs simplifies a lot of things. I would be okay with guaranteeing that repr(align(1)) doesn't change anything, though, because it doesn't. There's also some inclarity about certain special cases around ZSTs already when they combine with other repr attributes like repr(C).

Expand Down Expand Up @@ -1906,6 +1908,7 @@ mod prim_ref {}
/// [`Pointer`]: fmt::Pointer
/// [`UnwindSafe`]: panic::UnwindSafe
/// [`RefUnwindSafe`]: panic::RefUnwindSafe
/// [`Rust` representation]: <https://doc.rust-lang.org/reference/type-layout.html#the-rust-representation>
///
/// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because
/// these traits are specially known to the compiler.
Expand Down
Loading