mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
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
This commit is contained in:
commit
64f83915de
@ -1079,7 +1079,22 @@ impl<T> Vec<T> {
|
|||||||
pub fn retain<F>(&mut self, mut f: F)
|
pub fn retain<F>(&mut self, mut f: F)
|
||||||
where F: FnMut(&T) -> bool
|
where F: FnMut(&T) -> bool
|
||||||
{
|
{
|
||||||
self.drain_filter(|x| !f(x));
|
let len = self.len();
|
||||||
|
let mut del = 0;
|
||||||
|
{
|
||||||
|
let v = &mut **self;
|
||||||
|
|
||||||
|
for i in 0..len {
|
||||||
|
if !f(&v[i]) {
|
||||||
|
del += 1;
|
||||||
|
} else if del > 0 {
|
||||||
|
v.swap(i - del, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if del > 0 {
|
||||||
|
self.truncate(len - del);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all but the first of consecutive elements in the vector that resolve to the same
|
/// Removes all but the first of consecutive elements in the vector that resolve to the same
|
||||||
|
Loading…
Reference in New Issue
Block a user