about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoshua Wong <joshuawong@anticentri.st>2024-10-09 14:24:05 -0400
committerJoshua Wong <joshuawong@anticentri.st>2024-10-10 09:50:35 -0400
commit5e474f7d83fc931f355cfdadf394313e57290050 (patch)
treecd5470a173b6c0b02b29338104e98ccef0aa99cc
parentdd0620b86721ae8cae86736443acd3f72ba6fc32 (diff)
downloadrust-5e474f7d83fc931f355cfdadf394313e57290050.tar.gz
rust-5e474f7d83fc931f355cfdadf394313e57290050.zip
allocate before calling T::default in <Arc<T>>::default()
Same rationale as in the previous commit.
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/sync.rs8
-rw-r--r--tests/codegen/placement-new.rs4
3 files changed, 10 insertions, 3 deletions
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index c60c0743c7e..dcfe96be755 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -104,6 +104,7 @@
 #![feature(async_closure)]
 #![feature(async_fn_traits)]
 #![feature(async_iterator)]
+#![feature(box_uninit_write)]
 #![feature(clone_to_uninit)]
 #![feature(coerce_unsized)]
 #![feature(const_align_of_val)]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 5d099a49854..0038750d25d 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -3447,7 +3447,13 @@ impl<T: Default> Default for Arc<T> {
     /// assert_eq!(*x, 0);
     /// ```
     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)) }
     }
 }
 
diff --git a/tests/codegen/placement-new.rs b/tests/codegen/placement-new.rs
index d5c7969dd19..edb25df5eb4 100644
--- a/tests/codegen/placement-new.rs
+++ b/tests/codegen/placement-new.rs
@@ -19,9 +19,9 @@ pub fn box_default_inplace() -> Box<(String, String)> {
 // CHECK-LABEL: @arc_default_inplace
 #[no_mangle]
 pub fn arc_default_inplace() -> Arc<(String, String)> {
-    // CHECK: [[ALLOCA:%.*]] = alloca
+    // CHECK-NOT: alloca
     // CHECK: [[ARC:%.*]] = {{.*}}call {{.*}}__rust_alloc(
-    // CHECK: call void @llvm.memcpy
+    // CHECK-NOT: call void @llvm.memcpy
     // CHECK: ret ptr [[ARC]]
     Arc::default()
 }