about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-12-22 11:02:06 +0100
committerRalf Jung <post@ralfj.de>2019-01-28 10:48:38 +0100
commit22a947f3aa4b990efa135e3593fe7365bc7c36b9 (patch)
tree59e3051f236646814c60d51f5bcc0940f2b3e9a3
parent630aaa4e801393c55c8327f642aec2349adfaee3 (diff)
downloadrust-22a947f3aa4b990efa135e3593fe7365bc7c36b9.tar.gz
rust-22a947f3aa4b990efa135e3593fe7365bc7c36b9.zip
add macro for creating uninitialized array
-rw-r--r--src/liballoc/collections/btree/node.rs12
-rw-r--r--src/libcore/fmt/num.rs14
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/macros.rs17
-rw-r--r--src/libcore/slice/sort.rs11
5 files changed, 25 insertions, 30 deletions
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index 8dd4aec136a..25810d680fa 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -106,11 +106,8 @@ impl<K, V> LeafNode<K, V> {
         LeafNode {
             // As a general policy, we leave fields uninitialized if they can be, as this should
             // be both slightly faster and easier to track in Valgrind.
-            // Creating a `[MaybeUninit; N]` array by first creating a
-            // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
-            // array does not require initialization.
-            keys: MaybeUninit::uninitialized().into_inner(),
-            vals: MaybeUninit::uninitialized().into_inner(),
+            keys: uninitialized_array![_; CAPACITY],
+            vals: uninitialized_array![_; CAPACITY],
             parent: ptr::null(),
             parent_idx: MaybeUninit::uninitialized(),
             len: 0
@@ -162,10 +159,7 @@ impl<K, V> InternalNode<K, V> {
     unsafe fn new() -> Self {
         InternalNode {
             data: LeafNode::new(),
-            // Creating a `[MaybeUninit; N]` array by first creating a
-            // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
-            // array does not require initialization.
-            edges: MaybeUninit::uninitialized().into_inner(),
+            edges: uninitialized_array![_; 2*B],
         }
     }
 }
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index ff284d2978e..5283c6d7ef3 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -51,12 +51,7 @@ trait GenericRadix {
         // characters for a base 2 number.
         let zero = T::zero();
         let is_nonnegative = x >= zero;
-        // Creating a `[MaybeUninit; N]` array by first creating a
-        // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
-        // array does not require initialization.
-        let mut buf: [MaybeUninit<u8>; 128] = unsafe {
-            MaybeUninit::uninitialized().into_inner()
-        };
+        let mut buf = uninitialized_array![u8; 128];
         let mut curr = buf.len();
         let base = T::from_u8(Self::BASE);
         if is_nonnegative {
@@ -203,12 +198,7 @@ macro_rules! impl_Display {
                 // convert the negative num to positive by summing 1 to it's 2 complement
                 (!self.$conv_fn()).wrapping_add(1)
             };
-            // Creating a `[MaybeUninit; N]` array by first creating a
-            // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
-            // array does not require initialization.
-            let mut buf: [MaybeUninit<u8>; 39] = unsafe {
-                MaybeUninit::uninitialized().into_inner()
-            };
+            let mut buf = uninitialized_array![u8; 39];
             let mut curr = buf.len() as isize;
             let buf_ptr = MaybeUninit::first_mut_ptr(&mut buf);
             let lut_ptr = DEC_DIGITS_LUT.as_ptr();
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 4d7da3692fd..1295acb44a5 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -123,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/slice/sort.rs b/src/libcore/slice/sort.rs
index 8eb6a4d54c0..2ff67a4934f 100644
--- a/src/libcore/slice/sort.rs
+++ b/src/libcore/slice/sort.rs
@@ -216,21 +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();
-    // Creating a `[MaybeUninit; N]` array by first creating a
-    // `MaybeUninit<[MaybeUninit; N]>`; the `into_inner` is safe because the inner
-    // array does not require initialization.
-    let mut offsets_l: [MaybeUninit<u8>; BLOCK] = unsafe {
-        MaybeUninit::uninitialized().into_inner()
-    };
+    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] = unsafe {
-        MaybeUninit::uninitialized().into_inner()
-    };
+    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.