@@ -353,28 +353,60 @@ impl<T: Ord, const N: usize> Ord for [T; N] {
353
353
}
354
354
}
355
355
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 ! ( ) ;
366
388
}
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 ( )
373
394
}
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
+ }
375
408
}
376
409
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 }
378
410
379
411
#[ lang = "array" ]
380
412
impl < T , const N : usize > [ T ; N ] {
0 commit comments