Skip to content

Commit bf3a50e

Browse files
committed
Update discriminant-elision optimization on Option-like enums
1 parent 97cbda4 commit bf3a50e

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

reference/src/layout/enums.md

+30-7
Original file line numberDiff line numberDiff line change
@@ -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`
313317
may never be `NULL`, and hence defines a niche consisting of the
314318
bitstring `0`. Similarly, the standard library types [`NonZeroU8`]
315319
and 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] specified 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
324336
are guaranteed to be represented using the same memory layout as their
325337
payload.** 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

Comments
 (0)