about summary refs log tree commit diff
path: root/library/alloc/src
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:49:24 -0400
commitdd0620b86721ae8cae86736443acd3f72ba6fc32 (patch)
tree42eeb2a8ef0bfb161566045fe9c6e868071cc370 /library/alloc/src
parent8a1462265f839607f96acea4bed183736598422d (diff)
allocate before calling T::default in <Box<T>>::default()
The `Box<T: Default>` impl currently calls `T::default()` before allocating
the `Box`.

Most `Default` impls are trivial, which should in theory allow
LLVM to construct `T: Default` directly in the `Box` allocation when calling
`<Box<T>>::default()`.

However, the allocation may fail, which necessitates calling `T's` destructor if it has one.
If the destructor is non-trivial, then LLVM has a hard time proving that it's
sound to elide, which makes it construct `T` on the stack first, and then copy it into the allocation.

Create an uninit `Box` first, and then write `T::default` into it, so that LLVM now only needs to prove
that the `T::default` can't panic, which should be trivial for most `Default` impls.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/boxed.rs2
1 files changed, 1 insertions, 1 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 5f207295683..3e791416820 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1688,7 +1688,7 @@ impl<T: Default> Default for Box<T> {
     /// Creates a `Box<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> Self {
-        Box::new(T::default())
+        Box::write(Box::new_uninit(), T::default())
     }
 }