about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPetr Portnov <me@progrm-jarvis.ru>2023-11-20 16:47:32 +0300
committerPetr Portnov <me@progrm-jarvis.ru>2023-11-20 18:29:09 +0300
commit2fd9442afca446af8084c8b15feba2daa2fb4bb6 (patch)
tree04262afe8f40817b6d83c6a769489dec5918ab1b
parent79e961fa728e543e9b4f8b44f6bc2550ea867d4d (diff)
downloadrust-2fd9442afca446af8084c8b15feba2daa2fb4bb6.tar.gz
rust-2fd9442afca446af8084c8b15feba2daa2fb4bb6.zip
feat: specialize `SpecFromElem` for `()`
While a better approach would be to implement it for all ZSTs
which are `Copy` and have trivial `Clone`,
the last property cannot be detected for now.

Signed-off-by: Petr Portnov <me@progrm-jarvis.ru>
-rw-r--r--library/alloc/src/vec/spec_from_elem.rs23
1 files changed, 19 insertions, 4 deletions
diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs
index da43d17bf36..4e4150d9435 100644
--- a/library/alloc/src/vec/spec_from_elem.rs
+++ b/library/alloc/src/vec/spec_from_elem.rs
@@ -36,12 +36,12 @@ impl SpecFromElem for i8 {
         if elem == 0 {
             return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
         }
+        let mut v = Vec::with_capacity_in(n, alloc);
         unsafe {
-            let mut v = Vec::with_capacity_in(n, alloc);
             ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
             v.set_len(n);
-            v
         }
+        v
     }
 }
 
@@ -51,11 +51,26 @@ impl SpecFromElem for u8 {
         if elem == 0 {
             return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
         }
+        let mut v = Vec::with_capacity_in(n, alloc);
         unsafe {
-            let mut v = Vec::with_capacity_in(n, alloc);
             ptr::write_bytes(v.as_mut_ptr(), elem, n);
             v.set_len(n);
-            v
         }
+        v
+    }
+}
+
+// A better way would be to implement this for all ZSTs which are `Copy` and have trivial `Clone`
+// but this cannot be implemented currently
+impl SpecFromElem for () {
+    #[inline]
+    fn from_elem<A: Allocator>(elem: (), n: usize, alloc: A) -> Vec<(), A> {
+        let mut v = Vec::with_capacity_in(n, alloc);
+        // SAFETY: the capacity has just been set to `n` and `()`
+        // is a ZST with trivial `Clone` implementation
+        unsafe {
+            v.set_len(n);
+        }
+        v
     }
 }