Skip to content

Commit b12e142

Browse files
committed
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.
1 parent 3a1b3b3 commit b12e142

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

src/liballoc/boxed.rs

+27
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,33 @@ impl<T> Box<T> {
152152
Box(ptr.cast().into())
153153
}
154154

155+
/// Constructs a new `Box` with uninitialized contents, with the memory
156+
/// being filled with `0` bytes.
157+
///
158+
/// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
159+
/// of this method.
160+
///
161+
/// # Examples
162+
///
163+
/// ```
164+
/// #![feature(new_uninit)]
165+
///
166+
/// let zero = Box::<u32>::new_zeroed();
167+
/// let zero = unsafe { zero.assume_init() };
168+
///
169+
/// assert_eq!(*zero, 0)
170+
/// ```
171+
///
172+
/// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
173+
#[unstable(feature = "new_uninit", issue = "63291")]
174+
pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
175+
unsafe {
176+
let mut uninit = Self::new_uninit();
177+
ptr::write_bytes::<T>(uninit.as_mut_ptr(), 0, 1);
178+
uninit
179+
}
180+
}
181+
155182
/// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
156183
/// `x` will be pinned in memory and unable to be moved.
157184
#[stable(feature = "pin", since = "1.33.0")]

src/liballoc/rc.rs

+29
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,35 @@ impl<T> Rc<T> {
361361
}
362362
}
363363

364+
/// Constructs a new `Rc` with uninitialized contents, with the memory
365+
/// being filled with `0` bytes.
366+
///
367+
/// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and
368+
/// incorrect usage of this method.
369+
///
370+
/// # Examples
371+
///
372+
/// ```
373+
/// #![feature(new_uninit)]
374+
///
375+
/// use std::rc::Rc;
376+
///
377+
/// let zero = Rc::<u32>::new_zeroed();
378+
/// let zero = unsafe { zero.assume_init() };
379+
///
380+
/// assert_eq!(*zero, 0)
381+
/// ```
382+
///
383+
/// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
384+
#[unstable(feature = "new_uninit", issue = "63291")]
385+
pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
386+
unsafe {
387+
let mut uninit = Self::new_uninit();
388+
ptr::write_bytes::<T>(Rc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
389+
uninit
390+
}
391+
}
392+
364393
/// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
365394
/// `value` will be pinned in memory and unable to be moved.
366395
#[stable(feature = "pin", since = "1.33.0")]

src/liballoc/sync.rs

+29
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,35 @@ impl<T> Arc<T> {
341341
}
342342
}
343343

344+
/// Constructs a new `Arc` with uninitialized contents, with the memory
345+
/// being filled with `0` bytes.
346+
///
347+
/// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
348+
/// of this method.
349+
///
350+
/// # Examples
351+
///
352+
/// ```
353+
/// #![feature(new_uninit)]
354+
///
355+
/// use std::sync::Arc;
356+
///
357+
/// let zero = Arc::<u32>::new_zeroed();
358+
/// let zero = unsafe { zero.assume_init() };
359+
///
360+
/// assert_eq!(*zero, 0)
361+
/// ```
362+
///
363+
/// [zeroed]: ../../std/mem/union.MaybeUninit.html#method.zeroed
364+
#[unstable(feature = "new_uninit", issue = "63291")]
365+
pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
366+
unsafe {
367+
let mut uninit = Self::new_uninit();
368+
ptr::write_bytes::<T>(Arc::get_mut_unchecked(&mut uninit).as_mut_ptr(), 0, 1);
369+
uninit
370+
}
371+
}
372+
344373
/// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
345374
/// `data` will be pinned in memory and unable to be moved.
346375
#[stable(feature = "pin", since = "1.33.0")]

0 commit comments

Comments
 (0)