]> git.lizzy.rs Git - rust.git/commitdiff
Do raise a same-arms warning when the two arms are separated by an arm with a guard...
authorlaurent <laurent.mazare@gmail.com>
Fri, 1 Dec 2017 19:25:43 +0000 (19:25 +0000)
committerlaurent <laurent.mazare@gmail.com>
Fri, 1 Dec 2017 19:25:43 +0000 (19:25 +0000)
clippy_lints/src/copies.rs
tests/ui/matches.rs
tests/ui/matches.stderr
tests/ui/regex.stderr

index 5a693ce5524e6a42df12a7e4022ca232761297f6..140b895526dbbc7510b65e2072dc87e55cbf00ce 100644 (file)
@@ -178,22 +178,26 @@ fn lint_same_cond(cx: &LateContext, conds: &[&Expr]) {
 
 /// Implementation if `MATCH_SAME_ARMS`.
 fn lint_match_arms(cx: &LateContext, expr: &Expr) {
-    let hash = |arm: &Arm| -> u64 {
-        let mut h = SpanlessHash::new(cx);
-        h.hash_expr(&arm.body);
-        h.finish()
-    };
+    if let ExprMatch(_, ref arms, MatchSource::Normal) = expr.node {
+        let hash = |&(_, arm): &(usize, &Arm)| -> u64 {
+            let mut h = SpanlessHash::new(cx);
+            h.hash_expr(&arm.body);
+            h.finish()
+        };
 
-    let eq = |lhs: &Arm, rhs: &Arm| -> bool {
-        // Arms with a guard are ignored, those can’t always be merged together
-        lhs.guard.is_none() && rhs.guard.is_none() &&
-            SpanlessEq::new(cx).eq_expr(&lhs.body, &rhs.body) &&
-            // all patterns should have the same bindings
-            bindings(cx, &lhs.pats[0]) == bindings(cx, &rhs.pats[0])
-    };
+        let eq = |&(lindex, lhs): &(usize, &Arm), &(rindex, rhs): &(usize, &Arm)| -> bool {
+            let min_index = usize::min(lindex, rindex);
+            let max_index = usize::max(rindex, rindex);
+            // Arms with a guard are ignored, those can’t always be merged together
+            // This is also the case for arms in-between each there is an arm with a guard
+            (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
+                bindings(cx, &lhs.pats[0]) == bindings(cx, &rhs.pats[0])
+        };
 
-    if let ExprMatch(_, ref arms, MatchSource::Normal) = expr.node {
-        if let Some((i, j)) = search_same(arms, hash, eq) {
+        let indexed_arms: Vec<(usize, &Arm)> = arms.iter().enumerate().collect();
+        if let Some((&(_, i), &(_, j))) = search_same(&indexed_arms, hash, eq) {
             span_lint_and_then(
                 cx,
                 MATCH_SAME_ARMS,
index 352749d48e13f82360e8fb68122b3e3dbec77e11..8130436d485d9f2ccd72cd78404d69f266076af0 100644 (file)
@@ -285,7 +285,7 @@ fn match_wild_err_arm() {
         Err(_) => println!("err")
     }
 
-    // this is a current false positive, see #1996
+    // this used to be a false positive, see #1996
     match x {
         Ok(3) => println!("ok"),
         Ok(x) if x*x == 64 => println!("ok 64"),
index beb3387d0380de0a923ad82acb9d542d01723869..8c0ec49e626bce386ca905076754887dc108112c 100644 (file)
@@ -390,24 +390,6 @@ note: consider refactoring into `Ok(3) | Ok(_)`
     |                  ^^^^^^^^^^^^^^
     = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
-error: this `match` has identical arm bodies
-   --> $DIR/matches.rs:292:18
-    |
-292 |         Ok(_) => println!("ok"),
-    |                  ^^^^^^^^^^^^^^
-    |
-note: same as this
-   --> $DIR/matches.rs:290:18
-    |
-290 |         Ok(3) => println!("ok"),
-    |                  ^^^^^^^^^^^^^^
-note: consider refactoring into `Ok(3) | Ok(_)`
-   --> $DIR/matches.rs:290:18
-    |
-290 |         Ok(3) => println!("ok"),
-    |                  ^^^^^^^^^^^^^^
-    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
 error: this `match` has identical arm bodies
    --> $DIR/matches.rs:298:29
     |
index 9f1397990bbfbacec30229ffe968496ef89efaab..1c244c1df127e57511d1d82794256726ce4e4301 100644 (file)
@@ -112,7 +112,7 @@ error: trivial regex
 error: trivial regex
   --> $DIR/regex.rs:62:40
    |
-62 |     let trivial_backslash = Regex::new("a/.b");
+62 |     let trivial_backslash = Regex::new("a//.b");
    |                                        ^^^^^^^
    |
    = help: consider using consider using `str::contains`