Skip to content

new lint: avoid vec.drain(..).collect() in favor of std::mem::take(&mut vec) #10818

@iliana

Description

@iliana

What it does

This lint would see the use of vec.drain(..).collect(), which moves all the items from a Vec<T> into a new Vec<T> via FromIterator, and suggest to instead use std::mem::take(&mut vec).

This is similar to #9339, implemented as clear_with_drain.

Lint Name

collect_with_drain

Category

perf, pedantic

Advantage

  • Avoids FromIterator and new allocations.
  • (Subjectively) clearer code.

Drawbacks

  • By taking the Vec and replacing it with a new one, you've moved the capacity, but the author may have intended to keep the capacity in place and perform the allocation/memcpy. This situation seems rare to me.

Example

// self.vec is a Vec<u32>
fn func(&mut self) -> Vec<u32> {
    self.vec.drain(..).collect()
}

Could be written as:

fn func(&mut self) -> Vec<u32> {
    std::mem::take(&mut self.vec)
}

Metadata

Metadata

Assignees

Labels

A-lintArea: New lints

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions