Skip to content

Commit

Permalink
alloc: Add new_zeroed() versions like new_uninit().
Browse files Browse the repository at this point in the history
MaybeUninit has both uninit() and zeroed(), it seems reasonable to have the same
surface on Box/Rc/Arc.

Needs tests.
  • Loading branch information
emilio committed Nov 5, 2019
1 parent 3a1b3b3 commit b12e142
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
29 changes: 29 additions & 0 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
29 changes: 29 additions & 0 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down

0 comments on commit b12e142

Please sign in to comment.