diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 2825e0bbb4385..79cdc16009737 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -440,32 +440,23 @@ 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")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for [T; $n] where T: ~const 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")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for [T; $n] { - fn default() -> [T; $n] { [] } +#[stable(since = "1.67.0", feature = "array_default")] +impl Default for [T; N] +where + T: Default, +{ + fn default() -> Self { + // SAFETY: Array is initialized in the following line. + let mut arr: [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; + for elem in &mut arr[..] { + elem.write(T::default()); } - }; + // SAFETY: Manually drop the MaybeUninit array before returning the + // newly defaulted and initialized array. + unsafe { mem::transmute_copy(&mem::ManuallyDrop::new(arr)) } + } } -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/tests/array.rs b/library/core/tests/array.rs index f268fe3ae7ba8..644a05848b4a5 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -305,6 +305,18 @@ fn empty_array_is_always_default() { let _arr = <[DoesNotImplDefault; 0]>::default(); } +#[test] +fn all_arrays_are_generic_also_default() { + let _arr = <[u8; 1]>::default(); + let _arr = <[u8; 2]>::default(); + let _arr = <[u8; 4]>::default(); + let _arr = <[u8; 8]>::default(); + let _arr = <[u8; 16]>::default(); + let _arr = <[u8; 32]>::default(); + let _arr = <[u8; 64]>::default(); + let _arr = <[u8; 1337]>::default(); +} + #[test] fn array_map() { let a = [1, 2, 3];