use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_expr_path_def_path, is_trait_method, path_to_local_id, paths};
-use if_chain::if_chain;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use super::FILTER_MAP_IDENTITY;
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg: &hir::Expr<'_>, filter_map_span: Span) {
- if is_trait_method(cx, expr, sym::Iterator) {
- let apply_lint = |message: &str| {
- span_lint_and_sugg(
- cx,
- FILTER_MAP_IDENTITY,
- filter_map_span.with_hi(expr.span.hi()),
- message,
- "try",
- "flatten()".to_string(),
- Applicability::MachineApplicable,
- );
- };
-
- if_chain! {
- if let hir::ExprKind::Closure(_, _, body_id, _, _) = filter_map_arg.kind;
- let body = cx.tcx.hir().body(body_id);
-
- if let hir::PatKind::Binding(_, binding_id, ..) = body.params[0].pat.kind;
- if path_to_local_id(&body.value, binding_id);
- then {
- apply_lint("called `filter_map(|x| x)` on an `Iterator`");
- }
- }
-
- if is_expr_path_def_path(cx, filter_map_arg, &paths::CONVERT_IDENTITY) {
- apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
- }
+ if is_trait_method(cx, expr, sym::Iterator) && is_expr_identity_function(cx, filter_map_arg) {
+ span_lint_and_sugg(
+ cx,
+ FILTER_MAP_IDENTITY,
+ filter_map_span.with_hi(expr.span.hi()),
+ "use of `filter_map` with an identity function",
+ "try",
+ "flatten()".to_string(),
+ Applicability::MachineApplicable,
+ );
}
}