Do not make incomplete or invalid suggestions

The `unnecessary_filter_map` and `unnecessary_find_map` lints were
making partial suggestions, proposing to replace the whole expression by
only the method name, or a subexpression which contained explicit
placeholders.

Since even `MaybeIncorrect` suggestions must generate code that
compiles, this changes those lints to recommandation lints with no
code suggestion.
This commit is contained in:
Samuel Tardieu 2025-03-27 20:44:03 +01:00
parent a895265a4e
commit 01820a9efe
5 changed files with 48 additions and 69 deletions

View file

@ -1,11 +1,10 @@
use super::utils::clone_or_copy_needed;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_copy;
use clippy_utils::usage::mutated_variables;
use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
use core::ops::ControlFlow;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::LangItem::{OptionNone, OptionSome};
use rustc_lint::LateContext;
@ -45,30 +44,32 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
&& is_res_lang_ctor(cx, path_res(cx, expr), OptionSome)
&& let hir::ExprKind::Path(_) = args[0].kind
{
span_lint_and_sugg(
span_lint(
cx,
UNNECESSARY_FILTER_MAP,
expr.span,
format!("{name} is unnecessary"),
"try removing the filter_map",
String::new(),
Applicability::MaybeIncorrect,
String::from("this call to `.filter_map(..)` is unnecessary"),
);
return;
}
if name == "filter_map" {
"map(..)"
} else {
"map(..).next()"
}
if name == "filter_map" { "map" } else { "map(..).next()" }
} else if !found_mapping && !mutates_arg && (!clone_or_copy_needed || is_copy(cx, in_ty)) {
match cx.typeck_results().expr_ty(body.value).kind() {
ty::Adt(adt, subst)
if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && in_ty == subst.type_at(0) =>
{
if name == "filter_map" { "filter" } else { "find" }
if name == "filter_map" { "filter(..)" } else { "find(..)" }
},
_ => return,
}
} else {
return;
};
span_lint_and_sugg(
span_lint(
cx,
if name == "filter_map" {
UNNECESSARY_FILTER_MAP
@ -76,10 +77,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
UNNECESSARY_FIND_MAP
},
expr.span,
format!("this `.{name}` can be written more simply"),
"try instead",
sugg.to_string(),
Applicability::MaybeIncorrect,
format!("this `.{name}(..)` can be written more simply using `.{sugg}`"),
);
}
}