]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/neg_multiply.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / neg_multiply.rs
CommitLineData
17df50a5 1use clippy_utils::consts::{self, Constant};
a2a8927a
XL
2use clippy_utils::diagnostics::span_lint_and_sugg;
3use clippy_utils::source::snippet_with_applicability;
f20569fa 4use if_chain::if_chain;
a2a8927a 5use rustc_errors::Applicability;
f20569fa
XL
6use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
7use rustc_lint::{LateContext, LateLintPass};
8use rustc_session::{declare_lint_pass, declare_tool_lint};
9use rustc_span::source_map::Span;
10
f20569fa 11declare_clippy_lint! {
94222f64
XL
12 /// ### What it does
13 /// Checks for multiplication by -1 as a form of negation.
f20569fa 14 ///
94222f64
XL
15 /// ### Why is this bad?
16 /// It's more readable to just negate.
f20569fa 17 ///
94222f64
XL
18 /// ### Known problems
19 /// This only catches integers (for now).
f20569fa 20 ///
94222f64 21 /// ### Example
923072b8 22 /// ```rust,ignore
a2a8927a 23 /// let a = x * -1;
923072b8 24 /// ```
a2a8927a 25 ///
923072b8
FG
26 /// Use instead:
27 /// ```rust,ignore
28 /// let a = -x;
f20569fa 29 /// ```
a2a8927a 30 #[clippy::version = "pre 1.29.0"]
f20569fa
XL
31 pub NEG_MULTIPLY,
32 style,
a2a8927a 33 "multiplying integers by `-1`"
f20569fa
XL
34}
35
36declare_lint_pass!(NegMultiply => [NEG_MULTIPLY]);
37
f20569fa
XL
38impl<'tcx> LateLintPass<'tcx> for NegMultiply {
39 fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
cdc7bbd5 40 if let ExprKind::Binary(ref op, left, right) = e.kind {
f20569fa
XL
41 if BinOpKind::Mul == op.node {
42 match (&left.kind, &right.kind) {
43 (&ExprKind::Unary(..), &ExprKind::Unary(..)) => {},
cdc7bbd5
XL
44 (&ExprKind::Unary(UnOp::Neg, lit), _) => check_mul(cx, e.span, lit, right),
45 (_, &ExprKind::Unary(UnOp::Neg, lit)) => check_mul(cx, e.span, lit, left),
f20569fa
XL
46 _ => {},
47 }
48 }
49 }
50 }
51}
52
53fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
54 if_chain! {
55 if let ExprKind::Lit(ref l) = lit.kind;
04454e1e 56 if consts::lit_to_mir_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1);
f20569fa 57 if cx.typeck_results().expr_ty(exp).is_integral();
a2a8927a 58
f20569fa 59 then {
a2a8927a
XL
60 let mut applicability = Applicability::MachineApplicable;
61 let suggestion = format!("-{}", snippet_with_applicability(cx, exp.span, "..", &mut applicability));
62 span_lint_and_sugg(
63 cx,
64 NEG_MULTIPLY,
65 span,
66 "this multiplication by -1 can be written more succinctly",
67 "consider using",
68 suggestion,
69 applicability,
70 );
f20569fa
XL
71 }
72 }
73}