Skip to content

Commit 0d93262

Browse files
committed
Specialize array cloning for Copy types
Because after PR 86041, the optimizer no longer load-merges at the LLVM IR level, which might be part of the perf loss. (I'll run perf and see if this makes a difference.) Also I added a codegen test so this hopefully won't regress in future -- it passes on stable and with my change here, but not on the 2021-11-09 nightly.
1 parent c82b043 commit 0d93262

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

core/src/array/mod.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,7 @@ impl<T: Copy, const N: usize> Copy for [T; N] {}
339339
impl<T: Clone, const N: usize> Clone for [T; N] {
340340
#[inline]
341341
fn clone(&self) -> Self {
342-
// SAFETY: we know for certain that this iterator will yield exactly `N`
343-
// items.
344-
unsafe { collect_into_array_unchecked(&mut self.iter().cloned()) }
342+
SpecArrayClone::clone(self)
345343
}
346344

347345
#[inline]
@@ -350,6 +348,27 @@ impl<T: Clone, const N: usize> Clone for [T; N] {
350348
}
351349
}
352350

351+
#[cfg(not(bootstrap))]
352+
trait SpecArrayClone: Clone {
353+
fn clone<const N: usize>(array: &[Self; N]) -> [Self; N];
354+
}
355+
356+
#[cfg(not(bootstrap))]
357+
impl<T: Clone> SpecArrayClone for T {
358+
default fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
359+
// SAFETY: we know for certain that this iterator will yield exactly `N`
360+
// items.
361+
unsafe { collect_into_array_unchecked(&mut array.iter().cloned()) }
362+
}
363+
}
364+
365+
#[cfg(not(bootstrap))]
366+
impl<T: Copy> SpecArrayClone for T {
367+
fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
368+
*array
369+
}
370+
}
371+
353372
// The Default impls cannot be done with const generics because `[T; 0]` doesn't
354373
// require Default to be implemented, and having different impl blocks for
355374
// different numbers isn't supported yet.

0 commit comments

Comments
 (0)