From: Ralf Jung Date: Mon, 18 Mar 2019 21:45:02 +0000 (+0100) Subject: adjust MaybeUninit API to discussions X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=0e0383abc6d1f7d1edc456f66a2e3f4082e9a0a8;p=rust.git adjust MaybeUninit API to discussions uninitialized -> uninit into_initialized -> assume_init read_initialized -> read set -> write --- diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 66d619b1298..581c66c7086 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -109,7 +109,7 @@ unsafe fn new() -> Self { keys: uninitialized_array![_; CAPACITY], vals: uninitialized_array![_; CAPACITY], parent: ptr::null(), - parent_idx: MaybeUninit::uninitialized(), + parent_idx: MaybeUninit::uninit(), len: 0 } } @@ -129,7 +129,7 @@ unsafe impl Sync for NodeHeader<(), ()> {} // ever take a pointer past the first key. static EMPTY_ROOT_NODE: NodeHeader<(), ()> = NodeHeader { parent: ptr::null(), - parent_idx: MaybeUninit::uninitialized(), + parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [], }; @@ -261,7 +261,7 @@ pub fn push_level(&mut self) -> NodeRef, K, V, marker::Internal> { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); - new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); + new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); self.node = BoxedNode::from_internal(new_node); self.height += 1; @@ -737,7 +737,7 @@ pub fn push(&mut self, key: K, val: V, edge: Root) { unsafe { ptr::write(self.keys_mut().get_unchecked_mut(idx), key); ptr::write(self.vals_mut().get_unchecked_mut(idx), val); - self.as_internal_mut().edges.get_unchecked_mut(idx + 1).set(edge.node); + self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node); (*self.as_leaf_mut()).len += 1; @@ -1080,7 +1080,7 @@ fn correct_parent_link(mut self) { let mut child = self.descend(); unsafe { (*child.as_leaf_mut()).parent = ptr; - (*child.as_leaf_mut()).parent_idx.set(idx); + (*child.as_leaf_mut()).parent_idx.write(idx); } } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index edeb65afd67..5f4c6f7b0a3 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -10,8 +10,8 @@ fn float_to_decimal_common_exact(fmt: &mut Formatter, num: &T, where T: flt2dec::DecodableFloat { unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 + let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninit(); // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized // `MaybeUninit` (here and elsewhere in this file). Revisit this once // we decided whether that is valid or not. @@ -32,8 +32,8 @@ fn float_to_decimal_common_shortest(fmt: &mut Formatter, num: &T, { unsafe { // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized(); - let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); + let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, precision, false, buf.get_mut(), @@ -71,8 +71,8 @@ fn float_to_exponential_common_exact(fmt: &mut Formatter, num: &T, where T: flt2dec::DecodableFloat { unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 + let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, @@ -91,8 +91,8 @@ fn float_to_exponential_common_shortest(fmt: &mut Formatter, { unsafe { // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized(); - let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); + let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index b9fa3640371..e96dbcaa144 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -60,7 +60,7 @@ fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. + byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -72,7 +72,7 @@ fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. + byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index d77936c7ddd..ad8ce1af1f6 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -626,12 +626,12 @@ macro_rules! todo { #[macro_export] #[unstable(feature = "maybe_uninit_array", issue = "53491")] macro_rules! uninitialized_array { - // This `into_initialized` is safe because an array of `MaybeUninit` does not + // This `assume_init` is safe because an array of `MaybeUninit` does not // require initialization. // FIXME(#49147): Could be replaced by an array initializer, once those can // be any const expression. ($t:ty; $size:expr) => (unsafe { - MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_initialized() + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init() }); } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 3d2fcdc9793..66bcf1f7d01 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -622,7 +622,7 @@ pub unsafe fn zeroed() -> T { /// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html /// [`Drop`]: ../ops/trait.Drop.html #[inline] -#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninitialized` instead")] +#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); @@ -1058,7 +1058,7 @@ fn deref_mut(&mut self) -> &mut T { /// /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! /// // The equivalent code with `MaybeUninit<&i32>`: -/// let x: &i32 = unsafe { MaybeUninit::zeroed().into_initialized() }; // undefined behavior! +/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior! /// ``` /// /// This is exploited by the compiler for various optimizations, such as eliding @@ -1073,7 +1073,7 @@ fn deref_mut(&mut self) -> &mut T { /// /// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! /// // The equivalent code with `MaybeUninit`: -/// let b: bool = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior! +/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! /// ``` /// /// Moreover, uninitialized memory is special in that the compiler knows that @@ -1087,7 +1087,7 @@ fn deref_mut(&mut self) -> &mut T { /// /// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! /// // The equivalent code with `MaybeUninit`: -/// let x: i32 = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior! +/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! /// ``` /// (Notice that the rules around uninitialized integers are not finalized yet, but /// until they are, it is advisable to avoid them.) @@ -1102,12 +1102,12 @@ fn deref_mut(&mut self) -> &mut T { /// /// // Create an explicitly uninitialized reference. The compiler knows that data inside /// // a `MaybeUninit` may be invalid, and hence this is not UB: -/// let mut x = MaybeUninit::<&i32>::uninitialized(); +/// let mut x = MaybeUninit::<&i32>::uninit(); /// // Set it to a valid value. -/// x.set(&0); +/// x.write(&0); /// // Extract the initialized data -- this is only allowed *after* properly /// // initializing `x`! -/// let x = unsafe { x.into_initialized() }; +/// let x = unsafe { x.assume_init() }; /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. @@ -1148,10 +1148,19 @@ pub const fn new(val: T) -> MaybeUninit { /// It is your responsibility to make sure `T` gets dropped if it got initialized. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub const fn uninitialized() -> MaybeUninit { + pub const fn uninit() -> MaybeUninit { MaybeUninit { uninit: () } } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + // FIXME: still used by stdsimd + // #[rustc_deprecated(since = "1.35.0", reason = "use `uninit` instead")] + pub const fn uninitialized() -> MaybeUninit { + Self::uninit() + } + /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, @@ -1171,7 +1180,7 @@ pub const fn uninitialized() -> MaybeUninit { /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::<(u8, bool)>::zeroed(); - /// let x = unsafe { x.into_initialized() }; + /// let x = unsafe { x.assume_init() }; /// assert_eq!(x, (0, false)); /// ``` /// @@ -1185,14 +1194,14 @@ pub const fn uninitialized() -> MaybeUninit { /// enum NotZero { One = 1, Two = 2 }; /// /// let x = MaybeUninit::<(u8, NotZero)>::zeroed(); - /// let x = unsafe { x.into_initialized() }; + /// let x = unsafe { x.assume_init() }; /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant. /// // This is undefined behavior. /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline] pub fn zeroed() -> MaybeUninit { - let mut u = MaybeUninit::::uninitialized(); + let mut u = MaybeUninit::::uninit(); unsafe { u.as_mut_ptr().write_bytes(0u8, 1); } @@ -1205,13 +1214,21 @@ pub fn zeroed() -> MaybeUninit { /// reference to the (now safely initialized) contents of `self`. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub fn set(&mut self, val: T) -> &mut T { + pub fn write(&mut self, val: T) -> &mut T { unsafe { self.value = ManuallyDrop::new(val); self.get_mut() } } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + #[rustc_deprecated(since = "1.35.0", reason = "use `write` instead")] + pub fn set(&mut self, val: T) -> &mut T { + self.write(val) + } + /// Gets a pointer to the contained value. Reading from this pointer or turning it /// into a reference is undefined behavior unless the `MaybeUninit` is initialized. /// @@ -1223,7 +1240,7 @@ pub fn set(&mut self, val: T) -> &mut T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); } /// // Create a reference into the `MaybeUninit`. This is okay because we initialized it. /// let x_vec = unsafe { &*x.as_ptr() }; @@ -1236,7 +1253,7 @@ pub fn set(&mut self, val: T) -> &mut T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let x = MaybeUninit::>::uninitialized(); + /// let x = MaybeUninit::>::uninit(); /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` @@ -1260,7 +1277,7 @@ pub fn as_ptr(&self) -> *const T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); } /// // Create a reference into the `MaybeUninit>`. /// // This is okay because we initialized it. @@ -1275,7 +1292,7 @@ pub fn as_ptr(&self) -> *const T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` @@ -1306,9 +1323,9 @@ pub fn as_mut_ptr(&mut self) -> *mut T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::::uninitialized(); + /// let mut x = MaybeUninit::::uninit(); /// unsafe { x.as_mut_ptr().write(true); } - /// let x_init = unsafe { x.into_initialized() }; + /// let x_init = unsafe { x.assume_init() }; /// assert_eq!(x_init, true); /// ``` /// @@ -1318,21 +1335,30 @@ pub fn as_mut_ptr(&mut self) -> *mut T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let x = MaybeUninit::>::uninitialized(); - /// let x_init = unsafe { x.into_initialized() }; + /// let x = MaybeUninit::>::uninit(); + /// let x_init = unsafe { x.assume_init() }; /// // `x` had not been initialized yet, so this last line caused undefined behavior. /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn into_initialized(self) -> T { + pub unsafe fn assume_init(self) -> T { intrinsics::panic_if_uninhabited::(); ManuallyDrop::into_inner(self.value) } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + // FIXME: still used by stdsimd + // #[rustc_deprecated(since = "1.35.0", reason = "use `assume_init` instead")] + pub unsafe fn into_initialized(self) -> T { + self.assume_init() + } + /// Reads the value from the `MaybeUninit` container. The resulting `T` is subject /// to the usual drop handling. /// - /// Whenever possible, it is preferrable to use [`into_initialized`] instead, which + /// Whenever possible, it is preferrable to use [`assume_init`] instead, which /// prevents duplicating the content of the `MaybeUninit`. /// /// # Safety @@ -1342,11 +1368,11 @@ pub unsafe fn into_initialized(self) -> T { /// behavior. /// /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit`. When using - /// multiple copies of the data (by calling `read_initialized` multiple times, or first - /// calling `read_initialized` and then [`into_initialized`]), it is your responsibility + /// multiple copies of the data (by calling `read` multiple times, or first + /// calling `read` and then [`assume_init`]), it is your responsibility /// to ensure that that data may indeed be duplicated. /// - /// [`into_initialized`]: #method.into_initialized + /// [`assume_init`]: #method.assume_init /// /// # Examples /// @@ -1356,18 +1382,18 @@ pub unsafe fn into_initialized(self) -> T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::::uninitialized(); - /// x.set(13); - /// let x1 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::::uninit(); + /// x.write(13); + /// let x1 = unsafe { x.read() }; /// // `u32` is `Copy`, so we may read multiple times. - /// let x2 = unsafe { x.read_initialized() }; + /// let x2 = unsafe { x.read() }; /// assert_eq!(x1, x2); /// - /// let mut x = MaybeUninit::>>::uninitialized(); - /// x.set(None); - /// let x1 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::>>::uninit(); + /// x.write(None); + /// let x1 = unsafe { x.read() }; /// // Duplicating a `None` value is okay, so we may read multiple times. - /// let x2 = unsafe { x.read_initialized() }; + /// let x2 = unsafe { x.read() }; /// assert_eq!(x1, x2); /// ``` /// @@ -1377,20 +1403,28 @@ pub unsafe fn into_initialized(self) -> T { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>>::uninitialized(); - /// x.set(Some(vec![0,1,2])); - /// let x1 = unsafe { x.read_initialized() }; - /// let x2 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::>>::uninit(); + /// x.write(Some(vec![0,1,2])); + /// let x1 = unsafe { x.read() }; + /// let x2 = unsafe { x.read() }; /// // We now created two copies of the same vector, leading to a double-free when /// // they both get dropped! /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn read_initialized(&self) -> T { + pub unsafe fn read(&self) -> T { intrinsics::panic_if_uninhabited::(); self.as_ptr().read() } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + #[rustc_deprecated(since = "1.35.0", reason = "use `read` instead")] + pub unsafe fn read_initialized(&self) -> T { + self.read() + } + /// Gets a reference to the contained value. /// /// # Safety diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a9a029d606d..1cb21aa6be0 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -296,7 +296,7 @@ pub const fn null_mut() -> *mut T { 0 as *mut T } pub unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); // Perform the swap copy_nonoverlapping(x, tmp.as_mut_ptr(), 1); @@ -388,7 +388,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { while i + block_size <= len { // Create some uninitialized memory as scratch space // Declaring `t` here avoids aligning the stack when this loop is unused - let mut t = mem::MaybeUninit::::uninitialized(); + let mut t = mem::MaybeUninit::::uninit(); let t = t.as_mut_ptr() as *mut u8; let x = x.add(i); let y = y.add(i); @@ -403,7 +403,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { if i < len { // Swap any remaining bytes - let mut t = mem::MaybeUninit::::uninitialized(); + let mut t = mem::MaybeUninit::::uninit(); let rem = len - i; let t = t.as_mut_ptr() as *mut u8; @@ -571,9 +571,9 @@ pub unsafe fn replace(dst: *mut T, mut src: T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn read(src: *const T) -> T { - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - tmp.into_initialized() + tmp.assume_init() } /// Reads the value from `src` without moving it. This leaves the @@ -638,11 +638,11 @@ pub unsafe fn read(src: *const T) -> T { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] pub unsafe fn read_unaligned(src: *const T) -> T { - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::()); - tmp.into_initialized() + tmp.assume_init() } /// Overwrites a memory location with the given value without reading or diff --git a/src/libcore/slice/rotate.rs b/src/libcore/slice/rotate.rs index 9b35b51349a..8f10c3576a7 100644 --- a/src/libcore/slice/rotate.rs +++ b/src/libcore/slice/rotate.rs @@ -72,7 +72,7 @@ pub unsafe fn ptr_rotate(mut left: usize, mid: *mut T, mut right: usize) { } } - let mut rawarray = MaybeUninit::>::uninitialized(); + let mut rawarray = MaybeUninit::>::uninit(); let buf = &mut (*rawarray.as_mut_ptr()).typed as *mut [T; 2] as *mut T; let dim = mid.sub(left).add(right);