Update to handle GenericParam

introduced in https://github.com/rust-lang/rust/pull/45930
This commit is contained in:
Manish Goregaokar 2017-12-21 20:42:47 -08:00
parent ebcdf03147
commit 7e099903be
5 changed files with 31 additions and 25 deletions

View File

@ -2,7 +2,7 @@ use reexport::*;
use rustc::lint::*;
use rustc::hir::def::Def;
use rustc::hir::*;
use rustc::hir::intravisit::{walk_fn_decl, walk_generics, walk_ty, walk_ty_param_bound, NestedVisitorMap, Visitor};
use rustc::hir::intravisit::*;
use std::collections::{HashMap, HashSet};
use syntax::codemap::Span;
use utils::{in_external_macro, last_path_segment, span_lint};
@ -101,7 +101,7 @@ fn check_fn_inner<'a, 'tcx>(
}
let mut bounds_lts = Vec::new();
for typ in &generics.ty_params {
for typ in generics.ty_params() {
for bound in &typ.bounds {
if let TraitTyParamBound(ref trait_ref, _) = *bound {
let params = &trait_ref
@ -122,7 +122,7 @@ fn check_fn_inner<'a, 'tcx>(
}
}
}
if could_use_elision(cx, decl, body, &generics.lifetimes, bounds_lts) {
if could_use_elision(cx, decl, body, &generics.params, bounds_lts) {
span_lint(
cx,
NEEDLESS_LIFETIMES,
@ -137,7 +137,7 @@ fn could_use_elision<'a, 'tcx: 'a>(
cx: &LateContext<'a, 'tcx>,
func: &'tcx FnDecl,
body: Option<BodyId>,
named_lts: &'tcx [LifetimeDef],
named_generics: &'tcx [GenericParam],
bounds_lts: Vec<&'tcx Lifetime>,
) -> bool {
// There are two scenarios where elision works:
@ -147,7 +147,7 @@ fn could_use_elision<'a, 'tcx: 'a>(
// level of the current item.
// check named LTs
let allowed_lts = allowed_lts_from(named_lts);
let allowed_lts = allowed_lts_from(named_generics);
// these will collect all the lifetimes for references in arg/return types
let mut input_visitor = RefVisitor::new(cx);
@ -222,13 +222,15 @@ fn could_use_elision<'a, 'tcx: 'a>(
}
}
fn allowed_lts_from(named_lts: &[LifetimeDef]) -> HashSet<RefLt> {
fn allowed_lts_from(named_generics: &[GenericParam]) -> HashSet<RefLt> {
let mut allowed_lts = HashSet::new();
for lt in named_lts {
for par in named_generics.iter() {
if let GenericParam::Lifetime(ref lt) = *par {
if lt.bounds.is_empty() {
allowed_lts.insert(RefLt::Named(lt.lifetime.name.name()));
}
}
}
allowed_lts.insert(RefLt::Unnamed);
allowed_lts.insert(RefLt::Static);
allowed_lts
@ -370,7 +372,7 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: &
return true;
}
// if the bounds define new lifetimes, they are fine to occur
let allowed_lts = allowed_lts_from(&pred.bound_lifetimes);
let allowed_lts = allowed_lts_from(&pred.bound_generic_params);
// now walk the bounds
for bound in pred.bounds.iter() {
walk_ty_param_bound(&mut visitor, bound);
@ -408,12 +410,15 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker {
self.map.remove(&lifetime.name.name());
}
fn visit_lifetime_def(&mut self, _: &'tcx LifetimeDef) {
fn visit_generic_param(&mut self, param: &'tcx GenericParam) {
// 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
if param.is_type_param() {
walk_generic_param(self, param)
}
}
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::None
@ -422,8 +427,7 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker {
fn report_extra_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, func: &'tcx FnDecl, generics: &'tcx Generics) {
let hs = generics
.lifetimes
.iter()
.lifetimes()
.map(|lt| (lt.lifetime.name.name(), lt.lifetime.span))
.collect();
let mut checker = LifetimeChecker { map: hs };

View File

@ -1849,7 +1849,7 @@ impl SelfKind {
fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Generics, name: &[&str]) -> bool {
single_segment_ty(ty).map_or(false, |seg| {
generics.ty_params.iter().any(|param| {
generics.ty_params().any(|param| {
param.name == seg.name && param.bounds.iter().any(|bound| {
if let hir::TyParamBound::TraitTyParamBound(ref ptr, ..) = *bound {
let path = &ptr.trait_ref.path;

View File

@ -188,7 +188,8 @@ impl LintPass for MiscEarly {
impl EarlyLintPass for MiscEarly {
fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) {
for ty in &gen.ty_params {
for param in &gen.params {
if let GenericParam::Type(ref ty) = *param {
let name = ty.ident.name.as_str();
if constants::BUILTIN_TYPES.contains(&&*name) {
span_lint(
@ -200,6 +201,7 @@ impl EarlyLintPass for MiscEarly {
}
}
}
}
fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) {
if let PatKind::Struct(ref npat, ref pfields, _) = pat.node {

View File

@ -103,7 +103,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
// can't be implemented by default
return;
}
if !impl_item.generics.ty_params.is_empty() {
if impl_item.generics.params.iter().any(|gen| gen.is_type_param()) {
// when the result of `new()` depends on a type parameter we should not require
// an
// impl of `Default`

View File

@ -957,7 +957,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
TyTraitObject(ref param_bounds, _) => {
let has_lifetime_parameters = param_bounds
.iter()
.any(|bound| !bound.bound_lifetimes.is_empty());
.any(|bound| bound.bound_generic_params.iter().any(|gen| gen.is_lifetime_param()));
if has_lifetime_parameters {
// complex trait bounds like A<'a, 'b>
(50 * self.nest, 1)