Skip to content

Commit 9411648

Browse files
committed
implement more types to lint, fix wording
1 parent 7bc39f3 commit 9411648

File tree

4 files changed

+95
-20
lines changed

4 files changed

+95
-20
lines changed

clippy_lints/src/iter_over_hash_type.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use clippy_utils::diagnostics::span_lint;
22
use clippy_utils::higher::ForLoop;
3-
use clippy_utils::match_def_path;
4-
use clippy_utils::paths::{HASHMAP_KEYS, HASHMAP_VALUES, HASHSET_ITER_TY};
3+
use clippy_utils::paths::{
4+
HASHMAP_DRAIN, HASHMAP_ITER, HASHMAP_ITER_MUT, HASHMAP_KEYS, HASHMAP_VALUES, HASHMAP_VALUES_MUT, HASHSET_DRAIN,
5+
HASHSET_ITER_TY,
6+
};
57
use clippy_utils::ty::is_type_diagnostic_item;
8+
use clippy_utils::match_any_def_paths;
69
use rustc_lint::{LateContext, LateLintPass};
710
use rustc_session::{declare_lint_pass, declare_tool_lint};
811
use rustc_span::sym;
@@ -13,7 +16,7 @@ declare_clippy_lint! {
1316
///
1417
/// ### Why is this bad?
1518
/// Because hash types are unordered, when iterated through such as in a for loop, the values are returned in
16-
/// a pseudo-random order. As a result, on redundant systems this may cause inconsistencies and anomalies.
19+
/// an undefined order. As a result, on redundant systems this may cause inconsistencies and anomalies.
1720
/// In addition, the unknown order of the elements may reduce readability or introduce other undesired
1821
/// side effects.
1922
///
@@ -46,17 +49,29 @@ impl LateLintPass<'_> for IterOverHashType {
4649
&& let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs()
4750
&& let Some(adt) = ty.ty_adt_def()
4851
&& let did = adt.did()
49-
&& (match_def_path(cx, did, &HASHMAP_KEYS)
50-
|| match_def_path(cx, did, &HASHMAP_VALUES)
51-
|| match_def_path(cx, did, &HASHSET_ITER_TY)
52+
&& (match_any_def_paths(
53+
cx,
54+
did,
55+
&[
56+
&HASHMAP_KEYS,
57+
&HASHMAP_VALUES,
58+
&HASHMAP_VALUES_MUT,
59+
&HASHMAP_ITER,
60+
&HASHMAP_ITER_MUT,
61+
&HASHMAP_DRAIN,
62+
&HASHSET_ITER_TY,
63+
&HASHSET_DRAIN,
64+
],
65+
)
66+
.is_some()
5267
|| is_type_diagnostic_item(cx, ty, sym::HashMap)
5368
|| is_type_diagnostic_item(cx, ty, sym::HashSet))
5469
{
5570
span_lint(
5671
cx,
5772
ITER_OVER_HASH_TYPE,
5873
expr.span,
59-
"iterating over unordered hash-based type",
74+
"iteration over unordered hash-based type",
6075
);
6176
};
6277
}

clippy_utils/src/paths.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,15 @@ pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncRead
3232
pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"];
3333
pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"];
3434
pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"];
35+
pub const HASHMAP_ITER: [&str; 5] = ["std", "collections", "hash", "map", "Iter"];
36+
pub const HASHMAP_ITER_MUT: [&str; 5] = ["std", "collections", "hash", "map", "IterMut"];
3537
pub const HASHMAP_KEYS: [&str; 5] = ["std", "collections", "hash", "map", "Keys"];
3638
pub const HASHMAP_VALUES: [&str; 5] = ["std", "collections", "hash", "map", "Values"];
39+
pub const HASHMAP_DRAIN: [&str; 5] = ["std", "collections", "hash", "map", "Drain"];
40+
pub const HASHMAP_VALUES_MUT: [&str; 5] = ["std", "collections", "hash", "map", "ValuesMut"];
3741
pub const HASHSET_ITER_TY: [&str; 5] = ["std", "collections", "hash", "set", "Iter"];
3842
pub const HASHSET_ITER: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "iter"];
43+
pub const HASHSET_DRAIN: [&str; 5] = ["std", "collections", "hash", "set", "Drain"];
3944
pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
4045
pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"];
4146
pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"];

tests/ui/iter_over_hash_type.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use std::collections::{HashMap, HashSet};
66
extern crate proc_macros;
77

