about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Wright <mikerite@lavabit.com>2019-08-31 08:16:04 +0200
committerMichael Wright <mikerite@lavabit.com>2019-08-31 08:16:04 +0200
commit88750f9ad7dc8e7b2138f9a4a960937317e4100d (patch)
treed0a54580353432f4d0e5a006610ff9f72e9b96b3
parenta3fcaee5620d458af22682097c4ffb64b57c3327 (diff)
downloadrust-88750f9ad7dc8e7b2138f9a4a960937317e4100d.tar.gz
rust-88750f9ad7dc8e7b2138f9a4a960937317e4100d.zip
Fix `extra_unused_lifetimes` false positive
Fixes #4291
-rw-r--r--clippy_lints/src/lifetimes.rs6
-rw-r--r--tests/ui/extra_unused_lifetimes.rs19
2 files changed, 23 insertions, 2 deletions
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 72e28d23ebd..3a7863a0201 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -9,7 +9,7 @@ use syntax::source_map::Span;
 use syntax::symbol::kw;
 
 use crate::reexport::*;
-use crate::utils::{last_path_segment, span_lint};
+use crate::utils::{last_path_segment, span_lint, trait_ref_of_method};
 
 declare_clippy_lint! {
     /// **What it does:** Checks for lifetime annotations which can be removed by
@@ -66,7 +66,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Lifetimes {
 
     fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) {
         if let ImplItemKind::Method(ref sig, id) = item.node {
-            check_fn_inner(cx, &sig.decl, Some(id), &item.generics, item.span);
+            if trait_ref_of_method(cx, item.hir_id).is_none() {
+                check_fn_inner(cx, &sig.decl, Some(id), &item.generics, item.span);
+            }
         }
     }
 
diff --git a/tests/ui/extra_unused_lifetimes.rs b/tests/ui/extra_unused_lifetimes.rs
index 9f05f8c1ed0..66f6e67a75c 100644
--- a/tests/ui/extra_unused_lifetimes.rs
+++ b/tests/ui/extra_unused_lifetimes.rs
@@ -61,4 +61,23 @@ impl X {
     fn explicit_self_with_lifetime<'a>(self: &'a Self) {}
 }
 
+// Methods implementing traits must have matching lifetimes
+mod issue4291 {
+    #[derive(Debug)]
+    pub struct Foo<'a>(&'a std::marker::PhantomData<u8>);
+
+    #[derive(Debug)]
+    pub struct Bar<'a: 'b, 'b>(Foo<'a>, &'b std::marker::PhantomData<u8>);
+
+    trait LT {
+        fn test<'a: 'b, 'b>(foo: &Foo<'a>, bar: &Bar<'a, 'b>);
+    }
+
+    pub struct Baz;
+
+    impl LT for Baz {
+        fn test<'a: 'b, 'b>(_foo: &Foo, _bar: &Bar) {}
+    }
+}
+
 fn main() {}