Skip to content

Commit 13f4ae0

Browse files
authored
Add functions to allocate zeroed Arc and Rc (#283)
These require rustc 1.82
1 parent af8d110 commit 13f4ae0

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ transparentwrapper_extra = []
4747

4848
const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
4949

50+
alloc_uninit = [] # MSRV 1.82.0: support `zeroed_*rc*`
51+
5052
# Do not use if you can avoid it, because this is **unsound**!!!!
5153
unsound_ptr_pod_impl = []
5254

@@ -61,6 +63,7 @@ latest_stable_rust = [
6163
# Keep this list sorted.
6264
"aarch64_simd",
6365
"align_offset",
66+
"alloc_uninit",
6467
"const_zeroed",
6568
"derive",
6669
"min_const_generics",

src/allocation.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,38 @@ pub fn zeroed_slice_box<T: Zeroable>(length: usize) -> Box<[T]> {
149149
try_zeroed_slice_box(length).unwrap()
150150
}
151151

152+
/// Allocates a `Arc<T>` with all contents being zeroed out.
153+
#[cfg(all(feature = "alloc_uninit", target_has_atomic = "ptr"))]
154+
pub fn zeroed_arc<T: Zeroable>() -> Arc<T> {
155+
let mut arc = Arc::new_uninit();
156+
crate::write_zeroes(Arc::get_mut(&mut arc).unwrap()); // unwrap never fails for a newly allocated Arc
157+
unsafe { arc.assume_init() }
158+
}
159+
160+
/// Allocates a `Arc<[T]>` with all contents being zeroed out.
161+
#[cfg(all(feature = "alloc_uninit", target_has_atomic = "ptr"))]
162+
pub fn zeroed_arc_slice<T: Zeroable>(length: usize) -> Arc<[T]> {
163+
let mut arc = Arc::new_uninit_slice(length);
164+
crate::fill_zeroes(Arc::get_mut(&mut arc).unwrap()); // unwrap never fails for a newly allocated Arc
165+
unsafe { arc.assume_init() }
166+
}
167+
168+
/// Allocates a `Rc<T>` with all contents being zeroed out.
169+
#[cfg(feature = "alloc_uninit")]
170+
pub fn zeroed_rc<T: Zeroable>() -> Rc<T> {
171+
let mut rc = Rc::new_uninit();
172+
crate::write_zeroes(Rc::get_mut(&mut rc).unwrap()); // unwrap never fails for a newly allocated Rc
173+
unsafe { rc.assume_init() }
174+
}
175+
176+
/// Allocates a `Rc<[T]>` with all contents being zeroed out.
177+
#[cfg(feature = "alloc_uninit")]
178+
pub fn zeroed_rc_slice<T: Zeroable>(length: usize) -> Rc<[T]> {
179+
let mut rc = Rc::new_uninit_slice(length);
180+
crate::fill_zeroes(Rc::get_mut(&mut rc).unwrap()); // unwrap never fails for a newly allocated Rc
181+
unsafe { rc.assume_init() }
182+
}
183+
152184
/// As [`try_cast_slice_box`], but unwraps for you.
153185
#[inline]
154186
pub fn cast_slice_box<A: NoUninit, B: AnyBitPattern>(

0 commit comments

Comments
 (0)