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