Skip to content

Commit 130fb24

Browse files
committed
specialize slice::clone_from_slice() for T: Copy
1 parent 43e1ea2 commit 130fb24

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
@@ -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")]
34443466
impl<T> Default for &[T] {
34453467
/// Creates an empty slice.

0 commit comments

Comments
 (0)