Auto merge of #9409 - DesmondWillowbrook:iter_kv_map, r=xFrednet

Add `iter_kv_map` lint

fixes #9376

| before | after |
| -------------- | ------------------------- |
| `hmap.iter().map(\|(key, _)\| key)` | `hmap.keys()` |
| `hmap.iter().map(\|(_, v)\| v + 2)` | `hmap.values().map(\|v\| v + 2)` |
| `hmap.into_iter().map(\|(key, _)\| key)` | `hmap.into_keys()` |

Is `MachineApplicable`

changelog: [`iter_kv_map`]: added lint
This commit is contained in:
bors 2022-09-16 08:44:58 +00:00
commit 481dc2e81c
11 changed files with 414 additions and 0 deletions

View file

@ -0,0 +1,64 @@
// run-rustfix
#![warn(clippy::iter_kv_map)]
#![allow(clippy::redundant_clone)]
#![allow(clippy::suspicious_map)]
#![allow(clippy::map_identity)]
use std::collections::{BTreeMap, HashMap};
fn main() {
let get_key = |(key, _val)| key;
let map: HashMap<u32, u32> = HashMap::new();
let _ = map.keys().collect::<Vec<_>>();
let _ = map.values().collect::<Vec<_>>();
let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();
let _ = map.clone().into_keys().collect::<Vec<_>>();
let _ = map.clone().into_keys().map(|key| key + 2).collect::<Vec<_>>();
let _ = map.clone().into_values().collect::<Vec<_>>();
let _ = map.clone().into_values().map(|val| val + 2).collect::<Vec<_>>();
let _ = map.clone().values().collect::<Vec<_>>();
let _ = map.keys().filter(|x| *x % 2 == 0).count();
// Don't lint
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
let _ = map.iter().map(get_key).collect::<Vec<_>>();
// Linting the following could be an improvement to the lint
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
// Lint
let _ = map.keys().map(|key| key * 9).count();
let _ = map.values().map(|value| value * 17).count();
let map: BTreeMap<u32, u32> = BTreeMap::new();
let _ = map.keys().collect::<Vec<_>>();
let _ = map.values().collect::<Vec<_>>();
let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();
let _ = map.clone().into_keys().collect::<Vec<_>>();
let _ = map.clone().into_keys().map(|key| key + 2).collect::<Vec<_>>();
let _ = map.clone().into_values().collect::<Vec<_>>();
let _ = map.clone().into_values().map(|val| val + 2).collect::<Vec<_>>();
let _ = map.clone().values().collect::<Vec<_>>();
let _ = map.keys().filter(|x| *x % 2 == 0).count();
// Don't lint
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
let _ = map.iter().map(get_key).collect::<Vec<_>>();
// Linting the following could be an improvement to the lint
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
// Lint
let _ = map.keys().map(|key| key * 9).count();
let _ = map.values().map(|value| value * 17).count();
}

64
tests/ui/iter_kv_map.rs Normal file
View file

@ -0,0 +1,64 @@
// run-rustfix
#![warn(clippy::iter_kv_map)]
#![allow(clippy::redundant_clone)]
#![allow(clippy::suspicious_map)]
#![allow(clippy::map_identity)]
use std::collections::{BTreeMap, HashMap};
fn main() {
let get_key = |(key, _val)| key;
let map: HashMap<u32, u32> = HashMap::new();
let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
// Don't lint
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
let _ = map.iter().map(get_key).collect::<Vec<_>>();
// Linting the following could be an improvement to the lint
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
// Lint
let _ = map.iter().map(|(key, _value)| key * 9).count();
let _ = map.iter().map(|(_key, value)| value * 17).count();
let map: BTreeMap<u32, u32> = BTreeMap::new();
let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
// Don't lint
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
let _ = map.iter().map(get_key).collect::<Vec<_>>();
// Linting the following could be an improvement to the lint
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
// Lint
let _ = map.iter().map(|(key, _value)| key * 9).count();
let _ = map.iter().map(|(_key, value)| value * 17).count();
}

136
tests/ui/iter_kv_map.stderr Normal file
View file

@ -0,0 +1,136 @@
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:15:13
|
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
= note: `-D clippy::iter-kv-map` implied by `-D warnings`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:16:13
|
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:17:13
|
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:19:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:20:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:22:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:23:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:25:13
|
LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:26:13
|
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:36:13
|
LL | let _ = map.iter().map(|(key, _value)| key * 9).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:37:13
|
LL | let _ = map.iter().map(|(_key, value)| value * 17).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:41:13
|
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:42:13
|
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:43:13
|
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:45:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:46:13
|
LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:48:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:49:13
|
LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:51:13
|
LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:52:13
|
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
error: iterating on a map's keys
--> $DIR/iter_kv_map.rs:62:13
|
LL | let _ = map.iter().map(|(key, _value)| key * 9).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`
error: iterating on a map's values
--> $DIR/iter_kv_map.rs:63:13
|
LL | let _ = map.iter().map(|(_key, value)| value * 17).count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`
error: aborting due to 22 previous errors