@@ -79,7 +79,7 @@ use crate::ptr;
79
79
/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
80
80
/// let mut x = MaybeUninit::<&i32>::uninit();
81
81
/// // Set it to a valid value.
82
- /// unsafe { x.as_mut_ptr(). write(&0); }
82
+ /// x. write(&0);
83
83
/// // Extract the initialized data -- this is only allowed *after* properly
84
84
/// // initializing `x`!
85
85
/// let x = unsafe { x.assume_init() };
@@ -135,7 +135,7 @@ use crate::ptr;
135
135
/// // this loop, we have a memory leak, but there is no memory safety
136
136
/// // issue.
137
137
/// for elem in &mut data[..] {
138
- /// * elem = MaybeUninit::new (vec![42]);
138
+ /// elem.write (vec![42]);
139
139
/// }
140
140
///
141
141
/// // Everything is initialized. Transmute the array to the
@@ -161,7 +161,7 @@ use crate::ptr;
161
161
/// let mut data_len: usize = 0;
162
162
///
163
163
/// for elem in &mut data[0..500] {
164
- /// * elem = MaybeUninit::new (String::from("hello"));
164
+ /// elem.write (String::from("hello"));
165
165
/// data_len += 1;
166
166
/// }
167
167
///
@@ -410,7 +410,7 @@ impl<T> MaybeUninit<T> {
410
410
/// (now safely initialized) contents of `self`.
411
411
///
412
412
/// 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
414
414
/// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
415
415
/// the mutable reference returned by this function needs to keep this in
416
416
/// mind. The safety model of Rust regards leaks as safe, but they are
@@ -426,7 +426,6 @@ impl<T> MaybeUninit<T> {
426
426
/// Correct usage of this method:
427
427
///
428
428
/// ```rust
429
- /// #![feature(maybe_uninit_extra)]
430
429
/// use std::mem::MaybeUninit;
431
430
///
432
431
/// let mut x = MaybeUninit::<Vec<u8>>::uninit();
@@ -445,7 +444,6 @@ impl<T> MaybeUninit<T> {
445
444
/// This usage of the method causes a leak:
446
445
///
447
446
/// ```rust
448
- /// #![feature(maybe_uninit_extra)]
449
447
/// use std::mem::MaybeUninit;
450
448
///
451
449
/// let mut x = MaybeUninit::<String>::uninit();
@@ -456,8 +454,38 @@ impl<T> MaybeUninit<T> {
456
454
/// // x is initialized now:
457
455
/// let s = unsafe { x.assume_init() };
458
456
/// ```
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" ) ]
461
489
#[ inline( always) ]
462
490
pub const fn write ( & mut self , val : T ) -> & mut T {
463
491
* self = MaybeUninit :: new ( val) ;
@@ -478,7 +506,7 @@ impl<T> MaybeUninit<T> {
478
506
/// use std::mem::MaybeUninit;
479
507
///
480
508
/// 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]);
482
510
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
483
511
/// let x_vec = unsafe { &*x.as_ptr() };
484
512
/// assert_eq!(x_vec.len(), 3);
@@ -515,7 +543,7 @@ impl<T> MaybeUninit<T> {
515
543
/// use std::mem::MaybeUninit;
516
544
///
517
545
/// 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]);
519
547
/// // Create a reference into the `MaybeUninit<Vec<u32>>`.
520
548
/// // This is okay because we initialized it.
521
549
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
@@ -574,7 +602,7 @@ impl<T> MaybeUninit<T> {
574
602
/// use std::mem::MaybeUninit;
575
603
///
576
604
/// let mut x = MaybeUninit::<bool>::uninit();
577
- /// unsafe { x.as_mut_ptr(). write(true); }
605
+ /// x. write(true);
578
606
/// let x_init = unsafe { x.assume_init() };
579
607
/// assert_eq!(x_init, true);
580
608
/// ```
@@ -723,7 +751,7 @@ impl<T> MaybeUninit<T> {
723
751
///
724
752
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
725
753
/// // Initialize `x`:
726
- /// unsafe { x.as_mut_ptr(). write(vec![1, 2, 3]); }
754
+ /// x. write(vec![1, 2, 3]);
727
755
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
728
756
/// // create a shared reference to it:
729
757
/// let x: &Vec<u32> = unsafe {
@@ -897,9 +925,9 @@ impl<T> MaybeUninit<T> {
897
925
/// use std::mem::MaybeUninit;
898
926
///
899
927
/// 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);
903
931
///
904
932
/// // SAFETY: Now safe as we initialised all elements
905
933
/// let array = unsafe {
0 commit comments