Skip to content

Commit 64f8391

Browse files
authored
Rollup merge of #67300 - aloucks:issue-65970, r=rkruppe
Restore original implementation of Vec::retain This PR reverts #48065, which aimed to optimize `Vec::retain` by making use of `Vec::drain_filter`. Unfortunately at that time, `drain_filter` was unsound. The soundness hole in `Vec::drain_filter` was fixed in #61224 by guaranteeing that cleanup logic runs via a nested `Drop`, even in the event of a panic. Implementing this nested drop affects codegen (apparently?) and results in slower code. Fixes #65970
2 parents 8e2689c + 7ea6c46 commit 64f8391

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/liballoc/vec.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,22 @@ impl<T> Vec<T> {
10791079
pub fn retain<F>(&mut self, mut f: F)
10801080
where F: FnMut(&T) -> bool
10811081
{
1082-
self.drain_filter(|x| !f(x));
1082+
let len = self.len();
1083+
let mut del = 0;
1084+
{
1085+
let v = &mut **self;
1086+
1087+
for i in 0..len {
1088+
if !f(&v[i]) {
1089+
del += 1;
1090+
} else if del > 0 {
1091+
v.swap(i - del, i);
1092+
}
1093+
}
1094+
}
1095+
if del > 0 {
1096+
self.truncate(len - del);
1097+
}
10831098
}
10841099

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

0 commit comments

Comments
 (0)