@@ -1520,49 +1520,46 @@ impl<T, A: Allocator> Vec<T, A> {
1520
1520
1521
1521
let mut g = BackshiftOnDrop { v : self , processed_len : 0 , deleted_cnt : 0 , original_len } ;
1522
1522
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 ,
1526
1525
f : & mut F ,
1527
1526
g : & mut BackshiftOnDrop < ' _ , T , A > ,
1528
- ) -> bool
1529
- where
1527
+ ) where
1530
1528
F : FnMut ( & mut T ) -> bool ,
1531
1529
{
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
+ }
1549
1553
}
1554
+ g. processed_len += 1 ;
1550
1555
}
1551
- g. processed_len += 1 ;
1552
- return true ;
1553
1556
}
1554
1557
1555
1558
// 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) ;
1561
1560
1562
1561
// 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) ;
1566
1563
1567
1564
// All item are processed. This can be optimized to `set_len` by LLVM.
1568
1565
drop ( g) ;
0 commit comments