From 891e38788a36c3d217e4e06d52e4ee67797b8ccb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 Jan 2025 12:54:19 +0100 Subject: [PATCH 1/2] Don't emit machine applicable `map_flatten` lint if there are code comments --- clippy_lints/src/methods/map_flatten.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/methods/map_flatten.rs b/clippy_lints/src/methods/map_flatten.rs index 07a7a12b1627..f7bb8c1d696d 100644 --- a/clippy_lints/src/methods/map_flatten.rs +++ b/clippy_lints/src/methods/map_flatten.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::is_trait_method; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::{is_trait_method, span_contains_comment}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; @@ -17,10 +17,15 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, map_ let mut applicability = Applicability::MachineApplicable; let closure_snippet = snippet_with_applicability(cx, map_arg.span, "..", &mut applicability); + let span = expr.span.with_lo(map_span.lo()); + // If the methods are separated with comments, we don't apply suggestion automatically. + if span_contains_comment(cx.tcx.sess.source_map(), span) { + applicability = Applicability::Unspecified; + } span_lint_and_sugg( cx, MAP_FLATTEN, - expr.span.with_lo(map_span.lo()), + span, format!("called `map(..).flatten()` on `{caller_ty_name}`"), format!("try replacing `map` with `{method_to_use}` and remove the `.flatten()`"), format!("{method_to_use}({closure_snippet})"), From 78225ccca8980e357123ac936655a40e0b0c8b8f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 Jan 2025 12:55:09 +0100 Subject: [PATCH 2/2] Add regression test for #8528 --- tests/ui/map_flatten.rs | 12 ++++++++++++ tests/ui/map_flatten.stderr | 11 ++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/ui/map_flatten.rs b/tests/ui/map_flatten.rs index 76916d465919..eafc8b6e81ca 100644 --- a/tests/ui/map_flatten.rs +++ b/tests/ui/map_flatten.rs @@ -55,6 +55,18 @@ fn long_span() { .collect(); } +#[allow(clippy::useless_vec)] +fn no_suggestion_if_comments_present() { + let vec = vec![vec![1, 2, 3]]; + let _ = vec + .iter() + // a lovely comment explaining the code in very detail + .map(|x| x.iter()) + //~^ ERROR: called `map(..).flatten()` on `Iterator` + // the answer to life, the universe and everything could be here + .flatten(); +} + fn main() { long_span(); } diff --git a/tests/ui/map_flatten.stderr b/tests/ui/map_flatten.stderr index a5837b97617d..34bd174d7dde 100644 --- a/tests/ui/map_flatten.stderr +++ b/tests/ui/map_flatten.stderr @@ -102,5 +102,14 @@ LL + } LL + }) | -error: aborting due to 4 previous errors +error: called `map(..).flatten()` on `Iterator` + --> tests/ui/map_flatten.rs:64:10 + | +LL | .map(|x| x.iter()) + | __________^ +... | +LL | | .flatten(); + | |__________________^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| x.iter())` + +error: aborting due to 5 previous errors