@@ -353,28 +353,60 @@ impl<T: Ord, const N: usize> Ord for [T; N] {
353353 }
354354}
355355
356- // The Default impls cannot be generated using the array_impls! macro because
357- // they require array literals.
358-
359- macro_rules! array_impl_default {
360- { $n: expr, $t: ident $( $ts: ident) * } => {
361- #[ stable( since = "1.4.0" , feature = "array_default" ) ]
362- impl <T > Default for [ T ; $n] where T : Default {
363- fn default ( ) -> [ T ; $n] {
364- [ $t:: default ( ) , $( $ts:: default ( ) ) ,* ]
365- }
356+ /// This module implements `Default` for arrays.
357+ mod default_impls {
358+ // A trait implemented by all arrays which are either empty or contain a type implementing `Default`.
359+ #[ unstable(
360+ feature = "array_default_internals" ,
361+ reason = "implementation detail" ,
362+ issue = "none"
363+ ) ]
364+ #[ marker]
365+ pub trait ArrayDefault { }
366+
367+ #[ unstable(
368+ feature = "array_default_internals" ,
369+ reason = "implementation detail" ,
370+ issue = "none"
371+ ) ]
372+ impl < T > ArrayDefault for [ T ; 0 ] { }
373+
374+ #[ unstable(
375+ feature = "array_default_internals" ,
376+ reason = "implementation detail" ,
377+ issue = "none"
378+ ) ]
379+ impl < T : Default , const N : usize > ArrayDefault for [ T ; N ] { }
380+
381+ trait DefaultHack {
382+ fn default_hack ( ) -> Self ;
383+ }
384+
385+ impl < T > DefaultHack for T {
386+ default fn default_hack ( ) -> Self {
387+ unreachable ! ( ) ;
366388 }
367- array_impl_default!{ ( $n - 1 ) , $( $ts) * }
368- } ;
369- { $n: expr, } => {
370- #[ stable( since = "1.4.0" , feature = "array_default" ) ]
371- impl <T > Default for [ T ; $n] {
372- fn default ( ) -> [ T ; $n] { [ ] }
389+ }
390+
391+ impl < T : Default > DefaultHack for T {
392+ fn default_hack ( ) -> Self {
393+ Default :: default ( )
373394 }
374- } ;
395+ }
396+ #[ stable( since = "1.4.0" , feature = "array_default" ) ]
397+ impl < T , const N : usize > Default for [ T ; N ]
398+ where
399+ [ T ; N ] : ArrayDefault ,
400+ {
401+ fn default ( ) -> [ T ; N ] {
402+ assert_eq ! ( std:: mem:: size_of:: <[ ( ) ; N ] >( ) , 0 ) ;
403+ // SAFETY: it is always valid to use `ceroed` for zero-sized value.
404+ let arr: [ ( ) ; N ] = unsafe { std:: mem:: zeroed ( ) } ;
405+ arr. map ( DefaultHack :: default_hack)
406+ }
407+ }
375408}
376409
377- 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 }
378410
379411#[ lang = "array" ]
380412impl < T , const N : usize > [ T ; N ] {
0 commit comments