Skip to content

Commit 6fadf27

Browse files
committed
Specialize Clone impl for Box to use Crucible's allocator
Fixes #245.
1 parent f67613f commit 6fadf27

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

libs/Patches.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ 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+
* Specialize `Clone` impl for `Box` to use Crucible's allocator (last applied: Feburary 26, 2026)
94+
95+
The default `Clone` impl for `Box` is parameterized over an arbitrary
96+
allocator, and as a result, it has to call the `new_uninit_in` function,
97+
which `crucible-mir` cannot easily support. We add a specialized version of
98+
the `Clone` impl for the `Global` allocator that instead calls the more
99+
Crucible-friendly `new_uninit` function. (See also the `` Use crucible's
100+
allocator in `Box` constructors `` patch above.)
101+
93102
* Define `Arc`/`Rc` constructors in terms of `{Arc,Rc}::new` (last applied: January 20, 2026)
94103

95104
This ensures that all `Arc`/`Rc` constructors are defined in terms of

libs/alloc/src/boxed.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,7 +1755,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
17551755
/// assert_ne!(&*x as *const i32, &*y as *const i32);
17561756
/// ```
17571757
#[inline]
1758-
fn clone(&self) -> Self {
1758+
default fn clone(&self) -> Self {
17591759
// Pre-allocate memory to allow writing the cloned value directly.
17601760
let mut boxed = Self::new_uninit_in(self.1.clone());
17611761
unsafe {
@@ -1782,11 +1782,27 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
17821782
/// assert_eq!(yp, &*y);
17831783
/// ```
17841784
#[inline]
1785-
fn clone_from(&mut self, source: &Self) {
1785+
default fn clone_from(&mut self, source: &Self) {
17861786
(**self).clone_from(&(**source));
17871787
}
17881788
}
17891789

1790+
// A specialized version of the Clone impl that uses new_uninit() instead of
1791+
// new_uninit_in(), as the former is more Crucible-friendly.
1792+
#[cfg(not(no_global_oom_handling))]
1793+
#[stable(feature = "rust1", since = "1.0.0")]
1794+
impl<T: Clone> Clone for Box<T> {
1795+
#[inline]
1796+
fn clone(&self) -> Self {
1797+
// Pre-allocate memory to allow writing the cloned value directly.
1798+
let mut boxed = Self::new_uninit();
1799+
unsafe {
1800+
(**self).clone_to_uninit(boxed.as_mut_ptr().cast());
1801+
boxed.assume_init()
1802+
}
1803+
}
1804+
}
1805+
17901806
#[cfg(not(no_global_oom_handling))]
17911807
#[stable(feature = "box_slice_clone", since = "1.3.0")]
17921808
impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {

0 commit comments

Comments
 (0)