Skip to content

Remove drain-on-drop behavior from various DrainFilter iterators #136

@the8472

Description

@the8472

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:

  • Vec
  • LinkedList
  • BTree{Map, Set}
  • Hash{Map, Set}

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.

Links and related work

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions