Skip to content

Commit ba80c66

Browse files
committed
slice: Add a specialization for clone_into when T is Copy
The implementation for the ToOwned::clone_into method on [T] is a copy of the code for vec::clone_from. In 3613980 the code for vec::clone_from gained a specialization for when T is Copy. This commit copies that specialization over to the clone_into implementation.
1 parent d6f0642 commit ba80c66

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

library/alloc/src/slice.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,38 @@ impl<T, A: Allocator> BorrowMut<[T]> for Vec<T, A> {
782782
}
783783
}
784784

785+
// Specializable trait for implementing ToOwned::clone_into. This is
786+
// public in the crate and has the Allocator parameter so that
787+
// vec::clone_from use it too.
788+
#[cfg(not(no_global_oom_handling))]
789+
pub(crate) trait SpecCloneIntoVec<T, A: Allocator> {
790+
fn clone_into(&self, target: &mut Vec<T, A>);
791+
}
792+
793+
#[cfg(not(no_global_oom_handling))]
794+
impl<T: Clone, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
795+
default fn clone_into(&self, target: &mut Vec<T, A>) {
796+
// drop anything in target that will not be overwritten
797+
target.truncate(self.len());
798+
799+
// target.len <= self.len due to the truncate above, so the
800+
// slices here are always in-bounds.
801+
let (init, tail) = self.split_at(target.len());
802+
803+
// reuse the contained values' allocations/resources.
804+
target.clone_from_slice(init);
805+
target.extend_from_slice(tail);
806+
}
807+
}
808+
809+
#[cfg(not(no_global_oom_handling))]
810+
impl<T: Copy, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
811+
fn clone_into(&self, target: &mut Vec<T, A>) {
812+
target.clear();
813+
target.extend_from_slice(self);
814+
}
815+
}
816+
785817
#[cfg(not(no_global_oom_handling))]
786818
#[stable(feature = "rust1", since = "1.0.0")]
787819
impl<T: Clone> ToOwned for [T] {
@@ -797,16 +829,7 @@ impl<T: Clone> ToOwned for [T] {
797829
}
798830

799831
fn clone_into(&self, target: &mut Vec<T>) {
800-
// drop anything in target that will not be overwritten
801-
target.truncate(self.len());
802-
803-
// target.len <= self.len due to the truncate above, so the
804-
// slices here are always in-bounds.
805-
let (init, tail) = self.split_at(target.len());
806-
807-
// reuse the contained values' allocations/resources.
808-
target.clone_from_slice(init);
809-
target.extend_from_slice(tail);
832+
SpecCloneIntoVec::clone_into(self, target);
810833
}
811834
}
812835

0 commit comments

Comments
 (0)