about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2019-11-26 17:56:05 -0600
committerGitHub <noreply@github.com>2019-11-26 17:56:05 -0600
commit941d9159420123d4a439ff7052f4c08ce33581be (patch)
treed320c81f9aba2ba5d0dfa341ce40302bb98eb3b9 /src/liballoc
parent797fd92628842c1f5face9fb93b0fe4f1f9d297f (diff)
parentb12e142bc5a6f6312ce2fd3305f449d03410a37a (diff)
downloadrust-941d9159420123d4a439ff7052f4c08ce33581be.tar.gz
rust-941d9159420123d4a439ff7052f4c08ce33581be.zip
Rollup merge of #66128 - emilio:new-zeroed, r=SimonSapin
alloc: Add new_zeroed() versions like new_uninit().

MaybeUninit has both uninit() and zeroed(), it seems reasonable to have the same
surface on Box/Rc/Arc.

Needs tests.

cc #63291
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/boxed.rs27
-rw-r--r--src/liballoc/rc.rs29
-rw-r--r--src/liballoc/sync.rs29
3 files changed, 85 insertions, 0 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 567b8ea7224..51ad3a04e87 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -152,6 +152,33 @@ impl<T> Box<T> {
         Box(ptr.cast().into())
     }
 
+    /// Constructs a new `Box` with uninitialized contents, with the memory
+    /// being filled with `0` bytes.
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
+    /// of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let zero = Box::<u32>::new_zeroed();
+    /// let zero = unsafe { zero.assume_init() };
+    ///
+    /// assert_eq!(*zero, 0)
+    /// ```
+    ///
+    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
+        unsafe {
+            let mut uninit = Self::new_uninit();
+            ptr::write_bytes::<T>(uninit.as_mut_ptr(), 0, 1);
+            uninit
+        }
+    }
+
     /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
     /// `x` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index a11f9e8c145..ec08965674a 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -361,6 +361,35 @@ impl<T> Rc<T> {
         }
     }
 
+    /// Constructs a new `Rc` with uninitialized contents, with the memory
+    /// being filled with `0` bytes.
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
+    /// incorrect usage of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let zero = Rc::<u32>::new_zeroed();
+    /// let zero = unsafe { zero.assume_init() };
+    ///
+    /// assert_eq!(*zero, 0)
+    /// ```
+    ///
+    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
+        unsafe {
+            let mut uninit = Self::new_uninit();
+            ptr::write_bytes::<T>(Rc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
+            uninit
+        }
+    }
+
     /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
     /// `value` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 4b10f089c29..0deb321d623 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -341,6 +341,35 @@ impl<T> Arc<T> {
         }
     }
 
+    /// Constructs a new `Arc` with uninitialized contents, with the memory
+    /// being filled with `0` bytes.
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
+    /// of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let zero = Arc::<u32>::new_zeroed();
+    /// let zero = unsafe { zero.assume_init() };
+    ///
+    /// assert_eq!(*zero, 0)
+    /// ```
+    ///
+    /// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
+        unsafe {
+            let mut uninit = Self::new_uninit();
+            ptr::write_bytes::<T>(Arc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
+            uninit
+        }
+    }
+
     /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
     /// `data` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]