From df4b27ca4272e80b82c5a7f65f712b0fded82a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 19 Apr 2024 11:33:42 -0400 Subject: [PATCH] libstd: Use std::array::from_fn to implement Default for arrays larger than 32 elements. Much like #74060 did for every other trait. This avoids tools like rust-bindgen having to painfully work around this limitations, sometimes incorrectly like in https://github.com/rust-lang/rust-bindgen/issues/2803 --- library/core/src/array/mod.rs | 27 ++++--------------- library/core/src/primitive_docs.rs | 5 +--- .../core-traits-impls-length-32.rs | 4 +++ .../core-traits-impls-length-33.rs | 4 +++ 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 2a447aafe72d3..8ca3f5a3cd7c4 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -428,30 +428,13 @@ impl SpecArrayClone for T { } } -// The Default impls cannot be done with const generics because `[T; 0]` doesn't -// require Default to be implemented, and having different impl blocks for -// different numbers isn't supported yet. - -macro_rules! array_impl_default { - {$n:expr, $t:ident $($ts:ident)*} => { - #[stable(since = "1.4.0", feature = "array_default")] - impl Default for [T; $n] where T: Default { - fn default() -> [T; $n] { - [$t::default(), $($ts::default()),*] - } - } - array_impl_default!{($n - 1), $($ts)*} - }; - {$n:expr,} => { - #[stable(since = "1.4.0", feature = "array_default")] - impl Default for [T; $n] { - fn default() -> [T; $n] { [] } - } - }; +#[stable(feature = "default_array_lib", since = "1.79.0")] +impl Default for [T; N] where T: Default { + fn default() -> [T; N] { + from_fn::(|_| T::default()) + } } -array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} - impl [T; N] { /// Returns an array of the same size as `self`, with function `f` applied to each element /// in order. diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index e8e23f2a7ecc5..933aa65873e0b 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -589,16 +589,13 @@ mod prim_pointer {} /// - [`Copy`] /// - [`Clone`] /// - [`Debug`] +/// - [`Default`] /// - [`IntoIterator`] (implemented for `[T; N]`, `&[T; N]` and `&mut [T; N]`) /// - [`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] /// - [`Hash`] /// - [`AsRef`], [`AsMut`] /// - [`Borrow`], [`BorrowMut`] /// -/// Arrays of sizes from 0 to 32 (inclusive) implement the [`Default`] trait -/// if the element type allows it. As a stopgap, trait implementations are -/// statically generated up to size 32. -/// /// Arrays of sizes from 1 to 12 (inclusive) implement [`From`], where `Tuple` /// is a homogeneous [prim@tuple] of appropriate length. /// diff --git a/tests/ui/const-generics/array-impls/core-traits-impls-length-32.rs b/tests/ui/const-generics/array-impls/core-traits-impls-length-32.rs index fa907e3cae770..2f0d424223e08 100644 --- a/tests/ui/const-generics/array-impls/core-traits-impls-length-32.rs +++ b/tests/ui/const-generics/array-impls/core-traits-impls-length-32.rs @@ -63,4 +63,8 @@ pub fn yes_ord() -> impl Ord { [0; 32] } +pub fn yes_default() -> impl Default { + [0; 32] +} + fn main() {} diff --git a/tests/ui/const-generics/array-impls/core-traits-impls-length-33.rs b/tests/ui/const-generics/array-impls/core-traits-impls-length-33.rs index 768eb6308ce50..cce1d3cf59f19 100644 --- a/tests/ui/const-generics/array-impls/core-traits-impls-length-33.rs +++ b/tests/ui/const-generics/array-impls/core-traits-impls-length-33.rs @@ -63,4 +63,8 @@ pub fn yes_ord() -> impl Ord { [0; 33] } +pub fn yes_default() -> impl Default { + [0; 33] +} + fn main() {}