Skip to content

Commit d6ae15d

Browse files
authored
Merge pull request #221 from GaloisInc/T219-patch-new_uninit_zeroed
`libs`: More patches for `Arc` and `Rc`
2 parents 7e12cec + cff21a0 commit d6ae15d

File tree

3 files changed

+31
-57
lines changed

3 files changed

+31
-57
lines changed

libs/Patches.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,24 @@ into the main commit for that patch, and then the *Update* line can be removed.
9090
functions to call built-in Crucible allocation functions instead (e.g.
9191
`crucible::alloc::allocate`).
9292

93+
* Define `Arc`/`Rc` constructors in terms of `{Arc,Rc}::new` (last applied: January 20, 2026)
94+
95+
This ensures that all `Arc`/`Rc` constructors are defined in terms of
96+
`Box::new`, which uses Crucible's typed allocator instead of Rust's untyped
97+
allocator. (See the `` Use crucible's allocator in `Box` constructors ``
98+
patch above.)
99+
93100
* Don't deallocate in `Box::drop` (last applied: November 17, 2025)
94101

95102
Crucible doesn't support a `deallocate` operation.
96103

97-
* Don't deallocate in `Arc::drop` and related functions (last applied: November 17, 2025)
104+
* Don't deallocate in `Arc::drop`, `Rc::drop`, and related functions (last applied: November 17, 2025)
98105

99106
Crucible doesn't support a `deallocate` operation.
100107

108+
*Update* (January 20, 2026): Also patch out `Rc`-related functions (e.g.,
109+
`Rc::drop`).
110+
101111
* Skip `addr_eq` debug asserts in `Arc::drop` (last applied: November 20, 2025)
102112

103113
`Arc::drop` (and its corresponding `Weak::drop`) has a `debug_assert!` to

libs/alloc/src/rc.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -497,13 +497,7 @@ impl<T> Rc<T> {
497497
#[stable(feature = "new_uninit", since = "1.82.0")]
498498
#[must_use]
499499
pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
500-
unsafe {
501-
Rc::from_ptr(Rc::allocate_for_layout(
502-
Layout::new::<T>(),
503-
|layout| Global.allocate(layout),
504-
<*mut u8>::cast,
505-
))
506-
}
500+
Rc::new(mem::MaybeUninit::uninit())
507501
}
508502

509503
/// Constructs a new `Rc` with uninitialized contents, with the memory
@@ -530,13 +524,7 @@ impl<T> Rc<T> {
530524
#[unstable(feature = "new_zeroed_alloc", issue = "129396")]
531525
#[must_use]
532526
pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
533-
unsafe {
534-
Rc::from_ptr(Rc::allocate_for_layout(
535-
Layout::new::<T>(),
536-
|layout| Global.allocate_zeroed(layout),
537-
<*mut u8>::cast,
538-
))
539-
}
527+
Rc::new(mem::MaybeUninit::zeroed())
540528
}
541529

