It can make sense to `collect()` an iterator and then immediately iterate over it if the iterator has special methods that you need. For example, the Map iterator doesn't implement Clone, but the collection iterator might. Or the collection iterator might support slicing.
94 lines
3.4 KiB
Rust
94 lines
3.4 KiB
Rust
#![allow(unused, clippy::needless_if, clippy::suspicious_map, clippy::iter_count)]
|
|
|
|
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList};
|
|
|
|
#[warn(clippy::needless_collect)]
|
|
#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]
|
|
fn main() {
|
|
let sample = [1; 5];
|
|
let len = sample.iter().count();
|
|
if sample.iter().next().is_none() {
|
|
// Empty
|
|
}
|
|
sample.iter().cloned().any(|x| x == 1);
|
|
// #7164 HashMap's and BTreeMap's `len` usage should not be linted
|
|
sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().len();
|
|
sample.iter().map(|x| (x, x)).collect::<BTreeMap<_, _>>().len();
|
|
|
|
sample.iter().map(|x| (x, x)).next().is_none();
|
|
sample.iter().map(|x| (x, x)).next().is_none();
|
|
|
|
// Notice the `HashSet`--this should not be linted
|
|
sample.iter().collect::<HashSet<_>>().len();
|
|
// Neither should this
|
|
sample.iter().collect::<BTreeSet<_>>().len();
|
|
|
|
sample.iter().count();
|
|
sample.iter().next().is_none();
|
|
sample.iter().cloned().any(|x| x == 1);
|
|
sample.iter().any(|x| x == &1);
|
|
|
|
// `BinaryHeap` doesn't have `contains` method
|
|
sample.iter().count();
|
|
sample.iter().next().is_none();
|
|
|
|
// Don't lint string from str
|
|
let _ = ["", ""].into_iter().collect::<String>().is_empty();
|
|
|
|
let _ = sample.iter().next().is_none();
|
|
let _ = sample.iter().any(|x| x == &0);
|
|
|
|
struct VecWrapper<T>(Vec<T>);
|
|
impl<T> core::ops::Deref for VecWrapper<T> {
|
|
type Target = Vec<T>;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
impl<T> IntoIterator for VecWrapper<T> {
|
|
type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
|
|
type Item = <Vec<T> as IntoIterator>::Item;
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
self.0.into_iter()
|
|
}
|
|
}
|
|
impl<T> FromIterator<T> for VecWrapper<T> {
|
|
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
|
Self(Vec::from_iter(iter))
|
|
}
|
|
}
|
|
|
|
let _ = sample.iter().next().is_none();
|
|
let _ = sample.iter().any(|x| x == &0);
|
|
|
|
#[allow(clippy::double_parens)]
|
|
{
|
|
Vec::<u8>::new().extend((0..10));
|
|
foo((0..10));
|
|
bar((0..10).collect::<Vec<_>>(), (0..10));
|
|
baz((0..10), (), ('a'..='z'))
|
|
}
|
|
|
|
let values = [1, 2, 3, 4];
|
|
let mut out = vec![];
|
|
values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
|
|
let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
|
|
|
|
// Don't write a warning if we call `clone()` on the iterator
|
|
// https://github.com/rust-lang/rust-clippy/issues/13430
|
|
let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
|
|
let _cloned = my_collection.into_iter().clone();
|
|
let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
|
|
let my_iter = my_collection.into_iter();
|
|
let _cloned = my_iter.clone();
|
|
// Same for `as_slice()`, for same reason.
|
|
let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
|
|
let _sliced = my_collection.into_iter().as_slice();
|
|
let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
|
|
let my_iter = my_collection.into_iter();
|
|
let _sliced = my_iter.as_slice();
|
|
}
|
|
|
|
fn foo(_: impl IntoIterator<Item = usize>) {}
|
|
fn bar<I: IntoIterator<Item = usize>>(_: Vec<usize>, _: I) {}
|
|
fn baz<I: IntoIterator<Item = usize>>(_: I, _: (), _: impl IntoIterator<Item = char>) {}
|