diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index ce7ea2058b5..ffd6f5b31d4 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -2080,7 +2080,16 @@ impl<'a, T> IntoIterator for &'a mut Vec { impl Extend for Vec { #[inline] fn extend>(&mut self, iter: I) { - >::spec_extend(self, iter.into_iter()) + if self.capacity() > 0 { + >::spec_extend(self, iter.into_iter()) + } else { + // if self has no allocation then use the more powerful from_iter specializations + let other = SpecFrom::from_iter(iter.into_iter()); + // replace self, don't run drop since self was empty + unsafe { + ptr::write(self, other); + } + } } #[inline] @@ -2121,6 +2130,8 @@ where vector } }; + // must delegate to spec_extend() since extend() itself delegates + // to spec_from for empty Vecs as SpecExtend>::spec_extend(&mut vector, iterator); vector } @@ -2230,7 +2241,9 @@ impl SpecFrom> for Vec { } let mut vec = Vec::new(); - vec.extend(iterator); + // must delegate to spec_extend() since extend() itself delegates + // to spec_from for empty Vecs + vec.spec_extend(iterator); vec } } @@ -2475,7 +2488,16 @@ impl Vec { #[stable(feature = "extend_ref", since = "1.2.0")] impl<'a, T: 'a + Copy> Extend<&'a T> for Vec { fn extend>(&mut self, iter: I) { - self.spec_extend(iter.into_iter()) + if self.capacity() > 0 { + self.spec_extend(iter.into_iter()) + } else { + // if self has no allocation then use the more powerful from_iter specializations + let other = SpecFrom::from_iter(iter.into_iter()); + // replace self, don't run drop since self was empty + unsafe { + ptr::write(self, other); + } + } } #[inline]