88
fn main() {
9-
let hash_set = HashSet::<i32>::new();
10-
let hash_map = HashMap::<i32, i32>::new();
9+
let mut hash_set = HashSet::<i32>::new();
10+
let mut hash_map = HashMap::<i32, i32>::new();
1111
let vec = Vec::<i32>::new();
1212

1313
for x in &hash_set {
@@ -16,7 +16,10 @@ fn main() {
1616
for x in hash_set.iter() {
1717
let _ = x;
1818
}
19-
for x in hash_set {
19+
for x in hash_set.clone() {
20+
let _ = x;
21+
}
22+
for x in hash_set.drain() {
2023
let _ = x;
2124
}
2225
for (x, y) in &hash_map {
@@ -28,6 +31,18 @@ fn main() {
2831
for x in hash_map.values() {
2932
let _ = x;
3033
}
34+
for x in hash_map.values_mut() {
35+
*x += 1;
36+
}
37+
for x in hash_map.iter() {
38+
let _ = x;
39+
}
40+
for x in hash_map.clone() {
41+
let _ = x;
42+
}
43+
for x in hash_map.drain() {
44+
let _ = x;
45+
}
3146

3247
// shouldnt fire
3348
for x in &vec {

tests/ui/iter_over_hash_type.stderr

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: iterating over unordered hash-based type
1+
error: iteration over unordered hash-based type
22
--> $DIR/iter_over_hash_type.rs:13:5
33
|
44
LL | / for x in &hash_set {
@@ -9,45 +9,85 @@ LL | | }
99
= note: `-D clippy::iter-over-hash-type` implied by `-D warnings`
1010
= help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]`
1111

12-
error: iterating over unordered hash-based type
12+
error: iteration over unordered hash-based type
1313
--> $DIR/iter_over_hash_type.rs:16:5
1414
|
1515
LL | / for x in hash_set.iter() {
1616
LL | | let _ = x;
1717
LL | | }
1818
| |_____^
1919

20-
error: iterating over unordered hash-based type
20+
error: iteration over unordered hash-based type
2121
--> $DIR/iter_over_hash_type.rs:19:5
2222
|
23-
LL | / for x in hash_set {
23+
LL | / for x in hash_set.clone() {
2424
LL | | let _ = x;
2525
LL | | }
2626
| |_____^
2727

28-
error: iterating over unordered hash-based type
28+
error: iteration over unordered hash-based type
2929
--> $DIR/iter_over_hash_type.rs:22:5
3030
|
31+
LL | / for x in hash_set.drain() {
32+
LL | | let _ = x;
33+
LL | | }
34+
| |_____^
35+
36+
error: iteration over unordered hash-based type
37+
--> $DIR/iter_over_hash_type.rs:25:5
38+
|
3139
LL | / for (x, y) in &hash_map {
3240
LL | | let _ = (x, y);
3341
LL | | }
3442
| |_____^
3543

36-
error: iterating over unordered hash-based type
37-
--> $DIR/iter_over_hash_type.rs:25:5
44+
error: iteration over unordered hash-based type
45+
--> $DIR/iter_over_hash_type.rs:28:5
3846
|
3947
LL | / for x in hash_map.keys() {
4048
LL | | let _ = x;
4149
LL | | }
4250
| |_____^
4351

44-
error: iterating over unordered hash-based type
45-
--> $DIR/iter_over_hash_type.rs:28:5
52+
error: iteration over unordered hash-based type
53+
--> $DIR/iter_over_hash_type.rs:31:5
4654
|
4755
LL | / for x in hash_map.values() {
4856
LL | | let _ = x;
4957
LL | | }
5058
| |_____^
5159

52-
error: aborting due to 6 previous errors
60+
error: iteration over unordered hash-based type
61+
--> $DIR/iter_over_hash_type.rs:34:5
62+
|
63+
LL | / for x in hash_map.values_mut() {
64+
LL | | *x += 1;
65+
LL | | }
66+
| |_____^
67+
68+
error: iteration over unordered hash-based type
69+
--> $DIR/iter_over_hash_type.rs:37:5
70+
|
71+
LL | / for x in hash_map.iter() {
72+
LL | | let _ = x;
73+
LL | | }
74+
| |_____^
75+
76+
error: iteration over unordered hash-based type
77+
--> $DIR/iter_over_hash_type.rs:40:5
78+
|
79+
LL | / for x in hash_map.clone() {
80+
LL | | let _ = x;
81+
LL | | }
82+
| |_____^
83+
84+
error: iteration over unordered hash-based type
85+
--> $DIR/iter_over_hash_type.rs:43:5
86+
|
87+
LL | / for x in hash_map.drain() {
88+
LL | | let _ = x;
89+
LL | | }
90+
| |_____^
91+
92+
error: aborting due to 11 previous errors
5393

0 commit comments

Comments
 (0)