@@ -1034,7 +1034,41 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
1034
1034
}
1035
1035
}
1036
1036
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.
1038
1072
#[ allow( missing_debug_implementations) ]
1039
1073
#[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
1040
1074
// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::{uninitialized,zeroed}`
@@ -1101,11 +1135,18 @@ impl<T> MaybeUninit<T> {
1101
1135
/// state, otherwise this will immediately cause undefined behavior.
1102
1136
#[ unstable( feature = "maybe_uninit" , issue = "53491" ) ]
1103
1137
#[ inline( always) ]
1104
- pub unsafe fn into_inner ( self ) -> T {
1138
+ pub unsafe fn into_initialized ( self ) -> T {
1105
1139
intrinsics:: panic_if_uninhabited :: < T > ( ) ;
1106
1140
ManuallyDrop :: into_inner ( self . value )
1107
1141
}
1108
1142
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
+
1109
1150
/// Get a reference to the contained value.
1110
1151
///
1111
1152
/// # Unsafety
0 commit comments