Check for unused lifetimes in bounds (fixes #489)
This commit is contained in:
parent
b865e30b49
commit
b9546599e3
2 changed files with 24 additions and 4 deletions
|
@ -2,7 +2,7 @@ use rustc_front::hir::*;
|
||||||
use reexport::*;
|
use reexport::*;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use rustc_front::intravisit::{Visitor, walk_ty, walk_ty_param_bound, walk_fn_decl};
|
use rustc_front::intravisit::{Visitor, walk_ty, walk_ty_param_bound, walk_fn_decl, walk_generics};
|
||||||
use rustc::middle::def::Def::{DefTy, DefTrait, DefStruct};
|
use rustc::middle::def::Def::{DefTy, DefTrait, DefStruct};
|
||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::{HashSet, HashMap};
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ fn check_fn_inner(cx: &LateContext, decl: &FnDecl, slf: Option<&ExplicitSelf>,
|
||||||
span_lint(cx, NEEDLESS_LIFETIMES, span,
|
span_lint(cx, NEEDLESS_LIFETIMES, span,
|
||||||
"explicit lifetimes given in parameter types where they could be elided");
|
"explicit lifetimes given in parameter types where they could be elided");
|
||||||
}
|
}
|
||||||
report_extra_lifetimes(cx, decl, &generics.lifetimes);
|
report_extra_lifetimes(cx, decl, &generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn could_use_elision(cx: &LateContext, func: &FnDecl, slf: Option<&ExplicitSelf>,
|
fn could_use_elision(cx: &LateContext, func: &FnDecl, slf: Option<&ExplicitSelf>,
|
||||||
|
@ -276,12 +276,23 @@ impl<'v> Visitor<'v> for LifetimeChecker {
|
||||||
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
||||||
self.0.remove(&lifetime.name);
|
self.0.remove(&lifetime.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_lifetime_def(&mut self, _: &'v LifetimeDef) {
|
||||||
|
// don't actually visit `<'a>` or `<'a: 'b>`
|
||||||
|
// we've already visited the `'a` declarations and
|
||||||
|
// don't want to spuriously remove them
|
||||||
|
// `'b` in `'a: 'b` is useless unless used elsewhere in
|
||||||
|
// a non-lifetime bound
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl,
|
fn report_extra_lifetimes(cx: &LateContext, func: &FnDecl,
|
||||||
named_lts: &[LifetimeDef]) {
|
generics: &Generics) {
|
||||||
let hs = named_lts.iter().map(|lt| (lt.lifetime.name, lt.lifetime.span)).collect();
|
let hs = generics.lifetimes.iter()
|
||||||
|
.map(|lt| (lt.lifetime.name, lt.lifetime.span))
|
||||||
|
.collect();
|
||||||
let mut checker = LifetimeChecker(hs);
|
let mut checker = LifetimeChecker(hs);
|
||||||
|
walk_generics(&mut checker, generics);
|
||||||
walk_fn_decl(&mut checker, func);
|
walk_fn_decl(&mut checker, func);
|
||||||
for (_, v) in checker.0 {
|
for (_, v) in checker.0 {
|
||||||
span_lint(cx, UNUSED_LIFETIMES, v,
|
span_lint(cx, UNUSED_LIFETIMES, v,
|
||||||
|
|
|
@ -43,6 +43,15 @@ impl<'a> Foo<'a> for u8 {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test for #489 (used lifetimes in bounds)
|
||||||
|
pub fn parse<'a, I: Iterator<Item=&'a str>>(_it: &mut I) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
pub fn parse2<'a, I>(_it: &mut I) where I: Iterator<Item=&'a str>{
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue