]>
Commit | Line | Data |
---|---|---|
cdc7bbd5 XL |
1 | use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; |
2 | use clippy_utils::source::snippet; | |
3 | use clippy_utils::{is_trait_method, meets_msrv, msrvs}; | |
f20569fa XL |
4 | use rustc_errors::Applicability; |
5 | use rustc_hir as hir; | |
6 | use rustc_lint::LateContext; | |
7 | use rustc_semver::RustcVersion; | |
cdc7bbd5 | 8 | use rustc_span::sym; |
f20569fa XL |
9 | |
10 | use super::FILTER_MAP_NEXT; | |
11 | ||
f20569fa XL |
12 | pub(super) fn check<'tcx>( |
13 | cx: &LateContext<'tcx>, | |
14 | expr: &'tcx hir::Expr<'_>, | |
cdc7bbd5 XL |
15 | recv: &'tcx hir::Expr<'_>, |
16 | arg: &'tcx hir::Expr<'_>, | |
923072b8 | 17 | msrv: Option<RustcVersion>, |
f20569fa | 18 | ) { |
cdc7bbd5 | 19 | if is_trait_method(cx, expr, sym::Iterator) { |
923072b8 | 20 | if !meets_msrv(msrv, msrvs::ITERATOR_FIND_MAP) { |
f20569fa XL |
21 | return; |
22 | } | |
23 | ||
24 | let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \ | |
25 | `.find_map(..)` instead"; | |
cdc7bbd5 | 26 | let filter_snippet = snippet(cx, arg.span, ".."); |
f20569fa | 27 | if filter_snippet.lines().count() <= 1 { |
cdc7bbd5 | 28 | let iter_snippet = snippet(cx, recv.span, ".."); |
f20569fa XL |
29 | span_lint_and_sugg( |
30 | cx, | |
31 | FILTER_MAP_NEXT, | |
32 | expr.span, | |
33 | msg, | |
34 | "try this", | |
35 | format!("{}.find_map({})", iter_snippet, filter_snippet), | |
36 | Applicability::MachineApplicable, | |
37 | ); | |
38 | } else { | |
39 | span_lint(cx, FILTER_MAP_NEXT, expr.span, msg); | |
40 | } | |
41 | } | |
42 | } |