summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/operators/verbose_bit_mask.rs
blob: ff85fd554298822f768df19441cafa4b959f00c9 (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
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::sugg::Sugg;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::LateContext;

use super::VERBOSE_BIT_MASK;

pub(super) fn check<'tcx>(
    cx: &LateContext<'tcx>,
    e: &'tcx Expr<'_>,
    op: BinOpKind,
    left: &'tcx Expr<'_>,
    right: &'tcx Expr<'_>,
    threshold: u64,
) {
    if BinOpKind::Eq == op
        && let ExprKind::Binary(op1, left1, right1) = &left.kind
        && BinOpKind::BitAnd == op1.node
        && let ExprKind::Lit(lit) = &right1.kind
        && let LitKind::Int(n, _) = lit.node
        && let ExprKind::Lit(lit1) = &right.kind
        && let LitKind::Int(0, _) = lit1.node
        && n.leading_zeros() == n.count_zeros()
        && n > u128::from(threshold)
    {
        span_lint_and_then(
            cx,
            VERBOSE_BIT_MASK,
            e.span,
            "bit mask could be simplified with a call to `trailing_zeros`",
            |diag| {
                let sugg = Sugg::hir(cx, left1, "...").maybe_par();
                diag.span_suggestion(
                    e.span,
                    "try",
                    format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()),
                    Applicability::MaybeIncorrect,
                );
            },
        );
    }
}