allocate before calling T::default in <Arc<T>>::default()

Same rationale as in the previous commit.
This commit is contained in:
Joshua Wong 2024-10-09 14:24:05 -04:00
parent dd0620b867
commit 5e474f7d83
3 changed files with 10 additions and 3 deletions

View File

@ -104,6 +104,7 @@
#![feature(async_closure)] #![feature(async_closure)]
#![feature(async_fn_traits)] #![feature(async_fn_traits)]
#![feature(async_iterator)] #![feature(async_iterator)]
#![feature(box_uninit_write)]
#![feature(clone_to_uninit)] #![feature(clone_to_uninit)]
#![feature(coerce_unsized)] #![feature(coerce_unsized)]
#![feature(const_align_of_val)] #![feature(const_align_of_val)]

View File

@ -3447,7 +3447,13 @@ impl<T: Default> Default for Arc<T> {
/// assert_eq!(*x, 0); /// assert_eq!(*x, 0);
/// ``` /// ```
fn default() -> Arc<T> { fn default() -> Arc<T> {
Arc::new(Default::default()) let x = Box::into_raw(Box::write(Box::new_uninit(), ArcInner {
strong: atomic::AtomicUsize::new(1),
weak: atomic::AtomicUsize::new(1),
data: T::default(),
}));
// SAFETY: `Box::into_raw` consumes the `Box` and never returns null
unsafe { Self::from_inner(NonNull::new_unchecked(x)) }
} }
} }

View File

@ -19,9 +19,9 @@ pub fn box_default_inplace() -> Box<(String, String)> {
// CHECK-LABEL: @arc_default_inplace // CHECK-LABEL: @arc_default_inplace
#[no_mangle] #[no_mangle]
pub fn arc_default_inplace() -> Arc<(String, String)> { pub fn arc_default_inplace() -> Arc<(String, String)> {
// CHECK: [[ALLOCA:%.*]] = alloca // CHECK-NOT: alloca
// CHECK: [[ARC:%.*]] = {{.*}}call {{.*}}__rust_alloc( // CHECK: [[ARC:%.*]] = {{.*}}call {{.*}}__rust_alloc(
// CHECK: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy
// CHECK: ret ptr [[ARC]] // CHECK: ret ptr [[ARC]]
Arc::default() Arc::default()
} }