@@ -1520,49 +1520,46 @@ impl<T, A: Allocator> Vec<T, A> {
15201520
15211521 let mut g = BackshiftOnDrop { v : self , processed_len : 0 , deleted_cnt : 0 , original_len } ;
15221522
1523- // process_one return a bool indicates whether the processing element should be retained.
1524- #[ inline( always) ]
1525- fn process_one < F , T , A : Allocator , const DELETED : bool > (
1523+ fn process_loop < F , T , A : Allocator , const DELETED : bool > (
1524+ original_len : usize ,
15261525 f : & mut F ,
15271526 g : & mut BackshiftOnDrop < ' _ , T , A > ,
1528- ) -> bool
1529- where
1527+ ) where
15301528 F : FnMut ( & mut T ) -> bool ,
15311529 {
1532- // SAFETY: Unchecked element must be valid.
1533- let cur = unsafe { & mut * g. v . as_mut_ptr ( ) . add ( g. processed_len ) } ;
1534- if !f ( cur) {
1535- // Advance early to avoid double drop if `drop_in_place` panicked.
1536- g. processed_len += 1 ;
1537- g. deleted_cnt += 1 ;
1538- // SAFETY: We never touch this element again after dropped.
1539- unsafe { ptr:: drop_in_place ( cur) } ;
1540- // We already advanced the counter.
1541- return false ;
1542- }
1543- if DELETED {
1544- // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1545- // We use copy for move, and never touch this element again.
1546- unsafe {
1547- let hole_slot = g. v . as_mut_ptr ( ) . add ( g. processed_len - g. deleted_cnt ) ;
1548- ptr:: copy_nonoverlapping ( cur, hole_slot, 1 ) ;
1530+ while g. processed_len != original_len {
1531+ // SAFETY: Unchecked element must be valid.
1532+ let cur = unsafe { & mut * g. v . as_mut_ptr ( ) . add ( g. processed_len ) } ;
1533+ if !f ( cur) {
1534+ // Advance early to avoid double drop if `drop_in_place` panicked.
1535+ g. processed_len += 1 ;
1536+ g. deleted_cnt += 1 ;
1537+ // SAFETY: We never touch this element again after dropped.
1538+ unsafe { ptr:: drop_in_place ( cur) } ;
1539+ // We already advanced the counter.
1540+ if DELETED {
1541+ continue ;
1542+ } else {
1543+ break ;
1544+ }
1545+ }
1546+ if DELETED {
1547+ // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
1548+ // We use copy for move, and never touch this element again.
1549+ unsafe {
1550+ let hole_slot = g. v . as_mut_ptr ( ) . add ( g. processed_len - g. deleted_cnt ) ;
1551+ ptr:: copy_nonoverlapping ( cur, hole_slot, 1 ) ;
1552+ }
15491553 }
1554+ g. processed_len += 1 ;
15501555 }
1551- g. processed_len += 1 ;
1552- return true ;
15531556 }
15541557
15551558 // Stage 1: Nothing was deleted.
1556- while g. processed_len != original_len {
1557- if !process_one :: < F , T , A , false > ( & mut f, & mut g) {
1558- break ;
1559- }
1560- }
1559+ process_loop :: < F , T , A , false > ( original_len, & mut f, & mut g) ;
15611560
15621561 // Stage 2: Some elements were deleted.
1563- while g. processed_len != original_len {
1564- process_one :: < F , T , A , true > ( & mut f, & mut g) ;
1565- }
1562+ process_loop :: < F , T , A , true > ( original_len, & mut f, & mut g) ;
15661563
15671564 // All item are processed. This can be optimized to `set_len` by LLVM.
15681565 drop ( g) ;
0 commit comments