]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use crate::utils::{match_qpath, match_trait_method, 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::FLAT_MAP_IDENTITY; | |
9 | ||
10 | /// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient | |
11 | pub(super) fn check<'tcx>( | |
12 | cx: &LateContext<'tcx>, | |
13 | expr: &'tcx hir::Expr<'_>, | |
14 | flat_map_args: &'tcx [hir::Expr<'_>], | |
15 | flat_map_span: Span, | |
16 | ) { | |
17 | if match_trait_method(cx, expr, &paths::ITERATOR) { | |
18 | let arg_node = &flat_map_args[1].kind; | |
19 | ||
20 | let apply_lint = |message: &str| { | |
21 | span_lint_and_sugg( | |
22 | cx, | |
23 | FLAT_MAP_IDENTITY, | |
24 | flat_map_span.with_hi(expr.span.hi()), | |
25 | message, | |
26 | "try", | |
27 | "flatten()".to_string(), | |
28 | Applicability::MachineApplicable, | |
29 | ); | |
30 | }; | |
31 | ||
32 | if_chain! { | |
33 | if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node; | |
34 | let body = cx.tcx.hir().body(*body_id); | |
35 | ||
36 | if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind; | |
37 | if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = body.value.kind; | |
38 | ||
39 | if path.segments.len() == 1; | |
40 | if path.segments[0].ident.name == binding_ident.name; | |
41 | ||
42 | then { | |
43 | apply_lint("called `flat_map(|x| x)` on an `Iterator`"); | |
44 | } | |
45 | } | |
46 | ||
47 | if_chain! { | |
48 | if let hir::ExprKind::Path(ref qpath) = arg_node; | |
49 | ||
50 | if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY); | |
51 | ||
52 | then { | |
53 | apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`"); | |
54 | } | |
55 | } | |
56 | } | |
57 | } |