Remove drain-on-drop behavior from various DrainFilter iterators · Issue #136 · rust-lang/libs-team (original) (raw)

Proposal

Problem statement

The current implementations can double-panic (via a panic-drop-panic cascade), may become aborts even on a single panic if the deny panic-in-drop RFC goes through and are not consistent with general Iterator laziness.

Motivation, use-cases

A panicking closure can lead to a double-panic while iterating. Playground link

#![feature(drain_filter)] use std::collections::LinkedList;

fn main() { let mut c = LinkedList::from([1, 2, 3]); let c = c.drain_filter(|| panic!("panic")).collect::<Vec<_>>(); }

Solution sketches

Add #[must_use] and remove drain-on-drop behavior from the drain_filter impls for these collections:

Since it'll be redundant needed it will also remove vec::DrainFilter::keep_rest()

Additionally drain_filter can be renamed to extract_filter🚲🏚️ to avoid similarity to Drain which will retain its drain-on-drop behavior since it's less problematic as it doesn't evaluate a closure for each item. To be bikeshed.

Limitations

This may cause surprises with short-circuiting iterators. That can be worked around (unergonomically) by taking by_ref and then exhausting the rest once the main use is completed or by avoiding short-circuiting ops.

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.