diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 6677534eafc..1833a7f477f 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -424,29 +424,3 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { } } } - -#[cfg(not(no_global_oom_handling))] -/// Specialize clones into pre-allocated, uninitialized memory. -/// Used by `Box::clone` and `Rc`/`Arc::make_mut`. -pub(crate) trait WriteCloneIntoRaw: Sized { - unsafe fn write_clone_into_raw(&self, target: *mut Self); -} - -#[cfg(not(no_global_oom_handling))] -impl WriteCloneIntoRaw for T { - #[inline] - default unsafe fn write_clone_into_raw(&self, target: *mut Self) { - // Having allocated *first* may allow the optimizer to create - // the cloned value in-place, skipping the local and move. - unsafe { target.write(self.clone()) }; - } -} - -#[cfg(not(no_global_oom_handling))] -impl WriteCloneIntoRaw for T { - #[inline] - unsafe fn write_clone_into_raw(&self, target: *mut Self) { - // We can always copy in-place, without ever involving a local value. - unsafe { target.copy_from_nonoverlapping(self, 1) }; - } -} diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 01a954ed75b..1ec095a46f7 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -188,6 +188,8 @@ use core::any::Any; use core::async_iter::AsyncIterator; use core::borrow; +#[cfg(not(no_global_oom_handling))] +use core::clone::CloneToUninit; use core::cmp::Ordering; use core::error::Error; use core::fmt; @@ -207,7 +209,7 @@ use core::task::{Context, Poll}; #[cfg(not(no_global_oom_handling))] -use crate::alloc::{handle_alloc_error, WriteCloneIntoRaw}; +use crate::alloc::handle_alloc_error; use crate::alloc::{AllocError, Allocator, Global, Layout}; #[cfg(not(no_global_oom_handling))] use crate::borrow::Cow; @@ -1346,7 +1348,7 @@ fn clone(&self) -> Self { // Pre-allocate memory to allow writing the cloned value directly. let mut boxed = Self::new_uninit_in(self.1.clone()); unsafe { - (**self).write_clone_into_raw(boxed.as_mut_ptr()); + (**self).clone_to_uninit(boxed.as_mut_ptr()); boxed.assume_init() } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 022a14b931a..0f759d64f66 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -103,6 +103,7 @@ #![feature(assert_matches)] #![feature(async_fn_traits)] #![feature(async_iterator)] +#![feature(clone_to_uninit)] #![feature(coerce_unsized)] #![feature(const_align_of_val)] #![feature(const_box)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2b7ab2f6e25..f3a03698903 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -249,6 +249,8 @@ use core::any::Any; use core::borrow; use core::cell::Cell; +#[cfg(not(no_global_oom_handling))] +use core::clone::CloneToUninit; use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; @@ -268,8 +270,6 @@ #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; -#[cfg(not(no_global_oom_handling))] -use crate::alloc::WriteCloneIntoRaw; use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::borrow::{Cow, ToOwned}; #[cfg(not(no_global_oom_handling))] @@ -1810,7 +1810,7 @@ pub fn make_mut(this: &mut Self) -> &mut T { let mut rc = Self::new_uninit_in(this.alloc.clone()); unsafe { let data = Rc::get_mut_unchecked(&mut rc); - (**this).write_clone_into_raw(data.as_mut_ptr()); + (**this).clone_to_uninit(data.as_mut_ptr()); *this = rc.assume_init(); } } else if Rc::weak_count(this) != 0 { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index f9d884e0ea5..6570fab42be 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -10,6 +10,8 @@ use core::any::Any; use core::borrow; +#[cfg(not(no_global_oom_handling))] +use core::clone::CloneToUninit; use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; @@ -30,8 +32,6 @@ #[cfg(not(no_global_oom_handling))] use crate::alloc::handle_alloc_error; -#[cfg(not(no_global_oom_handling))] -use crate::alloc::WriteCloneIntoRaw; use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; @@ -2219,7 +2219,7 @@ pub fn make_mut(this: &mut Self) -> &mut T { let mut arc = Self::new_uninit_in(this.alloc.clone()); unsafe { let data = Arc::get_mut_unchecked(&mut arc); - (**this).write_clone_into_raw(data.as_mut_ptr()); + (**this).clone_to_uninit(data.as_mut_ptr()); *this = arc.assume_init(); } } else if this.inner().weak.load(Relaxed) != 1 {