about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Wright <mikerite@lavabit.com>2019-09-01 08:11:40 +0200
committerMichael Wright <mikerite@lavabit.com>2019-09-01 08:11:40 +0200
commit2fdfd60569f57c650b2b7875a683ab6daf774faa (patch)
treed56f4a5a7937a02e1c14097b810aa8ac9fd3a94a
parent4458bef5d153e81ebd5f21c29a75e37e44f997f1 (diff)
downloadrust-2fdfd60569f57c650b2b7875a683ab6daf774faa.tar.gz
rust-2fdfd60569f57c650b2b7875a683ab6daf774faa.zip
Fix `needless_lifetimes` false positive
-rw-r--r--clippy_lints/src/lifetimes.rs21
-rw-r--r--tests/ui/needless_lifetimes.rs11
-rw-r--r--tests/ui/needless_lifetimes.stderr14
3 files changed, 39 insertions, 7 deletions
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 3a7863a0201..e75e9c6541b 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -60,15 +60,21 @@ declare_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Lifetimes {
     fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
         if let ItemKind::Fn(ref decl, _, ref generics, id) = item.node {
-            check_fn_inner(cx, decl, Some(id), generics, item.span);
+            check_fn_inner(cx, decl, Some(id), generics, item.span, true);
         }
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) {
         if let ImplItemKind::Method(ref sig, id) = item.node {
-            if trait_ref_of_method(cx, item.hir_id).is_none() {
-                check_fn_inner(cx, &sig.decl, Some(id), &item.generics, item.span);
-            }
+            let report_extra_lifetimes = trait_ref_of_method(cx, item.hir_id).is_none();
+            check_fn_inner(
+                cx,
+                &sig.decl,
+                Some(id),
+                &item.generics,
+                item.span,
+                report_extra_lifetimes,
+            );
         }
     }
 
@@ -78,7 +84,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Lifetimes {
                 TraitMethod::Required(_) => None,
                 TraitMethod::Provided(id) => Some(id),
             };
-            check_fn_inner(cx, &sig.decl, body, &item.generics, item.span);
+            check_fn_inner(cx, &sig.decl, body, &item.generics, item.span, true);
         }
     }
 }
@@ -97,6 +103,7 @@ fn check_fn_inner<'a, 'tcx>(
     body: Option<BodyId>,
     generics: &'tcx Generics,
     span: Span,
+    report_extra_lifetimes: bool,
 ) {
     if in_external_macro(cx.sess(), span) || has_where_lifetimes(cx, &generics.where_clause) {
         return;
@@ -146,7 +153,9 @@ fn check_fn_inner<'a, 'tcx>(
              (or replaced with `'_` if needed by type declaration)",
         );
     }
-    report_extra_lifetimes(cx, decl, generics);
+    if report_extra_lifetimes {
+        self::report_extra_lifetimes(cx, decl, generics);
+    }
 }
 
 fn could_use_elision<'a, 'tcx>(
diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs
index f585be2fd03..f3fdd48633f 100644
--- a/tests/ui/needless_lifetimes.rs
+++ b/tests/ui/needless_lifetimes.rs
@@ -248,4 +248,15 @@ fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
     unimplemented!()
 }
 
+// Make sure we still warn on implementations
+mod issue4291 {
+    trait BadTrait {
+        fn needless_lt<'a>(x: &'a u8) {}
+    }
+
+    impl BadTrait for () {
+        fn needless_lt<'a>(_x: &'a u8) {}
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr
index bbb69aeda1c..ad55fc5f750 100644
--- a/tests/ui/needless_lifetimes.stderr
+++ b/tests/ui/needless_lifetimes.stderr
@@ -118,5 +118,17 @@ LL | |     unimplemented!()
 LL | | }
    | |_^
 
-error: aborting due to 15 previous errors
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:254:9
+   |
+LL |         fn needless_lt<'a>(x: &'a u8) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:258:9
+   |
+LL |         fn needless_lt<'a>(_x: &'a u8) {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 17 previous errors