Skip to content

Commit 7537f95

Browse files
committed
Auto merge of #38182 - bluss:more-vec-extend, r=alexcrichton
Specialization for Extend<&T> for vec Specialize to use copy_from_slice when extending a Vec with &[T] where T: Copy. This specialization results in `.clone()` not being called in `extend_from_slice` and `extend` when the element is `Copy`. Fixes #38021
2 parents 47ffafc + 02bf1ce commit 7537f95

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

src/libcollections/vec.rs

+33-6
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ impl<T: Clone> Vec<T> {
12441244
/// ```
12451245
#[stable(feature = "vec_extend_from_slice", since = "1.6.0")]
12461246
pub fn extend_from_slice(&mut self, other: &[T]) {
1247-
self.extend(other.iter().cloned())
1247+
self.spec_extend(other.iter())
12481248
}
12491249
}
12501250

@@ -1499,7 +1499,7 @@ impl<T> ops::DerefMut for Vec<T> {
14991499
impl<T> FromIterator<T> for Vec<T> {
15001500
#[inline]
15011501
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> {
1502-
<Self as SpecExtend<_>>::from_iter(iter.into_iter())
1502+
<Self as SpecExtend<_, _>>::from_iter(iter.into_iter())
15031503
}
15041504
}
15051505

@@ -1572,12 +1572,12 @@ impl<T> Extend<T> for Vec<T> {
15721572
}
15731573

15741574
// Specialization trait used for Vec::from_iter and Vec::extend
1575-
trait SpecExtend<I> {
1575+
trait SpecExtend<T, I> {
15761576
fn from_iter(iter: I) -> Self;
15771577
fn spec_extend(&mut self, iter: I);
15781578
}
15791579

1580-
impl<I, T> SpecExtend<I> for Vec<T>
1580+
impl<T, I> SpecExtend<T, I> for Vec<T>
15811581
where I: Iterator<Item=T>,
15821582
{
15831583
default fn from_iter(mut iterator: I) -> Self {
@@ -1607,7 +1607,7 @@ impl<I, T> SpecExtend<I> for Vec<T>
16071607
}
16081608
}
16091609

1610-
impl<I, T> SpecExtend<I> for Vec<T>
1610+
impl<T, I> SpecExtend<T, I> for Vec<T>
16111611
where I: TrustedLen<Item=T>,
16121612
{
16131613
fn from_iter(iterator: I) -> Self {
@@ -1642,6 +1642,33 @@ impl<I, T> SpecExtend<I> for Vec<T>
16421642
}
16431643
}
16441644

1645+
impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec<T>
1646+
where I: Iterator<Item=&'a T>,
1647+
T: Clone,
1648+
{
1649+
default fn from_iter(iterator: I) -> Self {
1650+
SpecExtend::from_iter(iterator.cloned())
1651+
}
1652+
1653+
default fn spec_extend(&mut self, iterator: I) {
1654+
self.spec_extend(iterator.cloned())
1655+
}
1656+
}
1657+
1658+
impl<'a, T: 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T>
1659+
where T: Copy,
1660+
{
1661+
fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
1662+
let slice = iterator.as_slice();
1663+
self.reserve(slice.len());
1664+
unsafe {
1665+
let len = self.len();
1666+
self.set_len(len + slice.len());
1667+
self.get_unchecked_mut(len..).copy_from_slice(slice);
1668+
}
1669+
}
1670+
}
1671+
16451672
impl<T> Vec<T> {
16461673
fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
16471674
// This is the case for a general iterator.
@@ -1669,7 +1696,7 @@ impl<T> Vec<T> {
16691696
#[stable(feature = "extend_ref", since = "1.2.0")]
16701697
impl<'a, T: 'a + Copy> Extend<&'a T> for Vec<T> {
16711698
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1672-
self.extend(iter.into_iter().map(|&x| x))
1699+
self.spec_extend(iter.into_iter())
16731700
}
16741701
}
16751702

0 commit comments

Comments
 (0)