about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-01-28 22:25:41 +0100
committerGitHub <noreply@github.com>2019-01-28 22:25:41 +0100
commitf21f83d11710f13e285dab4bea7b9bebd1d47814 (patch)
tree5107c096fdcbfc3170fc34efe95b28b02ac3033e /src/libcore
parentd8a0dd7ae88023bd09fa4b86c9ca1f6ed8095b43 (diff)
parent489a79247ddf5da8090019ff4da4b688ad55afa7 (diff)
downloadrust-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.rs2
-rw-r--r--src/libcore/fmt/num.rs20
-rw-r--r--src/libcore/hash/sip.rs2
-rw-r--r--src/libcore/lib.rs10
-rw-r--r--src/libcore/macros.rs17
-rw-r--r--src/libcore/mem.rs14
-rw-r--r--src/libcore/slice/sort.rs12
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 {