@@ -1035,7 +1035,42 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10351035 }
10361036}
10371037
1038- /// A newtype to construct uninitialized instances of `T`
1038+ /// A newtype to construct uninitialized instances of `T`.
1039+ ///
1040+ /// The compiler, in general, assumes that variables are properly initialized
1041+ /// at their respective type. For example, a variable of reference type must
1042+ /// be aligned and non-NULL. This is an invariant that must *always* be upheld,
1043+ /// even in unsafe code. As a consequence, 0-initializing a variable of reference
1044+ /// type causes instantaneous undefined behavior, no matter whether that reference
1045+ /// ever gets used to access memory:
1046+ /// ```rust,no_run
1047+ /// use std::mem;
1048+ ///
1049+ /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
1050+ /// ```
1051+ /// This is exploited by the compiler for various optimizations, such as eliding
1052+ /// run-time checks and optimizing `enum` layout.
1053+ ///
1054+ /// Not initializing memory at all (instead of 0-initializing it) causes the same
1055+ /// issue: after all, the initial value of the variable might just happen to be
1056+ /// one that violates the invariant.
1057+ ///
1058+ /// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data:
1059+ /// it is a signal to the compiler indicating that the data here might *not*
1060+ /// be initialized:
1061+ /// ```rust
1062+ /// #![feature(maybe_uninit)]
1063+ /// use std::mem::MaybeUninit;
1064+ ///
1065+ /// // Create an explicitly uninitialized reference.
1066+ /// let mut x = MaybeUninit::<&i32>::uninitialized();
1067+ /// // Set it to a valid value.
1068+ /// x.set(&0);
1069+ /// // Extract the initialized data -- this is only allowed *after* properly
1070+ /// // initializing `x`!
1071+ /// let x = unsafe { x.into_initialized() };
1072+ /// ```
1073+ /// The compiler then knows to not optimize this code.
10391074#[ allow( missing_debug_implementations) ]
10401075#[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
10411076// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::{uninitialized,zeroed}`
@@ -1084,11 +1119,14 @@ impl<T> MaybeUninit<T> {
10841119 }
10851120
10861121 /// Set the value of the `MaybeUninit`. This overwrites any previous value without dropping it.
1122+ /// For your convenience, this also returns a mutable reference to the (now
1123+ /// safely initialized) content of `self`.
10871124 #[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
10881125 #[ inline( always) ]
1089- pub fn set ( & mut self , val : T ) {
1126+ pub fn set ( & mut self , val : T ) -> & mut T {
10901127 unsafe {
10911128 self . value = ManuallyDrop :: new ( val) ;
1129+ self . get_mut ( )
10921130 }
10931131 }
10941132
@@ -1102,11 +1140,19 @@ impl<T> MaybeUninit<T> {
11021140 /// state, otherwise this will immediately cause undefined behavior.
11031141 #[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
11041142 #[ inline( always) ]
1105- pub unsafe fn into_inner ( self ) -> T {
1143+ pub unsafe fn into_initialized ( self ) -> T {
11061144 intrinsics:: panic_if_uninhabited :: < T > ( ) ;
11071145 ManuallyDrop :: into_inner ( self . value )
11081146 }
11091147
1148+ /// Deprecated alternative to `into_initialized`. Will never get stabilized.
1149+ /// Exists only to transition stdsimd to `into_initialized`.
1150+ #[ inline( always) ]
1151+ #[ allow( unused) ]
1152+ pub ( crate ) unsafe fn into_inner ( self ) -> T {
1153+ self . into_initialized ( )
1154+ }
1155+
11101156 /// Get a reference to the contained value.
11111157 ///
11121158 /// # Unsafety
@@ -1134,16 +1180,16 @@ impl<T> MaybeUninit<T> {
11341180 & mut * self . value
11351181 }
11361182
1137- /// Get a pointer to the contained value. Reading from this pointer will be undefined
1138- /// behavior unless the `MaybeUninit` is initialized.
1183+ /// Get a pointer to the contained value. Reading from this pointer or turning it
1184+ /// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
11391185 #[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
11401186 #[ inline( always) ]
11411187 pub fn as_ptr ( & self ) -> * const T {
11421188 unsafe { & * self . value as * const T }
11431189 }
11441190
1145- /// Get a mutable pointer to the contained value. Reading from this pointer will be undefined
1146- /// behavior unless the `MaybeUninit` is initialized.
1191+ /// Get a mutable pointer to the contained value. Reading from this pointer or turning it
1192+ /// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
11471193 #[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
11481194 #[ inline( always) ]
11491195 pub fn as_mut_ptr ( & mut self ) -> * mut T {
0 commit comments