@@ -1407,7 +1407,7 @@ impl<T> ops::DerefMut for Vec<T> {
1407
1407
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1408
1408
impl < T > FromIterator < T > for Vec < T > {
1409
1409
#[ inline]
1410
- fn from_iter < I : Iterator < Item =T > > ( iterator : I ) -> Vec < T > {
1410
+ fn from_iter < I : Iterator < Item =T > > ( mut iterator : I ) -> Vec < T > {
1411
1411
let ( lower, _) = iterator. size_hint ( ) ;
1412
1412
let mut vector = Vec :: with_capacity ( lower) ;
1413
1413
@@ -1417,22 +1417,31 @@ impl<T> FromIterator<T> for Vec<T> {
1417
1417
// vector.push(item);
1418
1418
// }
1419
1419
//
1420
- // This equivalent crucially runs the iterator precisely once. The
1421
- // optimization below (eliding bound/growth checks) means that we
1422
- // actually run the iterator twice. To ensure the "moral equivalent" we
1423
- // do a `fuse()` operation to ensure that the iterator continues to
1424
- // return `None` after seeing the first `None`.
1425
- let mut i = iterator. fuse ( ) ;
1426
- for element in i. by_ref ( ) . take ( vector. capacity ( ) ) {
1420
+ // This equivalent crucially runs the iterator precisely once. Below we
1421
+ // actually in theory run the iterator twice (one without bounds checks
1422
+ // and one with). To achieve the "moral equivalent", we use the `if`
1423
+ // statement below to break out early.
1424
+ //
1425
+ // If the first loop has terminated, then we have one of two conditions.
1426
+ //
1427
+ // 1. The underlying iterator returned `None`. In this case we are
1428
+ // guaranteed that less than `vector.capacity()` elements have been
1429
+ // returned, so we break out early.
1430
+ // 2. The underlying iterator yielded `vector.capacity()` elements and
1431
+ // has not yielded `None` yet. In this case we run the iterator to
1432
+ // its end below.
1433
+ for element in iterator. by_ref ( ) . take ( vector. capacity ( ) ) {
1427
1434
let len = vector. len ( ) ;
1428
1435
unsafe {
1429
1436
ptr:: write ( vector. get_unchecked_mut ( len) , element) ;
1430
1437
vector. set_len ( len + 1 ) ;
1431
1438
}
1432
1439
}
1433
1440
1434
- for element in i {
1435
- vector. push ( element)
1441
+ if vector. len ( ) == vector. capacity ( ) {
1442
+ for element in iterator {
1443
+ vector. push ( element) ;
1444
+ }
1436
1445
}
1437
1446
vector
1438
1447
}
0 commit comments