Skip to content

Commit 2a11c57

Browse files
committed
Fix and simplify
1 parent 969e552 commit 2a11c57

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

Diff for: library/alloc/src/vec/mod.rs

+22-22
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ impl<T, A: Allocator> Vec<T, A> {
13701370
where
13711371
F: FnMut(&T) -> bool,
13721372
{
1373-
let len = self.len();
1373+
let original_len = self.len();
13741374
// Avoid double drop if the drop guard is not executed,
13751375
// since we may make some holes during the process.
13761376
unsafe { self.set_len(0) };
@@ -1396,49 +1396,49 @@ impl<T, A: Allocator> Vec<T, A> {
13961396
impl<T, A: Allocator> Drop for BackshiftOnDrop<'_, T, A> {
13971397
fn drop(&mut self) {
13981398
if self.deleted_cnt > 0 {
1399-
// SAFETY: Fill the hole of dropped or moved
1399+
// SAFETY: Trailing unchecked items must be valid since we never touch them.
14001400
unsafe {
14011401
ptr::copy(
1402-
self.v.as_ptr().offset(self.processed_len as isize),
1403-
self.v
1404-
.as_mut_ptr()
1405-
.offset(self.processed_len as isize - self.deleted_cnt as isize),
1402+
self.v.as_ptr().add(self.processed_len),
1403+
self.v.as_mut_ptr().add(self.processed_len - self.deleted_cnt),
14061404
self.original_len - self.processed_len,
14071405
);
1408-
self.v.set_len(self.original_len - self.deleted_cnt);
14091406
}
14101407
}
1408+
// SAFETY: After filling holes, all items are in contiguous memory.
1409+
unsafe {
1410+
self.v.set_len(self.original_len - self.deleted_cnt);
1411+
}
14111412
}
14121413
}
14131414

1414-
let mut guard =
1415-
BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len: len };
1415+
let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len };
14161416

1417-
let mut del = 0usize;
1418-
for i in 0..len {
1417+
while g.processed_len < original_len {
14191418
// SAFETY: Unchecked element must be valid.
1420-
let cur = unsafe { &mut *guard.v.as_mut_ptr().offset(i as isize) };
1419+
let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) };
14211420
if !f(cur) {
1422-
del += 1;
14231421
// Advance early to avoid double drop if `drop_in_place` panicked.
1424-
guard.processed_len = i + 1;
1425-
guard.deleted_cnt = del;
1422+
g.processed_len += 1;
1423+
g.deleted_cnt += 1;
14261424
// SAFETY: We never touch this element again after dropped.
14271425
unsafe { ptr::drop_in_place(cur) };
1428-
} else if del > 0 {
1429-
// SAFETY: `del` > 0 so the hole slot must not overlap with current element.
1426+
// We already advanced the counter.
1427+
continue;
1428+
}
1429+
if g.deleted_cnt > 0 {
1430+
// SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
14301431
// We use copy for move, and never touch this element again.
14311432
unsafe {
1432-
let hole_slot = guard.v.as_mut_ptr().offset(i as isize - del as isize);
1433+
let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
14331434
ptr::copy_nonoverlapping(cur, hole_slot, 1);
14341435
}
1435-
guard.processed_len = i + 1;
14361436
}
1437+
g.processed_len += 1;
14371438
}
14381439

1439-
// All holes are at the end now. Simply cut them out.
1440-
unsafe { guard.v.set_len(len - del) };
1441-
mem::forget(guard);
1440+
// All item are processed. This can be optimized to `set_len` by LLVM.
1441+
drop(g);
14421442
}
14431443

14441444
/// Removes all but the first of consecutive elements in the vector that resolve to the same

0 commit comments

Comments
 (0)