diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2021-02-06 00:14:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-06 00:14:09 +0100 |
| commit | 43b3adb4e2f6f4da7e1bf20648533fc634395468 (patch) | |
| tree | ff2209b401953ae58c17a0b8c1b0a44bb003f2aa | |
| parent | cc882fc3bedec5047f055e5ff5a1908e730130bb (diff) | |
| parent | 21c2343d3f95348b10b3b6ff73c3c237eea89c32 (diff) | |
| download | rust-43b3adb4e2f6f4da7e1bf20648533fc634395468.tar.gz rust-43b3adb4e2f6f4da7e1bf20648533fc634395468.zip | |
Rollup merge of #81580 - rodrimati1992:patch-2, r=dtolnay
Document how `MaybeUninit<Struct>` can be initialized.
| -rw-r--r-- | library/core/src/mem/maybe_uninit.rs | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 05bcd90d3ca..3760f5c4794 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -172,11 +172,42 @@ use crate::ptr; /// /// ## Initializing a struct field-by-field /// -/// There is currently no supported way to create a raw pointer or reference -/// to a field of a struct inside `MaybeUninit<Struct>`. That means it is not possible -/// to create a struct by calling `MaybeUninit::uninit::<Struct>()` and then writing -/// to its fields. +/// You can use `MaybeUninit<T>`, and the [`std::ptr::addr_of_mut`] macro, to initialize structs field by field: /// +/// ```rust +/// use std::mem::MaybeUninit; +/// use std::ptr::addr_of_mut; +/// +/// #[derive(Debug, PartialEq)] +/// pub struct Foo { +/// name: String, +/// list: Vec<u8>, +/// } +/// +/// let foo = { +/// let mut uninit: MaybeUninit<Foo> = MaybeUninit::uninit(); +/// let ptr = uninit.as_mut_ptr(); +/// +/// // Initializing the `name` field +/// unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); } +/// +/// // Initializing the `list` field +/// // If there is a panic here, then the `String` in the `name` field leaks. +/// unsafe { addr_of_mut!((*ptr).list).write(vec![0, 1, 2]); } +/// +/// // All the fields are initialized, so we call `assume_init` to get an initialized Foo. +/// unsafe { uninit.assume_init() } +/// }; +/// +/// assert_eq!( +/// foo, +/// Foo { +/// name: "Bob".to_string(), +/// list: vec![0, 1, 2] +/// } +/// ); +/// ``` +/// [`std::ptr::addr_of_mut`]: crate::ptr::addr_of_mut /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Layout |
