diff --git a/src/items/unions.md b/src/items/unions.md index 7210b0b4c..c974a9a55 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -66,14 +66,18 @@ unsafe { } ``` -Writes to `Copy` union fields do not require reads for running destructors, so -these writes don't have to be placed in `unsafe` blocks +Writes to [`Copy`] or [`ManuallyDrop`][ManuallyDrop] union fields do not +require reads for running destructors, so these writes don't have to be placed +in `unsafe` blocks ```rust -# union MyUnion { f1: u32, f2: f32 } -# let mut u = MyUnion { f1: 1 }; -# +# use std::mem::ManuallyDrop; +union MyUnion { f1: u32, f2: ManuallyDrop } +let mut u = MyUnion { f1: 1 }; + +// These do not require `unsafe`. u.f1 = 2; +u.f2 = ManuallyDrop::new(String::from("example")); ``` Commonly, code using unions will provide safe wrappers around unsafe union @@ -82,9 +86,9 @@ field accesses. ## Unions and `Drop` When a union is dropped, it cannot know which of its fields needs to be dropped. -For this reason, all union fields must either be of a `Copy` type or of the -shape [`ManuallyDrop<_>`]. This ensures that a union does not need to drop -anything when it goes out of scope. +For this reason, all union fields must either be of a [`Copy`] type or of the +shape [`ManuallyDrop<_>`][ManuallyDrop]. This ensures that a union does not +need to drop anything when it goes out of scope. Like for structs and enums, it is possible to `impl Drop` for a union to manually define what happens when it gets dropped. @@ -177,4 +181,5 @@ checking, etc etc etc). [_WhereClause_]: generics.md#where-clauses [_StructFields_]: structs.md [`transmute`]: ../../std/mem/fn.transmute.html -[`ManuallyDrop<_>`]: ../../std/mem/struct.ManuallyDrop.html +[`Copy`]: ../../std/marker/trait.Copy.html +[ManuallyDrop]: ../../std/mem/struct.ManuallyDrop.html diff --git a/src/types/union.md b/src/types/union.md index 95fe70217..3f96cc96d 100644 --- a/src/types/union.md +++ b/src/types/union.md @@ -5,12 +5,14 @@ a [`union` item][item]. Unions have no notion of an "active field". Instead, every union access transmutes parts of the content of the union to the type of the accessed -field. Since transmutes can cause unexpected or undefined behaviour, `unsafe` is -required to read from a union field, or to write to a field that doesn't -implement [`Copy`]. See the [item] documentation for further details. +field. Since transmutes can cause unexpected or undefined behaviour, `unsafe` +is required to read from a union field, or to write to a field that doesn't +implement [`Copy`] or has a [`ManuallyDrop`] type. See the [item] documentation +for further details. The memory layout of a `union` is undefined by default, but the `#[repr(...)]` attribute can be used to fix a layout. [`Copy`]: ../special-types-and-traits.md#copy +[`ManuallyDrop`]: ../../std/mem/struct.ManuallyDrop.html [item]: ../items/unions.md