diff --git a/src/lifetimes.rs b/src/lifetimes.rs index 2de916cfe..1edd75a45 100644 --- a/src/lifetimes.rs +++ b/src/lifetimes.rs @@ -77,7 +77,7 @@ fn check_fn_inner(cx: &LateContext, decl: &FnDecl, slf: Option<&ExplicitSelf>, g span, "explicit lifetimes given in parameter types where they could be elided"); } - report_extra_lifetimes(cx, decl, &generics); + report_extra_lifetimes(cx, decl, &generics, slf); } fn could_use_elision(cx: &LateContext, func: &FnDecl, slf: Option<&ExplicitSelf>, named_lts: &[LifetimeDef]) -> bool { @@ -303,14 +303,25 @@ impl<'v> Visitor<'v> for LifetimeChecker { } } -fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl, generics: &Generics) { +fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl, + generics: &Generics, slf: Option<&ExplicitSelf>) { let hs = generics.lifetimes .iter() .map(|lt| (lt.lifetime.name, lt.lifetime.span)) .collect(); let mut checker = LifetimeChecker(hs); + walk_generics(&mut checker, generics); walk_fn_decl(&mut checker, func); + + if let Some(slf) = slf { + match slf.node { + SelfRegion(Some(ref lt), _, _) => checker.visit_lifetime(lt), + SelfExplicit(ref t, _) => walk_ty(&mut checker, t), + _ => {} + } + } + for (_, v) in checker.0 { span_lint(cx, UNUSED_LIFETIMES, v, "this lifetime isn't used in the function definition"); } diff --git a/tests/compile-fail/lifetimes.rs b/tests/compile-fail/lifetimes.rs index 4d454a738..99c169174 100644 --- a/tests/compile-fail/lifetimes.rs +++ b/tests/compile-fail/lifetimes.rs @@ -1,8 +1,8 @@ #![feature(plugin)] #![plugin(clippy)] -#![deny(needless_lifetimes)] -#![allow(dead_code, unused_lifetimes)] +#![deny(needless_lifetimes, unused_lifetimes)] +#![allow(dead_code)] fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) { } //~^ERROR explicit lifetimes given diff --git a/tests/compile-fail/unused_lt.rs b/tests/compile-fail/unused_lt.rs index 856671745..a35718b58 100644 --- a/tests/compile-fail/unused_lt.rs +++ b/tests/compile-fail/unused_lt.rs @@ -52,6 +52,13 @@ pub fn parse2<'a, I>(_it: &mut I) where I: Iterator{ unimplemented!() } +struct X { x: u32 } + +impl X { + fn self_ref_with_lifetime<'a>(&'a self) {} + fn explicit_self_with_lifetime<'a>(self: &'a Self) {} +} + fn main() { }