about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2021-02-06 00:14:09 +0100
committerGitHub <noreply@github.com>2021-02-06 00:14:09 +0100
commit43b3adb4e2f6f4da7e1bf20648533fc634395468 (patch)
treeff2209b401953ae58c17a0b8c1b0a44bb003f2aa
parentcc882fc3bedec5047f055e5ff5a1908e730130bb (diff)
parent21c2343d3f95348b10b3b6ff73c3c237eea89c32 (diff)
downloadrust-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.rs39
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