From 5f651da2de3e4141df42a47ef47762b642c447bc Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 3 Nov 2023 23:23:59 +0100 Subject: [PATCH] fix iter_kv_map dont suggest into_keys and into_values if msrv is to low --- clippy_config/src/msrvs.rs | 1 + clippy_lints/src/methods/iter_kv_map.rs | 5 ++ clippy_lints/src/methods/mod.rs | 2 +- tests/ui/iter_kv_map.fixed | 43 +++++++++++++++++ tests/ui/iter_kv_map.rs | 43 +++++++++++++++++ tests/ui/iter_kv_map.stderr | 62 ++++++++++++++++++++++++- 6 files changed, 154 insertions(+), 2 deletions(-) diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index 011d54629d4..b3ef666e306 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -23,6 +23,7 @@ msrv_aliases! { 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY } 1,55,0 { SEEK_REWIND } + 1,54,0 { INTO_KEYS } 1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR } 1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST } 1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS } diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index c5dbb6ad98b..e1b934d36ea 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -1,6 +1,7 @@ #![allow(unused_imports)] use super::ITER_KV_MAP; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::ty::is_type_diagnostic_item; @@ -21,7 +22,11 @@ pub(super) fn check<'tcx>( expr: &'tcx Expr<'tcx>, // .iter().map(|(_, v_| v)) recv: &'tcx Expr<'tcx>, // hashmap m_arg: &'tcx Expr<'tcx>, // |(_, v)| v + msrv: &Msrv, ) { + if map_type == "into_iter" && !msrv.meets(msrvs::INTO_KEYS) { + return; + } if !expr.span.from_expansion() && let ExprKind::Closure(c) = m_arg.kind && let Body { diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 57c3913944f..d9ab0f3b8ca 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -4255,7 +4255,7 @@ impl Methods { map_clone::check(cx, expr, recv, m_arg, &self.msrv); match method_call(recv) { Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => { - iter_kv_map::check(cx, map_name, expr, recv2, m_arg); + iter_kv_map::check(cx, map_name, expr, recv2, m_arg, &self.msrv); }, Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( cx, diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed index 566a5b690d8..2cbf972fca5 100644 --- a/tests/ui/iter_kv_map.fixed +++ b/tests/ui/iter_kv_map.fixed @@ -89,3 +89,46 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_values().count(); } + +#[clippy::msrv = "1.53"] +fn msrv_1_53() { + let map: HashMap = HashMap::new(); + + // Don't lint because into_iter is not supported + let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + + let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + + // Lint + let _ = map.keys().collect::>(); + //~^ ERROR: iterating on a map's keys + let _ = map.values().collect::>(); + //~^ ERROR: iterating on a map's values + let _ = map.values().map(|v| v + 2).collect::>(); + //~^ ERROR: iterating on a map's values +} + +#[clippy::msrv = "1.54"] +fn msrv_1_54() { + // Lint all + let map: HashMap = HashMap::new(); + + let _ = map.clone().into_keys().collect::>(); + //~^ ERROR: iterating on a map's keys + let _ = map.clone().into_keys().map(|key| key + 2).collect::>(); + //~^ ERROR: iterating on a map's keys + + let _ = map.clone().into_values().collect::>(); + //~^ ERROR: iterating on a map's values + let _ = map.clone().into_values().map(|val| val + 2).collect::>(); + //~^ ERROR: iterating on a map's values + + let _ = map.keys().collect::>(); + //~^ ERROR: iterating on a map's keys + let _ = map.values().collect::>(); + //~^ ERROR: iterating on a map's values + let _ = map.values().map(|v| v + 2).collect::>(); + //~^ ERROR: iterating on a map's values +} diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs index d85e501da48..6a9a4267a76 100644 --- a/tests/ui/iter_kv_map.rs +++ b/tests/ui/iter_kv_map.rs @@ -93,3 +93,46 @@ fn main() { // Don't let a mut interfere. let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); } + +#[clippy::msrv = "1.53"] +fn msrv_1_53() { + let map: HashMap = HashMap::new(); + + // Don't lint because into_iter is not supported + let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + + let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + + // Lint + let _ = map.iter().map(|(key, _)| key).collect::>(); + //~^ ERROR: iterating on a map's keys + let _ = map.iter().map(|(_, value)| value).collect::>(); + //~^ ERROR: iterating on a map's values + let _ = map.iter().map(|(_, v)| v + 2).collect::>(); + //~^ ERROR: iterating on a map's values +} + +#[clippy::msrv = "1.54"] +fn msrv_1_54() { + // Lint all + let map: HashMap = HashMap::new(); + + let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + //~^ ERROR: iterating on a map's keys + let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + //~^ ERROR: iterating on a map's keys + + let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + //~^ ERROR: iterating on a map's values + let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + //~^ ERROR: iterating on a map's values + + let _ = map.iter().map(|(key, _)| key).collect::>(); + //~^ ERROR: iterating on a map's keys + let _ = map.iter().map(|(_, value)| value).collect::>(); + //~^ ERROR: iterating on a map's values + let _ = map.iter().map(|(_, v)| v + 2).collect::>(); + //~^ ERROR: iterating on a map's values +} diff --git a/tests/ui/iter_kv_map.stderr b/tests/ui/iter_kv_map.stderr index 62155b7f838..471615978e1 100644 --- a/tests/ui/iter_kv_map.stderr +++ b/tests/ui/iter_kv_map.stderr @@ -201,5 +201,65 @@ error: iterating on a map's values LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` -error: aborting due to 28 previous errors +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:109:13 + | +LL | let _ = map.iter().map(|(key, _)| key).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:111:13 + | +LL | let _ = map.iter().map(|(_, value)| value).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:113:13 + | +LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` + +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:122:13 + | +LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()` + +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:124:13 + | +LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:127:13 + | +LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:129:13 + | +LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)` + +error: iterating on a map's keys + --> $DIR/iter_kv_map.rs:132:13 + | +LL | let _ = map.iter().map(|(key, _)| key).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:134:13 + | +LL | let _ = map.iter().map(|(_, value)| value).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()` + +error: iterating on a map's values + --> $DIR/iter_kv_map.rs:136:13 + | +LL | let _ = map.iter().map(|(_, v)| v + 2).collect::>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)` + +error: aborting due to 38 previous errors