From d9a80d2f84458dda53d31f627b27aa9b9b2bc39b Mon Sep 17 00:00:00 2001 From: flip1995 <9744647+flip1995@users.noreply.github.com> Date: Sun, 24 Jun 2018 15:32:40 +0200 Subject: [PATCH 1/4] Resolve field, struct and function renaming Addresses the errors produced by (re)moving, merging or renaming structs, fields and methods by rust-lang/rust#48149 and rust-lang/rust#51580 --- clippy_lints/src/attrs.rs | 2 +- clippy_lints/src/eval_order_dependence.rs | 2 +- clippy_lints/src/functions.rs | 12 ++-- clippy_lints/src/lifetimes.rs | 57 ++++++++++--------- clippy_lints/src/loops.rs | 2 +- clippy_lints/src/map_clone.rs | 2 +- clippy_lints/src/methods.rs | 47 ++++++++------- clippy_lints/src/misc_early.rs | 10 ++-- clippy_lints/src/needless_pass_by_value.rs | 6 +- clippy_lints/src/new_without_default.rs | 7 ++- clippy_lints/src/non_expressive_names.rs | 2 +- clippy_lints/src/ptr.rs | 6 +- clippy_lints/src/transmute.rs | 2 +- .../src/trivially_copy_pass_by_ref.rs | 4 +- clippy_lints/src/types.rs | 17 +++--- clippy_lints/src/unused_label.rs | 2 +- clippy_lints/src/use_self.rs | 2 +- clippy_lints/src/utils/author.rs | 2 +- clippy_lints/src/utils/hir_utils.rs | 10 ++-- clippy_lints/src/utils/inspector.rs | 2 +- clippy_lints/src/utils/mod.rs | 2 +- clippy_lints/src/utils/sugg.rs | 2 +- 22 files changed, 106 insertions(+), 94 deletions(-) diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 46ec02a3473..c861e4ee4e2 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -207,7 +207,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass { } fn is_relevant_item(tcx: TyCtxt, item: &Item) -> bool { - if let ItemFn(_, _, _, _, _, eid) = item.node { + if let ItemFn(_, _, _, eid) = item.node { is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value) } else { true diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index e58dbdd2289..d773289263e 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -124,7 +124,7 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> { fn visit_expr(&mut self, e: &'tcx Expr) { match e.node { - ExprAgain(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e), + ExprContinue(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e), ExprCall(ref func, _) => { let typ = self.cx.tables.expr_ty(func); match typ.sty { diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 904d0b1d245..554c983d7c5 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -92,8 +92,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { }; let unsafety = match kind { - hir::intravisit::FnKind::ItemFn(_, _, unsafety, _, _, _, _) => unsafety, - hir::intravisit::FnKind::Method(_, sig, _, _) => sig.unsafety, + hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety, + hir::intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety, hir::intravisit::FnKind::Closure(_) => return, }; @@ -101,8 +101,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { if !is_impl { // don't lint extern functions decls, it's not their fault either match kind { - hir::intravisit::FnKind::Method(_, &hir::MethodSig { abi: Abi::Rust, .. }, _, _) | - hir::intravisit::FnKind::ItemFn(_, _, _, _, Abi::Rust, _, _) => self.check_arg_number(cx, decl, span), + hir::intravisit::FnKind::Method(_, &hir::MethodSig { header: hir::FnHeader { abi: Abi::Rust, .. }, .. }, _, _) | + hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => self.check_arg_number(cx, decl, span), _ => {}, } } @@ -113,13 +113,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions { fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) { if let hir::TraitItemKind::Method(ref sig, ref eid) = item.node { // don't lint extern functions decls, it's not their fault - if sig.abi == Abi::Rust { + if sig.header.abi == Abi::Rust { self.check_arg_number(cx, &sig.decl, item.span); } if let hir::TraitMethod::Provided(eid) = *eid { let body = cx.tcx.hir.body(eid); - self.check_raw_ptr(cx, sig.unsafety, &sig.decl, body, item.id); + self.check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.id); } } } diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index f84d942e1c9..b0fd62089ba 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -59,7 +59,7 @@ impl LintPass for LifetimePass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { - if let ItemFn(ref decl, _, _, _, ref generics, id) = item.node { + if let ItemFn(ref decl, _, ref generics, id) = item.node { check_fn_inner(cx, decl, Some(id), generics, item.span); } } @@ -101,32 +101,35 @@ fn check_fn_inner<'a, 'tcx>( } let mut bounds_lts = Vec::new(); - for typ in generics.ty_params() { - for bound in &typ.bounds { - let mut visitor = RefVisitor::new(cx); - walk_ty_param_bound(&mut visitor, bound); - if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) { - return; - } - if let TraitTyParamBound(ref trait_ref, _) = *bound { - let params = &trait_ref - .trait_ref - .path - .segments - .last() - .expect("a path must have at least one segment") - .parameters; - if let Some(ref params) = *params { - for bound in ¶ms.lifetimes { - if bound.name.name() != "'static" && !bound.is_elided() { - return; + generics.params.iter().for_each(|param| match param.kind { + GenericParamKind::Lifetime { .. } => {}, + GenericParamKind::Type { .. } => { + for bound in ¶m.bounds { + let mut visitor = RefVisitor::new(cx); + walk_param_bound(&mut visitor, bound); + if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) { + return; + } + if let GenericBound::Trait(ref trait_ref, _) = *bound { + let params = &trait_ref + .trait_ref + .path + .segments + .last() + .expect("a path must have at least one segment") + .args; + if let Some(ref params) = *params { + for bound in ¶ms.lifetimes { + if bound.name.name() != "'static" && !bound.is_elided() { + return; + } + bounds_lts.push(bound); } - bounds_lts.push(bound); } } } - } - } + }, + }); if could_use_elision(cx, decl, body, &generics.params, bounds_lts) { span_lint( cx, @@ -295,7 +298,7 @@ impl<'v, 't> RefVisitor<'v, 't> { } fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) { - if let Some(ref last_path_segment) = last_path_segment(qpath).parameters { + if let Some(ref last_path_segment) = last_path_segment(qpath).args { if !last_path_segment.parenthesized && last_path_segment.lifetimes.is_empty() { let hir_id = self.cx.tcx.hir.node_to_hir_id(ty.id); match self.cx.tables.qpath_def(qpath, hir_id) { @@ -335,7 +338,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { TyImplTraitExistential(exist_ty_id, _, _) => { if let ItemExistential(ref exist_ty) = self.cx.tcx.hir.expect_item(exist_ty_id.id).node { for bound in &exist_ty.bounds { - if let RegionTyParamBound(_) = *bound { + if let GenericBound::Outlives(_) = *bound { self.record(&None); } } @@ -377,7 +380,7 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: & 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); + walk_param_bound(&mut visitor, bound); } // and check that all lifetimes are allowed match visitor.into_vec() { @@ -418,7 +421,7 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker { // 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() { + if let GenericParamKind::Type { .. } = param.kind { walk_generic_param(self, param) } } diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index cfea6053fac..8808de9025d 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -640,7 +640,7 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult { } }, ExprBlock(ref b, _) => never_loop_block(b, main_loop_id), - ExprAgain(d) => { + ExprContinue(d) => { let id = d.target_id .expect("target id can only be missing in the presence of compilation errors"); if id == main_loop_id { diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 2befba5767d..97c2522d2ce 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -104,7 +104,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool { let arg_segment = [ PathSegment { name: id, - parameters: None, + args: None, infer_types: true, }, ]; diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 6d93e5bbd09..2fe56bcdce1 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -7,7 +7,7 @@ use std::fmt; use std::iter; use syntax::ast; use syntax::codemap::{Span, BytePos}; -use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, is_expn_of, is_self, +use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, is_expn_of, is_self, is_self_ty, iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type, method_chain_args, match_var, return_ty, remove_blocks, same_tys, single_segment_path, snippet, span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; @@ -336,7 +336,7 @@ declare_clippy_lint! { /// /// **Known problems:** If the function has side-effects, not calling it will /// change the semantic of the program, but you shouldn't rely on that anyway. -/// +/// /// **Example:** /// ```rust /// foo.expect(&format("Err {}: {}", err_code, err_msg)) @@ -1020,7 +1020,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n } } }; - + snippet(cx, a.span, "..").into_owned() } @@ -1077,7 +1077,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n } let sugg: Cow<_> = snippet(cx, arg.span, ".."); - + span_lint_and_sugg( cx, EXPECT_FUN_CALL, @@ -2091,26 +2091,29 @@ 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().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; - match_path(path, name) && path.segments.last().map_or(false, |s| { - if let Some(ref params) = s.parameters { - if params.parenthesized { - false + generics.params.iter().any(|param| match param.kind { + hir::GenericParamKind::Type { .. } => { + param.name.name() == seg.name && param.bounds.iter().any(|bound| { + if let hir::GenericBound::Trait(ref ptr, ..) = *bound { + let path = &ptr.trait_ref.path; + match_path(path, name) && path.segments.last().map_or(false, |s| { + if let Some(ref params) = s.args { + if params.parenthesized { + false + } else { + params.types.len() == 1 + && (is_self_ty(¶ms.types[0]) || is_ty(&*params.types[0], self_ty)) + } } else { - params.types.len() == 1 - && (is_self_ty(¶ms.types[0]) || is_ty(&*params.types[0], self_ty)) + false } - } else { - false - } - }) - } else { - false - } - }) + }) + } else { + false + } + }) + }, + _ => false, }) }) } diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs index fcd88f9f219..94247e64b10 100644 --- a/clippy_lints/src/misc_early.rs +++ b/clippy_lints/src/misc_early.rs @@ -189,13 +189,13 @@ impl LintPass for MiscEarly { impl EarlyLintPass for MiscEarly { fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) { for param in &gen.params { - if let GenericParam::Type(ref ty) = *param { - let name = ty.ident.name.as_str(); + if let GenericParamKind::Type { .. } = param.kind { + let name = param.ident.name.as_str(); if constants::BUILTIN_TYPES.contains(&&*name) { span_lint( cx, BUILTIN_TYPE_SHADOW, - ty.ident.span, + param.ident.span, &format!("This generic shadows the built-in type `{}`", name), ); } @@ -296,7 +296,7 @@ impl EarlyLintPass for MiscEarly { } match expr.node { ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node { - if let ExprKind::Closure(_, _, ref decl, ref block, _) = closure.node { + if let ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.node { span_lint_and_then( cx, REDUNDANT_CLOSURE_CALL, @@ -327,7 +327,7 @@ impl EarlyLintPass for MiscEarly { if_chain! { if let StmtKind::Local(ref local) = w[0].node; if let Option::Some(ref t) = local.init; - if let ExprKind::Closure(_, _, _, _, _) = t.node; + if let ExprKind::Closure(..) = t.node; if let PatKind::Ident(_, ident, _) = local.pat.node; if let StmtKind::Semi(ref second) = w[1].node; if let ExprKind::Assign(_, ref call) = second.node; diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 36f5eaa8e18..7a250f93db5 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -72,8 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { } match kind { - FnKind::ItemFn(.., abi, _, attrs) => { - if abi != Abi::Rust { + FnKind::ItemFn(.., header, _, attrs) => { + if header.abi != Abi::Rust { return; } for a in attrs { @@ -218,7 +218,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { if let TyPath(QPath::Resolved(_, ref path)) = input.node; if let Some(elem_ty) = path.segments.iter() .find(|seg| seg.name == "Vec") - .and_then(|ps| ps.parameters.as_ref()) + .and_then(|ps| ps.args.as_ref()) .map(|params| ¶ms.types[0]); then { let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_")); diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index 8df4577650f..adc91bacdef 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -99,11 +99,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault { if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { let name = impl_item.name; let id = impl_item.id; - if sig.constness == hir::Constness::Const { + if sig.header.constness == hir::Constness::Const { // can't be implemented by default return; } - if impl_item.generics.params.iter().any(|gen| gen.is_type_param()) { + if impl_item.generics.params.iter().any(|gen| match gen.kind { + hir::GenericParamKind::Type { .. } => true, + _ => false + }) { // when the result of `new()` depends on a type parameter we should not require // an // impl of `Default` diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs index 69a02b0c50d..b49e3f87ec9 100644 --- a/clippy_lints/src/non_expressive_names.rs +++ b/clippy_lints/src/non_expressive_names.rs @@ -312,7 +312,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> { impl EarlyLintPass for NonExpressiveNames { fn check_item(&mut self, cx: &EarlyContext, item: &Item) { - if let ItemKind::Fn(ref decl, _, _, _, _, ref blk) = item.node { + if let ItemKind::Fn(ref decl, _, _, ref blk) = item.node { do_check(self, cx, &item.attrs, decl, blk); } } diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 2d5330f7b6b..fcd56c28218 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -103,7 +103,7 @@ impl LintPass for PointerPass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { - if let ItemFn(ref decl, _, _, _, _, body_id) = item.node { + if let ItemFn(ref decl, _, _, body_id) = item.node { check_fn(cx, decl, item.id, Some(body_id)); } } @@ -160,7 +160,7 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option< let mut ty_snippet = None; if_chain! { if let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node; - if let Some(&PathSegment{parameters: Some(ref parameters), ..}) = path.segments.last(); + if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last(); if parameters.types.len() == 1; then { ty_snippet = snippet_opt(cx, parameters.types[0].span); @@ -218,7 +218,7 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option< if let TyPath(ref path) = ty.node; if let QPath::Resolved(None, ref pp) = *path; if let [ref bx] = *pp.segments; - if let Some(ref params) = bx.parameters; + if let Some(ref params) = bx.args; if !params.parenthesized; if let [ref inner] = *params.types; then { diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index ace42c2fecd..2b27ed22c47 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -455,7 +455,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute { fn get_type_snippet(cx: &LateContext, path: &QPath, to_ref_ty: Ty) -> String { let seg = last_path_segment(path); if_chain! { - if let Some(ref params) = seg.parameters; + if let Some(ref params) = seg.args; if !params.parenthesized; if let Some(to_ty) = params.types.get(1); if let TyRptr(_, ref to_ty) = to_ty.node; diff --git a/clippy_lints/src/trivially_copy_pass_by_ref.rs b/clippy_lints/src/trivially_copy_pass_by_ref.rs index 4c8d0c9dab8..8d0ddbec988 100644 --- a/clippy_lints/src/trivially_copy_pass_by_ref.rs +++ b/clippy_lints/src/trivially_copy_pass_by_ref.rs @@ -84,8 +84,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TriviallyCopyPassByRef { } match kind { - FnKind::ItemFn(.., abi, _, attrs) => { - if abi != Abi::Rust { + FnKind::ItemFn(.., header, _, attrs) => { + if header.abi != Abi::Rust { return; } for a in attrs { diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 0888aef89fe..70625724040 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -180,7 +180,7 @@ fn check_fn_decl(cx: &LateContext, decl: &FnDecl) { fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool { let last = last_path_segment(qpath); if_chain! { - if let Some(ref params) = last.parameters; + if let Some(ref params) = last.args; if !params.parenthesized; if let Some(ty) = params.types.get(0); if let TyPath(ref qpath) = ty.node; @@ -244,7 +244,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { QPath::Resolved(Some(ref ty), ref p) => { check_ty(cx, ty, is_local); for ty in p.segments.iter().flat_map(|seg| { - seg.parameters + seg.args .as_ref() .map_or_else(|| [].iter(), |params| params.types.iter()) }) { @@ -252,7 +252,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { } }, QPath::Resolved(None, ref p) => for ty in p.segments.iter().flat_map(|seg| { - seg.parameters + seg.args .as_ref() .map_or_else(|| [].iter(), |params| params.types.iter()) }) { @@ -260,7 +260,7 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { }, QPath::TypeRelative(ref ty, ref seg) => { check_ty(cx, ty, is_local); - if let Some(ref params) = seg.parameters { + if let Some(ref params) = seg.args { for ty in params.types.iter() { check_ty(cx, ty, is_local); } @@ -288,7 +288,7 @@ fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifeti if Some(def_id) == cx.tcx.lang_items().owned_box(); if let QPath::Resolved(None, ref path) = *qpath; if let [ref bx] = *path.segments; - if let Some(ref params) = bx.parameters; + if let Some(ref params) = bx.args; if !params.parenthesized; if let [ref inner] = *params.types; then { @@ -1208,7 +1208,10 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyTraitObject(ref param_bounds, _) => { let has_lifetime_parameters = param_bounds .iter() - .any(|bound| bound.bound_generic_params.iter().any(|gen| gen.is_lifetime_param())); + .any(|bound| bound.bound_generic_params.iter().any(|gen| match gen.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + })); if has_lifetime_parameters { // complex trait bounds like A<'a, 'b> (50 * self.nest, 1) @@ -1859,7 +1862,7 @@ impl<'tcx> ImplicitHasherType<'tcx> { /// Checks that `ty` is a target type without a BuildHasher. fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty) -> Option { if let TyPath(QPath::Resolved(None, ref path)) = hir_ty.node { - let params = &path.segments.last().as_ref()?.parameters.as_ref()?.types; + let params = &path.segments.last().as_ref()?.args.as_ref()?.types; let params_len = params.len(); let ty = hir_ty_to_ty(cx.tcx, hir_ty); diff --git a/clippy_lints/src/unused_label.rs b/clippy_lints/src/unused_label.rs index c7a33ab33b2..ca300032675 100644 --- a/clippy_lints/src/unused_label.rs +++ b/clippy_lints/src/unused_label.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedLabel { impl<'a, 'tcx: 'a> Visitor<'tcx> for UnusedLabelVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { match expr.node { - hir::ExprBreak(destination, _) | hir::ExprAgain(destination) => if let Some(label) = destination.label { + hir::ExprBreak(destination, _) | hir::ExprContinue(destination) => if let Some(label) = destination.label { self.labels.remove(&label.name.as_str()); }, hir::ExprLoop(_, Some(label), _) | hir::ExprWhile(_, _, Some(label)) => { diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 581a8d47677..035471e4520 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { if let ItemImpl(.., ref item_type, ref refs) = item.node; if let Ty_::TyPath(QPath::Resolved(_, ref item_path)) = item_type.node; then { - let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).parameters; + let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; let should_check = if let Some(ref params) = *parameters { !params.parenthesized && params.lifetimes.len() == 0 } else { diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index e10fa60a38b..df6a06bc478 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -432,7 +432,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { } // FIXME: implement label printing }, - Expr_::ExprAgain(ref _destination) => { + Expr_::ExprContinue(ref _destination) => { let destination_pat = self.next("destination"); println!("Again(ref {}) = {};", destination_pat, current); // FIXME: implement label printing diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index ddac8bd3835..1cfb5a82f72 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { match (&left.node, &right.node) { (&ExprAddrOf(l_mut, ref le), &ExprAddrOf(r_mut, ref re)) => l_mut == r_mut && self.eq_expr(le, re), - (&ExprAgain(li), &ExprAgain(ri)) => { + (&ExprContinue(li), &ExprContinue(ri)) => { both(&li.label, &ri.label, |l, r| l.name.as_str() == r.name.as_str()) }, (&ExprAssign(ref ll, ref lr), &ExprAssign(ref rl, ref rr)) => self.eq_expr(ll, rl) && self.eq_expr(lr, rr), @@ -201,7 +201,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { && over(&left.segments, &right.segments, |l, r| self.eq_path_segment(l, r)) } - fn eq_path_parameters(&mut self, left: &PathParameters, right: &PathParameters) -> bool { + fn eq_path_parameters(&mut self, left: &GenericArgs, right: &GenericArgs) -> bool { if !(left.parenthesized || right.parenthesized) { over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r)) && over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) @@ -224,7 +224,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { if left.name.as_str() != right.name.as_str() { return false; } - match (&left.parameters, &right.parameters) { + match (&left.args, &right.args) { (&None, &None) => true, (&Some(ref l), &Some(ref r)) => self.eq_path_parameters(l, r), _ => false, @@ -345,8 +345,8 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> { m.hash(&mut self.s); self.hash_expr(e); }, - ExprAgain(i) => { - let c: fn(_) -> _ = ExprAgain; + ExprContinue(i) => { + let c: fn(_) -> _ = ExprContinue; c.hash(&mut self.s); if let Some(i) = i.label { self.hash_name(i.name); diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index 46b65cf39b6..9d92147048c 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -300,7 +300,7 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) { print_expr(cx, e, indent + 1); } }, - hir::ExprAgain(_) => println!("{}Again", ind), + hir::ExprContinue(_) => println!("{}Again", ind), hir::ExprRet(ref e) => { println!("{}Ret", ind); if let Some(ref e) = *e { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 612fdfafe3b..3adc65a2543 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -524,7 +524,7 @@ pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeI match node { Node::NodeBlock(block) => Some(block), Node::NodeItem(&Item { - node: ItemFn(_, _, _, _, _, eid), + node: ItemFn(_, _, _, eid), .. }) | Node::NodeImplItem(&ImplItem { node: ImplItemKind::Method(_, eid), diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 6add947cf9e..9482cc6bc0e 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -52,7 +52,7 @@ impl<'a> Sugg<'a> { hir::ExprIf(..) | hir::ExprUnary(..) | hir::ExprMatch(..) => Sugg::MaybeParen(snippet), - hir::ExprAgain(..) | + hir::ExprContinue(..) | hir::ExprYield(..) | hir::ExprArray(..) | hir::ExprBlock(..) | From c83fd39e0e4a8e9262fc31823303df7bcb522720 Mon Sep 17 00:00:00 2001 From: flip1995 <9744647+flip1995@users.noreply.github.com> Date: Sun, 24 Jun 2018 23:42:52 +0200 Subject: [PATCH 2/4] Resolve conflicts produced by GenericArgs Addresses the move/zip of Lifetimes and Types vectors from hir::PathParameters into the args vector of GenericArgs --- clippy_lints/src/lifetimes.rs | 35 ++++++++++++++-------- clippy_lints/src/methods.rs | 10 +++++-- clippy_lints/src/needless_pass_by_value.rs | 5 +++- clippy_lints/src/ptr.rs | 12 ++++++-- clippy_lints/src/transmute.rs | 5 +++- clippy_lints/src/types.rs | 31 +++++++++++++++---- clippy_lints/src/use_self.rs | 5 +++- clippy_lints/src/utils/hir_utils.rs | 11 +++++-- clippy_lints/src/utils/sugg.rs | 1 + 9 files changed, 86 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index b0fd62089ba..7e22fda4006 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -119,12 +119,15 @@ fn check_fn_inner<'a, 'tcx>( .expect("a path must have at least one segment") .args; if let Some(ref params) = *params { - for bound in ¶ms.lifetimes { - if bound.name.name() != "'static" && !bound.is_elided() { - return; - } - bounds_lts.push(bound); - } + params.args.iter().for_each(|param| match param { + GenericArg::Lifetime(bound) => { + if bound.name.name() != "'static" && !bound.is_elided() { + return; + } + bounds_lts.push(bound); + }, + _ => {}, + }); } } } @@ -233,9 +236,9 @@ fn could_use_elision<'a, 'tcx: 'a>( fn allowed_lts_from(named_generics: &[GenericParam]) -> HashSet { let mut allowed_lts = HashSet::new(); 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())); + if let GenericParamKind::Lifetime { .. } = par.kind { + if par.bounds.is_empty() { + allowed_lts.insert(RefLt::Named(par.name.name())); } } } @@ -299,7 +302,11 @@ impl<'v, 't> RefVisitor<'v, 't> { fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) { if let Some(ref last_path_segment) = last_path_segment(qpath).args { - if !last_path_segment.parenthesized && last_path_segment.lifetimes.is_empty() { + if !last_path_segment.parenthesized + && !last_path_segment.args.iter().any(|arg| match arg { + GenericArg::Lifetime(_) => true, + GenericArg::Type(_) => false, + }) { let hir_id = self.cx.tcx.hir.node_to_hir_id(ty.id); match self.cx.tables.qpath_def(qpath, hir_id) { Def::TyAlias(def_id) | Def::Struct(def_id) => { @@ -431,9 +438,11 @@ 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() - .map(|lt| (lt.lifetime.name.name(), lt.lifetime.span)) + let hs = generics.params.iter() + .filter_map(|par| match par.kind { + GenericParamKind::Lifetime { .. } => Some((par.name.name(), par.span)), + _ => None, + }) .collect(); let mut checker = LifetimeChecker { map: hs }; diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 2fe56bcdce1..b5e1780fd0c 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -2101,8 +2101,14 @@ fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Gener if params.parenthesized { false } else { - params.types.len() == 1 - && (is_self_ty(¶ms.types[0]) || is_ty(&*params.types[0], self_ty)) + // FIXME(flip1995): messy, improve if there is a better option + // in the compiler + let types: Vec<_> = params.args.iter().filter_map(|arg| match arg { + hir::GenericArg::Type(ty) => Some(ty), + _ => None, + }).collect(); + types.len() == 1 + && (is_self_ty(&types[0]) || is_ty(&*types[0], self_ty)) } } else { false diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 7a250f93db5..03a45bc1847 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -219,7 +219,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { if let Some(elem_ty) = path.segments.iter() .find(|seg| seg.name == "Vec") .and_then(|ps| ps.args.as_ref()) - .map(|params| ¶ms.types[0]); + .map(|params| params.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }).unwrap()); then { let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_")); db.span_suggestion(input.span, diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index fcd56c28218..78a07eddd4e 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -161,9 +161,14 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option< if_chain! { if let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node; if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last(); - if parameters.types.len() == 1; then { - ty_snippet = snippet_opt(cx, parameters.types[0].span); + let types: Vec<_> = parameters.args.iter().filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }).collect(); + if types.len() == 1 { + ty_snippet = snippet_opt(cx, types[0].span); + } } }; if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_owned()")]) { @@ -220,7 +225,8 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option< if let [ref bx] = *pp.segments; if let Some(ref params) = bx.args; if !params.parenthesized; - if let [ref inner] = *params.types; + if let [ref inner] = *params.args; + if let GenericArg::Type(inner) = inner; then { let replacement = snippet_opt(cx, inner.span); if let Some(r) = replacement { diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index 2b27ed22c47..c2e981979a1 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -457,7 +457,10 @@ fn get_type_snippet(cx: &LateContext, path: &QPath, to_ref_ty: Ty) -> String { if_chain! { if let Some(ref params) = seg.args; if !params.parenthesized; - if let Some(to_ty) = params.types.get(1); + if let Some(to_ty) = params.args.iter().filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }).nth(1); if let TyRptr(_, ref to_ty) = to_ty.node; then { return snippet(cx, to_ty.ty.span, &to_ref_ty.to_string()).to_string(); diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 70625724040..ee5611a50a1 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -182,7 +182,10 @@ fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool if_chain! { if let Some(ref params) = last.args; if !params.parenthesized; - if let Some(ty) = params.types.get(0); + if let Some(ty) = params.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }); if let TyPath(ref qpath) = ty.node; if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(ty.id))); if match_def_path(cx.tcx, did, path); @@ -246,7 +249,11 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { for ty in p.segments.iter().flat_map(|seg| { seg.args .as_ref() - .map_or_else(|| [].iter(), |params| params.types.iter()) + .map_or_else(|| [].iter(), |params| params.args.iter()) + .filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }) }) { check_ty(cx, ty, is_local); } @@ -254,14 +261,21 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) { QPath::Resolved(None, ref p) => for ty in p.segments.iter().flat_map(|seg| { seg.args .as_ref() - .map_or_else(|| [].iter(), |params| params.types.iter()) + .map_or_else(|| [].iter(), |params| params.args.iter()) + .filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }) }) { check_ty(cx, ty, is_local); }, QPath::TypeRelative(ref ty, ref seg) => { check_ty(cx, ty, is_local); if let Some(ref params) = seg.args { - for ty in params.types.iter() { + for ty in params.args.iter().filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }) { check_ty(cx, ty, is_local); } } @@ -290,7 +304,8 @@ fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifeti if let [ref bx] = *path.segments; if let Some(ref params) = bx.args; if !params.parenthesized; - if let [ref inner] = *params.types; + if let [ref inner] = *params.args; + if let GenericArg::Type(inner) = inner; then { if is_any_trait(inner) { // Ignore `Box` types, see #1884 for details. @@ -1862,7 +1877,11 @@ impl<'tcx> ImplicitHasherType<'tcx> { /// Checks that `ty` is a target type without a BuildHasher. fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty) -> Option { if let TyPath(QPath::Resolved(None, ref path)) = hir_ty.node { - let params = &path.segments.last().as_ref()?.args.as_ref()?.types; + let params: Vec<_> = path.segments.last().as_ref()?.args.as_ref()? + .args.iter().filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }).collect(); let params_len = params.len(); let ty = hir_ty_to_ty(cx.tcx, hir_ty); diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index 035471e4520..170db6ceabb 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -60,7 +60,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { then { let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; let should_check = if let Some(ref params) = *parameters { - !params.parenthesized && params.lifetimes.len() == 0 + !params.parenthesized && !params.args.iter().any(|arg| match arg { + GenericArg::Lifetime(_) => true, + GenericArg::Type(_) => false, + }) } else { true }; diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index 1cfb5a82f72..ee6b004dc6c 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -152,6 +152,14 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { left.ident.name == right.ident.name && self.eq_expr(&left.expr, &right.expr) } + fn eq_generic_arg(&mut self, left: &GenericArg, right: &GenericArg) -> bool { + match (left, right) { + (GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => self.eq_lifetime(l_lt, r_lt), + (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty), + _ => false, + } + } + fn eq_lifetime(&mut self, left: &Lifetime, right: &Lifetime) -> bool { left.name == right.name } @@ -203,8 +211,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> { fn eq_path_parameters(&mut self, left: &GenericArgs, right: &GenericArgs) -> bool { if !(left.parenthesized || right.parenthesized) { - over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r)) - && over(&left.types, &right.types, |l, r| self.eq_ty(l, r)) + over(&left.args, &right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work && over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r)) } else if left.parenthesized && right.parenthesized { over(left.inputs(), right.inputs(), |l, r| self.eq_ty(l, r)) diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index 9482cc6bc0e..eb2197a5891 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -100,6 +100,7 @@ impl<'a> Sugg<'a> { ast::ExprKind::ObsoleteInPlace(..) | ast::ExprKind::Unary(..) | ast::ExprKind::Match(..) => Sugg::MaybeParen(snippet), + ast::ExprKind::Async(..) | ast::ExprKind::Block(..) | ast::ExprKind::Break(..) | ast::ExprKind::Call(..) | From 535c16879111b7e6e3d55f43e469a8cccb6dbe05 Mon Sep 17 00:00:00 2001 From: flip1995 <9744647+flip1995@users.noreply.github.com> Date: Mon, 25 Jun 2018 02:06:57 +0200 Subject: [PATCH 3/4] Fix the tests that got broken by the fixes --- clippy_lints/src/lifetimes.rs | 60 ++++++++++++++++++----------------- clippy_lints/src/ptr.rs | 6 ++-- clippy_lints/src/types.rs | 6 ++-- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs index 7e22fda4006..1c063464fcc 100644 --- a/clippy_lints/src/lifetimes.rs +++ b/clippy_lints/src/lifetimes.rs @@ -101,38 +101,40 @@ fn check_fn_inner<'a, 'tcx>( } let mut bounds_lts = Vec::new(); - generics.params.iter().for_each(|param| match param.kind { - GenericParamKind::Lifetime { .. } => {}, - GenericParamKind::Type { .. } => { - for bound in ¶m.bounds { - let mut visitor = RefVisitor::new(cx); - walk_param_bound(&mut visitor, bound); - if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) { - return; - } - if let GenericBound::Trait(ref trait_ref, _) = *bound { - let params = &trait_ref - .trait_ref - .path - .segments - .last() - .expect("a path must have at least one segment") - .args; - if let Some(ref params) = *params { - params.args.iter().for_each(|param| match param { - GenericArg::Lifetime(bound) => { - if bound.name.name() != "'static" && !bound.is_elided() { - return; - } - bounds_lts.push(bound); - }, - _ => {}, - }); + let types = generics.params.iter().filter_map(|param| match param.kind { + GenericParamKind::Type { .. } => Some(param), + GenericParamKind::Lifetime { .. } => None, + }); + for typ in types { + for bound in &typ.bounds { + let mut visitor = RefVisitor::new(cx); + walk_param_bound(&mut visitor, bound); + if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) { + return; + } + if let GenericBound::Trait(ref trait_ref, _) = *bound { + let params = &trait_ref + .trait_ref + .path + .segments + .last() + .expect("a path must have at least one segment") + .args; + if let Some(ref params) = *params { + let lifetimes = params.args.iter().filter_map(|arg| match arg { + GenericArg::Lifetime(lt) => Some(lt), + GenericArg::Type(_) => None, + }); + for bound in lifetimes { + if bound.name.name() != "'static" && !bound.is_elided() { + return; + } + bounds_lts.push(bound); } } } - }, - }); + } + } if could_use_elision(cx, decl, body, &generics.params, bounds_lts) { span_lint( cx, diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 78a07eddd4e..68cecc8de67 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -225,8 +225,10 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option< if let [ref bx] = *pp.segments; if let Some(ref params) = bx.args; if !params.parenthesized; - if let [ref inner] = *params.args; - if let GenericArg::Type(inner) = inner; + if let Some(inner) = params.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }); then { let replacement = snippet_opt(cx, inner.span); if let Some(r) = replacement { diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index ee5611a50a1..887e9f12712 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -304,8 +304,10 @@ fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifeti if let [ref bx] = *path.segments; if let Some(ref params) = bx.args; if !params.parenthesized; - if let [ref inner] = *params.args; - if let GenericArg::Type(inner) = inner; + if let Some(inner) = params.args.iter().find_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + GenericArg::Lifetime(_) => None, + }); then { if is_any_trait(inner) { // Ignore `Box` types, see #1884 for details. From 203ad28021ddad978285f2533bdb678bed05f2e3 Mon Sep 17 00:00:00 2001 From: flip1995 <9744647+flip1995@users.noreply.github.com> Date: Mon, 25 Jun 2018 11:53:00 +0200 Subject: [PATCH 4/4] resolve merge of NameAndSpan and ExpnInfo rust-lang/rust#51726 --- clippy_lints/src/misc.rs | 2 +- clippy_lints/src/utils/mod.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index a1cb1910e20..414e507a55b 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -558,7 +558,7 @@ fn in_attributes_expansion(expr: &Expr) -> bool { .ctxt() .outer() .expn_info() - .map_or(false, |info| matches!(info.callee.format, ExpnFormat::MacroAttribute(_))) + .map_or(false, |info| matches!(info.format, ExpnFormat::MacroAttribute(_))) } /// Test whether `def` is a variable defined outside a macro. diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 3adc65a2543..ae8ffcf2fce 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -57,7 +57,7 @@ pub fn in_constant(cx: &LateContext, id: NodeId) -> bool { /// Returns true if this `expn_info` was expanded by any macro. pub fn in_macro(span: Span) -> bool { span.ctxt().outer().expn_info().map_or(false, |info| { - match info.callee.format { + match info.format { // don't treat range expressions desugared to structs as "in_macro" ExpnFormat::CompilerDesugaring(kind) => kind != CompilerDesugaringKind::DotFill, _ => true, @@ -68,7 +68,7 @@ pub fn in_macro(span: Span) -> bool { /// Returns true if `expn_info` was expanded by range expressions. pub fn is_range_expression(span: Span) -> bool { span.ctxt().outer().expn_info().map_or(false, |info| { - match info.callee.format { + match info.format { ExpnFormat::CompilerDesugaring(CompilerDesugaringKind::DotFill) => true, _ => false, } @@ -84,12 +84,12 @@ pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool { /// this after other checks have already happened. fn in_macro_ext<'a, T: LintContext<'a>>(cx: &T, info: &ExpnInfo) -> bool { // no ExpnInfo = no macro - if let ExpnFormat::MacroAttribute(..) = info.callee.format { + if let ExpnFormat::MacroAttribute(..) = info.format { // these are all plugins return true; } // no span for the callee = external macro - info.callee.span.map_or(true, |span| { + info.def_site.map_or(true, |span| { // no snippet = external macro or compiler-builtin expansion cx.sess() .codemap() @@ -768,7 +768,7 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option { let span_name_span = span.ctxt() .outer() .expn_info() - .map(|ei| (ei.callee.name(), ei.call_site)); + .map(|ei| (ei.format.name(), ei.call_site)); match span_name_span { Some((mac_name, new_span)) if mac_name == name => return Some(new_span), @@ -791,7 +791,7 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option { let span_name_span = span.ctxt() .outer() .expn_info() - .map(|ei| (ei.callee.name(), ei.call_site)); + .map(|ei| (ei.format.name(), ei.call_site)); match span_name_span { Some((mac_name, new_span)) if mac_name == name => Some(new_span),