@@ -2944,15 +2944,7 @@ impl<T> [T] {
2944
2944
where
2945
2945
T : Clone ,
2946
2946
{
2947
- assert ! ( self . len( ) == src. len( ) , "destination and source slices have different lengths" ) ;
2948
- // NOTE: We need to explicitly slice them to the same length
2949
- // for bounds checking to be elided, and the optimizer will
2950
- // generate memcpy for simple cases (for example T = u8).
2951
- let len = self . len ( ) ;
2952
- let src = & src[ ..len] ;
2953
- for i in 0 ..len {
2954
- self [ i] . clone_from ( & src[ i] ) ;
2955
- }
2947
+ self . spec_clone_from ( src) ;
2956
2948
}
2957
2949
2958
2950
/// Copies all elements from `src` into `self`, using a memcpy.
@@ -3461,6 +3453,36 @@ impl<T> [T] {
3461
3453
}
3462
3454
}
3463
3455
3456
+ trait CloneFromSpec < T > {
3457
+ fn spec_clone_from ( & mut self , src : & [ T ] ) ;
3458
+ }
3459
+
3460
+ impl < T > CloneFromSpec < T > for [ T ]
3461
+ where
3462
+ T : Clone ,
3463
+ {
3464
+ default fn spec_clone_from ( & mut self , src : & [ T ] ) {
3465
+ assert ! ( self . len( ) == src. len( ) , "destination and source slices have different lengths" ) ;
3466
+ // NOTE: We need to explicitly slice them to the same length
3467
+ // to make it easier for the optimizer to elide bounds checking.
3468
+ // But since it can't be relied on we also have an explicit specialization for T: Copy.
3469
+ let len = self . len ( ) ;
3470
+ let src = & src[ ..len] ;
3471
+ for i in 0 ..len {
3472
+ self [ i] . clone_from ( & src[ i] ) ;
3473
+ }
3474
+ }
3475
+ }
3476
+
3477
+ impl < T > CloneFromSpec < T > for [ T ]
3478
+ where
3479
+ T : Copy ,
3480
+ {
3481
+ fn spec_clone_from ( & mut self , src : & [ T ] ) {
3482
+ self . copy_from_slice ( src) ;
3483
+ }
3484
+ }
3485
+
3464
3486
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3465
3487
impl < T > Default for & [ T ] {
3466
3488
/// Creates an empty slice.
0 commit comments