]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/neg_multiply.rs
Fix lines that exceed max width manually
[rust.git] / clippy_lints / src / neg_multiply.rs
1 use rustc::hir::*;
2 use rustc::lint::*;
3 use syntax::codemap::{Span, Spanned};
4
5 use consts::{self, Constant};
6 use utils::span_lint;
7
8 /// **What it does:** Checks for multiplication by -1 as a form of negation.
9 ///
10 /// **Why is this bad?** It's more readable to just negate.
11 ///
12 /// **Known problems:** This only catches integers (for now).
13 ///
14 /// **Example:**
15 /// ```rust
16 /// x * -1
17 /// ```
18 declare_lint! {
19     pub NEG_MULTIPLY,
20     Warn,
21     "multiplying integers with -1"
22 }
23
24 #[derive(Copy, Clone)]
25 pub struct NegMultiply;
26
27 impl LintPass for NegMultiply {
28     fn get_lints(&self) -> LintArray {
29         lint_array!(NEG_MULTIPLY)
30     }
31 }
32
33 #[allow(match_same_arms)]
34 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
35     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
36         if let ExprBinary(Spanned { node: BiMul, .. }, ref l, ref r) = e.node {
37             match (&l.node, &r.node) {
38                 (&ExprUnary(..), &ExprUnary(..)) => (),
39                 (&ExprUnary(UnNeg, ref lit), _) => check_mul(cx, e.span, lit, r),
40                 (_, &ExprUnary(UnNeg, ref lit)) => check_mul(cx, e.span, lit, l),
41                 _ => (),
42             }
43         }
44     }
45 }
46
47 fn check_mul(cx: &LateContext, span: Span, lit: &Expr, exp: &Expr) {
48     if_chain! {
49         if let ExprLit(ref l) = lit.node;
50         if let Constant::Int(ref ci) = consts::lit_to_constant(&l.node, cx.tcx, cx.tables.expr_ty(lit));
51         if let Some(val) = ci.to_u64();
52         if val == 1;
53         if cx.tables.expr_ty(exp).is_integral();
54         then {
55             span_lint(cx,
56                       NEG_MULTIPLY,
57                       span,
58                       "Negation by multiplying with -1");
59         }
60     }
61 }