From 7580da306e338089b1cffedb09a71cb11debddf5 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 21 Aug 2015 20:49:59 +0200 Subject: [PATCH] matches: special message for this case match &e { &Pat1 => {}, &Pat2 => {}, ... } (inspired by dogfood fixes) --- src/matches.rs | 27 ++++++++++++++------------- tests/compile-fail/matches.rs | 6 ++++++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/matches.rs b/src/matches.rs index b704a2b47bbc..002da07f50b7 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -55,9 +55,15 @@ impl LintPass for MatchPass { // check preconditions for MATCH_REF_PATS if has_only_ref_pats(arms) { - span_lint(cx, MATCH_REF_PATS, expr.span, &format!( - "instead of prefixing all patterns with `&`, you can dereference the \ - expression to match: `match *{} {{ ...`", snippet(cx, ex.span, ".."))); + if let ExprAddrOf(Mutability::MutImmutable, ref inner) = ex.node { + span_lint(cx, MATCH_REF_PATS, expr.span, &format!( + "you don't need to add `&` to both the expression to match \ + and the patterns: use `match {} {{ ...`", snippet(cx, inner.span, ".."))); + } else { + span_lint(cx, MATCH_REF_PATS, expr.span, &format!( + "instead of prefixing all patterns with `&`, you can dereference the \ + expression to match: `match *{} {{ ...`", snippet(cx, ex.span, ".."))); + } } } } @@ -72,14 +78,9 @@ fn is_unit_expr(expr: &Expr) -> bool { } fn has_only_ref_pats(arms: &[Arm]) -> bool { - for arm in arms { - for pat in &arm.pats { - match pat.node { - PatRegion(..) => (), // &-patterns - PatWild(..) => (), // an "anything" wildcard is also fine - _ => return false, - } - } - } - true + arms.iter().flat_map(|a| &a.pats).all(|p| match p.node { + PatRegion(..) => true, // &-patterns + PatWild(..) => true, // an "anything" wildcard is also fine + _ => false, + }) } diff --git a/tests/compile-fail/matches.rs b/tests/compile-fail/matches.rs index 43cf43b68df5..3cc540992c99 100755 --- a/tests/compile-fail/matches.rs +++ b/tests/compile-fail/matches.rs @@ -53,6 +53,12 @@ fn ref_pats() { &(v, 1) => println!("{}", v), _ => println!("none"), } + // special case: using & both in expr and pats + let w = Some(0); + match &w { //~ERROR you don't need to add `&` to both + &Some(v) => println!("{:?}", v), + &None => println!("none"), + } } fn main() {