]>
Commit | Line | Data |
---|---|---|
ed00b5ec | 1 | use clippy_config::msrvs::{self, Msrv}; |
add651ee | 2 | use clippy_utils::diagnostics::span_lint_and_sugg; |
add651ee FG |
3 | use clippy_utils::source::snippet_opt; |
4 | use clippy_utils::ty::implements_trait; | |
4b012472 | 5 | use clippy_utils::{is_from_proc_macro, is_trait_method}; |
fe692bf9 | 6 | use rustc_errors::Applicability; |
add651ee FG |
7 | use rustc_hir::def::{DefKind, Res}; |
8 | use rustc_hir::{Expr, ExprKind}; | |
fe692bf9 FG |
9 | use rustc_lint::{LateContext, LintContext}; |
10 | use rustc_middle::lint::in_external_macro; | |
4b012472 | 11 | use rustc_span::{sym, Span}; |
fe692bf9 FG |
12 | |
13 | use super::MANUAL_TRY_FOLD; | |
14 | ||
15 | pub(super) fn check<'tcx>( | |
16 | cx: &LateContext<'tcx>, | |
17 | expr: &Expr<'tcx>, | |
18 | init: &Expr<'_>, | |
19 | acc: &Expr<'_>, | |
20 | fold_span: Span, | |
21 | msrv: &Msrv, | |
22 | ) { | |
23 | if !in_external_macro(cx.sess(), fold_span) | |
ed00b5ec | 24 | && msrv.meets(msrvs::ITERATOR_TRY_FOLD) |
4b012472 | 25 | && is_trait_method(cx, expr, sym::Iterator) |
fe692bf9 FG |
26 | && let init_ty = cx.typeck_results().expr_ty(init) |
27 | && let Some(try_trait) = cx.tcx.lang_items().try_trait() | |
28 | && implements_trait(cx, init_ty, try_trait, &[]) | |
29 | && let ExprKind::Call(path, [first, rest @ ..]) = init.kind | |
30 | && let ExprKind::Path(qpath) = path.kind | |
31 | && let Res::Def(DefKind::Ctor(_, _), _) = cx.qpath_res(&qpath, path.hir_id) | |
32 | && let ExprKind::Closure(closure) = acc.kind | |
33 | && !is_from_proc_macro(cx, expr) | |
34 | && let Some(args_snip) = closure.fn_arg_span.and_then(|fn_arg_span| snippet_opt(cx, fn_arg_span)) | |
35 | { | |
36 | let init_snip = rest | |
37 | .is_empty() | |
38 | .then_some(first.span) | |
39 | .and_then(|span| snippet_opt(cx, span)) | |
40 | .unwrap_or("...".to_owned()); | |
41 | ||
42 | span_lint_and_sugg( | |
43 | cx, | |
44 | MANUAL_TRY_FOLD, | |
45 | fold_span, | |
46 | "usage of `Iterator::fold` on a type that implements `Try`", | |
47 | "use `try_fold` instead", | |
ed00b5ec | 48 | format!("try_fold({init_snip}, {args_snip} ...)",), |
fe692bf9 FG |
49 | Applicability::HasPlaceholders, |
50 | ); | |
51 | } | |
52 | } |