Auto merge of #13548 - wowinter13:unnecessary_filter_map_filter_map_some, r=llogiq

fix: remove unnecessary filter_map usages

fixes https://github.com/rust-lang/rust-clippy/issues/12556

(Fixed version of https://github.com/rust-lang/rust-clippy/pull/12766)

changelog: [unnecessary_filter_map]: filter map improvements
This commit is contained in:
bors 2024-10-27 22:27:49 +00:00
commit 73bad368f2
5 changed files with 92 additions and 44 deletions

View file

@ -1,13 +1,15 @@
use super::utils::clone_or_copy_needed;
use clippy_utils::diagnostics::span_lint;
use clippy_utils::diagnostics::span_lint_and_sugg;
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 clippy_utils::{MaybePath, 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;
use rustc_middle::query::Key;
use rustc_middle::ty;
use rustc_span::sym;
@ -36,9 +38,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
ControlFlow::Continue(Descend::Yes)
}
});
let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
let sugg = if !found_filtering {
// Check if the closure is .filter_map(|x| Some(x))
if name == "filter_map"
&& let hir::ExprKind::Call(expr, args) = body.value.kind
&& is_res_lang_ctor(cx, path_res(cx, expr), OptionSome)
&& arg_id.ty_def_id() == args[0].hir_id().ty_def_id()
&& let hir::ExprKind::Path(_) = args[0].kind
{
span_lint_and_sugg(
cx,
UNNECESSARY_FILTER_MAP,
expr.span,
format!("{name} is unnecessary"),
"try removing the filter_map",
String::new(),
Applicability::MaybeIncorrect,
);
}
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() {
@ -52,7 +70,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
} else {
return;
};
span_lint(
span_lint_and_sugg(
cx,
if name == "filter_map" {
UNNECESSARY_FILTER_MAP
@ -60,7 +78,10 @@ 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 using `.{sugg}`"),
format!("this `.{name}` can be written more simply"),
"try instead",
sugg.to_string(),
Applicability::MaybeIncorrect,
);
}
}