]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/operators/erasing_op.rs
Rollup merge of #103305 - c410-f3r:moar-errors, r=petrochenkov
[rust.git] / src / tools / clippy / clippy_lints / src / operators / erasing_op.rs
1 use clippy_utils::consts::{constant_simple, Constant};
2 use clippy_utils::diagnostics::span_lint;
3 use clippy_utils::ty::same_type_and_consts;
4
5 use rustc_hir::{BinOpKind, Expr};
6 use rustc_lint::LateContext;
7 use rustc_middle::ty::TypeckResults;
8
9 use super::ERASING_OP;
10
11 pub(super) fn check<'tcx>(
12     cx: &LateContext<'tcx>,
13     e: &'tcx Expr<'_>,
14     op: BinOpKind,
15     left: &'tcx Expr<'_>,
16     right: &'tcx Expr<'_>,
17 ) {
18     let tck = cx.typeck_results();
19     match op {
20         BinOpKind::Mul | BinOpKind::BitAnd => {
21             check_op(cx, tck, left, right, e);
22             check_op(cx, tck, right, left, e);
23         },
24         BinOpKind::Div => check_op(cx, tck, left, right, e),
25         _ => (),
26     }
27 }
28
29 fn different_types(tck: &TypeckResults<'_>, input: &Expr<'_>, output: &Expr<'_>) -> bool {
30     let input_ty = tck.expr_ty(input).peel_refs();
31     let output_ty = tck.expr_ty(output).peel_refs();
32     !same_type_and_consts(input_ty, output_ty)
33 }
34
35 fn check_op<'tcx>(
36     cx: &LateContext<'tcx>,
37     tck: &TypeckResults<'tcx>,
38     op: &Expr<'tcx>,
39     other: &Expr<'tcx>,
40     parent: &Expr<'tcx>,
41 ) {
42     if constant_simple(cx, tck, op) == Some(Constant::Int(0)) {
43         if different_types(tck, other, parent) {
44             return;
45         }
46         span_lint(
47             cx,
48             ERASING_OP,
49             parent.span,
50             "this operation will always return zero. This is likely not the intended outcome",
51         );
52     }
53 }