]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/methods/filter_map_identity.rs
Merge remote-tracking branch 'upstream/master' into rustup
[rust.git] / clippy_lints / src / methods / filter_map_identity.rs
1 use crate::utils::{match_qpath, match_trait_method, path_to_local_id, paths, span_lint_and_sugg};
2 use if_chain::if_chain;
3 use rustc_errors::Applicability;
4 use rustc_hir as hir;
5 use rustc_lint::LateContext;
6 use rustc_span::source_map::Span;
7
8 use super::FILTER_MAP_IDENTITY;
9
10 pub(super) fn check(
11     cx: &LateContext<'_>,
12     expr: &hir::Expr<'_>,
13     filter_map_args: &[hir::Expr<'_>],
14     filter_map_span: Span,
15 ) {
16     if match_trait_method(cx, expr, &paths::ITERATOR) {
17         let arg_node = &filter_map_args[1].kind;
18
19         let apply_lint = |message: &str| {
20             span_lint_and_sugg(
21                 cx,
22                 FILTER_MAP_IDENTITY,
23                 filter_map_span.with_hi(expr.span.hi()),
24                 message,
25                 "try",
26                 "flatten()".to_string(),
27                 Applicability::MachineApplicable,
28             );
29         };
30
31         if_chain! {
32             if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
33             let body = cx.tcx.hir().body(*body_id);
34
35             if let hir::PatKind::Binding(_, binding_id, ..) = body.params[0].pat.kind;
36             if path_to_local_id(&body.value, binding_id);
37             then {
38                 apply_lint("called `filter_map(|x| x)` on an `Iterator`");
39             }
40         }
41
42         if_chain! {
43             if let hir::ExprKind::Path(ref qpath) = arg_node;
44
45             if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
46
47             then {
48                 apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
49             }
50         }
51     }
52 }