@@ -2298,30 +2298,44 @@ impl<'bump, T: 'bump> Vec<'bump, T> {
22982298 // for item in iterator {
22992299 // self.push(item);
23002300 // }
2301+ let mut len = self . len_usize ( ) ;
23012302 while let Some ( element) = iterator. next ( ) {
2302- let len = self . len_usize ( ) ;
23032303 if len == self . capacity_usize ( ) {
23042304 // This reallocation path is rarely taken, especially with prior reservation,
23052305 // so mark it `#[cold]` and `#[inline(never)]` helps the compiler optimize the
23062306 // common case, and prevents this cold path from being inlined to the `while` loop,
23072307 // which increases the execution instructions and hits the performance.
23082308 #[ cold]
23092309 #[ inline( never) ]
2310- fn reserve_slow < T > ( v : & mut Vec < T > , iterator : & impl Iterator ) {
2310+ fn reserve_slow < T > ( v : & mut Vec < T > , iterator : & impl Iterator , len : usize ) {
2311+ // `len` is always `<= u32::MAX`. If attempted to grow the `Vec` beyond this
2312+ // on a previous turn, `RawVec::reserve` would have panicked.
2313+ #[ expect( clippy:: cast_possible_truncation) ]
2314+ let len = len as u32 ;
2315+
23112316 let ( lower, _) = iterator. size_hint ( ) ;
2312- v. reserve ( lower. saturating_add ( 1 ) ) ;
2317+ v. buf . reserve ( len , lower. saturating_add ( 1 ) ) ;
23132318 }
23142319
2315- reserve_slow ( self , & iterator) ;
2320+ reserve_slow ( self , & iterator, len ) ;
23162321 }
23172322 unsafe {
23182323 ptr:: write ( self . as_mut_ptr ( ) . add ( len) , element) ;
2319- // Since next() executes user code which can panic we have to bump the length
2320- // after each step.
2321- // NB can't overflow since we would have had to alloc the address space
2322- self . set_len ( len + 1 ) ;
2324+ // Can't overflow since we would have had to alloc the address space
2325+ len += 1 ;
23232326 }
23242327 }
2328+
2329+ // Update `len` to reflect the extra elements we've pushed.
2330+ //
2331+ // std library version of this method updates `len` after writing each element,
2332+ // because `iterator.next()` could panic.
2333+ // If that happens, `len` needs to contain all the elements written so far,
2334+ // so they get dropped when the `Vec` is dropped.
2335+ // But our `Vec` requires that `T` is not `Drop`, so we don't need to worry about that.
2336+ //
2337+ // SAFETY: `len` cannot be `> u32::MAX` because `reserve` would have already panicked if it was.
2338+ unsafe { self . set_len ( len) } ;
23252339 }
23262340}
23272341
0 commit comments