@@ -2,6 +2,7 @@ use crate::any::type_name;
2
2
use crate :: fmt;
3
3
use crate :: intrinsics;
4
4
use crate :: mem:: ManuallyDrop ;
5
+ use crate :: ptr;
5
6
6
7
/// A wrapper type to construct uninitialized instances of `T`.
7
8
///
@@ -471,6 +472,8 @@ impl<T> MaybeUninit<T> {
471
472
/// *immediate* undefined behavior, but will cause undefined behavior with most
472
473
/// safe operations (including dropping it).
473
474
///
475
+ /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
476
+ ///
474
477
/// # Examples
475
478
///
476
479
/// Correct usage of this method:
@@ -519,8 +522,8 @@ impl<T> MaybeUninit<T> {
519
522
/// this initialization invariant.
520
523
///
521
524
/// 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
524
527
/// to ensure that that data may indeed be duplicated.
525
528
///
526
529
/// [inv]: #initialization-invariant
@@ -536,16 +539,16 @@ impl<T> MaybeUninit<T> {
536
539
///
537
540
/// let mut x = MaybeUninit::<u32>::uninit();
538
541
/// x.write(13);
539
- /// let x1 = unsafe { x.read () };
542
+ /// let x1 = unsafe { x.assume_init_read () };
540
543
/// // `u32` is `Copy`, so we may read multiple times.
541
- /// let x2 = unsafe { x.read () };
544
+ /// let x2 = unsafe { x.assume_init_read () };
542
545
/// assert_eq!(x1, x2);
543
546
///
544
547
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
545
548
/// x.write(None);
546
- /// let x1 = unsafe { x.read () };
549
+ /// let x1 = unsafe { x.assume_init_read () };
547
550
/// // 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 () };
549
552
/// assert_eq!(x1, x2);
550
553
/// ```
551
554
///
@@ -557,14 +560,14 @@ impl<T> MaybeUninit<T> {
557
560
///
558
561
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
559
562
/// 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 () };
562
565
/// // We now created two copies of the same vector, leading to a double-free ⚠️ when
563
566
/// // they both get dropped!
564
567
/// ```
565
568
#[ unstable( feature = "maybe_uninit_extra" , issue = "63567" ) ]
566
569
#[ inline( always) ]
567
- pub unsafe fn read ( & self ) -> T {
570
+ pub unsafe fn assume_init_read ( & self ) -> T {
568
571
// SAFETY: the caller must guarantee that `self` is initialized.
569
572
// Reading from `self.as_ptr()` is safe since `self` should be initialized.
570
573
unsafe {
@@ -573,6 +576,34 @@ impl<T> MaybeUninit<T> {
573
576
}
574
577
}
575
578
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
+
576
607
/// Gets a shared reference to the contained value.
577
608
///
578
609
/// This can be useful when we want to access a `MaybeUninit` that has been
0 commit comments