]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/erasing_op.rs
Fix ICE for issues 2767, 2499, 1782
[rust.git] / clippy_lints / src / erasing_op.rs
1 use consts::{constant_simple, Constant};
2 use rustc::hir::*;
3 use rustc::lint::*;
4 use syntax::codemap::Span;
5 use utils::{in_macro, span_lint};
6
7 /// **What it does:** Checks for erasing operations, e.g. `x * 0`.
8 ///
9 /// **Why is this bad?** The whole expression can be replaced by zero.
10 /// This is most likely not the intended outcome and should probably be
11 /// corrected
12 ///
13 /// **Known problems:** None.
14 ///
15 /// **Example:**
16 /// ```rust
17 /// 0 / x; 0 * x; x & 0
18 /// ```
19 declare_clippy_lint! {
20     pub ERASING_OP,
21     correctness,
22     "using erasing operations, e.g. `x * 0` or `y & 0`"
23 }
24
25 #[derive(Copy, Clone)]
26 pub struct ErasingOp;
27
28 impl LintPass for ErasingOp {
29     fn get_lints(&self) -> LintArray {
30         lint_array!(ERASING_OP)
31     }
32 }
33
34 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ErasingOp {
35     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
36         if in_macro(e.span) {
37             return;
38         }
39         if let ExprBinary(ref cmp, ref left, ref right) = e.node {
40             match cmp.node {
41                 BiMul | BiBitAnd => {
42                     check(cx, left, e.span);
43                     check(cx, right, e.span);
44                 },
45                 BiDiv => check(cx, left, e.span),
46                 _ => (),
47             }
48         }
49     }
50 }
51
52 fn check(cx: &LateContext, e: &Expr, span: Span) {
53     if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables, e) {
54         if v == 0 {
55             span_lint(
56                 cx,
57                 ERASING_OP,
58                 span,
59                 "this operation will always return zero. This is likely not the intended outcome",
60             );
61         }
62     }
63 }