@@ -1732,8 +1732,72 @@ mod dyn_keyword {}
17321732//
17331733/// The [Rust equivalent of a C-style union][union].
17341734///
1735- /// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1735+ /// A `union` looks like a [`struct`] in terms of declaration, but all of its
1736+ /// fields exist in the same memory, superimposed over one another. For instance,
1737+ /// if we wanted some bits in memory that we sometimes interpret as a `u32` and
1738+ /// sometimes as an `f32`, we could write:
1739+ ///
1740+ /// ```rust
1741+ /// union IntOrFloat {
1742+ /// i: u32,
1743+ /// f: f32,
1744+ /// }
1745+ ///
1746+ /// let mut u = IntOrFloat { f: 1.0 };
1747+ /// // Reading the fields of an union is always unsafe
1748+ /// assert_eq!(unsafe { u.i }, 1065353216);
1749+ /// // Updating through any of the field will modify all of them
1750+ /// u.i = 1073741824;
1751+ /// assert_eq!(unsafe { u.f }, 2.0);
1752+ /// ```
1753+ ///
1754+ /// # Matching on unions
1755+ ///
1756+ /// It is possible to use pattern matching on `union`s. A single field name must
1757+ /// be used and it must match the name of one of the `union`'s field.
1758+ /// Like reading from a `union`, pattern matching on a `union` requires `unsafe`.
1759+ ///
1760+ /// ```rust
1761+ /// union IntOrFloat {
1762+ /// i: u32,
1763+ /// f: f32,
1764+ /// }
1765+ ///
1766+ /// let u = IntOrFloat { f: 1.0 };
1767+ ///
1768+ /// unsafe {
1769+ /// match u {
1770+ /// IntOrFloat { i: 10 } => println!("Found exactly ten!"),
1771+ /// // Matching the field `f` provides an `f32`.
1772+ /// IntOrFloat { f } => println!("Found f = {} !", f),
1773+ /// }
1774+ /// }
1775+ /// ```
1776+ ///
1777+ /// # References to union fields
1778+ ///
1779+ /// All fields in a `union` are all at the same place in memory which means
1780+ /// borrowing one borrows the entire `union`, for the same lifetime:
1781+ ///
1782+ /// ```rust,compile_fail,E0502
1783+ /// union IntOrFloat {
1784+ /// i: u32,
1785+ /// f: f32,
1786+ /// }
17361787///
1788+ /// let mut u = IntOrFloat { f: 1.0 };
1789+ ///
1790+ /// let f = unsafe { &u.f };
1791+ /// // This will not compile because the field has already been borrowed, even
1792+ /// // if only immutably
1793+ /// let i = unsafe { &mut u.i };
1794+ ///
1795+ /// *i = 10;
1796+ /// println!("f = {} and i = {}", f, i);
1797+ /// ```
1798+ ///
1799+ /// See the [Reference][union] for more informations on `union`s.
1800+ ///
1801+ /// [`struct`]: keyword.struct.html
17371802/// [union]: ../reference/items/unions.html
1738- /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
17391803mod union_keyword { }
0 commit comments