-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Vec::retain leaks items when predicate panics #52267
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
cc @rust-lang/libs -- I believe this is allowed per stability, but we should discuss at least |
I know that leaking memory is not considered unsafe, but I assume that the standard library strives to not leak. |
Looks like the relevant change in 1.26.0 was #48065. |
Thanks for narrowing this down @dtolnay, that makes sense in that I believe the That being said it'd of course be great to solve this! |
Fixed by #61224 (which includes a test). Closing. |
Optimize Vec::retain Use `copy_non_overlapping` instead of `swap` to reduce memory writes, like what we've done in rust-lang#44355 and `String::retain`. rust-lang#48065 already tried to do this optimization but it is reverted in rust-lang#67300 due to bad codegen of `DrainFilter::drop`. This PR re-implement the drop-then-move approach. I did a [benchmark](https://gist.github.com/oxalica/3360eec9376f22533fcecff02798b698) on small-no-drop, small-need-drop, large-no-drop elements with different predicate functions. It turns out that the new implementation is >20% faster in average for almost all cases. Only 2/24 cases are slower by 3% and 5%. See the link above for more detail. I think regression in may-panic cases is due to drop-guard preventing some optimization. If it's permitted to leak elements when predicate function of element's `drop` panic, the new implementation should be almost always faster than current one. I'm not sure if we should leak on panic, since there is indeed an issue (rust-lang#52267) complains about it before.
Uh oh!
There was an error while loading. Please reload this page.
Since the implementation of
Vec::retain
changed after Rust 1.25, items may not be dropped when the predicate panics.Reproduction example
Expected result
All 3
Foo
instances are dropped. The output should look like (with Rust 1.25):Actual result
Only one
Foo
instance is dropped. The output since Rust 1.26 (and with 1.27.1) is:Edited to clarify item leak (i.e. not dropped).
The text was updated successfully, but these errors were encountered: