From 2fdfd60569f57c650b2b7875a683ab6daf774faa Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Sun, 1 Sep 2019 08:11:40 +0200 Subject: [PATCH] Fix `needless_lifetimes` false positive --- clippy_lints/src/lifetimes.rs | 21 +++++++++++++++------ tests/ui/needless_lifetimes.rs | 11 +++++++++++ tests/ui/needless_lifetimes.stderr | 14 +++++++++++++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 3a7863a02..e75e9c654 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, 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 f585be2fd..f3fdd4863 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 bbb69aeda..ad55fc5f7 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