@@ -46,10 +46,10 @@ As in C, discriminant values that are not specified are defined as
46
46
either 0 (for the first variant) or as one more than the prior
47
47
variant.
48
48
49
- ** Data-carrying enums.** Enums whose variants have fields are called
50
- "data-carrying" enums. Note that for the purposes of this definition,
51
- it is not relevant whether those fields are zero-sized. Therefore this
52
- enum is considered "data-carrying":
49
+ ** Data-carrying enums.** Enums with at least one variant with fields are called
50
+ "data-carrying" enums. Note that for the purposes of this definition, it is not
51
+ relevant whether the variant fields are zero-sized. Therefore this enum is
52
+ considered "data-carrying":
53
53
54
54
``` rust
55
55
enum Foo {
@@ -378,90 +378,31 @@ enum Enum2<T> {
378
378
379
379
[niche]: ../glossary.html#niche
380
380
381
- ## Unresolved questions
382
-
383
- ### Layout of single variant enums
381
+ ### Layout of enums with a single variant
384
382
385
- [Issue # 79 .](https: // github.com/rust-rfcs/unsafe-code-guidelines/issues/79)
383
+ > **NOTE**: the guarantees in this section have not been approved by an RFC process.
386
384
387
- Enums that contain a **single variant** and which do not have an
388
- explicit `#[repr]` annotation are an important special case . Since
389
- there is only a single variant, the enum must be instantiated with
390
- that variant, which means that the enum is in fact equivalent to a
391
- struct . The question then is to what extent we should ** guarantee**
392
- that the two share an equivalent layout, and also how to define the
393
- interaction with uninhabited types.
385
+ **Data-carrying** enums with a single variant without a `repr()` annotation have
386
+ the same layout as the variant field. **Fieldless** enums with a single variant
387
+ have the same layout as a unit struct .
394
388
395
- As presently implemented, the compiler will use the same layout for
396
- structs and for single variant enums (as long as they do not have a
397
- ` #[repr] ` annotation that overrides that choice). So, for example, the
398
- struct ` SomeStruct ` and the enum ` SomeEnum ` would have an equivalent
399
- layout ([ playground] ( https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3697ac684c3d021892694956df957653 ) ):
389
+ For example, here:
400
390
401
391
``` rust
402
- struct SomeStruct ;
403
- enum SomeEnum {
404
- SomeVariant ,
405
- }
392
+ struct UnitStruct ;
393
+ enum FieldlessSingleVariant { FieldlessVariant }
406
394
407
- # fn main () {
408
- # use std :: mem;
409
- let x = SomeStruct ;
410
- let y = SomeEnum :: SomeVariant ;
411
- assert_eq! (
412
- mem :: size_of_val (& x ),
413
- mem :: size_of_val (& y ),
414
- " types have different sizes" ,
415
- );
416
- println! (" types both have size {}" , std :: mem :: size_of_val (& x ));
417
- # }
418
- ```
419
-
420
- Similarly, the struct ` SomeStruct ` and the enum ` SomeVariant ` in this
421
- example would also be equivalent in their layout
422
- ([playground](https:// play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=924724764419f846c788a8763da45992)):
423
-
424
- ```rust
425
395
struct SomeStruct { x : u32 }
426
- enum SomeEnum {
427
- SomeVariant { x: u32 },
428
- }
429
-
430
- # fn main() {
431
- # use std::mem;
432
- let x = SomeStruct { x: 22 };
433
- let y = SomeEnum::SomeVariant { x: 22 };
434
- assert_eq!(
435
- mem::size_of_val(&x),
436
- mem::size_of_val(&y),
437
- "types have different sizes",
438
- );
439
- println!(" types both have size {}" , mem::size_of_val(&x));
396
+ enum DataCarryingSingleVariant {
397
+ DataCarryingVariant (SomeStruct ),
440
398
}
441
399
```
442
400
443
- In fact, the compiler will use this optimized layout even for enums
444
- that define multiple variants, as long as all but one of the variants
445
- is uninhabited
446
- ([ playground] ( https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3cc1484c5b91097f3dc2015b7c207a0e ) ):
401
+ * ` FieldSingleVariant ` has the same layout as ` UnitStruct ` ,
402
+ * ` DataCarryingSingleVariant ` has the same layout as ` SomeStruct ` .
447
403
448
- ``` rust
449
- # enum Void { }
450
- struct SomeStruct { x : u32 }
451
- enum SomeEnum {
452
- SomeVariant { x : u32 },
453
- UninhabitedVariant { y : Void },
454
- }
404
+ ## Unresolved questions
455
405
456
- # fn main () {
457
- # use std :: mem;
458
- let x = SomeStruct { x : 22 };
459
- let y = SomeEnum :: SomeVariant { x : 22 };
460
- assert_eq! (
461
- mem :: size_of_val (& x ),
462
- mem :: size_of_val (& y ),
463
- " types have different sizes" ,
464
- );
465
- println! (" types both have size {}" , mem :: size_of_val (& x ));
466
- # }
467
- ```
406
+ See [ Issue #79 .] ( https://github.com/rust-rfcs/unsafe-code-guidelines/issues/79 ) :
407
+
408
+ * Layout of multi-variant enums where only one variant is inhabited.
0 commit comments