Skip to content

Update discriminant-elision optimization on Option-like enums #149

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 12 commits into from
Jul 18, 2019
39 changes: 32 additions & 7 deletions reference/src/layout/enums.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,15 @@ apply, as described below.

#### Discriminant elision on Option-like enums

(Meta-note: The content in this section is not described by any RFC
and is therefore "non-normative".)
(Meta-note: The content in this section is not fully described by any RFC and is
therefore "non-normative". Parts of it were specified in
[rust-lang/rust#60300]).

**Definition.** An **option-like enum** is a 2-variant enum where:
[rust-lang/rust#60300]: https://github.com/rust-lang/rust/pull/60300

**Definition.** An **option-like enum** is a 2-variant `enum` where:

- the `enum` has no explicit `#[repr(...)]`, and
- one variant has a single field, and
- the other variant has no fields (the "unit variant").

Expand All @@ -313,13 +317,23 @@ values, which are called **niches**. For example, a value of type `&T`
may never be `NULL`, and hence defines a niche consisting of the
bitstring `0`. Similarly, the standard library types [`NonZeroU8`]
and friends may never be zero, and hence also define the value of `0`
as a niche. (Types that define niche values will say so as part of the
description of their validity invariant, which -- as of this writing
-- are the next topic up for discussion in the unsafe code guidelines
process.)
as a niche.

[`NonZeroU8`]: https://doc.rust-lang.org/std/num/struct.NonZeroU8.html

The niche values must be disjoint from the values allowed by the validity
invariant. The validity invariant is, as of this writing, is the current active
discussion topic in the unsafe code guidelines process. [rust-lang/rust#60300]
specifies that the following types have at least one niche (the all-zeros
bit-pattern):

* `&T`
* `&mut T`
* `extern "C" fn`
* `core::num::NonZero*`
* `core::ptr::NonNull<T>`
* `#[repr(transparent)] struct` around one of the types in this list.

**Option-like enums where the payload defines at least one niche value
are guaranteed to be represented using the same memory layout as their
payload.** This is called **discriminant elision**, as there is no
Expand Down Expand Up @@ -351,6 +365,17 @@ enum Enum1<T> {
}
```

**Example.** The following enum definition is **not** option-like,
as it has an explicit `repr` attribute.

```rust
#[repr(u8)]
enum Enum2<T> {
Present(T),
Absent1,
}
```

## Unresolved questions

### Layout of single variant enums
Expand Down