@@ -172,11 +172,42 @@ use crate::ptr;
172172///
173173/// ## Initializing a struct field-by-field
174174///
175- /// There is currently no supported way to create a raw pointer or reference
176- /// to a field of a struct inside `MaybeUninit<Struct>`. That means it is not possible
177- /// to create a struct by calling `MaybeUninit::uninit::<Struct>()` and then writing
178- /// to its fields.
175+ /// You can use `MaybeUninit<T>`, and the [`std::ptr::addr_of_mut`] macro, to initialize structs field by field:
179176///
177+ /// ```rust
178+ /// use std::mem::MaybeUninit;
179+ /// use std::ptr::addr_of_mut;
180+ ///
181+ /// #[derive(Debug, PartialEq)]
182+ /// pub struct Foo {
183+ /// name: String,
184+ /// list: Vec<u8>,
185+ /// }
186+ ///
187+ /// let foo = {
188+ /// let mut uninit: MaybeUninit<Foo> = MaybeUninit::uninit();
189+ /// let ptr = uninit.as_mut_ptr();
190+ ///
191+ /// // Initializing the `name` field
192+ /// unsafe { addr_of_mut!((*ptr).name).write("Bob".to_string()); }
193+ ///
194+ /// // Initializing the `list` field
195+ /// // If there is a panic here, then the `String` in the `name` field leaks.
196+ /// unsafe { addr_of_mut!((*ptr).list).write(vec![0, 1, 2]); }
197+ ///
198+ /// // All the fields are initialized, so we call `assume_init` to get an initialized Foo.
199+ /// unsafe { uninit.assume_init() }
200+ /// };
201+ ///
202+ /// assert_eq!(
203+ /// foo,
204+ /// Foo {
205+ /// name: "Bob".to_string(),
206+ /// list: vec![0, 1, 2]
207+ /// }
208+ /// );
209+ /// ```
210+ /// [`std::ptr::addr_of_mut`]: crate::ptr::addr_of_mut
180211/// [ub]: ../../reference/behavior-considered-undefined.html
181212///
182213/// # Layout
0 commit comments