summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
blob: dd7fae79d9ba842aa78b3cdf523328e4d0f8a974 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use super::UNUSED_ENUMERATE_INDEX;
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::{pat_is_wild, sugg};
use rustc_hir::def::DefKind;
use rustc_hir::{Expr, ExprKind, Pat, PatKind};
use rustc_lint::LateContext;
use rustc_middle::ty;

/// Checks for the `UNUSED_ENUMERATE_INDEX` lint.
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>) {
    let PatKind::Tuple([index, elem], _) = pat.kind else {
        return;
    };

    let ExprKind::MethodCall(_method, self_arg, [], _) = arg.kind else {
        return;
    };

    let ty = cx.typeck_results().expr_ty(arg);

    if !pat_is_wild(cx, &index.kind, body) {
        return;
    }

    let name = match *ty.kind() {
        ty::Adt(base, _substs) => cx.tcx.def_path_str(base.did()),
        _ => return,
    };

    if name != "std::iter::Enumerate" && name != "core::iter::Enumerate" {
        return;
    }

    let Some((DefKind::AssocFn, call_id)) = cx.typeck_results().type_dependent_def(arg.hir_id) else {
        return;
    };

    let call_name = cx.tcx.def_path_str(call_id);

    if call_name != "std::iter::Iterator::enumerate" && call_name != "core::iter::Iterator::enumerate" {
        return;
    }

    span_lint_and_then(
        cx,
        UNUSED_ENUMERATE_INDEX,
        arg.span,
        "you seem to use `.enumerate()` and immediately discard the index",
        |diag| {
            let base_iter = sugg::Sugg::hir(cx, self_arg, "base iter");
            multispan_sugg(
                diag,
                "remove the `.enumerate()` call",
                vec![
                    (pat.span, snippet(cx, elem.span, "..").into_owned()),
                    (arg.span, base_iter.to_string()),
                ],
            );
        },
    );
}