@@ -2,6 +2,7 @@ use crate::any::type_name;
22use crate :: fmt;
33use crate :: intrinsics;
44use crate :: mem:: ManuallyDrop ;
5+ use crate :: ptr;
56
67/// A wrapper type to construct uninitialized instances of `T`.
78///
@@ -471,6 +472,8 @@ impl<T> MaybeUninit<T> {
471472 /// *immediate* undefined behavior, but will cause undefined behavior with most
472473 /// safe operations (including dropping it).
473474 ///
475+ /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
476+ ///
474477 /// # Examples
475478 ///
476479 /// Correct usage of this method:
@@ -519,8 +522,8 @@ impl<T> MaybeUninit<T> {
519522 /// this initialization invariant.
520523 ///
521524 /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
522- /// multiple copies of the data (by calling `read ` multiple times, or first
523- /// calling `read ` and then [`assume_init`]), it is your responsibility
525+ /// multiple copies of the data (by calling `assume_init_read ` multiple times, or first
526+ /// calling `assume_init_read ` and then [`assume_init`]), it is your responsibility
524527 /// to ensure that that data may indeed be duplicated.
525528 ///
526529 /// [inv]: #initialization-invariant
@@ -536,16 +539,16 @@ impl<T> MaybeUninit<T> {
536539 ///
537540 /// let mut x = MaybeUninit::<u32>::uninit();
538541 /// x.write(13);
539- /// let x1 = unsafe { x.read () };
542+ /// let x1 = unsafe { x.assume_init_read () };
540543 /// // `u32` is `Copy`, so we may read multiple times.
541- /// let x2 = unsafe { x.read () };
544+ /// let x2 = unsafe { x.assume_init_read () };
542545 /// assert_eq!(x1, x2);
543546 ///
544547 /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
545548 /// x.write(None);
546- /// let x1 = unsafe { x.read () };
549+ /// let x1 = unsafe { x.assume_init_read () };
547550 /// // Duplicating a `None` value is okay, so we may read multiple times.
548- /// let x2 = unsafe { x.read () };
551+ /// let x2 = unsafe { x.assume_init_read () };
549552 /// assert_eq!(x1, x2);
550553 /// ```
551554 ///
@@ -557,14 +560,14 @@ impl<T> MaybeUninit<T> {
557560 ///
558561 /// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
559562 /// x.write(Some(vec![0,1,2]));
560- /// let x1 = unsafe { x.read () };
561- /// let x2 = unsafe { x.read () };
563+ /// let x1 = unsafe { x.assume_init_read () };
564+ /// let x2 = unsafe { x.assume_init_read () };
562565 /// // We now created two copies of the same vector, leading to a double-free ⚠️ when
563566 /// // they both get dropped!
564567 /// ```
565568 #[ unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
566569 #[ inline( always) ]
567- pub unsafe fn read ( & self ) -> T {
570+ pub unsafe fn assume_init_read ( & self ) -> T {
568571 // SAFETY: the caller must guarantee that `self` is initialized.
569572 // Reading from `self.as_ptr()` is safe since `self` should be initialized.
570573 unsafe {
@@ -573,6 +576,34 @@ impl<T> MaybeUninit<T> {
573576 }
574577 }
575578
579+ /// Drops the contained value in place.
580+ ///
581+ /// If you have ownership of the `MaybeUninit`, you can use [`assume_init`] instead.
582+ ///
583+ /// # Safety
584+ ///
585+ /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is
586+ /// in an initialized state. Calling this when the content is not yet fully
587+ /// initialized causes undefined behavior.
588+ ///
589+ /// On top of that, all additional invariants of the type `T` must be
590+ /// satisfied, as the `Drop` implementation of `T` (or its members) may
591+ /// rely on this. For example, a `1`-initialized [`Vec<T>`] is considered
592+ /// initialized (under the current implementation; this does not constitute
593+ /// a stable guarantee) because the only requirement the compiler knows
594+ /// about it is that the data pointer must be non-null. Dropping such a
595+ /// `Vec<T>` however will cause undefined behaviour.
596+ ///
597+ /// [`assume_init`]: MaybeUninit::assume_init
598+ /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
599+ #[ unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
600+ pub unsafe fn assume_init_drop ( & mut self ) {
601+ // SAFETY: the caller must guarantee that `self` is initialized and
602+ // satisfies all invariants of `T`.
603+ // Dropping the value in place is safe if that is the case.
604+ unsafe { ptr:: drop_in_place ( self . as_mut_ptr ( ) ) }
605+ }
606+
576607 /// Gets a shared reference to the contained value.
577608 ///
578609 /// This can be useful when we want to access a `MaybeUninit` that has been
0 commit comments