@@ -2927,15 +2927,7 @@ impl<T> [T] {
29272927 where
29282928 T : Clone ,
29292929 {
2930- assert ! ( self . len( ) == src. len( ) , "destination and source slices have different lengths" ) ;
2931- // NOTE: We need to explicitly slice them to the same length
2932- // for bounds checking to be elided, and the optimizer will
2933- // generate memcpy for simple cases (for example T = u8).
2934- let len = self . len ( ) ;
2935- let src = & src[ ..len] ;
2936- for i in 0 ..len {
2937- self [ i] . clone_from ( & src[ i] ) ;
2938- }
2930+ self . spec_clone_from ( src) ;
29392931 }
29402932
29412933 /// Copies all elements from `src` into `self`, using a memcpy.
@@ -3440,6 +3432,36 @@ impl<T> [T] {
34403432 }
34413433}
34423434
3435+ trait CloneFromSpec < T > {
3436+ fn spec_clone_from ( & mut self , src : & [ T ] ) ;
3437+ }
3438+
3439+ impl < T > CloneFromSpec < T > for [ T ]
3440+ where
3441+ T : Clone ,
3442+ {
3443+ default fn spec_clone_from ( & mut self , src : & [ T ] ) {
3444+ assert ! ( self . len( ) == src. len( ) , "destination and source slices have different lengths" ) ;
3445+ // NOTE: We need to explicitly slice them to the same length
3446+ // to make it easier for the optimizer to elide bounds checking.
3447+ // But since it can't be relied on we also have an explicit specialization for T: Copy.
3448+ let len = self . len ( ) ;
3449+ let src = & src[ ..len] ;
3450+ for i in 0 ..len {
3451+ self [ i] . clone_from ( & src[ i] ) ;
3452+ }
3453+ }
3454+ }
3455+
3456+ impl < T > CloneFromSpec < T > for [ T ]
3457+ where
3458+ T : Copy ,
3459+ {
3460+ fn spec_clone_from ( & mut self , src : & [ T ] ) {
3461+ self . copy_from_slice ( src) ;
3462+ }
3463+ }
3464+
34433465#[ stable( feature = "rust1" , since = "1.0.0" ) ]
34443466impl < T > Default for & [ T ] {
34453467 /// Creates an empty slice.
0 commit comments