@@ -2944,15 +2944,7 @@ impl<T> [T] {
29442944 where
29452945 T : Clone ,
29462946 {
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) ;
29562948 }
29572949
29582950 /// Copies all elements from `src` into `self`, using a memcpy.
@@ -3461,6 +3453,36 @@ impl<T> [T] {
34613453 }
34623454}
34633455
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+
34643486#[ stable( feature = "rust1" , since = "1.0.0" ) ]
34653487impl < T > Default for & [ T ] {
34663488 /// Creates an empty slice.
0 commit comments