@@ -79,7 +79,7 @@ use crate::ptr;
7979/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
8080/// let mut x = MaybeUninit::<&i32>::uninit();
8181/// // Set it to a valid value.
82- /// unsafe { x.as_mut_ptr(). write(&0); }
82+ /// x. write(&0);
8383/// // Extract the initialized data -- this is only allowed *after* properly
8484/// // initializing `x`!
8585/// let x = unsafe { x.assume_init() };
@@ -135,7 +135,7 @@ use crate::ptr;
135135/// // this loop, we have a memory leak, but there is no memory safety
136136/// // issue.
137137/// for elem in &mut data[..] {
138- /// * elem = MaybeUninit::new (vec![42]);
138+ /// elem.write (vec![42]);
139139/// }
140140///
141141/// // Everything is initialized. Transmute the array to the
@@ -161,7 +161,7 @@ use crate::ptr;
161161/// let mut data_len: usize = 0;
162162///
163163/// for elem in &mut data[0..500] {
164- /// * elem = MaybeUninit::new (String::from("hello"));
164+ /// elem.write (String::from("hello"));
165165/// data_len += 1;
166166/// }
167167///
@@ -410,7 +410,7 @@ impl<T> MaybeUninit<T> {
410410 /// (now safely initialized) contents of `self`.
411411 ///
412412 /// As the content is stored inside a `MaybeUninit`, the destructor is not
413- /// ran for the inner data if the MaybeUninit leaves scope without a call to
413+ /// run for the inner data if the MaybeUninit leaves scope without a call to
414414 /// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
415415 /// the mutable reference returned by this function needs to keep this in
416416 /// mind. The safety model of Rust regards leaks as safe, but they are
@@ -426,7 +426,6 @@ impl<T> MaybeUninit<T> {
426426 /// Correct usage of this method:
427427 ///
428428 /// ```rust
429- /// #![feature(maybe_uninit_extra)]
430429 /// use std::mem::MaybeUninit;
431430 ///
432431 /// let mut x = MaybeUninit::<Vec<u8>>::uninit();
@@ -445,7 +444,6 @@ impl<T> MaybeUninit<T> {
445444 /// This usage of the method causes a leak:
446445 ///
447446 /// ```rust
448- /// #![feature(maybe_uninit_extra)]
449447 /// use std::mem::MaybeUninit;
450448 ///
451449 /// let mut x = MaybeUninit::<String>::uninit();
@@ -456,8 +454,38 @@ impl<T> MaybeUninit<T> {
456454 /// // x is initialized now:
457455 /// let s = unsafe { x.assume_init() };
458456 /// ```
459- #[ unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
460- #[ rustc_const_unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
457+ ///
458+ /// This method can be used to avoid unsafe in some cases. The example below
459+ /// shows a part of an implementation of a fixed sized arena that lends out
460+ /// pinned references.
461+ /// With `write`, we can avoid the need to write through a raw pointer:
462+ ///
463+ /// ```rust
464+ /// #![feature(maybe_uninit_extra)]
465+ /// use core::pin::Pin;
466+ /// use core::mem::MaybeUninit;
467+ ///
468+ /// struct PinArena<T> {
469+ /// memory: Box<[MaybeUninit<T>]>,
470+ /// len: usize,
471+ /// }
472+ ///
473+ /// impl <T> PinArena<T> {
474+ /// pub fn capacity(&self) -> usize {
475+ /// self.memory.len()
476+ /// }
477+ /// pub fn push(&mut self, val: T) -> Pin<&mut T> {
478+ /// if self.len >= self.capacity() {
479+ /// panic!("Attempted to push to a full pin arena!");
480+ /// }
481+ /// let ref_ = self.memory[self.len].write(val);
482+ /// self.len += 1;
483+ /// unsafe { Pin::new_unchecked(ref_) }
484+ /// }
485+ /// }
486+ /// ```
487+ #[ stable( feature = "maybe_uninit_write" , since = "1.55.0" ) ]
488+ #[ rustc_const_unstable( feature = "const_maybe_uninit_write" , issue = "63567" ) ]
461489 #[ inline( always) ]
462490 pub const fn write ( & mut self , val : T ) -> & mut T {
463491 * self = MaybeUninit :: new ( val) ;
@@ -478,7 +506,7 @@ impl<T> MaybeUninit<T> {
478506 /// use std::mem::MaybeUninit;
479507 ///
480508 /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
481- /// unsafe { x.as_mut_ptr(). write(vec![0, 1, 2]); }
509+ /// x. write(vec![0, 1, 2]);
482510 /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
483511 /// let x_vec = unsafe { &*x.as_ptr() };
484512 /// assert_eq!(x_vec.len(), 3);
@@ -515,7 +543,7 @@ impl<T> MaybeUninit<T> {
515543 /// use std::mem::MaybeUninit;
516544 ///
517545 /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
518- /// unsafe { x.as_mut_ptr(). write(vec![0, 1, 2]); }
546+ /// x. write(vec![0, 1, 2]);
519547 /// // Create a reference into the `MaybeUninit<Vec<u32>>`.
520548 /// // This is okay because we initialized it.
521549 /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
@@ -574,7 +602,7 @@ impl<T> MaybeUninit<T> {
574602 /// use std::mem::MaybeUninit;
575603 ///
576604 /// let mut x = MaybeUninit::<bool>::uninit();
577- /// unsafe { x.as_mut_ptr(). write(true); }
605+ /// x. write(true);
578606 /// let x_init = unsafe { x.assume_init() };
579607 /// assert_eq!(x_init, true);
580608 /// ```
@@ -723,7 +751,7 @@ impl<T> MaybeUninit<T> {
723751 ///
724752 /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
725753 /// // Initialize `x`:
726- /// unsafe { x.as_mut_ptr(). write(vec![1, 2, 3]); }
754+ /// x. write(vec![1, 2, 3]);
727755 /// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
728756 /// // create a shared reference to it:
729757 /// let x: &Vec<u32> = unsafe {
@@ -897,9 +925,9 @@ impl<T> MaybeUninit<T> {
897925 /// use std::mem::MaybeUninit;
898926 ///
899927 /// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
900- /// array[0] = MaybeUninit::new (0);
901- /// array[1] = MaybeUninit::new (1);
902- /// array[2] = MaybeUninit::new (2);
928+ /// array[0].write (0);
929+ /// array[1].write (1);
930+ /// array[2].write (2);
903931 ///
904932 /// // SAFETY: Now safe as we initialised all elements
905933 /// let array = unsafe {
0 commit comments