rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

New lint: suggest transforming `[T, ...].into_iter().collect()` to `[T, ...].into()`

Open strohel opened this issue 3 years ago • 0 comments

What it does

These collection types implement From<[T; N]>: HashSet, BTreeSet, BinaryHeap, LinkedList, VecDeque (and Vec). These collection types implement From<[(K, V); N]>: HashMap, BTreeMap.

Suppose you want to construct one of these collections from variables that you have at hand. Constructing Vec is covered by the vec![] macro, but for other collections users may tend to write (I did): myset: HashSet<i32> = [1, 2].into_iter().collect();, but more concise form is myset: HashSet<i32> = [1, 2].into().

All these From<[...]> implementations were stabilized in Rust 1.56 with the 2021 edition. Rust code migrated from previous editions may also contain the superseded pattern.

Optionally this lint could also suggest to transform HashSet::from_iterator([1, 2].into_iterator()) into HashSet::from([1, 2]). Alternatively, users can opt into from_iter_instead_of_collect and then get the original lint.

This lint can be also viewed as a variant of iter_cloned_collect, but for arrays rather than slices.

Lint Name

array_into_std_collections

Category

complexity

Advantage

  • More concise and explicit expression of intent.
  • Not sure if there can be performance and/or compile-time evaluation advantages?

Drawbacks

None known.

Example

    let _: HashSet<i32> = [1, 2].into_iter().collect();
    let _: BTreeSet<i32> = [1, 2].into_iter().collect();
    let _: BinaryHeap<i32> = [1, 2].into_iter().collect();
    let _: LinkedList<i32> = [1, 2].into_iter().collect();
    let _: VecDeque<i32> = [1, 2].into_iter().collect();

    let _: HashMap<&str, i32> = [("a", 1), ("b", 2)].into_iter().collect();
    let _: BTreeMap<&str, i32> = [("a", 1), ("b", 2)].into_iter().collect();

Could be written as:

    let _: HashSet<i32> = [1, 2].into();
    let _: BTreeSet<i32> = [1, 2].into();
    let _: BinaryHeap<i32> = [1, 2].into();
    let _: LinkedList<i32> = [1, 2].into();
    let _: VecDeque<i32> = [1, 2].into();

    let _: HashMap<&str, i32> = [("a", 1), ("b", 2)].into();
    let _: BTreeMap<&str, i32> = [("a", 1), ("b", 2)].into();

strohel avatar Sep 23 '22 10:09 strohel