From 2fd9442afca446af8084c8b15feba2daa2fb4bb6 Mon Sep 17 00:00:00 2001 From: Petr Portnov Date: Mon, 20 Nov 2023 16:47:32 +0300 Subject: [PATCH 1/3] 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 --- library/alloc/src/vec/spec_from_elem.rs | 23 +++++++++++++++++++---- 1 file 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(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 } } From 91fcdde51b477e8def5e8cca2807a2dc12c8f06d Mon Sep 17 00:00:00 2001 From: Petr Portnov Date: Mon, 20 Nov 2023 18:33:55 +0300 Subject: [PATCH 2/3] chore(GH-118094): explicitly mark `_elem` as unused Signed-off-by: Petr Portnov --- library/alloc/src/vec/spec_from_elem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs index 4e4150d9435..63225b41cbd 100644 --- a/library/alloc/src/vec/spec_from_elem.rs +++ b/library/alloc/src/vec/spec_from_elem.rs @@ -64,7 +64,7 @@ impl SpecFromElem for u8 { // but this cannot be implemented currently impl SpecFromElem for () { #[inline] - fn from_elem(elem: (), n: usize, alloc: A) -> Vec<(), A> { + fn from_elem(_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 From 72a8633ee8ab8986ab32fb29c2ebd9e2d98c723b Mon Sep 17 00:00:00 2001 From: Petr Portnov Date: Mon, 20 Nov 2023 18:35:04 +0300 Subject: [PATCH 3/3] docs(GH-118094): make docs a bit more explicit Signed-off-by: Petr Portnov --- library/alloc/src/vec/spec_from_elem.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs index 63225b41cbd..01a6db14474 100644 --- a/library/alloc/src/vec/spec_from_elem.rs +++ b/library/alloc/src/vec/spec_from_elem.rs @@ -61,13 +61,13 @@ impl SpecFromElem for u8 { } // A better way would be to implement this for all ZSTs which are `Copy` and have trivial `Clone` -// but this cannot be implemented currently +// but the latter cannot be detected currently impl SpecFromElem for () { #[inline] fn from_elem(_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 + // SAFETY: the capacity has just been set to `n` + // and `()` is a ZST with trivial `Clone` implementation unsafe { v.set_len(n); }