Skip to content

Commit 3158857

Browse files
committed
Auto merge of rust-lang#81854 - the8472:specialize-clone-slice, r=Mark-Simulacrum
specialize slice::clone_from_slice() for T: Copy
2 parents dd4851d + 130fb24 commit 3158857

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

library/core/src/slice/mod.rs

+31-9
Original file line numberDiff line numberDiff line change
@@ -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")]
34653487
impl<T> Default for &[T] {
34663488
/// Creates an empty slice.

0 commit comments

Comments
 (0)