Skip to content

Commit b5ab2c7

Browse files
committed
split MaybeUninit into several features, expand docs a bit
1 parent e544947 commit b5ab2c7

File tree

5 files changed

+55
-33
lines changed

5 files changed

+55
-33
lines changed

src/liballoc/collections/btree/node.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
453453
root: self.root,
454454
_marker: PhantomData
455455
},
456-
idx: unsafe { usize::from(*self.as_header().parent_idx.get_ref()) },
456+
idx: unsafe { usize::from(*self.as_header().parent_idx.as_ptr()) },
457457
_marker: PhantomData
458458
})
459459
} else {
@@ -1143,7 +1143,7 @@ impl<BorrowType, K, V>
11431143
NodeRef {
11441144
height: self.node.height - 1,
11451145
node: unsafe {
1146-
self.node.as_internal().edges.get_unchecked(self.idx).get_ref().as_ptr()
1146+
(&*self.node.as_internal().edges.get_unchecked(self.idx).as_ptr()).as_ptr()
11471147
},
11481148
root: self.node.root,
11491149
_marker: PhantomData

src/liballoc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
#![feature(rustc_const_unstable)]
113113
#![feature(const_vec_new)]
114114
#![feature(slice_partition_dedup)]
115-
#![feature(maybe_uninit)]
115+
#![feature(maybe_uninit, maybe_uninit_slice)]
116116
#![feature(alloc_layout_extra)]
117117
#![feature(try_trait)]
118118

src/libcore/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
#![feature(structural_match)]
123123
#![feature(abi_unadjusted)]
124124
#![feature(adx_target_feature)]
125-
#![feature(maybe_uninit)]
125+
#![feature(maybe_uninit, maybe_uninit_slice)]
126126
#![feature(unrestricted_attribute_tokens)]
127127

128128
#[prelude_import]

src/libcore/macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -563,11 +563,11 @@ macro_rules! unimplemented {
563563

564564
/// A macro to create an array of [`MaybeUninit`]
565565
///
566-
/// This macro constructs and uninitialized array of the type `[MaybeUninit<K>; N]`.
566+
/// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
567567
///
568568
/// [`MaybeUninit`]: mem/union.MaybeUninit.html
569569
#[macro_export]
570-
#[unstable(feature = "maybe_uninit", issue = "53491")]
570+
#[unstable(feature = "maybe_uninit_slice", issue = "53491")]
571571
macro_rules! uninitialized_array {
572572
// This `into_initialized` is safe because an array of `MaybeUninit` does not
573573
// require initialization.

src/libcore/mem.rs

+49-27
Original file line numberDiff line numberDiff line change
@@ -1045,17 +1045,34 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10451045
/// ever gets used to access memory:
10461046
///
10471047
/// ```rust,no_run
1048-
/// use std::mem;
1048+
/// #![feature(maybe_uninit)]
1049+
/// use std::mem::{self, MaybeUninit};
10491050
///
10501051
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
1052+
/// // equivalent code with `MaybeUninit`
1053+
/// let x: &i32 = unsafe { MaybeUninit::zeroed().into_initialized() }; // undefined behavior!
10511054
/// ```
10521055
///
10531056
/// This is exploited by the compiler for various optimizations, such as eliding
10541057
/// run-time checks and optimizing `enum` layout.
10551058
///
1056-
/// Not initializing memory at all (instead of zero--initializing it) causes the same
1059+
/// Not initializing memory at all (instead of zero-initializing it) causes the same
10571060
/// issue: after all, the initial value of the variable might just happen to be
1058-
/// one that violates the invariant.
1061+
/// one that violates the invariant. Moreover, uninitialized memory is special
1062+
/// in that the compiler knows that it does not have a fixed value. This makes
1063+
/// it undefined behavior to have uninitialized data in a variable even if that
1064+
/// variable has otherwise no restrictions about which values are valid:
1065+
///
1066+
/// ```rust,no_run
1067+
/// #![feature(maybe_uninit)]
1068+
/// use std::mem::{self, MaybeUninit};
1069+
///
1070+
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
1071+
/// // equivalent code with `MaybeUninit`
1072+
/// let x: i32 = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior!
1073+
/// ```
1074+
/// (Notice that the rules around uninitialized integers are not finalized yet, but
1075+
/// until they are, it is advisable to avoid them.)
10591076
///
10601077
/// `MaybeUninit` serves to enable unsafe code to deal with uninitialized data:
10611078
/// it is a signal to the compiler indicating that the data here might *not*
@@ -1065,7 +1082,8 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10651082
/// #![feature(maybe_uninit)]
10661083
/// use std::mem::MaybeUninit;
10671084
///
1068-
/// // Create an explicitly uninitialized reference.
1085+
/// // Create an explicitly uninitialized reference. The compiler knows that data inside
1086+
/// // a `MaybeUninit` may be invalid, and hence this is not UB:
10691087
/// let mut x = MaybeUninit::<&i32>::uninitialized();
10701088
/// // Set it to a valid value.
10711089
/// x.set(&0);
@@ -1075,6 +1093,7 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10751093
/// ```
10761094
///
10771095
/// The compiler then knows to not optimize this code.
1096+
// FIXME before stabilizing, explain how to initialize a struct field-by-field.
10781097
#[allow(missing_debug_implementations)]
10791098
#[unstable(feature = "maybe_uninit", issue = "53491")]
10801099
// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::{uninitialized,zeroed}`
@@ -1134,14 +1153,31 @@ impl<T> MaybeUninit<T> {
11341153
}
11351154
}
11361155

1156+
/// Gets a pointer to the contained value. Reading from this pointer or turning it
1157+
/// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
1158+
#[unstable(feature = "maybe_uninit", issue = "53491")]
1159+
#[inline(always)]
1160+
pub fn as_ptr(&self) -> *const T {
1161+
unsafe { &*self.value as *const T }
1162+
}
1163+
1164+
/// Gets a mutable pointer to the contained value. Reading from this pointer or turning it
1165+
/// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
1166+
#[unstable(feature = "maybe_uninit", issue = "53491")]
1167+
#[inline(always)]
1168+
pub fn as_mut_ptr(&mut self) -> *mut T {
1169+
unsafe { &mut *self.value as *mut T }
1170+
}
1171+
11371172
/// Extracts the value from the `MaybeUninit` container. This is a great way
11381173
/// to ensure that the data will get dropped, because the resulting `T` is
11391174
/// subject to the usual drop handling.
11401175
///
11411176
/// # Unsafety
11421177
///
11431178
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
1144-
/// state, otherwise this will immediately cause undefined behavior.
1179+
/// state. Calling this when the content is not yet fully initialized causes undefined
1180+
/// behavior.
11451181
#[unstable(feature = "maybe_uninit", issue = "53491")]
11461182
#[inline(always)]
11471183
pub unsafe fn into_initialized(self) -> T {
@@ -1162,8 +1198,9 @@ impl<T> MaybeUninit<T> {
11621198
/// # Unsafety
11631199
///
11641200
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
1165-
/// state, otherwise this will immediately cause undefined behavior.
1166-
#[unstable(feature = "maybe_uninit", issue = "53491")]
1201+
/// state. Calling this when the content is not yet fully initialized causes undefined
1202+
/// behavior.
1203+
#[unstable(feature = "maybe_uninit_ref", issue = "53491")]
11671204
#[inline(always)]
11681205
pub unsafe fn get_ref(&self) -> &T {
11691206
&*self.value
@@ -1174,41 +1211,26 @@ impl<T> MaybeUninit<T> {
11741211
/// # Unsafety
11751212
///
11761213
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
1177-
/// state, otherwise this will immediately cause undefined behavior.
1214+
/// state. Calling this when the content is not yet fully initialized causes undefined
1215+
/// behavior.
11781216
// FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
11791217
// to uninitialized data (e.g., in `libcore/fmt/float.rs`). We should make
11801218
// a final decision about the rules before stabilization.
1181-
#[unstable(feature = "maybe_uninit", issue = "53491")]
1219+
#[unstable(feature = "maybe_uninit_ref", issue = "53491")]
11821220
#[inline(always)]
11831221
pub unsafe fn get_mut(&mut self) -> &mut T {
11841222
&mut *self.value
11851223
}
11861224

1187-
/// Gets a pointer to the contained value. Reading from this pointer or turning it
1188-
/// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
1189-
#[unstable(feature = "maybe_uninit", issue = "53491")]
1190-
#[inline(always)]
1191-
pub fn as_ptr(&self) -> *const T {
1192-
unsafe { &*self.value as *const T }
1193-
}
1194-
1195-
/// Get sa mutable pointer to the contained value. Reading from this pointer or turning it
1196-
/// into a reference will be undefined behavior unless the `MaybeUninit` is initialized.
1197-
#[unstable(feature = "maybe_uninit", issue = "53491")]
1198-
#[inline(always)]
1199-
pub fn as_mut_ptr(&mut self) -> *mut T {
1200-
unsafe { &mut *self.value as *mut T }
1201-
}
1202-
12031225
/// Gets a pointer to the first element of the array.
1204-
#[unstable(feature = "maybe_uninit", issue = "53491")]
1226+
#[unstable(feature = "maybe_uninit_slice", issue = "53491")]
12051227
#[inline(always)]
12061228
pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
12071229
this as *const [MaybeUninit<T>] as *const T
12081230
}
12091231

12101232
/// Gets a mutable pointer to the first element of the array.
1211-
#[unstable(feature = "maybe_uninit", issue = "53491")]
1233+
#[unstable(feature = "maybe_uninit_slice", issue = "53491")]
12121234
#[inline(always)]
12131235
pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T {
12141236
this as *mut [MaybeUninit<T>] as *mut T

0 commit comments

Comments
 (0)