@@ -292,11 +292,15 @@ apply, as described below.
292292
293293#### Discriminant elision on Option-like enums
294294
295- (Meta-note: The content in this section is not described by any RFC
296- and is therefore "non-normative".)
295+ (Meta-note: The content in this section is not fully described by any RFC and is
296+ therefore "non-normative". Parts of it were specified in
297+ [rust-lang/rust#60300].
297298
298- **Definition.** An **option-like enum** is a 2-variant enum where:
299+ [rust-lang/rust#60300]: https://github.com/rust-lang/rust/pull/60300
299300
301+ **Definition.** An **option-like enum** is a 2-variant `enum` where:
302+
303+ - the `enum` has no explicit `#[repr(...)]`, and
300304- one variant has a single field, and
301305- the other variant has no fields (the "unit variant").
302306
@@ -313,13 +317,21 @@ values, which are called **niches**. For example, a value of type `&T`
313317may never be `NULL`, and hence defines a niche consisting of the
314318bitstring `0`. Similarly, the standard library types [`NonZeroU8`]
315319and friends may never be zero, and hence also define the value of `0`
316- as a niche. (Types that define niche values will say so as part of the
317- description of their validity invariant, which -- as of this writing
318- -- are the next topic up for discussion in the unsafe code guidelines
319- process.)
320+ as a niche.
320321
321322[`NonZeroU8`]: https://doc.rust-lang.org/std/num/struct.NonZeroU8.html
322323
324+ The niche values of a type are parts of its validity invariant which, as of this
325+ writing, is the current active discussion topic in the unsafe code guidelines
326+ process. [rust-lang/rust#60300] specifies that the following types have a niche:
327+
328+ * `&T`
329+ * `&mut T`
330+ * `extern "C" fn`
331+ * `core::num::NonZero*`
332+ * `core::ptr::NonNull<T>`
333+ * `#[repr(transparent)] struct` around one of the types in this list.
334+
323335**Option-like enums where the payload defines at least one niche value
324336are guaranteed to be represented using the same memory layout as their
325337payload.** This is called **discriminant elision**, as there is no
@@ -351,6 +363,17 @@ enum Enum1<T> {
351363}
352364```
353365
366+ ** Example.** The following enum definition is ** not** option-like,
367+ as it has an explicit ` repr ` attribute.
368+
369+ ``` rust
370+ #[repr(u8 )]
371+ enum Enum2 <T > {
372+ Present (T ),
373+ Absent1 ,
374+ }
375+ ```
376+
354377## Unresolved questions
355378
356379### Layout of single variant enums
0 commit comments