]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/methods/flat_map_identity.rs
Add disallowed_types lint, this adds a field to the Conf struct
[rust.git] / clippy_lints / src / methods / flat_map_identity.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::{is_expr_path_def_path, is_trait_method, paths};
3 use if_chain::if_chain;
4 use rustc_errors::Applicability;
5 use rustc_hir as hir;
6 use rustc_lint::LateContext;
7 use rustc_span::{source_map::Span, sym};
8
9 use super::FLAT_MAP_IDENTITY;
10
11 /// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient
12 pub(super) fn check<'tcx>(
13     cx: &LateContext<'tcx>,
14     expr: &'tcx hir::Expr<'_>,
15     flat_map_arg: &'tcx hir::Expr<'_>,
16     flat_map_span: Span,
17 ) {
18     if is_trait_method(cx, expr, sym::Iterator) {
19         let apply_lint = |message: &str| {
20             span_lint_and_sugg(
21                 cx,
22                 FLAT_MAP_IDENTITY,
23                 flat_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, _, _) = flat_map_arg.kind;
33             let body = cx.tcx.hir().body(body_id);
34
35             if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind;
36             if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = body.value.kind;
37
38             if path.segments.len() == 1;
39             if path.segments[0].ident.name == binding_ident.name;
40
41             then {
42                 apply_lint("called `flat_map(|x| x)` on an `Iterator`");
43             }
44         }
45
46         if is_expr_path_def_path(cx, flat_map_arg, &paths::CONVERT_IDENTITY) {
47             apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
48         }
49     }
50 }