rust/tests/ui/needless_collect.fixed
Michael Howell c012693961 needless_collect: avoid warning if non-iterator methods are used
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.
2025-02-04 13:07:06 -07:00

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>) {}