]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/assign_ops.rs
Merge remote-tracking branch 'upstream/master' into rustup
[rust.git] / clippy_lints / src / assign_ops.rs
index 7ad0ce2320232db5939c054e85e3dce8c6b1fd66..b3185b88840142253648eb1eb033dca657d20aa6 100644 (file)
@@ -1,13 +1,13 @@
 use crate::utils::{
-    get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method, SpanlessEq,
+    eq_expr_value, get_trait_def_id, implements_trait, snippet_opt, span_lint_and_then, trait_ref_of_method,
 };
 use crate::utils::{higher, sugg};
 use if_chain::if_chain;
-use rustc::hir::map::Map;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::hir::map::Map;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
 declare_clippy_lint! {
     /// let mut a = 5;
     /// let b = 0;
     /// // ...
+    /// // Bad
     /// a = a + b;
+    ///
+    /// // Good
+    /// a += b;
     /// ```
     pub ASSIGN_OP_PATTERN,
     style,
@@ -56,9 +60,9 @@
 
 declare_lint_pass!(AssignOps => [ASSIGN_OP_PATTERN, MISREFACTORED_ASSIGN_OP]);
 
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
+impl<'tcx> LateLintPass<'tcx> for AssignOps {
     #[allow(clippy::too_many_lines)]
-    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
         match &expr.kind {
             hir::ExprKind::AssignOp(op, lhs, rhs) => {
                 if let hir::ExprKind::Binary(binop, l, r) = &rhs.kind {
@@ -66,21 +70,20 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>)
                         return;
                     }
                     // lhs op= l op r
-                    if SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, l) {
+                    if eq_expr_value(cx, lhs, l) {
                         lint_misrefactored_assign_op(cx, expr, *op, rhs, lhs, r);
                     }
                     // lhs op= l commutative_op r
-                    if is_commutative(op.node) && SpanlessEq::new(cx).ignore_fn().eq_expr(lhs, r) {
+                    if is_commutative(op.node) && eq_expr_value(cx, lhs, r) {
                         lint_misrefactored_assign_op(cx, expr, *op, rhs, lhs, l);
                     }
                 }
             },
             hir::ExprKind::Assign(assignee, e, _) => {
                 if let hir::ExprKind::Binary(op, l, r) = &e.kind {
-                    #[allow(clippy::cognitive_complexity)]
                     let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {
-                        let ty = cx.tables.expr_ty(assignee);
-                        let rty = cx.tables.expr_ty(rhs);
+                        let ty = cx.typeck_results().expr_ty(assignee);
+                        let rty = cx.typeck_results().expr_ty(rhs);
                         macro_rules! ops {
                             ($op:expr,
                              $cx:expr,
@@ -132,11 +135,11 @@ macro_rules! ops {
                                 ASSIGN_OP_PATTERN,
                                 expr.span,
                                 "manual implementation of an assign operation",
-                                |db| {
+                                |diag| {
                                     if let (Some(snip_a), Some(snip_r)) =
                                         (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
                                     {
-                                        db.span_suggestion(
+                                        diag.span_suggestion(
                                             expr.span,
                                             "replace it with",
                                             format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
@@ -158,14 +161,12 @@ macro_rules! ops {
 
                     if visitor.counter == 1 {
                         // a = a op b
-                        if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, l) {
+                        if eq_expr_value(cx, assignee, l) {
                             lint(assignee, r);
                         }
                         // a = b commutative_op a
                         // Limited to primitive type as these ops are know to be commutative
-                        if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r)
-                            && cx.tables.expr_ty(assignee).is_primitive_ty()
-                        {
+                        if eq_expr_value(cx, assignee, r) && cx.typeck_results().expr_ty(assignee).is_primitive_ty() {
                             match op.node {
                                 hir::BinOpKind::Add
                                 | hir::BinOpKind::Mul
@@ -188,7 +189,7 @@ macro_rules! ops {
 }
 
 fn lint_misrefactored_assign_op(
-    cx: &LateContext<'_, '_>,
+    cx: &LateContext<'_>,
     expr: &hir::Expr<'_>,
     op: hir::BinOp,
     rhs: &hir::Expr<'_>,
@@ -200,12 +201,12 @@ fn lint_misrefactored_assign_op(
         MISREFACTORED_ASSIGN_OP,
         expr.span,
         "variable appears on both sides of an assignment operation",
-        |db| {
+        |diag| {
             if let (Some(snip_a), Some(snip_r)) = (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs_other.span)) {
                 let a = &sugg::Sugg::hir(cx, assignee, "..");
                 let r = &sugg::Sugg::hir(cx, rhs, "..");
                 let long = format!("{} = {}", snip_a, sugg::make_binop(higher::binop(op.node), a, r));
-                db.span_suggestion(
+                diag.span_suggestion(
                     expr.span,
                     &format!(
                         "Did you mean `{} = {} {} {}` or `{}`? Consider replacing it with",
@@ -218,7 +219,7 @@ fn lint_misrefactored_assign_op(
                     format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
                     Applicability::MaybeIncorrect,
                 );
-                db.span_suggestion(
+                diag.span_suggestion(
                     expr.span,
                     "or",
                     long,
@@ -231,7 +232,9 @@ fn lint_misrefactored_assign_op(
 
 #[must_use]
 fn is_commutative(op: hir::BinOpKind) -> bool {
-    use rustc_hir::BinOpKind::*;
+    use rustc_hir::BinOpKind::{
+        Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub,
+    };
     match op {
         Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true,
         Sub | Div | Rem | Shl | Shr | Lt | Le | Ge | Gt => false,
@@ -241,20 +244,20 @@ fn is_commutative(op: hir::BinOpKind) -> bool {
 struct ExprVisitor<'a, 'tcx> {
     assignee: &'a hir::Expr<'a>,
     counter: u8,
-    cx: &'a LateContext<'a, 'tcx>,
+    cx: &'a LateContext<'tcx>,
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
     type Map = Map<'tcx>;
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
-        if SpanlessEq::new(self.cx).ignore_fn().eq_expr(self.assignee, expr) {
+        if eq_expr_value(self.cx, self.assignee, expr) {
             self.counter += 1;
         }
 
         walk_expr(self, expr);
     }
-    fn nested_visit_map(&mut self) -> NestedVisitorMap<'_, Self::Map> {
+    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
         NestedVisitorMap::None
     }
 }