Skip to content

Commit 13ffbee

Browse files
committed
Add MaybeUninit::read_uninitialized
Also remove a no-longer accurate comments
1 parent e1c6d00 commit 13ffbee

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

src/libcore/mem.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,61 @@ impl<T> MaybeUninit<T> {
11851185
ManuallyDrop::into_inner(self.value)
11861186
}
11871187

1188+
/// Reads the value from the `MaybeUninit` container. The resulting `T` is subject
1189+
/// to the usual drop handling.
1190+
///
1191+
/// # Unsafety
1192+
///
1193+
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
1194+
/// state. Calling this when the content is not yet fully initialized causes undefined
1195+
/// behavior.
1196+
///
1197+
/// Moreover, this leaves a copy of the same data behind in the `MaybeUninit`. When using
1198+
/// multiple copies of the data (by calling `read_initialized` multiple times, or first
1199+
/// calling `read_initialized` and then [`into_initialized`]), it is your responsibility
1200+
/// to ensure that that data may indeed be duplicated.
1201+
///
1202+
/// # Examples
1203+
///
1204+
/// Correct usage of this method:
1205+
///
1206+
/// ```rust
1207+
/// #![feature(maybe_uninit)]
1208+
/// use std::mem::MaybeUninit;
1209+
///
1210+
/// let mut x = MaybeUninit::<u32>::uninitialized();
1211+
/// x.set(13);
1212+
/// let x1 = unsafe { x.read_initialized() };
1213+
/// // `u32` is `Copy`, so we may read multiple times.
1214+
/// let x2 = unsafe { x.read_initialized() };
1215+
///
1216+
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninitialized();
1217+
/// x.set(None);
1218+
/// let x1 = unsafe { x.read_initialized() };
1219+
/// // Duplicating a `None` value is okay, so we may read multiple times.
1220+
/// let x2 = unsafe { x.read_initialized() };
1221+
/// ```
1222+
///
1223+
/// *Incorrect* usafe of this method:
1224+
///
1225+
/// ```rust,no_run
1226+
/// #![feature(maybe_uninit)]
1227+
/// use std::mem::MaybeUninit;
1228+
///
1229+
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninitialized();
1230+
/// x.set(Some(vec![0,1,2]));
1231+
/// let x1 = unsafe { x.read_initialized() };
1232+
/// let x2 = unsafe { x.read_initialized() };
1233+
/// // We now created two copies of the same vector, leading to a double-free when
1234+
/// // they both get dropped!
1235+
/// ```
1236+
#[unstable(feature = "maybe_uninit", issue = "53491")]
1237+
#[inline(always)]
1238+
pub unsafe fn read_initialized(&self) -> T {
1239+
intrinsics::panic_if_uninhabited::<T>();
1240+
self.as_ptr().read()
1241+
}
1242+
11881243
/// Gets a reference to the contained value.
11891244
///
11901245
/// # Unsafety

0 commit comments

Comments
 (0)