@@ -21,6 +21,7 @@ There are several kinds of item:
21
21
* [ type definitions] ( ../grammar.html#type-definitions )
22
22
* [ struct definitions] ( #structs )
23
23
* [ enumeration definitions] ( #enumerations )
24
+ * [ union definitions] ( #unions )
24
25
* [ constant items] ( #constant-items )
25
26
* [ static items] ( #static-items )
26
27
* [ trait definitions] ( #traits )
@@ -569,6 +570,142 @@ let x = Foo::Bar as u32; // x is now 123u32
569
570
This only works as long as none of the variants have data attached. If
570
571
it were ` Bar(i32) ` , this is disallowed.
571
572
573
+ ## Unions
574
+
575
+ A union declaration uses the same syntax as a struct declaration, except with
576
+ ` union ` in place of ` struct ` .
577
+
578
+ ``` rust
579
+ #[repr(C )]
580
+ union MyUnion {
581
+ f1 : u32 ,
582
+ f2 : f32 ,
583
+ }
584
+ ```
585
+
586
+ The key property of unions is that all fields of a union share common storage.
587
+ As a result writes to one field of a union can overwrite its other fields,
588
+ and size of a union is determined by the size of its largest field.
589
+
590
+ A value of a union type can be created using the same syntax that is used for
591
+ struct types, except that it must specify exactly one field:
592
+
593
+ ``` rust
594
+ let u = MyUnion { f1 : 1 };
595
+ ```
596
+
597
+ The expression above creates a value of type ` MyUnion ` with active field ` f1 ` .
598
+ Active field of a union can be accessed using the same syntax as struct fields:
599
+
600
+ ``` rust
601
+ let f = u . f1;
602
+ ```
603
+
604
+ Inactive fields can be accessed as well (using the same syntax) if they are
605
+ sufficiently layout compatible with the
606
+ current value kept by the union. Reading incompatible fields results in
607
+ undefined behavior.
608
+ However, the active field is not generally known statically, so all reads of
609
+ union fields have to be placed in ` unsafe ` blocks.
610
+
611
+ ``` rust
612
+ unsafe {
613
+ let f = u . f1;
614
+ }
615
+ ```
616
+
617
+ Writes to union fields may generally require reads (for running destructors),
618
+ so these writes have to be placed in ` unsafe ` blocks too.
619
+
620
+ ``` rust
621
+ unsafe {
622
+ u . f1 = 2 ;
623
+ }
624
+ ```
625
+
626
+ Commonly, code using unions will provide safe wrappers around unsafe
627
+ union field accesses.
628
+
629
+ Another way to access union fields is to use pattern matching.
630
+ Pattern matching on union fields uses the same syntax as struct patterns,
631
+ except that the pattern must specify exactly one field.
632
+ Since pattern matching accesses potentially inactive fields it has
633
+ to be placed in ` unsafe ` blocks as well.
634
+
635
+ ``` rust
636
+ fn f (u : MyUnion ) {
637
+ unsafe {
638
+ match u {
639
+ MyUnion { f1 : 10 } => { println! (" ten" ); }
640
+ MyUnion { f2 } => { println! (" {}" , f2 ); }
641
+ }
642
+ }
643
+ }
644
+ ```
645
+
646
+ Pattern matching may match a union as a field of a larger structure. In
647
+ particular, when using a Rust union to implement a C tagged union via FFI, this
648
+ allows matching on the tag and the corresponding field simultaneously:
649
+
650
+ ``` rust
651
+ #[repr(u32 )]
652
+ enum Tag { I , F }
653
+
654
+ #[repr(C )]
655
+ union U {
656
+ i : i32 ,
657
+ f : f32 ,
658
+ }
659
+
660
+ #[repr(C )]
661
+ struct Value {
662
+ tag : Tag ,
663
+ u : U ,
664
+ }
665
+
666
+ fn is_zero (v : Value ) -> bool {
667
+ unsafe {
668
+ match v {
669
+ Value { tag : I , u : U { i : 0 } } => true ,
670
+ Value { tag : F , u : U { f : 0.0 } } => true ,
671
+ _ => false ,
672
+ }
673
+ }
674
+ }
675
+ ```
676
+
677
+ Since union fields share common storage, gaining write access to one
678
+ field of a union can give write access to all its remaining fields.
679
+ Borrow checking rules have to be adjusted to account for this fact.
680
+ As a result, if one field of a union is borrowed, all its remaining fields
681
+ are borrowed as well for the same lifetime.
682
+
683
+ ``` rust
684
+ // ERROR: cannot borrow `u` (via `u.f2`) as mutable more than once at a time
685
+ fn test () {
686
+ let mut u = MyUnion { f1 : 1 };
687
+ unsafe {
688
+ let b1 = & mut u . f1;
689
+ ---- first mutable borrow occurs here (via `u . f1`)
690
+ let b2 = & mut u . f2;
691
+ ^^^^ second mutable borrow occurs here (via `u . f2`)
692
+ * b1 = 5 ;
693
+ }
694
+ - first borrow ends here
695
+ assert_eq! (unsafe { u . f1 }, 5 );
696
+ }
697
+ ```
698
+
699
+ As you could see, in many aspects (except for layouts, safety and ownership)
700
+ unions behave exactly like structs, largely as a consequence of inheriting their
701
+ syntactic shape from structs.
702
+ This is also true for many unmentioned aspects of Rust language (such as
703
+ privacy, name resolution, type inference, generics, trait implementations,
704
+ inherent implementations, coherence, pattern checking, etc etc etc).
705
+
706
+ More detailed specification for unions, including unstable bits, can be found in
707
+ [ RFC 1897 "Unions v1.2"] ( https://github.com/rust-lang/rfcs/pull/1897 ) .
708
+
572
709
## Constant items
573
710
574
711
A * constant item* is a named _ constant value_ which is not associated with a
0 commit comments