Skip to content

Commit 9a460aa

Browse files
committed
some type-level docs for MaybeUninit; rename into_inner -> into_initialized
1 parent 2966fbc commit 9a460aa

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

src/libcore/macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,12 +555,12 @@ macro_rules! unimplemented {
555555
#[macro_export]
556556
#[unstable(feature = "maybe_uninit", issue = "53491")]
557557
macro_rules! uninitialized_array {
558-
// This `into_inner` is safe because an array of `MaybeUninit` does not
558+
// This `into_initialized` is safe because an array of `MaybeUninit` does not
559559
// require initialization.
560560
// FIXME(#49147): Could be replaced by an array initializer, once those can
561561
// be any const expression.
562562
($t:ty; $size:expr) => (unsafe {
563-
MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_inner()
563+
MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_initialized()
564564
});
565565
}
566566

src/libcore/mem.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,41 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10341034
}
10351035
}
10361036

1037-
/// A newtype to construct uninitialized instances of `T`
1037+
/// A newtype to construct uninitialized instances of `T`.
1038+
///
1039+
/// The compiler, in general, assumes that variables are properly initialized
1040+
/// at their respective type. For example, a variable of reference type must
1041+
/// be aligned and non-NULL. This is an invariant that must *always* be upheld,
1042+
/// even in unsafe code. As a consequence, 0-initializing a variable of reference
1043+
/// type causes instantaneous undefined behavior, no matter whether that reference
1044+
/// ever gets used to access memory:
1045+
/// ```rust,ignore
1046+
/// use std::mem;
1047+
///
1048+
/// let x: &i32 = mem::zeroed(); // undefined behavior!
1049+
/// ```
1050+
/// This is exploitet by the compiler for various optimizations, such as eliding
1051+
/// run-time checks and optimizing `enum` layout.
1052+
///
1053+
/// Not initializing memory at all (instead of 0-initializing it) causes the same
1054+
/// issue: after all, the initial value of the variable might just happen to be
1055+
/// one that violates the invariant.
1056+
///
1057+
/// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data:
1058+
/// it is a signal to the compiler indicating that the data here may *not*
1059+
/// be initialized:
1060+
/// ```rust
1061+
/// use std::mem::MaybeUninit;
1062+
///
1063+
/// // Create an explicitly uninitialized reference.
1064+
/// let mut x = MaybeUninit::<&i32>::uninitialized();
1065+
/// // Set it to a valid value.
1066+
/// x.set(&0);
1067+
/// // Extract the initialized data -- this is only allowed *after* properly
1068+
/// initializing `x`!
1069+
/// let x = unsafe { x.into_initialized() };
1070+
/// ```
1071+
/// The compiler then knows to not optimize this code.
10381072
#[allow(missing_debug_implementations)]
10391073
#[unstable(feature = "maybe_uninit", issue = "53491")]
10401074
// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::{uninitialized,zeroed}`
@@ -1101,11 +1135,18 @@ impl<T> MaybeUninit<T> {
11011135
/// state, otherwise this will immediately cause undefined behavior.
11021136
#[unstable(feature = "maybe_uninit", issue = "53491")]
11031137
#[inline(always)]
1104-
pub unsafe fn into_inner(self) -> T {
1138+
pub unsafe fn into_initialized(self) -> T {
11051139
intrinsics::panic_if_uninhabited::<T>();
11061140
ManuallyDrop::into_inner(self.value)
11071141
}
11081142

1143+
/// Deprecated alternative to `into_initialized`. Will never get stabilized.
1144+
/// Exists only to transition stdsimd to `into_initialized`.
1145+
#[inline(always)]
1146+
pub(crate) unsafe fn into_inner(self) -> T {
1147+
self.into_initialized()
1148+
}
1149+
11091150
/// Get a reference to the contained value.
11101151
///
11111152
/// # Unsafety

src/libcore/ptr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
573573
pub unsafe fn read<T>(src: *const T) -> T {
574574
let mut tmp = MaybeUninit::<T>::uninitialized();
575575
copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
576-
tmp.into_inner()
576+
tmp.into_initialized()
577577
}
578578

579579
/// Reads the value from `src` without moving it. This leaves the
@@ -642,7 +642,7 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
642642
copy_nonoverlapping(src as *const u8,
643643
tmp.as_mut_ptr() as *mut u8,
644644
mem::size_of::<T>());
645-
tmp.into_inner()
645+
tmp.into_initialized()
646646
}
647647

648648
/// Overwrites a memory location with the given value without reading or

0 commit comments

Comments
 (0)