diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 5477a1f6331..24f8e3a2d91 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1499,26 +1499,7 @@ impl ops::DerefMut for Vec { impl FromIterator for Vec { #[inline] fn from_iter>(iter: I) -> Vec { - // Unroll the first iteration, as the vector is going to be - // expanded on this iteration in every case when the iterable is not - // empty, but the loop in extend_desugared() is not going to see the - // vector being full in the few subsequent loop iterations. - // So we get better branch prediction. - let mut iterator = iter.into_iter(); - let mut vector = match iterator.next() { - None => return Vec::new(), - Some(element) => { - let (lower, _) = iterator.size_hint(); - let mut vector = Vec::with_capacity(lower.saturating_add(1)); - unsafe { - ptr::write(vector.get_unchecked_mut(0), element); - vector.set_len(1); - } - vector - } - }; - vector.extend(iterator); - vector + >::from_iter(iter.into_iter()) } } @@ -1590,13 +1571,37 @@ impl Extend for Vec { } } +// Specialization trait used for Vec::from_iter and Vec::extend trait SpecExtend { + fn from_iter(iter: I) -> Self; fn spec_extend(&mut self, iter: I); } impl SpecExtend for Vec where I: Iterator, { + default fn from_iter(mut iterator: I) -> Self { + // Unroll the first iteration, as the vector is going to be + // expanded on this iteration in every case when the iterable is not + // empty, but the loop in extend_desugared() is not going to see the + // vector being full in the few subsequent loop iterations. + // So we get better branch prediction. + let mut vector = match iterator.next() { + None => return Vec::new(), + Some(element) => { + let (lower, _) = iterator.size_hint(); + let mut vector = Vec::with_capacity(lower.saturating_add(1)); + unsafe { + ptr::write(vector.get_unchecked_mut(0), element); + vector.set_len(1); + } + vector + } + }; + vector.spec_extend(iterator); + vector + } + default fn spec_extend(&mut self, iter: I) { self.extend_desugared(iter) } @@ -1605,6 +1610,12 @@ impl SpecExtend for Vec impl SpecExtend for Vec where I: TrustedLen, { + fn from_iter(iterator: I) -> Self { + let mut vector = Vec::new(); + vector.spec_extend(iterator); + vector + } + fn spec_extend(&mut self, iterator: I) { // This is the case for a TrustedLen iterator. let (low, high) = iterator.size_hint();