Skip to content

Commit

Permalink
Update to handle GenericParam
Browse files Browse the repository at this point in the history
introduced in rust-lang/rust#45930
  • Loading branch information
Manishearth committed Dec 22, 2017
1 parent ebcdf03 commit 7e09990
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 25 deletions.
30 changes: 17 additions & 13 deletions clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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:
Expand All @@ -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);
Expand Down Expand Up @@ -222,11 +222,13 @@ 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 {
if lt.bounds.is_empty() {
allowed_lts.insert(RefLt::Named(lt.lifetime.name.name()));
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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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 };
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 11 additions & 9 deletions clippy_lints/src/misc_early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,17 @@ impl LintPass for MiscEarly {

impl EarlyLintPass for MiscEarly {
fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) {
for ty in &gen.ty_params {
let name = ty.ident.name.as_str();
if constants::BUILTIN_TYPES.contains(&&*name) {
span_lint(
cx,
BUILTIN_TYPE_SHADOW,
ty.span,
&format!("This generic shadows the built-in type `{}`", name),
);
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(
cx,
BUILTIN_TYPE_SHADOW,
ty.span,
&format!("This generic shadows the built-in type `{}`", name),
);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/new_without_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 7e09990

Please sign in to comment.