From cb90674aed9ec7b6c7bb471d2ec8cc3b36745b79 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Sat, 11 Nov 2023 00:20:47 +0000 Subject: [PATCH 1/5] add iter_over_hash_type lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/iter_over_hash_type.rs | 63 +++++++++++++++++++++++++ clippy_lints/src/lib.rs | 2 + clippy_utils/src/paths.rs | 3 ++ tests/ui/iter_over_hash_type.rs | 44 +++++++++++++++++ tests/ui/iter_over_hash_type.stderr | 53 +++++++++++++++++++++ 7 files changed, 167 insertions(+) create mode 100644 clippy_lints/src/iter_over_hash_type.rs create mode 100644 tests/ui/iter_over_hash_type.rs create mode 100644 tests/ui/iter_over_hash_type.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 87a96bdeba6..5448b1267be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5123,6 +5123,7 @@ Released 2018-09-13 [`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections [`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items [`iter_out_of_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_out_of_bounds +[`iter_over_hash_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_over_hash_type [`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned [`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next [`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_zero diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 04dcccede08..b4d5e074cdd 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -230,6 +230,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO, crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO, crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO, + crate::iter_over_hash_type::ITER_OVER_HASH_TYPE_INFO, crate::iter_without_into_iter::INTO_ITER_WITHOUT_ITER_INFO, crate::iter_without_into_iter::ITER_WITHOUT_INTO_ITER_INFO, crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO, diff --git a/clippy_lints/src/iter_over_hash_type.rs b/clippy_lints/src/iter_over_hash_type.rs new file mode 100644 index 00000000000..554790ac61b --- /dev/null +++ b/clippy_lints/src/iter_over_hash_type.rs @@ -0,0 +1,63 @@ +use clippy_utils::paths::{HASHMAP_KEYS, HASHMAP_VALUES, HASHSET_ITER_TY}; +use clippy_utils::{diagnostics::span_lint, match_def_path}; +use clippy_utils::higher::ForLoop; +use clippy_utils::ty::is_type_diagnostic_item; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; + +declare_clippy_lint! { + /// ### What it does + /// This is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops. + /// + /// ### Why is this bad? + /// Because hash types are unordered, when iterated through such as in a for loop, the values are returned in + /// a pseudo-random order. As a result, on redundant systems this may cause inconsistencies and anomalies. + /// In addition, the unknown order of the elements may reduce readability or introduce other undesired + /// side effects. + /// + /// ### Example + /// ```no_run + /// let my_map = new Hashmap(); + /// for (key, value) in my_map { /* ... */ } + /// ``` + /// Use instead: + /// ```no_run + /// let my_map = new Hashmap(); + /// let mut keys = my_map.keys().clone().collect::(); + /// keys.sort(); + /// for key in keys { + /// let value = &my_map[value]; + /// } + /// ``` + #[clippy::version = "1.75.0"] + pub ITER_OVER_HASH_TYPE, + restriction, + "iterating over unordered hash-based types (`HashMap` and `HashSet`)" +} + +declare_lint_pass!(IterOverHashType => [ITER_OVER_HASH_TYPE]); + +impl LateLintPass<'_> for IterOverHashType { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>) { + if let Some(for_loop) = ForLoop::hir(expr) + && !for_loop.body.span.from_expansion() + && let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs() + && let Some(adt) = ty.ty_adt_def() + && let did = adt.did() + && (match_def_path(cx, did, &HASHMAP_KEYS) + || match_def_path(cx, did, &HASHMAP_VALUES) + || match_def_path(cx, did, &HASHSET_ITER_TY) + || is_type_diagnostic_item(cx, ty, sym::HashMap) + || is_type_diagnostic_item(cx, ty, sym::HashSet)) + { + span_lint( + cx, + ITER_OVER_HASH_TYPE, + expr.span, + "iterating over unordered hash-based type", + ); + }; + } +} + diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index e5f8bd5c471..9bdf6b0224d 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -165,6 +165,7 @@ mod item_name_repetitions; mod items_after_statements; mod items_after_test_module; mod iter_not_returning_iterator; +mod iter_over_hash_type; mod iter_without_into_iter; mod large_const_arrays; mod large_enum_variant; @@ -1065,6 +1066,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: }); store.register_late_pass(move |_| Box::new(manual_hash_one::ManualHashOne::new(msrv()))); store.register_late_pass(|_| Box::new(iter_without_into_iter::IterWithoutIntoIter)); + store.register_late_pass(|_| Box::new(iter_over_hash_type::IterOverHashType)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 859bffd6c9c..9c9fb381e54 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -32,6 +32,9 @@ pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncRead pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"]; pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"]; pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"]; +pub const HASHMAP_KEYS: [&str; 5] = ["std", "collections", "hash", "map", "Keys"]; +pub const HASHMAP_VALUES: [&str; 5] = ["std", "collections", "hash", "map", "Values"]; +pub const HASHSET_ITER_TY: [&str; 5] = ["std", "collections", "hash", "set", "Iter"]; pub const HASHSET_ITER: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "iter"]; pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; diff --git a/tests/ui/iter_over_hash_type.rs b/tests/ui/iter_over_hash_type.rs new file mode 100644 index 00000000000..fc340abf146 --- /dev/null +++ b/tests/ui/iter_over_hash_type.rs @@ -0,0 +1,44 @@ +//@aux-build:proc_macros.rs + +#![warn(clippy::iter_over_hash_type)] +use std::collections::{HashMap, HashSet}; + +extern crate proc_macros; + +fn main() { + let hash_set = HashSet::::new(); + let hash_map = HashMap::::new(); + let vec = Vec::::new(); + + for x in &hash_set { + let _ = x; + } + for x in hash_set.iter() { + let _ = x; + } + for x in hash_set { + let _ = x; + } + for (x, y) in &hash_map { + let _ = (x, y); + } + for x in hash_map.keys() { + let _ = x; + } + for x in hash_map.values() { + let _ = x; + } + + // shouldnt fire + for x in &vec { + let _ = x; + } + for x in vec { + let _ = x; + } + + // should not lint, this comes from an external crate + proc_macros::external! { + for _ in HashMap::::new() {} + } +} diff --git a/tests/ui/iter_over_hash_type.stderr b/tests/ui/iter_over_hash_type.stderr new file mode 100644 index 00000000000..72d621c7b59 --- /dev/null +++ b/tests/ui/iter_over_hash_type.stderr @@ -0,0 +1,53 @@ +error: iterating over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:13:5 + | +LL | / for x in &hash_set { +LL | | let _ = x; +LL | | } + | |_____^ + | + = note: `-D clippy::iter-over-hash-type` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]` + +error: iterating over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:16:5 + | +LL | / for x in hash_set.iter() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iterating over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:19:5 + | +LL | / for x in hash_set { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iterating over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:22:5 + | +LL | / for (x, y) in &hash_map { +LL | | let _ = (x, y); +LL | | } + | |_____^ + +error: iterating over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:25:5 + | +LL | / for x in hash_map.keys() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iterating over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:28:5 + | +LL | / for x in hash_map.values() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: aborting due to 6 previous errors + From 7bc39f3af855868705b697888383ce00eb6d1bf4 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Sat, 11 Nov 2023 00:21:35 +0000 Subject: [PATCH 2/5] format and fix examples --- clippy_lints/src/iter_over_hash_type.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/clippy_lints/src/iter_over_hash_type.rs b/clippy_lints/src/iter_over_hash_type.rs index 554790ac61b..607d8e5fc28 100644 --- a/clippy_lints/src/iter_over_hash_type.rs +++ b/clippy_lints/src/iter_over_hash_type.rs @@ -1,6 +1,7 @@ -use clippy_utils::paths::{HASHMAP_KEYS, HASHMAP_VALUES, HASHSET_ITER_TY}; -use clippy_utils::{diagnostics::span_lint, match_def_path}; +use clippy_utils::diagnostics::span_lint; use clippy_utils::higher::ForLoop; +use clippy_utils::match_def_path; +use clippy_utils::paths::{HASHMAP_KEYS, HASHMAP_VALUES, HASHSET_ITER_TY}; use clippy_utils::ty::is_type_diagnostic_item; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -18,16 +19,16 @@ declare_clippy_lint! { /// /// ### Example /// ```no_run - /// let my_map = new Hashmap(); + /// let my_map = std::collections::HashMap::::new(); /// for (key, value) in my_map { /* ... */ } /// ``` /// Use instead: /// ```no_run - /// let my_map = new Hashmap(); - /// let mut keys = my_map.keys().clone().collect::(); + /// let my_map = std::collections::HashMap::::new(); + /// let mut keys = my_map.keys().clone().collect::>(); /// keys.sort(); /// for key in keys { - /// let value = &my_map[value]; + /// let value = &my_map[key]; /// } /// ``` #[clippy::version = "1.75.0"] @@ -45,10 +46,10 @@ impl LateLintPass<'_> for IterOverHashType { && let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs() && let Some(adt) = ty.ty_adt_def() && let did = adt.did() - && (match_def_path(cx, did, &HASHMAP_KEYS) + && (match_def_path(cx, did, &HASHMAP_KEYS) || match_def_path(cx, did, &HASHMAP_VALUES) || match_def_path(cx, did, &HASHSET_ITER_TY) - || is_type_diagnostic_item(cx, ty, sym::HashMap) + || is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::HashSet)) { span_lint( @@ -60,4 +61,3 @@ impl LateLintPass<'_> for IterOverHashType { }; } } - From 941164807f235e6609e697fa32e983f417d878ed Mon Sep 17 00:00:00 2001 From: Jacherr Date: Sat, 11 Nov 2023 21:26:50 +0000 Subject: [PATCH 3/5] implement more types to lint, fix wording --- clippy_lints/src/iter_over_hash_type.rs | 29 +++++++++--- clippy_utils/src/paths.rs | 5 +++ tests/ui/iter_over_hash_type.rs | 21 +++++++-- tests/ui/iter_over_hash_type.stderr | 60 ++++++++++++++++++++----- 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/clippy_lints/src/iter_over_hash_type.rs b/clippy_lints/src/iter_over_hash_type.rs index 607d8e5fc28..d0fedcfc2f4 100644 --- a/clippy_lints/src/iter_over_hash_type.rs +++ b/clippy_lints/src/iter_over_hash_type.rs @@ -1,8 +1,11 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::higher::ForLoop; -use clippy_utils::match_def_path; -use clippy_utils::paths::{HASHMAP_KEYS, HASHMAP_VALUES, HASHSET_ITER_TY}; +use clippy_utils::paths::{ + HASHMAP_DRAIN, HASHMAP_ITER, HASHMAP_ITER_MUT, HASHMAP_KEYS, HASHMAP_VALUES, HASHMAP_VALUES_MUT, HASHSET_DRAIN, + HASHSET_ITER_TY, +}; use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::match_any_def_paths; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; @@ -13,7 +16,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// Because hash types are unordered, when iterated through such as in a for loop, the values are returned in - /// a pseudo-random order. As a result, on redundant systems this may cause inconsistencies and anomalies. + /// an undefined order. As a result, on redundant systems this may cause inconsistencies and anomalies. /// In addition, the unknown order of the elements may reduce readability or introduce other undesired /// side effects. /// @@ -46,9 +49,21 @@ impl LateLintPass<'_> for IterOverHashType { && let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs() && let Some(adt) = ty.ty_adt_def() && let did = adt.did() - && (match_def_path(cx, did, &HASHMAP_KEYS) - || match_def_path(cx, did, &HASHMAP_VALUES) - || match_def_path(cx, did, &HASHSET_ITER_TY) + && (match_any_def_paths( + cx, + did, + &[ + &HASHMAP_KEYS, + &HASHMAP_VALUES, + &HASHMAP_VALUES_MUT, + &HASHMAP_ITER, + &HASHMAP_ITER_MUT, + &HASHMAP_DRAIN, + &HASHSET_ITER_TY, + &HASHSET_DRAIN, + ], + ) + .is_some() || is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::HashSet)) { @@ -56,7 +71,7 @@ impl LateLintPass<'_> for IterOverHashType { cx, ITER_OVER_HASH_TYPE, expr.span, - "iterating over unordered hash-based type", + "iteration over unordered hash-based type", ); }; } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 9c9fb381e54..0a820a1754c 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -32,10 +32,15 @@ pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncRead pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"]; pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"]; pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"]; +pub const HASHMAP_ITER: [&str; 5] = ["std", "collections", "hash", "map", "Iter"]; +pub const HASHMAP_ITER_MUT: [&str; 5] = ["std", "collections", "hash", "map", "IterMut"]; pub const HASHMAP_KEYS: [&str; 5] = ["std", "collections", "hash", "map", "Keys"]; pub const HASHMAP_VALUES: [&str; 5] = ["std", "collections", "hash", "map", "Values"]; +pub const HASHMAP_DRAIN: [&str; 5] = ["std", "collections", "hash", "map", "Drain"]; +pub const HASHMAP_VALUES_MUT: [&str; 5] = ["std", "collections", "hash", "map", "ValuesMut"]; pub const HASHSET_ITER_TY: [&str; 5] = ["std", "collections", "hash", "set", "Iter"]; pub const HASHSET_ITER: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "iter"]; +pub const HASHSET_DRAIN: [&str; 5] = ["std", "collections", "hash", "set", "Drain"]; pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"]; pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"]; pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"]; diff --git a/tests/ui/iter_over_hash_type.rs b/tests/ui/iter_over_hash_type.rs index fc340abf146..9c3f5d33752 100644 --- a/tests/ui/iter_over_hash_type.rs +++ b/tests/ui/iter_over_hash_type.rs @@ -6,8 +6,8 @@ use std::collections::{HashMap, HashSet}; extern crate proc_macros; fn main() { - let hash_set = HashSet::::new(); - let hash_map = HashMap::::new(); + let mut hash_set = HashSet::::new(); + let mut hash_map = HashMap::::new(); let vec = Vec::::new(); for x in &hash_set { @@ -16,7 +16,10 @@ fn main() { for x in hash_set.iter() { let _ = x; } - for x in hash_set { + for x in hash_set.clone() { + let _ = x; + } + for x in hash_set.drain() { let _ = x; } for (x, y) in &hash_map { @@ -28,6 +31,18 @@ fn main() { for x in hash_map.values() { let _ = x; } + for x in hash_map.values_mut() { + *x += 1; + } + for x in hash_map.iter() { + let _ = x; + } + for x in hash_map.clone() { + let _ = x; + } + for x in hash_map.drain() { + let _ = x; + } // shouldnt fire for x in &vec { diff --git a/tests/ui/iter_over_hash_type.stderr b/tests/ui/iter_over_hash_type.stderr index 72d621c7b59..1204b88d283 100644 --- a/tests/ui/iter_over_hash_type.stderr +++ b/tests/ui/iter_over_hash_type.stderr @@ -1,4 +1,4 @@ -error: iterating over unordered hash-based type +error: iteration over unordered hash-based type --> $DIR/iter_over_hash_type.rs:13:5 | LL | / for x in &hash_set { @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::iter-over-hash-type` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]` -error: iterating over unordered hash-based type +error: iteration over unordered hash-based type --> $DIR/iter_over_hash_type.rs:16:5 | LL | / for x in hash_set.iter() { @@ -17,37 +17,77 @@ LL | | let _ = x; LL | | } | |_____^ -error: iterating over unordered hash-based type +error: iteration over unordered hash-based type --> $DIR/iter_over_hash_type.rs:19:5 | -LL | / for x in hash_set { +LL | / for x in hash_set.clone() { LL | | let _ = x; LL | | } | |_____^ -error: iterating over unordered hash-based type +error: iteration over unordered hash-based type --> $DIR/iter_over_hash_type.rs:22:5 | +LL | / for x in hash_set.drain() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:25:5 + | LL | / for (x, y) in &hash_map { LL | | let _ = (x, y); LL | | } | |_____^ -error: iterating over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:25:5 +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:28:5 | LL | / for x in hash_map.keys() { LL | | let _ = x; LL | | } | |_____^ -error: iterating over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:28:5 +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:31:5 | LL | / for x in hash_map.values() { LL | | let _ = x; LL | | } | |_____^ -error: aborting due to 6 previous errors +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:34:5 + | +LL | / for x in hash_map.values_mut() { +LL | | *x += 1; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:37:5 + | +LL | / for x in hash_map.iter() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:40:5 + | +LL | / for x in hash_map.clone() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:43:5 + | +LL | / for x in hash_map.drain() { +LL | | let _ = x; +LL | | } + | |_____^ + +error: aborting due to 11 previous errors From 938984a24e09b20bf972eff0a6e790b61b482b85 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Sat, 11 Nov 2023 21:29:09 +0000 Subject: [PATCH 4/5] run cargo dev fmt --- clippy_lints/src/iter_over_hash_type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/iter_over_hash_type.rs b/clippy_lints/src/iter_over_hash_type.rs index d0fedcfc2f4..7755adc4c1d 100644 --- a/clippy_lints/src/iter_over_hash_type.rs +++ b/clippy_lints/src/iter_over_hash_type.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::higher::ForLoop; +use clippy_utils::match_any_def_paths; use clippy_utils::paths::{ HASHMAP_DRAIN, HASHMAP_ITER, HASHMAP_ITER_MUT, HASHMAP_KEYS, HASHMAP_VALUES, HASHMAP_VALUES_MUT, HASHSET_DRAIN, HASHSET_ITER_TY, }; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::match_any_def_paths; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; From f8ea496495d2766536d7f0fe11c03d609e8ed837 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Mon, 13 Nov 2023 16:48:52 +0000 Subject: [PATCH 5/5] add tests for type-aliased hash types --- tests/ui/iter_over_hash_type.rs | 17 +++++++++++- tests/ui/iter_over_hash_type.stderr | 40 ++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/tests/ui/iter_over_hash_type.rs b/tests/ui/iter_over_hash_type.rs index 9c3f5d33752..7000c8bf96f 100644 --- a/tests/ui/iter_over_hash_type.rs +++ b/tests/ui/iter_over_hash_type.rs @@ -1,15 +1,20 @@ //@aux-build:proc_macros.rs - +#![feature(rustc_private)] #![warn(clippy::iter_over_hash_type)] use std::collections::{HashMap, HashSet}; +extern crate rustc_data_structures; + extern crate proc_macros; fn main() { let mut hash_set = HashSet::::new(); let mut hash_map = HashMap::::new(); + let mut fx_hash_map = rustc_data_structures::fx::FxHashMap::::default(); + let mut fx_hash_set = rustc_data_structures::fx::FxHashMap::::default(); let vec = Vec::::new(); + // test hashset for x in &hash_set { let _ = x; } @@ -22,6 +27,8 @@ fn main() { for x in hash_set.drain() { let _ = x; } + + // test hashmap for (x, y) in &hash_map { let _ = (x, y); } @@ -44,6 +51,14 @@ fn main() { let _ = x; } + // test type-aliased hashers + for x in fx_hash_set { + let _ = x; + } + for x in fx_hash_map { + let _ = x; + } + // shouldnt fire for x in &vec { let _ = x; diff --git a/tests/ui/iter_over_hash_type.stderr b/tests/ui/iter_over_hash_type.stderr index 1204b88d283..cf420fb8e99 100644 --- a/tests/ui/iter_over_hash_type.stderr +++ b/tests/ui/iter_over_hash_type.stderr @@ -1,5 +1,5 @@ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:13:5 + --> $DIR/iter_over_hash_type.rs:18:5 | LL | / for x in &hash_set { LL | | let _ = x; @@ -10,7 +10,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]` error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:16:5 + --> $DIR/iter_over_hash_type.rs:21:5 | LL | / for x in hash_set.iter() { LL | | let _ = x; @@ -18,7 +18,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:19:5 + --> $DIR/iter_over_hash_type.rs:24:5 | LL | / for x in hash_set.clone() { LL | | let _ = x; @@ -26,7 +26,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:22:5 + --> $DIR/iter_over_hash_type.rs:27:5 | LL | / for x in hash_set.drain() { LL | | let _ = x; @@ -34,7 +34,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:25:5 + --> $DIR/iter_over_hash_type.rs:32:5 | LL | / for (x, y) in &hash_map { LL | | let _ = (x, y); @@ -42,7 +42,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:28:5 + --> $DIR/iter_over_hash_type.rs:35:5 | LL | / for x in hash_map.keys() { LL | | let _ = x; @@ -50,7 +50,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:31:5 + --> $DIR/iter_over_hash_type.rs:38:5 | LL | / for x in hash_map.values() { LL | | let _ = x; @@ -58,7 +58,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:34:5 + --> $DIR/iter_over_hash_type.rs:41:5 | LL | / for x in hash_map.values_mut() { LL | | *x += 1; @@ -66,7 +66,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:37:5 + --> $DIR/iter_over_hash_type.rs:44:5 | LL | / for x in hash_map.iter() { LL | | let _ = x; @@ -74,7 +74,7 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:40:5 + --> $DIR/iter_over_hash_type.rs:47:5 | LL | / for x in hash_map.clone() { LL | | let _ = x; @@ -82,12 +82,28 @@ LL | | } | |_____^ error: iteration over unordered hash-based type - --> $DIR/iter_over_hash_type.rs:43:5 + --> $DIR/iter_over_hash_type.rs:50:5 | LL | / for x in hash_map.drain() { LL | | let _ = x; LL | | } | |_____^ -error: aborting due to 11 previous errors +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:55:5 + | +LL | / for x in fx_hash_set { +LL | | let _ = x; +LL | | } + | |_____^ + +error: iteration over unordered hash-based type + --> $DIR/iter_over_hash_type.rs:58:5 + | +LL | / for x in fx_hash_map { +LL | | let _ = x; +LL | | } + | |_____^ + +error: aborting due to 13 previous errors