about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-14 05:23:45 +0000
committerbors <bors@rust-lang.org>2020-07-14 05:23:45 +0000
commit4a689da944977496fb758cc2d700984cc6a10b7f (patch)
treea288820eaba278c687bb3f088e40c19ad999dd4c /src/libstd
parent9d09331e00b02f81c714b0c41ce3a38380dd36a2 (diff)
parent9a1df31d5581811516874f24a2896ba682422bcc (diff)
downloadrust-4a689da944977496fb758cc2d700984cc6a10b7f.tar.gz
rust-4a689da944977496fb758cc2d700984cc6a10b7f.zip
Auto merge of #74313 - Manishearth:rollup-b55rn6t, r=Manishearth
Rollup of 8 pull requests

Successful merges:

 - #73354 (Update RELEASES.md for 1.45.0)
 - #73852 (rustdoc: insert newlines between attributes)
 - #73867 (Document the union keyword)
 - #74046 (Fix caching issue when building tools.)
 - #74123 (clean up E0718 explanation)
 - #74147 (rustdoc: Allow linking from private items to private types)
 - #74285 (#71669: add ui, codegen tests for volatile + nearby int intrinsics)
 - #74286 (Added detailed error code explanation for issue E0688 in Rust compiler.)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/keyword_docs.rs68
1 files changed, 66 insertions, 2 deletions
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index 0b3386c05d5..a53e7f5cf57 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -1732,8 +1732,72 @@ mod dyn_keyword {}
 //
 /// The [Rust equivalent of a C-style union][union].
 ///
-/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+/// A `union` looks like a [`struct`] in terms of declaration, but all of its
+/// fields exist in the same memory, superimposed over one another. For instance,
+/// if we wanted some bits in memory that we sometimes interpret as a `u32` and
+/// sometimes as an `f32`, we could write:
+///
+/// ```rust
+/// union IntOrFloat {
+///     i: u32,
+///     f: f32,
+/// }
+///
+/// let mut u = IntOrFloat { f: 1.0 };
+/// // Reading the fields of an union is always unsafe
+/// assert_eq!(unsafe { u.i }, 1065353216);
+/// // Updating through any of the field will modify all of them
+/// u.i = 1073741824;
+/// assert_eq!(unsafe { u.f }, 2.0);
+/// ```
+///
+/// # Matching on unions
+///
+/// It is possible to use pattern matching on `union`s. A single field name must
+/// be used and it must match the name of one of the `union`'s field.
+/// Like reading from a `union`, pattern matching on a `union` requires `unsafe`.
+///
+/// ```rust
+/// union IntOrFloat {
+///     i: u32,
+///     f: f32,
+/// }
+///
+/// let u = IntOrFloat { f: 1.0 };
+///
+/// unsafe {
+///     match u {
+///         IntOrFloat { i: 10 } => println!("Found exactly ten!"),
+///         // Matching the field `f` provides an `f32`.
+///         IntOrFloat { f } => println!("Found f = {} !", f),
+///     }
+/// }
+/// ```
+///
+/// # References to union fields
+///
+/// All fields in a `union` are all at the same place in memory which means
+/// borrowing one borrows the entire `union`, for the same lifetime:
+///
+/// ```rust,compile_fail,E0502
+/// union IntOrFloat {
+///     i: u32,
+///     f: f32,
+/// }
 ///
+/// let mut u = IntOrFloat { f: 1.0 };
+///
+/// let f = unsafe { &u.f };
+/// // This will not compile because the field has already been borrowed, even
+/// // if only immutably
+/// let i = unsafe { &mut u.i };
+///
+/// *i = 10;
+/// println!("f = {} and i = {}", f, i);
+/// ```
+///
+/// See the [Reference][union] for more informations on `union`s.
+///
+/// [`struct`]: keyword.struct.html
 /// [union]: ../reference/items/unions.html
-/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
 mod union_keyword {}