diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-28 22:25:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-28 22:25:41 +0100 |
| commit | f21f83d11710f13e285dab4bea7b9bebd1d47814 (patch) | |
| tree | 5107c096fdcbfc3170fc34efe95b28b02ac3033e /src/libcore | |
| parent | d8a0dd7ae88023bd09fa4b86c9ca1f6ed8095b43 (diff) | |
| parent | 489a79247ddf5da8090019ff4da4b688ad55afa7 (diff) | |
| download | rust-f21f83d11710f13e285dab4bea7b9bebd1d47814.tar.gz rust-f21f83d11710f13e285dab4bea7b9bebd1d47814.zip | |
Rollup merge of #57045 - RalfJung:kill-more-uninit, r=SimonSapin
Kill remaining uses of mem::uninitialized in libcore, liballoc
Kill remaining uses of mem::uninitialized in libcore and liballoc, and enable a lint that will warn when uses are added again in the future.
To avoid casting raw pointers around (which is always very dangerous because it is not typechecked at all -- it doesn't even get the "same size" sanity check that `transmute` gets), I also added two new functions to `MaybeUninit`:
```rust
/// Get a pointer to the first contained values.
pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
this as *const [MaybeUninit<T>] as *const T
}
/// Get a mutable pointer to the first contained values.
pub fn first_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
this as *mut [MaybeUninit<T>] as *mut T
}
```
I changed some of the existing code to use array-of-`MaybeUninit` instead of `MaybeUninit`-of-array, successfully removing raw pointer casts there as well.
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/fmt/mod.rs | 2 | ||||
| -rw-r--r-- | src/libcore/fmt/num.rs | 20 | ||||
| -rw-r--r-- | src/libcore/hash/sip.rs | 2 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 10 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 17 | ||||
| -rw-r--r-- | src/libcore/mem.rs | 14 | ||||
| -rw-r--r-- | src/libcore/slice/sort.rs | 12 |
7 files changed, 56 insertions, 21 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 935579f4943..530b2f52c0d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -2048,7 +2048,7 @@ macro_rules! tuple { ( $($name:ident,)+ ) => ( #[stable(feature = "rust1", since = "1.0.0")] impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { - #[allow(non_snake_case, unused_assignments, deprecated)] + #[allow(non_snake_case, unused_assignments)] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index c7c8fc50efa..3a812337bb1 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -1,14 +1,12 @@ //! Integer and floating-point number formatting -#![allow(deprecated)] - use fmt; use ops::{Div, Rem, Sub}; use str; use slice; use ptr; -use mem; +use mem::MaybeUninit; #[doc(hidden)] trait Int: PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> + @@ -53,7 +51,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf: [u8; 128] = unsafe { mem::uninitialized() }; + let mut buf = uninitialized_array![u8; 128]; let mut curr = buf.len(); let base = T::from_u8(Self::BASE); if is_nonnegative { @@ -62,7 +60,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -74,7 +72,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. + byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -82,7 +80,11 @@ trait GenericRadix { }; } } - let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; + let buf = &buf[curr..]; + let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( + MaybeUninit::first_ptr(buf), + buf.len() + )) }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } } @@ -196,9 +198,9 @@ macro_rules! impl_Display { // convert the negative num to positive by summing 1 to it's 2 complement (!self.$conv_fn()).wrapping_add(1) }; - let mut buf: [u8; 39] = unsafe { mem::uninitialized() }; + let mut buf = uninitialized_array![u8; 39]; let mut curr = buf.len() as isize; - let buf_ptr = buf.as_mut_ptr(); + let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf); let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 3377b831a9d..18f09f4c5dd 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -1,6 +1,6 @@ //! An implementation of SipHash. -#![allow(deprecated)] +#![allow(deprecated)] // the types in this module are deprecated use marker::PhantomData; use ptr; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 825e5148fd5..1ef21832592 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -58,11 +58,12 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] - #![no_core] -#![deny(missing_docs)] -#![deny(intra_doc_link_resolution_failure)] -#![deny(missing_debug_implementations)] + +#![warn(deprecated_in_future)] +#![warn(missing_docs)] +#![warn(intra_doc_link_resolution_failure)] +#![warn(missing_debug_implementations)] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] @@ -122,6 +123,7 @@ #![feature(structural_match)] #![feature(abi_unadjusted)] #![feature(adx_target_feature)] +#![feature(maybe_uninit)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 2f350df2f5c..12b7adb8a9d 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -547,6 +547,23 @@ macro_rules! unimplemented { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } +/// A macro to create an array of [`MaybeUninit`] +/// +/// This macro constructs and uninitialized array of the type `[MaybeUninit<K>; N]`. +/// +/// [`MaybeUninit`]: mem/union.MaybeUninit.html +#[macro_export] +#[unstable(feature = "maybe_uninit", issue = "53491")] +macro_rules! uninitialized_array { + // This `into_inner` 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_inner() + }); +} + /// Built-in macros to the compiler itself. /// /// These macros do not have any corresponding definition with a `macro_rules!` diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 0eeac5e1ea9..8b6d9d882b5 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1148,4 +1148,18 @@ impl<T> MaybeUninit<T> { pub fn as_mut_ptr(&mut self) -> *mut T { unsafe { &mut *self.value as *mut T } } + + /// Get a pointer to the first element of the array. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T { + this as *const [MaybeUninit<T>] as *const T + } + + /// Get a mutable pointer to the first element of the array. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T { + this as *mut [MaybeUninit<T>] as *mut T + } } diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index dd9b49fb7a0..3f84faa0499 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -216,14 +216,14 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize let mut block_l = BLOCK; let mut start_l = ptr::null_mut(); let mut end_l = ptr::null_mut(); - let mut offsets_l = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + let mut offsets_l: [MaybeUninit<u8>; BLOCK] = uninitialized_array![u8; BLOCK]; // The current block on the right side (from `r.sub(block_r)` to `r`). let mut r = unsafe { l.add(v.len()) }; let mut block_r = BLOCK; let mut start_r = ptr::null_mut(); let mut end_r = ptr::null_mut(); - let mut offsets_r = MaybeUninit::<[u8; BLOCK]>::uninitialized(); + let mut offsets_r: [MaybeUninit<u8>; BLOCK] = uninitialized_array![u8; BLOCK]; // FIXME: When we get VLAs, try creating one array of length `min(v.len(), 2 * BLOCK)` rather // than two fixed-size arrays of length `BLOCK`. VLAs might be more cache-efficient. @@ -262,8 +262,8 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_l == end_l { // Trace `block_l` elements from the left side. - start_l = offsets_l.as_mut_ptr() as *mut u8; - end_l = offsets_l.as_mut_ptr() as *mut u8; + start_l = MaybeUninit::first_ptr_mut(&mut offsets_l); + end_l = MaybeUninit::first_ptr_mut(&mut offsets_l); let mut elem = l; for i in 0..block_l { @@ -278,8 +278,8 @@ fn partition_in_blocks<T, F>(v: &mut [T], pivot: &T, is_less: &mut F) -> usize if start_r == end_r { // Trace `block_r` elements from the right side. - start_r = offsets_r.as_mut_ptr() as *mut u8; - end_r = offsets_r.as_mut_ptr() as *mut u8; + start_r = MaybeUninit::first_ptr_mut(&mut offsets_r); + end_r = MaybeUninit::first_ptr_mut(&mut offsets_r); let mut elem = r; for i in 0..block_r { |
