@@ -68,7 +68,7 @@ use core::cmp::Ordering;
68
68
use core:: fmt;
69
69
use core:: hash:: { self , Hash } ;
70
70
use core:: intrinsics:: { arith_offset, assume} ;
71
- use core:: iter:: { FromIterator , FusedIterator } ;
71
+ use core:: iter:: { FromIterator , FusedIterator , TrustedLen } ;
72
72
use core:: mem;
73
73
use core:: ops:: { Index , IndexMut } ;
74
74
use core:: ops;
@@ -1589,23 +1589,49 @@ impl<T> SpecExtend<Vec<T>> for Vec<T> {
1589
1589
}
1590
1590
}
1591
1591
1592
+ trait IsTrustedLen : Iterator {
1593
+ fn trusted_len ( & self ) -> Option < usize > { None }
1594
+ }
1595
+ impl < I > IsTrustedLen for I where I : Iterator { }
1596
+
1597
+ impl < I > IsTrustedLen for I where I : TrustedLen
1598
+ {
1599
+ fn trusted_len ( & self ) -> Option < usize > {
1600
+ self . size_hint ( ) . 1
1601
+ }
1602
+ }
1603
+
1592
1604
impl < T > Vec < T > {
1593
1605
fn extend_desugared < I : Iterator < Item = T > > ( & mut self , mut iterator : I ) {
1594
1606
// This function should be the moral equivalent of:
1595
1607
//
1596
1608
// for item in iterator {
1597
1609
// self.push(item);
1598
1610
// }
1599
- while let Some ( element) = iterator. next ( ) {
1600
- let len = self . len ( ) ;
1601
- if len == self . capacity ( ) {
1602
- let ( lower, _) = iterator. size_hint ( ) ;
1603
- self . reserve ( lower. saturating_add ( 1 ) ) ;
1604
- }
1611
+ if let Some ( additional) = iterator. trusted_len ( ) {
1612
+ self . reserve ( additional) ;
1605
1613
unsafe {
1606
- ptr:: write ( self . get_unchecked_mut ( len) , element) ;
1607
- // NB can't overflow since we would have had to alloc the address space
1608
- self . set_len ( len + 1 ) ;
1614
+ let mut ptr = self . as_mut_ptr ( ) . offset ( self . len ( ) as isize ) ;
1615
+ let mut local_len = SetLenOnDrop :: new ( & mut self . len ) ;
1616
+ for element in iterator {
1617
+ ptr:: write ( ptr, element) ;
1618
+ ptr = ptr. offset ( 1 ) ;
1619
+ // NB can't overflow since we would have had to alloc the address space
1620
+ local_len. increment_len ( 1 ) ;
1621
+ }
1622
+ }
1623
+ } else {
1624
+ while let Some ( element) = iterator. next ( ) {
1625
+ let len = self . len ( ) ;
1626
+ if len == self . capacity ( ) {
1627
+ let ( lower, _) = iterator. size_hint ( ) ;
1628
+ self . reserve ( lower. saturating_add ( 1 ) ) ;
1629
+ }
1630
+ unsafe {
1631
+ ptr:: write ( self . get_unchecked_mut ( len) , element) ;
1632
+ // NB can't overflow since we would have had to alloc the address space
1633
+ self . set_len ( len + 1 ) ;
1634
+ }
1609
1635
}
1610
1636
}
1611
1637
}
0 commit comments