@@ -292,11 +292,15 @@ apply, as described below.
292
292
293
293
#### Discriminant elision on Option-like enums
294
294
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].
297
298
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
299
300
301
+ **Definition.** An **option-like enum** is a 2-variant `enum` where:
302
+
303
+ - the `enum` has no explicit `#[repr(...)]`, and
300
304
- one variant has a single field, and
301
305
- the other variant has no fields (the "unit variant").
302
306
@@ -313,13 +317,21 @@ values, which are called **niches**. For example, a value of type `&T`
313
317
may never be `NULL`, and hence defines a niche consisting of the
314
318
bitstring `0`. Similarly, the standard library types [`NonZeroU8`]
315
319
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.
320
321
321
322
[`NonZeroU8`]: https://doc.rust-lang.org/std/num/struct.NonZeroU8.html
322
323
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
+
323
335
**Option-like enums where the payload defines at least one niche value
324
336
are guaranteed to be represented using the same memory layout as their
325
337
payload.** This is called **discriminant elision**, as there is no
@@ -351,6 +363,17 @@ enum Enum1<T> {
351
363
}
352
364
```
353
365
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
+
354
377
## Unresolved questions
355
378
356
379
### Layout of single variant enums
0 commit comments