diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index 3fbac7bc1..803c79d42 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -215,7 +215,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { lint(assignee, r); } // a = b commutative_op a - if SpanlessEq::new(cx).ignore_fn().eq_expr(assignee, r) { + // 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() { match op.node { hir::BinOpKind::Add | hir::BinOpKind::Mul diff --git a/tests/ui/assign_ops2.rs b/tests/ui/assign_ops2.rs index 9eef898c9..60a9d2fb7 100644 --- a/tests/ui/assign_ops2.rs +++ b/tests/ui/assign_ops2.rs @@ -53,3 +53,18 @@ impl MulAssign for Wrap { *self = *self * rhs } } + +fn cow_add_assign() { + use std::borrow::Cow; + let mut buf = Cow::Owned(String::from("bar")); + let cows = Cow::Borrowed("foo"); + + // this can be linted + buf = buf + cows.clone(); + + // this should not as cow Add is not commutative + buf = cows + buf; + println!("{}", buf); + +} + diff --git a/tests/ui/assign_ops2.stderr b/tests/ui/assign_ops2.stderr index 8e44fc13b..bd49c3cdd 100644 --- a/tests/ui/assign_ops2.stderr +++ b/tests/ui/assign_ops2.stderr @@ -126,5 +126,13 @@ help: or 26 | a = a * a * a; | ^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: manual implementation of an assign operation + --> $DIR/assign_ops2.rs:63:5 + | +63 | buf = buf + cows.clone(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `buf += cows.clone()` + | + = note: `-D clippy::assign-op-pattern` implied by `-D warnings` + +error: aborting due to 10 previous errors