@@ -1383,7 +1383,7 @@ impl<T> ops::DerefMut for Vec<T> {
1383
1383
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1384
1384
impl < T > FromIterator < T > for Vec < T > {
1385
1385
#[ inline]
1386
- fn from_iter < I : Iterator < Item =T > > ( iterator : I ) -> Vec < T > {
1386
+ fn from_iter < I : Iterator < Item =T > > ( mut iterator : I ) -> Vec < T > {
1387
1387
let ( lower, _) = iterator. size_hint ( ) ;
1388
1388
let mut vector = Vec :: with_capacity ( lower) ;
1389
1389
@@ -1393,22 +1393,31 @@ impl<T> FromIterator<T> for Vec<T> {
1393
1393
// vector.push(item);
1394
1394
// }
1395
1395
//
1396
- // This equivalent crucially runs the iterator precisely once. The
1397
- // optimization below (eliding bound/growth checks) means that we
1398
- // actually run the iterator twice. To ensure the "moral equivalent" we
1399
- // do a `fuse()` operation to ensure that the iterator continues to
1400
- // return `None` after seeing the first `None`.
1401
- let mut i = iterator. fuse ( ) ;
1402
- for element in i. by_ref ( ) . take ( vector. capacity ( ) ) {
1396
+ // This equivalent crucially runs the iterator precisely once. Below we
1397
+ // actually in theory run the iterator twice (one without bounds checks
1398
+ // and one with). To achieve the "moral equivalent", we use the `if`
1399
+ // statement below to break out early.
1400
+ //
1401
+ // If the first loop has terminated, then we have one of two conditions.
1402
+ //
1403
+ // 1. The underlying iterator returned `None`. In this case we are
1404
+ // guaranteed that less than `vector.capacity()` elements have been
1405
+ // returned, so we break out early.
1406
+ // 2. The underlying iterator yielded `vector.capacity()` elements and
1407
+ // has not yielded `None` yet. In this case we run the iterator to
1408
+ // its end below.
1409
+ for element in iterator. by_ref ( ) . take ( vector. capacity ( ) ) {
1403
1410
let len = vector. len ( ) ;
1404
1411
unsafe {
1405
1412
ptr:: write ( vector. get_unchecked_mut ( len) , element) ;
1406
1413
vector. set_len ( len + 1 ) ;
1407
1414
}
1408
1415
}
1409
1416
1410
- for element in i {
1411
- vector. push ( element)
1417
+ if vector. len ( ) == vector. capacity ( ) {
1418
+ for element in iterator {
1419
+ vector. push ( element) ;
1420
+ }
1412
1421
}
1413
1422
vector
1414
1423
}
0 commit comments