#![warn(clippy::needless_for_each)] #![allow(unused)] #![allow( clippy::let_unit_value, clippy::match_single_binding, clippy::needless_return, clippy::uninlined_format_args )] use std::collections::HashMap; fn should_lint() { let v: Vec = Vec::new(); let mut acc = 0; for elem in v.iter() { acc += elem; } for elem in v.into_iter() { acc += elem; } for elem in [1, 2, 3].iter() { acc += elem; } let mut hash_map: HashMap = HashMap::new(); for (k, v) in hash_map.iter() { acc += k + v; } for (k, v) in hash_map.iter_mut() { acc += *k + *v; } for k in hash_map.keys() { acc += k; } for v in hash_map.values() { acc += v; } fn my_vec() -> Vec { Vec::new() } for elem in my_vec().iter() { acc += elem; } } fn should_not_lint() { let v: Vec = Vec::new(); let mut acc = 0; // `for_each` argument is not closure. fn print(x: &i32) { println!("{}", x); } v.iter().for_each(print); // User defined type. struct MyStruct { v: Vec, } impl MyStruct { fn iter(&self) -> impl Iterator { self.v.iter() } } let s = MyStruct { v: Vec::new() }; s.iter().for_each(|elem| { acc += elem; }); // `for_each` follows long iterator chain. v.iter().chain(v.iter()).for_each(|v| { acc += v; }); v.as_slice().iter().for_each(|v| { acc += v; }); s.v.iter().for_each(|v| { acc += v; }); // `return` is used in `Loop` of the closure. v.iter().for_each(|v| { for i in 0..*v { if i == 10 { return; } else { println!("{}", v); } } if *v == 20 { return; } else { println!("{}", v); } }); // Previously transformed iterator variable. let it = v.iter(); it.chain(v.iter()).for_each(|elem| { acc += elem; }); // `for_each` is not directly in a statement. match 1 { _ => v.iter().for_each(|elem| { acc += elem; }), } // `for_each` is in a let binding. let _ = v.iter().for_each(|elem| { acc += elem; }); } fn main() {}