summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/matches/mod.rs8
-rw-r--r--clippy_lints/src/matches/redundant_pattern_match.rs21
-rw-r--r--tests/ui/redundant_pattern_matching_option.fixed12
-rw-r--r--tests/ui/redundant_pattern_matching_option.rs12
-rw-r--r--tests/ui/redundant_pattern_matching_option.stderr44
-rw-r--r--tests/ui/redundant_pattern_matching_result.fixed15
-rw-r--r--tests/ui/redundant_pattern_matching_result.rs15
-rw-r--r--tests/ui/redundant_pattern_matching_result.stderr46
8 files changed, 125 insertions, 48 deletions
diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs
index 55ec9d4474f..0d91051632a 100644
--- a/clippy_lints/src/matches/mod.rs
+++ b/clippy_lints/src/matches/mod.rs
@@ -25,7 +25,7 @@ mod wild_in_or_pats;
 
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{snippet_opt, walk_span_to_context};
-use clippy_utils::{higher, in_constant, is_span_match, tokenize_with_text};
+use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text};
 use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
 use rustc_lexer::TokenKind;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -974,12 +974,16 @@ impl_lint_pass!(Matches => [
 
 impl<'tcx> LateLintPass<'tcx> for Matches {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if is_direct_expn_of(expr.span, "matches").is_none() && in_external_macro(cx.sess(), expr.span) {
             return;
         }
         let from_expansion = expr.span.from_expansion();
 
         if let ExprKind::Match(ex, arms, source) = expr.kind {
+            if is_direct_expn_of(expr.span, "matches").is_some() {
+                redundant_pattern_match::check_match(cx, expr, ex, arms);
+            }
+
             if source == MatchSource::Normal && !is_span_match(cx, expr.span) {
                 return;
             }
diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs
index e81e09da425..479cfd83512 100644
--- a/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -1,10 +1,10 @@
 use super::REDUNDANT_PATTERN_MATCHING;
-use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::{snippet, walk_span_to_context};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop};
 use clippy_utils::visitors::any_temporaries_need_ordered_drop;
-use clippy_utils::{higher, is_trait_method};
+use clippy_utils::{higher, is_expn_of, is_trait_method};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -190,24 +190,19 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
         let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
 
         if let Some(good_method) = found_good_method(cx, arms, node_pair) {
-            let span = expr.span.to(op.span);
+            let span = is_expn_of(expr.span, "matches").unwrap_or(expr.span.to(op.span));
             let result_expr = match &op.kind {
                 ExprKind::AddrOf(_, _, borrowed) => borrowed,
                 _ => op,
             };
-            span_lint_and_then(
+            span_lint_and_sugg(
                 cx,
                 REDUNDANT_PATTERN_MATCHING,
-                expr.span,
+                span,
                 &format!("redundant pattern matching, consider using `{good_method}`"),
-                |diag| {
-                    diag.span_suggestion(
-                        span,
-                        "try this",
-                        format!("{}.{good_method}", snippet(cx, result_expr.span, "_")),
-                        Applicability::MaybeIncorrect, // snippet
-                    );
-                },
+                "try this",
+                format!("{}.{good_method}", snippet(cx, result_expr.span, "_")),
+                Applicability::MachineApplicable,
             );
         }
     }
diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed
index accdf1da9dd..dae931541d4 100644
--- a/tests/ui/redundant_pattern_matching_option.fixed
+++ b/tests/ui/redundant_pattern_matching_option.fixed
@@ -47,6 +47,7 @@ fn main() {
 
     issue6067();
     issue10726();
+    issue10803();
 
     let _ = if gen_opt().is_some() {
         1
@@ -107,3 +108,14 @@ fn issue10726() {
         _ => false,
     };
 }
+
+fn issue10803() {
+    let x = Some(42);
+
+    let _ = x.is_some();
+
+    let _ = x.is_none();
+
+    // Don't lint
+    let _ = matches!(x, Some(16));
+}
diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs
index ec684bdf71c..3f2fa3f53ce 100644
--- a/tests/ui/redundant_pattern_matching_option.rs
+++ b/tests/ui/redundant_pattern_matching_option.rs
@@ -56,6 +56,7 @@ fn main() {
 
     issue6067();
     issue10726();
+    issue10803();
 
     let _ = if let Some(_) = gen_opt() {
         1
@@ -134,3 +135,14 @@ fn issue10726() {
         _ => false,
     };
 }
+
+fn issue10803() {
+    let x = Some(42);
+
+    let _ = matches!(x, Some(_));
+
+    let _ = matches!(x, None);
+
+    // Don't lint
+    let _ = matches!(x, Some(16));
+}
diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr
index a69eb390520..93760ce97a8 100644
--- a/tests/ui/redundant_pattern_matching_option.stderr
+++ b/tests/ui/redundant_pattern_matching_option.stderr
@@ -77,49 +77,49 @@ LL |     let _ = 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_option.rs:60:20
+  --> $DIR/redundant_pattern_matching_option.rs:61: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_option.rs:62:19
+  --> $DIR/redundant_pattern_matching_option.rs:63:19
    |
 LL |     } else if let None = gen_opt() {
    |            -------^^^^------------ help: try this: `if gen_opt().is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:68:12
+  --> $DIR/redundant_pattern_matching_option.rs:69:12
    |
 LL |     if let Some(..) = gen_opt() {}
    |     -------^^^^^^^^------------ help: try this: `if gen_opt().is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:83:12
+  --> $DIR/redundant_pattern_matching_option.rs:84:12
    |
 LL |     if let Some(_) = Some(42) {}
    |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:85:12
+  --> $DIR/redundant_pattern_matching_option.rs:86: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_option.rs:87:15
+  --> $DIR/redundant_pattern_matching_option.rs:88: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_option.rs:89:15
+  --> $DIR/redundant_pattern_matching_option.rs:90:15
    |
 LL |     while let None = None::<()> {}
    |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:91:5
+  --> $DIR/redundant_pattern_matching_option.rs:92:5
    |
 LL | /     match Some(42) {
 LL | |         Some(_) => true,
@@ -128,7 +128,7 @@ LL | |     };
    | |_____^ help: try this: `Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:96:5
+  --> $DIR/redundant_pattern_matching_option.rs:97:5
    |
 LL | /     match None::<()> {
 LL | |         Some(_) => false,
@@ -137,19 +137,19 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:104:12
+  --> $DIR/redundant_pattern_matching_option.rs:105:12
    |
 LL |     if let None = *(&None::<()>) {}
    |     -------^^^^----------------- help: try this: `if (&None::<()>).is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:105:12
+  --> $DIR/redundant_pattern_matching_option.rs:106: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_option.rs:111:5
+  --> $DIR/redundant_pattern_matching_option.rs:112:5
    |
 LL | /     match x {
 LL | |         Some(_) => true,
@@ -158,7 +158,7 @@ LL | |     };
    | |_____^ help: try this: `x.is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:116:5
+  --> $DIR/redundant_pattern_matching_option.rs:117:5
    |
 LL | /     match x {
 LL | |         None => true,
@@ -167,7 +167,7 @@ LL | |     };
    | |_____^ help: try this: `x.is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:121:5
+  --> $DIR/redundant_pattern_matching_option.rs:122:5
    |
 LL | /     match x {
 LL | |         Some(_) => false,
@@ -176,7 +176,7 @@ LL | |     };
    | |_____^ help: try this: `x.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:126:5
+  --> $DIR/redundant_pattern_matching_option.rs:127:5
    |
 LL | /     match x {
 LL | |         None => false,
@@ -184,5 +184,17 @@ LL | |         _ => true,
 LL | |     };
    | |_____^ help: try this: `x.is_some()`
 
-error: aborting due to 26 previous errors
+error: redundant pattern matching, consider using `is_some()`
+  --> $DIR/redundant_pattern_matching_option.rs:142:13
+   |
+LL |     let _ = matches!(x, Some(_));
+   |             ^^^^^^^^^^^^^^^^^^^^ help: try this: `x.is_some()`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/redundant_pattern_matching_option.rs:144:13
+   |
+LL |     let _ = matches!(x, None);
+   |             ^^^^^^^^^^^^^^^^^ help: try this: `x.is_none()`
+
+error: aborting due to 28 previous errors
 
diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed
index e4032ae44b7..d77a2af7616 100644
--- a/tests/ui/redundant_pattern_matching_result.fixed
+++ b/tests/ui/redundant_pattern_matching_result.fixed
@@ -44,6 +44,7 @@ fn main() {
     issue6067();
     issue6065();
     issue10726();
+    issue10803();
 
     let _ = if gen_res().is_ok() {
         1
@@ -133,3 +134,17 @@ fn issue10726() {
         _ => true,
     };
 }
+
+fn issue10803() {
+    let x: Result<i32, i32> = Ok(42);
+
+    let _ = x.is_ok();
+
+    let _ = x.is_err();
+
+    // Don't lint
+    let _ = matches!(x, Ok(16));
+
+    // Don't lint
+    let _ = matches!(x, Err(16));
+}
diff --git a/tests/ui/redundant_pattern_matching_result.rs b/tests/ui/redundant_pattern_matching_result.rs
index 39eb10df878..aa884ac6bb1 100644
--- a/tests/ui/redundant_pattern_matching_result.rs
+++ b/tests/ui/redundant_pattern_matching_result.rs
@@ -56,6 +56,7 @@ fn main() {
     issue6067();
     issue6065();
     issue10726();
+    issue10803();
 
     let _ = if let Ok(_) = gen_res() {
         1
@@ -163,3 +164,17 @@ fn issue10726() {
         _ => true,
     };
 }
+
+fn issue10803() {
+    let x: Result<i32, i32> = Ok(42);
+
+    let _ = matches!(x, Ok(_));
+
+    let _ = matches!(x, Err(_));
+
+    // Don't lint
+    let _ = matches!(x, Ok(16));
+
+    // Don't lint
+    let _ = matches!(x, Err(16));
+}
diff --git a/tests/ui/redundant_pattern_matching_result.stderr b/tests/ui/redundant_pattern_matching_result.stderr
index 5893ae4dcc4..b462f7f41b9 100644
--- a/tests/ui/redundant_pattern_matching_result.stderr
+++ b/tests/ui/redundant_pattern_matching_result.stderr
@@ -73,67 +73,67 @@ 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_ok()`
-  --> $DIR/redundant_pattern_matching_result.rs:60:20
+  --> $DIR/redundant_pattern_matching_result.rs:61:20
    |
 LL |     let _ = 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_result.rs:62:19
+  --> $DIR/redundant_pattern_matching_result.rs:63: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_result.rs:85:19
+  --> $DIR/redundant_pattern_matching_result.rs:86: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_result.rs:86:16
+  --> $DIR/redundant_pattern_matching_result.rs:87: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_result.rs:92:12
+  --> $DIR/redundant_pattern_matching_result.rs:93: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_result.rs:93:15
+  --> $DIR/redundant_pattern_matching_result.rs:94:15
    |
 LL |     while let Some(_) = m!() {}
    |     ----------^^^^^^^------- help: try this: `while m!().is_some()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching_result.rs:111:12
+  --> $DIR/redundant_pattern_matching_result.rs:112: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_result.rs:113:12
+  --> $DIR/redundant_pattern_matching_result.rs:114: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_ok()`
-  --> $DIR/redundant_pattern_matching_result.rs:115:15
+  --> $DIR/redundant_pattern_matching_result.rs:116: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_result.rs:117:15
+  --> $DIR/redundant_pattern_matching_result.rs:118: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_ok()`
-  --> $DIR/redundant_pattern_matching_result.rs:119:5
+  --> $DIR/redundant_pattern_matching_result.rs:120:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -142,7 +142,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching_result.rs:124:5
+  --> $DIR/redundant_pattern_matching_result.rs:125:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -151,7 +151,7 @@ LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching_result.rs:134:5
+  --> $DIR/redundant_pattern_matching_result.rs:135:5
    |
 LL | /     match x {
 LL | |         Ok(_) => true,
@@ -160,7 +160,7 @@ LL | |     };
    | |_____^ help: try this: `x.is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching_result.rs:139:5
+  --> $DIR/redundant_pattern_matching_result.rs:140:5
    |
 LL | /     match x {
 LL | |         Ok(_) => false,
@@ -169,7 +169,7 @@ LL | |     };
    | |_____^ help: try this: `x.is_err()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching_result.rs:144:5
+  --> $DIR/redundant_pattern_matching_result.rs:145:5
    |
 LL | /     match x {
 LL | |         Err(_) => true,
@@ -178,7 +178,7 @@ LL | |     };
    | |_____^ help: try this: `x.is_err()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching_result.rs:149:5
+  --> $DIR/redundant_pattern_matching_result.rs:150:5
    |
 LL | /     match x {
 LL | |         Err(_) => false,
@@ -186,5 +186,17 @@ LL | |         _ => true,
 LL | |     };
    | |_____^ help: try this: `x.is_ok()`
 
-error: aborting due to 26 previous errors
+error: redundant pattern matching, consider using `is_ok()`
+  --> $DIR/redundant_pattern_matching_result.rs:171:13
+   |
+LL |     let _ = matches!(x, Ok(_));
+   |             ^^^^^^^^^^^^^^^^^^ help: try this: `x.is_ok()`
+
+error: redundant pattern matching, consider using `is_err()`
+  --> $DIR/redundant_pattern_matching_result.rs:173:13
+   |
+LL |     let _ = matches!(x, Err(_));
+   |             ^^^^^^^^^^^^^^^^^^^ help: try this: `x.is_err()`
+
+error: aborting due to 28 previous errors