Skip to content

Commit db2ec96

Browse files
authored
Unrolled build for #141947
Rollup merge of #141947 - zachs18:patch-4, r=workingjubilee,traviscross Specify that "option-like" enums must be `#[repr(Rust)]` to be ABI-compatible with their non-1ZST field. Add that the enum must be `#[repr(Rust)]` and not `#[repr(packed)]` or `#[repr(align)]` in order to be ABI-compatible with its null-pointer-optimized field. The specific rules here were decided on here: #130628 (comment) but `repr` was not mentioned. In practice, only `#[repr(Rust)]` (or no `repr` attribute, which is equivalent) works for this, so add that to the docs. ----- Restrict to `#[repr(Rust)]` only, since: * `#[repr(C)]` and the primitive representations (`#[repr(u8)]` etc) definitely disqualify the enum from NPO, since they have defined layouts that store the tag separately to the payload. * `#[repr(transparent)]` enums are covered two bullet points above this (line 1830), and cannot have multiple variants, so would fail the "The enum has exactly two variants" requirement anyway. As for `#[repr(align)]`: my current wording that it is completely disallowed may be too strong: it seems like `#[repr(align(<= alignment of T))] enum Foo { X, Y(T) }` currently does still have the same ABI as `T` in practice, though this may not be something we want to promise. (`#[repr(align(> alignment of T))]` definitely disqualifies the enum from being ABI-compatible with T currently). I added the note about `packed` to match `align`, but `#[repr(packed)]` currently can't be applied to `enum`s at all anyway, so might be unnecessary. ----- I think this needs T-lang approval? cc ``````@workingjubilee``````
2 parents ed44c0e + c0851d7 commit db2ec96

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

library/core/src/primitive_docs.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,8 @@ mod prim_ref {}
18471847
/// - If `T` is guaranteed to be subject to the [null pointer
18481848
/// optimization](option/index.html#representation), and `E` is an enum satisfying the following
18491849
/// requirements, then `T` and `E` are ABI-compatible. Such an enum `E` is called "option-like".
1850+
/// - The enum `E` uses the [`Rust` representation], and is not modified by the `align` or
1851+
/// `packed` representation modifiers.
18501852
/// - The enum `E` has exactly two variants.
18511853
/// - One variant has exactly one field, of type `T`.
18521854
/// - All fields of the other variant are zero-sized with 1-byte alignment.
@@ -1920,6 +1922,7 @@ mod prim_ref {}
19201922
/// [`Pointer`]: fmt::Pointer
19211923
/// [`UnwindSafe`]: panic::UnwindSafe
19221924
/// [`RefUnwindSafe`]: panic::RefUnwindSafe
1925+
/// [`Rust` representation]: <https://doc.rust-lang.org/reference/type-layout.html#the-rust-representation>
19231926
///
19241927
/// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because
19251928
/// these traits are specially known to the compiler.

0 commit comments

Comments
 (0)