From 7c5d4a41459abeb40eea734efaf08657602815cb Mon Sep 17 00:00:00 2001
From: JarredAllen <jarredallen73@gmail.com>
Date: Fri, 17 Jul 2020 09:27:43 -0700
Subject: [PATCH 1/2] Add test for correct behavior

---
 tests/ui/redundant_pattern_matching.fixed  |  3 +
 tests/ui/redundant_pattern_matching.rs     |  3 +
 tests/ui/redundant_pattern_matching.stderr | 68 ++++++++++++----------
 3 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/tests/ui/redundant_pattern_matching.fixed b/tests/ui/redundant_pattern_matching.fixed
index ce8582d2b22..adbff8af8d9 100644
--- a/tests/ui/redundant_pattern_matching.fixed
+++ b/tests/ui/redundant_pattern_matching.fixed
@@ -11,6 +11,9 @@
 )]
 
 fn main() {
+    let result: Result<usize, usize> = Err(5);
+    if result.is_ok() {}
+
     if Ok::<i32, i32>(42).is_ok() {}
 
     if Err::<i32, i32>(42).is_err() {}
diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs
index a3a9aa40e3b..4c2870e7803 100644
--- a/tests/ui/redundant_pattern_matching.rs
+++ b/tests/ui/redundant_pattern_matching.rs
@@ -11,6 +11,9 @@
 )]
 
 fn main() {
+    let result: Result<usize, usize> = Err(5);
+    if let Ok(_) = &result {}
+
     if let Ok(_) = Ok::<i32, i32>(42) {}
 
     if let Err(_) = Err::<i32, i32>(42) {}
diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr
index 25d1476062e..d3c9ceaa3d7 100644
--- a/tests/ui/redundant_pattern_matching.stderr
+++ b/tests/ui/redundant_pattern_matching.stderr
@@ -1,73 +1,79 @@
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:14:12
+  --> $DIR/redundant_pattern_matching.rs:15:12
    |
-LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
-   |     -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
+LL |     if let Ok(_) = &result {}
+   |     -------^^^^^---------- help: try this: `if result.is_ok()`
    |
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
+error: redundant pattern matching, consider using `is_ok()`
+  --> $DIR/redundant_pattern_matching.rs:17:12
+   |
+LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
+   |     -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
+
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:16:12
+  --> $DIR/redundant_pattern_matching.rs:19:12
    |
 LL |     if let Err(_) = Err::<i32, i32>(42) {}
    |     -------^^^^^^---------------------- help: try this: `if Err::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:18:12
+  --> $DIR/redundant_pattern_matching.rs:21:12
    |
 LL |     if let None = None::<()> {}
    |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:20:12
+  --> $DIR/redundant_pattern_matching.rs:23:12
    |
 LL |     if let Some(_) = Some(42) {}
    |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:22:12
+  --> $DIR/redundant_pattern_matching.rs:25:12
    |
 LL |     if let Some(_) = Some(42) {
    |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:28:15
+  --> $DIR/redundant_pattern_matching.rs:31:15
    |
 LL |     while let Some(_) = Some(42) {}
    |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:30:15
+  --> $DIR/redundant_pattern_matching.rs:33:15
    |
 LL |     while let None = Some(42) {}
    |     ----------^^^^----------- help: try this: `while Some(42).is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:32:15
+  --> $DIR/redundant_pattern_matching.rs:35:15
    |
 LL |     while let None = None::<()> {}
    |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:34:15
+  --> $DIR/redundant_pattern_matching.rs:37:15
    |
 LL |     while let Ok(_) = Ok::<i32, i32>(10) {}
    |     ----------^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:36:15
+  --> $DIR/redundant_pattern_matching.rs:39:15
    |
 LL |     while let Err(_) = Ok::<i32, i32>(10) {}
    |     ----------^^^^^^--------------------- help: try this: `while Ok::<i32, i32>(10).is_err()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:39:15
+  --> $DIR/redundant_pattern_matching.rs:42:15
    |
 LL |     while let Some(_) = v.pop() {
    |     ----------^^^^^^^---------- help: try this: `while v.pop().is_some()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:55:5
+  --> $DIR/redundant_pattern_matching.rs:58:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -76,7 +82,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:60:5
+  --> $DIR/redundant_pattern_matching.rs:63:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -85,7 +91,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:65:5
+  --> $DIR/redundant_pattern_matching.rs:68:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -94,7 +100,7 @@ LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:70:5
+  --> $DIR/redundant_pattern_matching.rs:73:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -103,7 +109,7 @@ LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:75:5
+  --> $DIR/redundant_pattern_matching.rs:78:5
    |
 LL | /     match Some(42) {
 LL | |         Some(_) => true,
@@ -112,7 +118,7 @@ LL | |     };
    | |_____^ help: try this: `Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:80:5
+  --> $DIR/redundant_pattern_matching.rs:83:5
    |
 LL | /     match None::<()> {
 LL | |         Some(_) => false,
@@ -121,7 +127,7 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:85:13
+  --> $DIR/redundant_pattern_matching.rs:88:13
    |
 LL |       let _ = match None::<()> {
    |  _____________^
@@ -131,64 +137,64 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:90:20
+  --> $DIR/redundant_pattern_matching.rs:93:20
    |
 LL |     let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };
    |             -------^^^^^--------------------- help: try this: `if Ok::<usize, ()>(4).is_ok()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:93:20
+  --> $DIR/redundant_pattern_matching.rs:96:20
    |
 LL |     let x = if let Some(_) = opt { true } else { false };
    |             -------^^^^^^^------ help: try this: `if opt.is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:99:20
+  --> $DIR/redundant_pattern_matching.rs:102:20
    |
 LL |     let _ = if let Some(_) = gen_opt() {
    |             -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:101:19
+  --> $DIR/redundant_pattern_matching.rs:104:19
    |
 LL |     } else if let None = gen_opt() {
    |            -------^^^^------------ help: try this: `if gen_opt().is_none()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:103:19
+  --> $DIR/redundant_pattern_matching.rs:106:19
    |
 LL |     } else if let Ok(_) = gen_res() {
    |            -------^^^^^------------ help: try this: `if gen_res().is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:105:19
+  --> $DIR/redundant_pattern_matching.rs:108:19
    |
 LL |     } else if let Err(_) = gen_res() {
    |            -------^^^^^^------------ help: try this: `if gen_res().is_err()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:138:19
+  --> $DIR/redundant_pattern_matching.rs:141:19
    |
 LL |         while let Some(_) = r#try!(result_opt()) {}
    |         ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:139:16
+  --> $DIR/redundant_pattern_matching.rs:142:16
    |
 LL |         if let Some(_) = r#try!(result_opt()) {}
    |         -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:145:12
+  --> $DIR/redundant_pattern_matching.rs:148:12
    |
 LL |     if let Some(_) = m!() {}
    |     -------^^^^^^^------- help: try this: `if m!().is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:146:15
+  --> $DIR/redundant_pattern_matching.rs:149:15
    |
 LL |     while let Some(_) = m!() {}
    |     ----------^^^^^^^------- help: try this: `while m!().is_some()`
 
-error: aborting due to 28 previous errors
+error: aborting due to 29 previous errors
 

From e85b590936863e88da4ccd73af9f5da0787b9609 Mon Sep 17 00:00:00 2001
From: JarredAllen <jarredallen73@gmail.com>
Date: Fri, 17 Jul 2020 10:40:01 -0700
Subject: [PATCH 2/2] Fix bug in lint

---
 clippy_lints/src/matches.rs | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index bd474c20807..fe00a48adef 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -1512,6 +1512,10 @@ mod redundant_pattern_match {
             }
         }
 
+        let result_expr = match &op.kind {
+            ExprKind::AddrOf(_, _, borrowed) => borrowed,
+            _ => op,
+        };
         span_lint_and_then(
             cx,
             REDUNDANT_PATTERN_MATCHING,
@@ -1524,7 +1528,7 @@ mod redundant_pattern_match {
 
                 // while let ... = ... { ... }
                 //                 ^^^
-                let op_span = op.span.source_callsite();
+                let op_span = result_expr.span.source_callsite();
 
                 // while let ... = ... { ... }
                 // ^^^^^^^^^^^^^^^^^^^
@@ -1589,17 +1593,21 @@ mod redundant_pattern_match {
             };
 
             if let Some(good_method) = found_good_method {
+                let span = expr.span.to(op.span);
+                let result_expr = match &op.kind {
+                    ExprKind::AddrOf(_, _, borrowed) => borrowed,
+                    _ => op,
+                };
                 span_lint_and_then(
                     cx,
                     REDUNDANT_PATTERN_MATCHING,
                     expr.span,
                     &format!("redundant pattern matching, consider using `{}`", good_method),
                     |diag| {
-                        let span = expr.span.to(op.span);
                         diag.span_suggestion(
                             span,
                             "try this",
-                            format!("{}.{}", snippet(cx, op.span, "_"), good_method),
+                            format!("{}.{}", snippet(cx, result_expr.span, "_"), good_method),
                             Applicability::MaybeIncorrect, // snippet
                         );
                     },