about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/inherent_impl.rs5
-rw-r--r--tests/ui/crashes/inherent_impl.rs26
2 files changed, 29 insertions, 2 deletions
diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs
index 0eaff14b7bd..063aade4e7f 100644
--- a/clippy_lints/src/inherent_impl.rs
+++ b/clippy_lints/src/inherent_impl.rs
@@ -1,6 +1,6 @@
 //! lint on inherent implementations
 
-use crate::utils::span_lint_and_then;
+use crate::utils::{in_macro, span_lint_and_then};
 use rustc::hir::*;
 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
 use rustc::{declare_tool_lint, impl_lint_pass};
@@ -52,7 +52,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MultipleInherentImpl {
         if let ItemKind::Impl(_, _, _, ref generics, None, _, _) = item.kind {
             // Remember for each inherent implementation encoutered its span and generics
             // but filter out implementations that have generic params (type or lifetime)
-            if generics.params.len() == 0 {
+            // or are derived from a macro
+            if !in_macro(item.span) && generics.params.len() == 0 {
                 self.impls.insert(item.hir_id.owner_def_id(), item.span);
             }
         }
diff --git a/tests/ui/crashes/inherent_impl.rs b/tests/ui/crashes/inherent_impl.rs
new file mode 100644
index 00000000000..aeb27b5ba8c
--- /dev/null
+++ b/tests/ui/crashes/inherent_impl.rs
@@ -0,0 +1,26 @@
+#![deny(clippy::multiple_inherent_impl)]
+
+/// Test for https://github.com/rust-lang/rust-clippy/issues/4578
+
+macro_rules! impl_foo {
+    ($struct:ident) => {
+        impl $struct {
+            fn foo() {}
+        }
+    };
+}
+
+macro_rules! impl_bar {
+    ($struct:ident) => {
+        impl $struct {
+            fn bar() {}
+        }
+    };
+}
+
+struct MyStruct;
+
+impl_foo!(MyStruct);
+impl_bar!(MyStruct);
+
+fn main() {}