From 5aded99033a84ed875d9ea1b60309bf375b1f517 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 19 Dec 2016 11:13:07 +0100 Subject: [PATCH] don't lint on x = x + y inside an AddAssign impl fixes #1302 --- clippy_lints/src/assign_ops.rs | 14 ++++++++++++++ tests/compile-fail/assign_ops2.rs | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs index ef6898cef..5f5cddc64 100644 --- a/clippy_lints/src/assign_ops.rs +++ b/clippy_lints/src/assign_ops.rs @@ -1,5 +1,6 @@ use rustc::hir; use rustc::lint::*; +use syntax::ast; use utils::{span_lint_and_then, snippet_opt, SpanlessEq, get_trait_def_id, implements_trait}; use utils::{higher, sugg}; @@ -135,6 +136,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps { } else { return; // useless if the trait doesn't exist }; + // check that we are not inside an `impl AssignOp` of this exact operation + let parent_fn = cx.tcx.map.get_parent(e.id); + let parent_impl = cx.tcx.map.get_parent(parent_fn); + // the crate node is the only one that is not in the map + if parent_impl != ast::CRATE_NODE_ID { + if let hir::map::Node::NodeItem(item) = cx.tcx.map.get(parent_impl) { + if let hir::Item_::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node { + if trait_ref.path.def.def_id() == trait_id { + return; + } + } + } + } implements_trait($cx, $ty, trait_id, vec![$rty]) },)* _ => false, diff --git a/tests/compile-fail/assign_ops2.rs b/tests/compile-fail/assign_ops2.rs index 1537232bf..e8549c01b 100644 --- a/tests/compile-fail/assign_ops2.rs +++ b/tests/compile-fail/assign_ops2.rs @@ -34,3 +34,24 @@ fn main() { a %= 42 % a; a <<= 6 << a; } + +// check that we don't lint on op assign impls, because that's just the way to impl them + +use std::ops::{Mul, MulAssign}; + +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct Wrap(i64); + +impl Mul for Wrap { + type Output = Self; + + fn mul(self, rhs: i64) -> Self { + Wrap(self.0 * rhs) + } +} + +impl MulAssign for Wrap { + fn mul_assign(&mut self, rhs: i64) { + *self = *self * rhs + } +}