542530
/// Constructs a new `Rc<T>`, returning an error if the allocation fails
@@ -591,13 +579,7 @@ impl<T> Rc<T> {
591579
#[unstable(feature = "allocator_api", issue = "32838")]
592580
// #[unstable(feature = "new_uninit", issue = "63291")]
593581
pub fn try_new_uninit() -> Result<Rc<mem::MaybeUninit<T>>, AllocError> {
594-
unsafe {
595-
Ok(Rc::from_ptr(Rc::try_allocate_for_layout(
596-
Layout::new::<T>(),
597-
|layout| Global.allocate(layout),
598-
<*mut u8>::cast,
599-
)?))
600-
}
582+
Rc::try_new(mem::MaybeUninit::uninit())
601583
}
602584

603585
/// Constructs a new `Rc` with uninitialized contents, with the memory
@@ -624,13 +606,7 @@ impl<T> Rc<T> {
624606
#[unstable(feature = "allocator_api", issue = "32838")]
625607
//#[unstable(feature = "new_uninit", issue = "63291")]
626608
pub fn try_new_zeroed() -> Result<Rc<mem::MaybeUninit<T>>, AllocError> {
627-
unsafe {
628-
Ok(Rc::from_ptr(Rc::try_allocate_for_layout(
629-
Layout::new::<T>(),
630-
|layout| Global.allocate_zeroed(layout),
631-
<*mut u8>::cast,
632-
)?))
633-
}
609+
Rc::try_new(mem::MaybeUninit::zeroed())
634610
}
635611
/// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
636612
/// `value` will be pinned in memory and unable to be moved.
@@ -2181,7 +2157,10 @@ impl<T> Rc<[T]> {
21812157
let slice = from_raw_parts_mut(self.elems, self.n_elems);
21822158
ptr::drop_in_place(slice);
21832159

2160+
// Crucible: skip deallocation, which is currently unimplemented in crucible-mir.
2161+
/*
21842162
Global.deallocate(self.mem, self.layout);
2163+
*/
21852164
}
21862165
}
21872166
}
@@ -3489,9 +3468,12 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak<T, A> {
34893468
// the weak count starts at 1, and will only go to zero if all
34903469
// the strong pointers have disappeared.
34913470
if inner.weak() == 0 {
3471+
// Crucible: skip deallocation, which is currently unimplemented in crucible-mir.
3472+
/*
34923473
unsafe {
34933474
self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr()));
34943475
}
3476+
*/
34953477
}
34963478
}
34973479
}
@@ -4101,7 +4083,10 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc<T, A> {
41014083
self.ptr.as_ref().dec_weak();
41024084

41034085
if self.ptr.as_ref().weak() == 0 {
4086+
// Crucible: skip deallocation, which is currently unimplemented in crucible-mir.
4087+
/*
41044088
self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr()));
4089+
*/
41054090
}
41064091
}
41074092
}
@@ -4160,6 +4145,8 @@ impl<T: ?Sized, A: Allocator> UniqueRcUninit<T, A> {
41604145
#[cfg(not(no_global_oom_handling))]
41614146
impl<T: ?Sized, A: Allocator> Drop for UniqueRcUninit<T, A> {
41624147
fn drop(&mut self) {
4148+
// Crucible: skip deallocation, which is currently unimplemented in crucible-mir.
4149+
/*
41634150
// SAFETY:
41644151
// * new() produced a pointer safe to deallocate.
41654152
// * We own the pointer unless into_rc() was called, which forgets us.
@@ -4169,5 +4156,6 @@ impl<T: ?Sized, A: Allocator> Drop for UniqueRcUninit<T, A> {
41694156
rc_inner_layout_for_value_layout(self.layout_for_value),
41704157
);
41714158
}
4159+
*/
41724160
}
41734161
}

libs/alloc/src/sync.rs

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,7 @@ impl<T> Arc<T> {
498498
#[stable(feature = "new_uninit", since = "1.82.0")]
499499
#[must_use]
500500
pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
501-
unsafe {
502-
Arc::from_ptr(Arc::allocate_for_layout(
503-
Layout::new::<T>(),
504-
|layout| Global.allocate(layout),
505-
<*mut u8>::cast,
506-
))
507-
}
501+
Arc::new(mem::MaybeUninit::uninit())
508502
}
509503

510504
/// Constructs a new `Arc` with uninitialized contents, with the memory
@@ -532,13 +526,7 @@ impl<T> Arc<T> {
532526
#[unstable(feature = "new_zeroed_alloc", issue = "129396")]
533527
#[must_use]
534528
pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
535-
unsafe {
536-
Arc::from_ptr(Arc::allocate_for_layout(
537-
Layout::new::<T>(),
538-
|layout| Global.allocate_zeroed(layout),
539-
<*mut u8>::cast,
540-
))
541-
}
529+
Arc::new(mem::MaybeUninit::zeroed())
542530
}
543531

544532
/// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
@@ -605,13 +593,7 @@ impl<T> Arc<T> {
605593
#[unstable(feature = "allocator_api", issue = "32838")]
606594
// #[unstable(feature = "new_uninit", issue = "63291")]
607595
pub fn try_new_uninit() -> Result<Arc<mem::MaybeUninit<T>>, AllocError> {
608-
unsafe {
609-
Ok(Arc::from_ptr(Arc::try_allocate_for_layout(
610-
Layout::new::<T>(),
611-
|layout| Global.allocate(layout),
612-
<*mut u8>::cast,
613-
)?))
614-
}
596+
Arc::try_new(mem::MaybeUninit::uninit())
615597
}
616598

617599
/// Constructs a new `Arc` with uninitialized contents, with the memory
@@ -638,13 +620,7 @@ impl<T> Arc<T> {
638620
#[unstable(feature = "allocator_api", issue = "32838")]
639621
// #[unstable(feature = "new_uninit", issue = "63291")]
640622
pub fn try_new_zeroed() -> Result<Arc<mem::MaybeUninit<T>>, AllocError> {
641-
unsafe {
642-
Ok(Arc::from_ptr(Arc::try_allocate_for_layout(
643-
Layout::new::<T>(),
644-
|layout| Global.allocate_zeroed(layout),
645-
<*mut u8>::cast,
646-
)?))
647-
}
623+
Arc::try_new(mem::MaybeUninit::zeroed())
648624
}
649625
}
650626

0 commit comments

Comments
 (0)