Skip to content

Commit d9614db

Browse files
authored
Rollup merge of rust-lang#73867 - poliorcetics:union-keyword, r=joshtriplett
Document the union keyword Partial fix of rust-lang#34601. This documents the `union` keyword by presenting three cases: simply using a union, matching on a union and referencing the fields of a union. @rustbot modify labels: T-doc,C-enhancement
2 parents eb7fdb2 + 614f773 commit d9614db

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

src/libstd/keyword_docs.rs

+66-2
Original file line numberDiff line numberDiff line change
@@ -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
17391803
mod union_keyword {}

0 commit comments

Comments
 (0)