From 7cfe7b07b0e7394b22f9440a44ad9f017b53fe8e Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Fri, 9 Oct 2026 17:01:15 +0200 Subject: [PATCH 1/6] alloc: Unstably add `Vec::from_elem` and `Vec::from_elem_in` These methods are of particular interest for users because they perform better due to specialization, e.g. when `elem` is zero. In that case, it will result in a call to `calloc` or equivalent, which is better than a call to `malloc` followed by `memset`. We also forward the existing `std::vec::from_elem` and `std::vec::from_elem_in` to these new associated methods on `Vec`. The module-level methods could potentially be removed in a follow-up. --- library/alloc/src/vec/mod.rs | 58 ++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 8bcad62226a0b..2a99ec0480571 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3564,7 +3564,61 @@ where { } +impl Vec { + /// Create a new `Vec` that contains `elem` `n` times. + /// + /// This method requires `T` to implement [`Clone`], + /// in order to be able to clone the passed value. + /// + /// If `n` is zero, the vector will not allocate. + /// + /// # Panics + /// + /// Panics if `size_of::() * n` exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_from_elem)] + /// let vec = Vec::from_elem(0, 3); + /// assert_eq!(vec, [0; 3]); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "vec_from_elem", issue = "none")] + #[inline] + pub fn from_elem(elem: T, n: usize) -> Self { + ::from_elem(elem, n, Global) + } +} + impl Vec { + /// Create a new `Vec` with the provided allocator that contains `elem` `n` times. + /// + /// This method requires `T` to implement [`Clone`], + /// in order to be able to clone the passed value. + /// + /// If `n` is zero, the vector will not allocate. + /// + /// # Panics + /// + /// Panics if `size_of::() * n` exceeds `isize::MAX` bytes. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_ext)] + /// use std::alloc::System; + /// + /// let vec = Vec::from_elem_in(0, 3, System); + /// assert_eq!(vec, [0; 3]); + /// ``` + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[inline] + pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Self { + ::from_elem(elem, n, alloc) + } + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. /// /// If `new_len` is greater than `len`, the `Vec` is extended by the @@ -3801,14 +3855,14 @@ impl Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "vec_from_elem"] pub fn from_elem(elem: T, n: usize) -> Vec { - ::from_elem(elem, n, Global) + Vec::from_elem(elem, n) } #[doc(hidden)] #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec { - ::from_elem(elem, n, alloc) + Vec::from_elem_in(elem, n, alloc) } #[cfg(not(no_global_oom_handling))] From bc2387a22c7cd6cb785307fbb12e00f656b59188 Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Mon, 12 Oct 2026 16:42:36 +0200 Subject: [PATCH 2/6] Bless test --- tests/ui/suggestions/deref-path-method.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/suggestions/deref-path-method.stderr b/tests/ui/suggestions/deref-path-method.stderr index 8cf8ec9146d74..859e535d22c1e 100644 --- a/tests/ui/suggestions/deref-path-method.stderr +++ b/tests/ui/suggestions/deref-path-method.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec<_, _>` consider using one of the foll Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 7 others + and 9 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: the function `contains` is implemented on `[_]` | From ff731d75ea29d031e01bfaea0cd2d10b07bebe3b Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Mon, 12 Oct 2026 16:47:22 +0200 Subject: [PATCH 3/6] Put Vec::from_elem_in behind vec_from_elem feature --- library/alloc/src/vec/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 2a99ec0480571..911c447f4b04c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3613,7 +3613,7 @@ impl Vec { /// assert_eq!(vec, [0; 3]); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] + #[unstable(feature = "vec_from_elem", issue = "none")] #[inline] pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Self { ::from_elem(elem, n, alloc) From 96e1e2ae604df7da83242b46ac144fc5dd401eb3 Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Mon, 12 Oct 2026 16:47:46 +0200 Subject: [PATCH 4/6] Delete alloc::vec::from_elem_in --- library/alloc/src/vec/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 911c447f4b04c..1098f645dd347 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3858,13 +3858,6 @@ pub fn from_elem(elem: T, n: usize) -> Vec { Vec::from_elem(elem, n) } -#[doc(hidden)] -#[cfg(not(no_global_oom_handling))] -#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")] -pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec { - Vec::from_elem_in(elem, n, alloc) -} - #[cfg(not(no_global_oom_handling))] trait ExtendFromWithinSpec { /// # Safety From db623c8f4f35feb301a65dec2201afefb05dcec4 Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Mon, 12 Oct 2026 17:09:47 +0200 Subject: [PATCH 5/6] Link to tracking issue --- library/alloc/src/vec/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1098f645dd347..5ba45c780945f 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3584,7 +3584,7 @@ impl Vec { /// assert_eq!(vec, [0; 3]); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "vec_from_elem", issue = "none")] + #[unstable(feature = "vec_from_elem", issue = "164215")] #[inline] pub fn from_elem(elem: T, n: usize) -> Self { ::from_elem(elem, n, Global) @@ -3613,7 +3613,7 @@ impl Vec { /// assert_eq!(vec, [0; 3]); /// ``` #[cfg(not(no_global_oom_handling))] - #[unstable(feature = "vec_from_elem", issue = "none")] + #[unstable(feature = "vec_from_elem", issue = "164215")] #[inline] pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Self { ::from_elem(elem, n, alloc) From 9c0a9c69a4b8847c6ef3493a6d24a7d477d86ea8 Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Mon, 12 Oct 2026 17:45:05 +0200 Subject: [PATCH 6/6] Use the correct feature in the doctest --- library/alloc/src/vec/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 5ba45c780945f..cdae4e87d2aab 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3606,7 +3606,7 @@ impl Vec { /// # Examples /// /// ``` - /// #![feature(allocator_ext)] + /// #![feature(vec_from_elem)] /// use std::alloc::System; /// /// let vec = Vec::from_elem_in(0, 3, System);