From 68c26b325b35e6984b585d285b17dd5eadb3c860 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Sep 2019 04:16:25 -0700 Subject: [PATCH 1/4] Rustup to rustc 1.39.0-nightly (acf7b50c7 2019-09-25) - Addresses inference error - Updates compiletest --- Cargo.toml | 2 +- tests/ui/many_single_char_names.rs | 2 +- tests/ui/many_single_char_names.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8c70bb189..7ab20320e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util"} [dev-dependencies] cargo_metadata = "0.8.0" -compiletest_rs = { version = "0.3.22", features = ["tmp"] } +compiletest_rs = { version = "0.3.23", features = ["tmp"] } lazy_static = "1.0" clippy-mini-macro-test = { version = "0.2", path = "mini-macro" } serde = { version = "1.0", features = ["derive"] } diff --git a/tests/ui/many_single_char_names.rs b/tests/ui/many_single_char_names.rs index 81c042730..80800e487 100644 --- a/tests/ui/many_single_char_names.rs +++ b/tests/ui/many_single_char_names.rs @@ -29,7 +29,7 @@ fn bla() { fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {} fn bindings2() { - let (a, b, c, d, e, f, g, h) = unimplemented!(); + let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); } fn shadowing() { diff --git a/tests/ui/many_single_char_names.stderr b/tests/ui/many_single_char_names.stderr index a746667ba..27e62e641 100644 --- a/tests/ui/many_single_char_names.stderr +++ b/tests/ui/many_single_char_names.stderr @@ -44,7 +44,7 @@ LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) error: 8 bindings with single-character names in scope --> $DIR/many_single_char_names.rs:32:10 | -LL | let (a, b, c, d, e, f, g, h) = unimplemented!(); +LL | let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!(); | ^ ^ ^ ^ ^ ^ ^ ^ error: aborting due to 5 previous errors From 982c51e769c693644eec19ac9f1e339997bbe579 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Sep 2019 12:00:17 -0700 Subject: [PATCH 2/4] arm.pats -> arm.pat --- clippy_lints/src/cognitive_complexity.rs | 3 +- clippy_lints/src/copies.rs | 37 ++++----- clippy_lints/src/format.rs | 3 +- .../src/infallible_destructuring_match.rs | 4 +- clippy_lints/src/loops.rs | 6 +- clippy_lints/src/matches.rs | 83 +++++++------------ clippy_lints/src/ok_if_let.rs | 2 +- .../src/redundant_pattern_matching.rs | 66 +++++++-------- clippy_lints/src/shadow.rs | 16 ++-- clippy_lints/src/utils/author.rs | 7 +- clippy_lints/src/utils/hir_utils.rs | 2 +- clippy_lints/src/utils/inspector.rs | 4 +- clippy_lints/src/utils/mod.rs | 8 +- tests/ui/author/for_loop.stdout | 9 +- tests/ui/shadow.rs | 7 +- tests/ui/shadow.stderr | 46 +++++----- tests/ui/wildcard_enum_match_arm.fixed | 2 +- tests/ui/wildcard_enum_match_arm.rs | 2 +- 18 files changed, 136 insertions(+), 171 deletions(-) diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index 3e7f3c980..33603b27b 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -112,8 +112,7 @@ impl<'tcx> Visitor<'tcx> for CCHelper { walk_expr(self, e); match e.node { ExprKind::Match(_, ref arms, _) => { - let arms_n: u64 = arms.iter().map(|arm| arm.pats.len() as u64).sum(); - if arms_n > 1 { + if arms.len() > 1 { self.cc += 1; } self.cc += arms.iter().filter(|arm| arm.guard.is_some()).count() as u64; diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index b01ce7eeb..bdef21b0e 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -193,7 +193,7 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr) { (min_index..=max_index).all(|index| arms[index].guard.is_none()) && SpanlessEq::new(cx).eq_expr(&lhs.body, &rhs.body) && // all patterns should have the same bindings - same_bindings(cx, &bindings(cx, &lhs.pats[0]), &bindings(cx, &rhs.pats[0])) + same_bindings(cx, &bindings(cx, &lhs.pat), &bindings(cx, &rhs.pat)) }; let indexed_arms: Vec<(usize, &Arm)> = arms.iter().enumerate().collect(); @@ -213,27 +213,22 @@ fn lint_match_arms<'tcx>(cx: &LateContext<'_, 'tcx>, expr: &Expr) { // span for the whole pattern, the suggestion is only shown when there is only // one pattern. The user should know about `|` if they are already using it… - if i.pats.len() == 1 && j.pats.len() == 1 { - let lhs = snippet(cx, i.pats[0].span, ""); - let rhs = snippet(cx, j.pats[0].span, ""); + let lhs = snippet(cx, i.pat.span, ""); + let rhs = snippet(cx, j.pat.span, ""); - if let PatKind::Wild = j.pats[0].node { - // if the last arm is _, then i could be integrated into _ - // note that i.pats[0] cannot be _, because that would mean that we're - // hiding all the subsequent arms, and rust won't compile - db.span_note( - i.body.span, - &format!( - "`{}` has the same arm body as the `_` wildcard, consider removing it`", - lhs - ), - ); - } else { - db.span_help( - i.pats[0].span, - &format!("consider refactoring into `{} | {}`", lhs, rhs), - ); - } + if let PatKind::Wild = j.pat.node { + // if the last arm is _, then i could be integrated into _ + // note that i.pat cannot be _, because that would mean that we're + // hiding all the subsequent arms, and rust won't compile + db.span_note( + i.body.span, + &format!( + "`{}` has the same arm body as the `_` wildcard, consider removing it`", + lhs + ), + ); + } else { + db.span_help(i.pat.span, &format!("consider refactoring into `{} | {}`", lhs, rhs)); } }, ); diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 1df6b9294..4f763863f 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -84,9 +84,8 @@ fn on_argumentv1_new<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, arm if let ExprKind::Path(ref qpath) = args[1].node; if let Some(did) = resolve_node(cx, qpath, args[1].hir_id).opt_def_id(); if match_def_path(cx, did, &paths::DISPLAY_FMT_METHOD); - if arms[0].pats.len() == 1; // check `(arg0,)` in match block - if let PatKind::Tuple(ref pats, None) = arms[0].pats[0].node; + if let PatKind::Tuple(ref pats, None) = arms[0].pat.node; if pats.len() == 1; then { let ty = walk_ptrs_ty(cx.tables.pat_ty(&pats[0])); diff --git a/clippy_lints/src/infallible_destructuring_match.rs b/clippy_lints/src/infallible_destructuring_match.rs index a977a8273..2ae2e2006 100644 --- a/clippy_lints/src/infallible_destructuring_match.rs +++ b/clippy_lints/src/infallible_destructuring_match.rs @@ -47,8 +47,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InfallibleDestructingMatch { if_chain! { if let Some(ref expr) = local.init; if let ExprKind::Match(ref target, ref arms, MatchSource::Normal) = expr.node; - if arms.len() == 1 && arms[0].pats.len() == 1 && arms[0].guard.is_none(); - if let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pats[0].node; + if arms.len() == 1 && arms[0].guard.is_none(); + if let PatKind::TupleStruct(QPath::Resolved(None, ref variant_name), ref args, _) = arms[0].pat.node; if args.len() == 1; if let Some(arg) = get_arg_name(&args[0]); let body = remove_blocks(&arms[0].body); diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 0032cfd19..94328a2b5 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -517,9 +517,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { match *source { MatchSource::Normal | MatchSource::IfLetDesugar { .. } => { if arms.len() == 2 - && arms[0].pats.len() == 1 && arms[0].guard.is_none() - && arms[1].pats.len() == 1 && arms[1].guard.is_none() && is_simple_break_expr(&arms[1].body) { @@ -541,7 +539,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { "try", format!( "while let {} = {} {{ .. }}", - snippet_with_applicability(cx, arms[0].pats[0].span, "..", &mut applicability), + snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability), snippet_with_applicability(cx, matchexpr.span, "..", &mut applicability), ), applicability, @@ -554,7 +552,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Loops { } } if let ExprKind::Match(ref match_expr, ref arms, MatchSource::WhileLetDesugar) = expr.node { - let pat = &arms[0].pats[0].node; + let pat = &arms[0].pat.node; if let ( &PatKind::TupleStruct(ref qpath, ref pat_args, _), &ExprKind::MethodCall(ref method_path, _, ref method_args), diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 2a65ea000..3d765af21 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -14,7 +14,6 @@ use rustc::{declare_lint_pass, declare_tool_lint}; use rustc_errors::Applicability; use std::cmp::Ordering; use std::collections::Bound; -use std::ops::Deref; use syntax::ast::LitKind; use syntax::source_map::Span; @@ -255,9 +254,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches { #[rustfmt::skip] fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { - if arms.len() == 2 && - arms[0].pats.len() == 1 && arms[0].guard.is_none() && - arms[1].pats.len() == 1 && arms[1].guard.is_none() { + if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { let els = remove_blocks(&arms[1].body); let els = if is_unit_expr(els) { None @@ -283,7 +280,7 @@ fn check_single_match_single_pattern( expr: &Expr, els: Option<&Expr>, ) { - if is_wild(&arms[1].pats[0]) { + if is_wild(&arms[1].pat) { report_single_match_single_pattern(cx, ex, arms, expr, els); } } @@ -308,7 +305,7 @@ fn report_single_match_single_pattern( "try this", format!( "if let {} = {} {}{}", - snippet(cx, arms[0].pats[0].span, ".."), + snippet(cx, arms[0].pat.span, ".."), snippet(cx, ex.span, ".."), expr_block(cx, &arms[0].body, None, ".."), els_str, @@ -336,7 +333,7 @@ fn check_single_match_opt_like( (&paths::RESULT, "Ok"), ]; - let path = match arms[1].pats[0].node { + let path = match arms[1].pat.node { PatKind::TupleStruct(ref path, ref inner, _) => { // Contains any non wildcard patterns (e.g., `Err(err)`)? if !inner.iter().all(is_wild) { @@ -365,9 +362,9 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Ex expr.span, "you seem to be trying to match on a boolean expression", move |db| { - if arms.len() == 2 && arms[0].pats.len() == 1 { + if arms.len() == 2 { // no guards - let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pats[0].node { + let exprs = if let PatKind::Lit(ref arm_bool) = arms[0].pat.node { if let ExprKind::Lit(ref lit) = arm_bool.node { match lit.node { LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)), @@ -446,7 +443,7 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) { let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex)); if match_type(cx, ex_ty, &paths::RESULT) { for arm in arms { - if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pats[0].node { + if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pat.node { let path_str = print::to_string(print::NO_ANN, |s| s.print_qpath(path, false)); if_chain! { if path_str == "Err"; @@ -457,9 +454,9 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) { // `Err(_)` arm with `panic!` found span_note_and_lint(cx, MATCH_WILD_ERR_ARM, - arm.pats[0].span, + arm.pat.span, "Err(_) will match all errors, maybe not a good idea", - arm.pats[0].span, + arm.pat.span, "to remove this warning, match each error separately \ or use unreachable macro"); } @@ -482,13 +479,11 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) { let mut wildcard_span = None; let mut wildcard_ident = None; for arm in arms { - for pat in &arm.pats { - if let PatKind::Wild = pat.node { - wildcard_span = Some(pat.span); - } else if let PatKind::Binding(_, _, ident, None) = pat.node { - wildcard_span = Some(pat.span); - wildcard_ident = Some(ident); - } + if let PatKind::Wild = arm.pat.node { + wildcard_span = Some(arm.pat.span); + } else if let PatKind::Binding(_, _, ident, None) = arm.pat.node { + wildcard_span = Some(arm.pat.span); + wildcard_ident = Some(ident); } } @@ -510,15 +505,13 @@ fn check_wild_enum_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) { // covered by the set of guards that cover it, but that's really hard to do. continue; } - for pat in &arm.pats { - if let PatKind::Path(ref path) = pat.deref().node { - if let QPath::Resolved(_, p) = path { - missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id())); - } - } else if let PatKind::TupleStruct(ref path, ..) = pat.deref().node { - if let QPath::Resolved(_, p) = path { - missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id())); - } + if let PatKind::Path(ref path) = arm.pat.node { + if let QPath::Resolved(_, p) = path { + missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id())); + } + } else if let PatKind::TupleStruct(ref path, ..) = arm.pat.node { + if let QPath::Resolved(_, p) = path { + missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id())); } } } @@ -588,9 +581,9 @@ fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: ) }; - suggs.extend(arms.iter().flat_map(|a| &a.pats).filter_map(|p| { - if let PatKind::Ref(ref refp, _) = p.node { - Some((p.span, snippet(cx, refp.span, "..").to_string())) + suggs.extend(arms.iter().filter_map(|a| { + if let PatKind::Ref(ref refp, _) = a.pat.node { + Some((a.pat.span, snippet(cx, refp.span, "..").to_string())) } else { None } @@ -605,12 +598,7 @@ fn check_match_ref_pats(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: } fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { - if arms.len() == 2 - && arms[0].pats.len() == 1 - && arms[0].guard.is_none() - && arms[1].pats.len() == 1 - && arms[1].guard.is_none() - { + if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { let arm_ref: Option = if is_none_arm(&arms[0]) { is_ref_some_arm(&arms[1]) } else if is_none_arm(&arms[1]) { @@ -666,14 +654,9 @@ fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm]) -> Vec(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm]) -> Vec bool { // Checks if arm has the form `None => None` fn is_none_arm(arm: &Arm) -> bool { - match arm.pats[0].node { + match arm.pat.node { PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => true, _ => false, } @@ -752,7 +734,7 @@ fn is_none_arm(arm: &Arm) -> bool { // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`) fn is_ref_some_arm(arm: &Arm) -> Option { if_chain! { - if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pats[0].node; + if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pat.node; if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME); if let PatKind::Binding(rb, .., ident, _) = pats[0].node; if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut; @@ -772,9 +754,8 @@ fn is_ref_some_arm(arm: &Arm) -> Option { fn has_only_ref_pats(arms: &[Arm]) -> bool { let mapped = arms .iter() - .flat_map(|a| &a.pats) - .map(|p| { - match p.node { + .map(|a| { + match a.pat.node { PatKind::Ref(..) => Some(true), // &-patterns PatKind::Wild => Some(false), // an "anything" wildcard is also fine _ => None, // any other pattern is not fine diff --git a/clippy_lints/src/ok_if_let.rs b/clippy_lints/src/ok_if_let.rs index 01d41f679..7105376d5 100644 --- a/clippy_lints/src/ok_if_let.rs +++ b/clippy_lints/src/ok_if_let.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OkIfLet { if let ExprKind::Match(ref op, ref body, ref source) = expr.node; //test if expr is a match if let MatchSource::IfLetDesugar { .. } = *source; //test if it is an If Let if let ExprKind::MethodCall(_, _, ref result_types) = op.node; //check is expr.ok() has type Result.ok() - if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pats[0].node; //get operation + if let PatKind::TupleStruct(QPath::Resolved(_, ref x), ref y, _) = body[0].pat.node; //get operation if method_chain_args(op, &["ok"]).is_some(); //test to see if using ok() methoduse std::marker::Sized; then { diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs index 68862f838..b8d1ea385 100644 --- a/clippy_lints/src/redundant_pattern_matching.rs +++ b/clippy_lints/src/redundant_pattern_matching.rs @@ -57,50 +57,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantPatternMatching { } fn find_sugg_for_if_let<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, op: &P, arms: &HirVec) { - if arms[0].pats.len() == 1 { - let good_method = match arms[0].pats[0].node { - PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => { - if let PatKind::Wild = patterns[0].node { - if match_qpath(path, &paths::RESULT_OK) { - "is_ok()" - } else if match_qpath(path, &paths::RESULT_ERR) { - "is_err()" - } else if match_qpath(path, &paths::OPTION_SOME) { - "is_some()" - } else { - return; - } + let good_method = match arms[0].pat.node { + PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => { + if let PatKind::Wild = patterns[0].node { + if match_qpath(path, &paths::RESULT_OK) { + "is_ok()" + } else if match_qpath(path, &paths::RESULT_ERR) { + "is_err()" + } else if match_qpath(path, &paths::OPTION_SOME) { + "is_some()" } else { return; } - }, + } else { + return; + } + }, - PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()", + PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => "is_none()", - _ => return, - }; + _ => return, + }; - span_lint_and_then( - cx, - REDUNDANT_PATTERN_MATCHING, - arms[0].pats[0].span, - &format!("redundant pattern matching, consider using `{}`", good_method), - |db| { - let span = expr.span.to(op.span); - db.span_suggestion( - span, - "try this", - format!("{}.{}", snippet(cx, op.span, "_"), good_method), - Applicability::MaybeIncorrect, // snippet - ); - }, - ); - } + span_lint_and_then( + cx, + REDUNDANT_PATTERN_MATCHING, + arms[0].pat.span, + &format!("redundant pattern matching, consider using `{}`", good_method), + |db| { + let span = expr.span.to(op.span); + db.span_suggestion( + span, + "try this", + format!("{}.{}", snippet(cx, op.span, "_"), good_method), + Applicability::MaybeIncorrect, // snippet + ); + }, + ); } fn find_sugg_for_match<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, op: &P, arms: &HirVec) { if arms.len() == 2 { - let node_pair = (&arms[0].pats[0].node, &arms[1].pats[0].node); + let node_pair = (&arms[0].pat.node, &arms[1].pat.node); let found_good_method = match node_pair { ( diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index b30f8d415..ebef0449c 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -328,17 +328,15 @@ fn check_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, bindings: check_expr(cx, init, bindings); let len = bindings.len(); for arm in arms { - for pat in &arm.pats { - check_pat(cx, pat, Some(&**init), pat.span, bindings); - // This is ugly, but needed to get the right type - if let Some(ref guard) = arm.guard { - match guard { - Guard::If(if_expr) => check_expr(cx, if_expr, bindings), - } + check_pat(cx, &arm.pat, Some(&**init), arm.pat.span, bindings); + // This is ugly, but needed to get the right type + if let Some(ref guard) = arm.guard { + match guard { + Guard::If(if_expr) => check_expr(cx, if_expr, bindings), } - check_expr(cx, &arm.body, bindings); - bindings.truncate(len); } + check_expr(cx, &arm.body, bindings); + bindings.truncate(len); } }, _ => (), diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 87208dd4b..044e98380 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -354,11 +354,8 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor { }, } } - println!(" if {}[{}].pats.len() == {};", arms_pat, i, arm.pats.len()); - for (j, pat) in arm.pats.iter().enumerate() { - self.current = format!("{}[{}].pats[{}]", arms_pat, i, j); - self.visit_pat(pat); - } + self.current = format!("{}[{}].pat", arms_pat, i); + self.visit_pat(&arm.pat); } }, ExprKind::Closure(ref _capture_clause, ref _func, _, _, _) => { diff --git a/clippy_lints/src/utils/hir_utils.rs b/clippy_lints/src/utils/hir_utils.rs index 6fc5939a2..deea5823f 100644 --- a/clippy_lints/src/utils/hir_utils.rs +++ b/clippy_lints/src/utils/hir_utils.rs @@ -124,7 +124,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> { && over(la, ra, |l, r| { self.eq_expr(&l.body, &r.body) && both(&l.guard, &r.guard, |l, r| self.eq_guard(l, r)) - && over(&l.pats, &r.pats, |l, r| self.eq_pat(l, r)) + && self.eq_pat(&l.pat, &r.pat) }) }, (&ExprKind::MethodCall(ref l_path, _, ref l_args), &ExprKind::MethodCall(ref r_path, _, ref r_args)) => { diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs index ba0e56c99..d70f8bab8 100644 --- a/clippy_lints/src/utils/inspector.rs +++ b/clippy_lints/src/utils/inspector.rs @@ -101,9 +101,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { if !has_attr(cx.sess(), &arm.attrs) { return; } - for pat in &arm.pats { - print_pat(cx, pat, 1); - } + print_pat(cx, &arm.pat, 1); if let Some(ref guard) = arm.guard { println!("guard:"); print_guard(cx, guard, 1); diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 9165f8d74..88229da8c 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -909,7 +909,7 @@ pub fn iter_input_pats<'tcx>(decl: &FnDecl, body: &'tcx Body) -> impl Iterator Option<&Expr> { fn is_ok(arm: &Arm) -> bool { if_chain! { - if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pats[0].node; + if let PatKind::TupleStruct(ref path, ref pat, None) = arm.pat.node; if match_qpath(path, &paths::RESULT_OK[1..]); if let PatKind::Binding(_, hir_id, _, None) = pat[0].node; if let ExprKind::Path(QPath::Resolved(None, ref path)) = arm.body.node; @@ -923,7 +923,7 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { } fn is_err(arm: &Arm) -> bool { - if let PatKind::TupleStruct(ref path, _, _) = arm.pats[0].node { + if let PatKind::TupleStruct(ref path, _, _) = arm.pat.node { match_qpath(path, &paths::RESULT_ERR[1..]) } else { false @@ -938,8 +938,8 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> { if_chain! { if arms.len() == 2; - if arms[0].pats.len() == 1 && arms[0].guard.is_none(); - if arms[1].pats.len() == 1 && arms[1].guard.is_none(); + if arms[0].guard.is_none(); + if arms[1].guard.is_none(); if (is_ok(&arms[0]) && is_err(&arms[1])) || (is_ok(&arms[1]) && is_err(&arms[0])); then { diff --git a/tests/ui/author/for_loop.stdout b/tests/ui/author/for_loop.stdout index 7ce04e44b..d195c7fdb 100644 --- a/tests/ui/author/for_loop.stdout +++ b/tests/ui/author/for_loop.stdout @@ -31,14 +31,12 @@ if_chain! { if match_qpath(path4, &["__next"]); if let ExprKind::Path(ref path5) = value.node; if match_qpath(path5, &["val"]); - if arms1[0].pats.len() == 1; - if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pats[0].node; + if let PatKind::TupleStruct(ref path6, ref fields1, None) = arms1[0].pat.node; if match_qpath(path6, &["{{root}}", "std", "option", "Option", "Some"]); if fields1.len() == 1; // unimplemented: field checks if let ExprKind::Break(ref destination, None) = arms1[1].body.node; - if arms1[1].pats.len() == 1; - if let PatKind::Path(ref path7) = arms1[1].pats[0].node; + if let PatKind::Path(ref path7) = arms1[1].pat.node; if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]); if let StmtKind::Local(ref local1) = body.stmts[2].node; if let Some(ref init) = local1.init; @@ -56,8 +54,7 @@ if_chain! { if match_qpath(path9, &["y"]); if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.node; if name2.node.as_str() == "z"; - if arms[0].pats.len() == 1; - if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pats[0].node; + if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pat.node; if name3.node.as_str() == "iter"; then { // report your lint here diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs index a9c77aca6..7a5da67e0 100644 --- a/tests/ui/shadow.rs +++ b/tests/ui/shadow.rs @@ -5,7 +5,12 @@ clippy::shadow_reuse, clippy::shadow_unrelated )] -#![allow(unused_parens, unused_variables, clippy::missing_docs_in_private_items)] +#![allow( + unused_parens, + unused_variables, + clippy::missing_docs_in_private_items, + clippy::single_match +)] fn id(x: T) -> T { x diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr index ada8b07d6..184e781ae 100644 --- a/tests/ui/shadow.stderr +++ b/tests/ui/shadow.stderr @@ -1,135 +1,135 @@ error: `x` is shadowed by itself in `&mut x` - --> $DIR/shadow.rs:20:5 + --> $DIR/shadow.rs:25:5 | LL | let x = &mut x; | ^^^^^^^^^^^^^^^ | = note: `-D clippy::shadow-same` implied by `-D warnings` note: previous binding is here - --> $DIR/shadow.rs:19:13 + --> $DIR/shadow.rs:24:13 | LL | let mut x = 1; | ^ error: `x` is shadowed by itself in `{ x }` - --> $DIR/shadow.rs:21:5 + --> $DIR/shadow.rs:26:5 | LL | let x = { x }; | ^^^^^^^^^^^^^^ | note: previous binding is here - --> $DIR/shadow.rs:20:9 + --> $DIR/shadow.rs:25:9 | LL | let x = &mut x; | ^ error: `x` is shadowed by itself in `(&*x)` - --> $DIR/shadow.rs:22:5 + --> $DIR/shadow.rs:27:5 | LL | let x = (&*x); | ^^^^^^^^^^^^^^ | note: previous binding is here - --> $DIR/shadow.rs:21:9 + --> $DIR/shadow.rs:26:9 | LL | let x = { x }; | ^ error: `x` is shadowed by `{ *x + 1 }` which reuses the original value - --> $DIR/shadow.rs:23:9 + --> $DIR/shadow.rs:28:9 | LL | let x = { *x + 1 }; | ^ | = note: `-D clippy::shadow-reuse` implied by `-D warnings` note: initialization happens here - --> $DIR/shadow.rs:23:13 + --> $DIR/shadow.rs:28:13 | LL | let x = { *x + 1 }; | ^^^^^^^^^^ note: previous binding is here - --> $DIR/shadow.rs:22:9 + --> $DIR/shadow.rs:27:9 | LL | let x = (&*x); | ^ error: `x` is shadowed by `id(x)` which reuses the original value - --> $DIR/shadow.rs:24:9 + --> $DIR/shadow.rs:29:9 | LL | let x = id(x); | ^ | note: initialization happens here - --> $DIR/shadow.rs:24:13 + --> $DIR/shadow.rs:29:13 | LL | let x = id(x); | ^^^^^ note: previous binding is here - --> $DIR/shadow.rs:23:9 + --> $DIR/shadow.rs:28:9 | LL | let x = { *x + 1 }; | ^ error: `x` is shadowed by `(1, x)` which reuses the original value - --> $DIR/shadow.rs:25:9 + --> $DIR/shadow.rs:30:9 | LL | let x = (1, x); | ^ | note: initialization happens here - --> $DIR/shadow.rs:25:13 + --> $DIR/shadow.rs:30:13 | LL | let x = (1, x); | ^^^^^^ note: previous binding is here - --> $DIR/shadow.rs:24:9 + --> $DIR/shadow.rs:29:9 | LL | let x = id(x); | ^ error: `x` is shadowed by `first(x)` which reuses the original value - --> $DIR/shadow.rs:26:9 + --> $DIR/shadow.rs:31:9 | LL | let x = first(x); | ^ | note: initialization happens here - --> $DIR/shadow.rs:26:13 + --> $DIR/shadow.rs:31:13 | LL | let x = first(x); | ^^^^^^^^ note: previous binding is here - --> $DIR/shadow.rs:25:9 + --> $DIR/shadow.rs:30:9 | LL | let x = (1, x); | ^ error: `x` is shadowed by `y` - --> $DIR/shadow.rs:28:9 + --> $DIR/shadow.rs:33:9 | LL | let x = y; | ^ | = note: `-D clippy::shadow-unrelated` implied by `-D warnings` note: initialization happens here - --> $DIR/shadow.rs:28:13 + --> $DIR/shadow.rs:33:13 | LL | let x = y; | ^ note: previous binding is here - --> $DIR/shadow.rs:26:9 + --> $DIR/shadow.rs:31:9 | LL | let x = first(x); | ^ error: `x` shadows a previous declaration - --> $DIR/shadow.rs:30:5 + --> $DIR/shadow.rs:35:5 | LL | let x; | ^^^^^^ | note: previous binding is here - --> $DIR/shadow.rs:28:9 + --> $DIR/shadow.rs:33:9 | LL | let x = y; | ^ diff --git a/tests/ui/wildcard_enum_match_arm.fixed b/tests/ui/wildcard_enum_match_arm.fixed index 01c861282..af67f326f 100644 --- a/tests/ui/wildcard_enum_match_arm.fixed +++ b/tests/ui/wildcard_enum_match_arm.fixed @@ -1,7 +1,7 @@ // run-rustfix #![deny(clippy::wildcard_enum_match_arm)] -#![allow(unreachable_code, unused_variables)] +#![allow(unreachable_code, unused_variables, dead_code)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Color { diff --git a/tests/ui/wildcard_enum_match_arm.rs b/tests/ui/wildcard_enum_match_arm.rs index d33c68a6c..049596d34 100644 --- a/tests/ui/wildcard_enum_match_arm.rs +++ b/tests/ui/wildcard_enum_match_arm.rs @@ -1,7 +1,7 @@ // run-rustfix #![deny(clippy::wildcard_enum_match_arm)] -#![allow(unreachable_code, unused_variables)] +#![allow(unreachable_code, unused_variables, dead_code)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] enum Color { From b5cadd734eed6f4ba317550f8d6e3ab019fe1bcb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Sep 2019 13:34:55 -0700 Subject: [PATCH 3/4] ignore single-match for or patterns --- clippy_lints/src/matches.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 3d765af21..ac4f012f3 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -255,6 +255,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches { #[rustfmt::skip] fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) { if arms.len() == 2 && arms[0].guard.is_none() && arms[1].guard.is_none() { + if let PatKind::Or(..) = arms[0].pat.node { + // don't lint for or patterns for now, this makes + // the lint noisy in unnecessary situations + return; + } let els = remove_blocks(&arms[1].body); let els = if is_unit_expr(els) { None From a756b9bd2dd3d5f4d7d7beb66505e42c3f1995e1 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 25 Sep 2019 13:51:29 -0700 Subject: [PATCH 4/4] allow osx failures --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9c1d004d6..b29b13627 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,6 +85,8 @@ matrix: allow_failures: - os: windows env: CARGO_INCREMENTAL=0 BASE_TESTS=true OS_WINDOWS=true + - os: osx # run base tests on both platforms + env: BASE_TESTS=true # prevent these jobs with default env vars exclude: - os: linux