diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 71c49ee616cbc..53b7ae0703bf4 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1586,36 +1586,34 @@ impl<'a, T> IntoIterator for &'a mut Vec { impl Extend for Vec { #[inline] fn extend>(&mut self, iter: I) { - self.extend_desugared(iter.into_iter()) + self.spec_extend(iter.into_iter()) } } -trait IsTrustedLen : Iterator { - fn trusted_len(&self) -> Option { None } +trait SpecExtend { + fn spec_extend(&mut self, iter: I); } -impl IsTrustedLen for I where I: Iterator { } -impl IsTrustedLen for I where I: TrustedLen +impl SpecExtend for Vec + where I: Iterator, { - fn trusted_len(&self) -> Option { - let (low, high) = self.size_hint(); + default fn spec_extend(&mut self, iter: I) { + self.extend_desugared(iter) + } +} + +impl SpecExtend for Vec + where I: TrustedLen, +{ + fn spec_extend(&mut self, iterator: I) { + // This is the case for a TrustedLen iterator. + let (low, high) = iterator.size_hint(); if let Some(high_value) = high { debug_assert_eq!(low, high_value, "TrustedLen iterator's size hint is not exact: {:?}", (low, high)); } - high - } -} - -impl Vec { - fn extend_desugared>(&mut self, mut iterator: I) { - // This function should be the moral equivalent of: - // - // for item in iterator { - // self.push(item); - // } - if let Some(additional) = iterator.trusted_len() { + if let Some(additional) = high { self.reserve(additional); unsafe { let mut ptr = self.as_mut_ptr().offset(self.len() as isize); @@ -1628,17 +1626,30 @@ impl Vec { } } } else { - while let Some(element) = iterator.next() { - let len = self.len(); - if len == self.capacity() { - let (lower, _) = iterator.size_hint(); - self.reserve(lower.saturating_add(1)); - } - unsafe { - ptr::write(self.get_unchecked_mut(len), element); - // NB can't overflow since we would have had to alloc the address space - self.set_len(len + 1); - } + self.extend_desugared(iterator) + } + } +} + +impl Vec { + fn extend_desugared>(&mut self, mut iterator: I) { + // This is the case for a general iterator. + // + // This function should be the moral equivalent of: + // + // for item in iterator { + // self.push(item); + // } + while let Some(element) = iterator.next() { + let len = self.len(); + if len == self.capacity() { + let (lower, _) = iterator.size_hint(); + self.reserve(lower.saturating_add(1)); + } + unsafe { + ptr::write(self.get_unchecked_mut(len), element); + // NB can't overflow since we would have had to alloc the address space + self.set_len(len + 1); } } }