about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-10 18:10:08 +0000
committerbors <bors@rust-lang.org>2020-07-10 18:10:08 +0000
commit7d611d92240d43d9a04cf8db0cb4fb5690f8249c (patch)
tree77fa94daf53e0cb5ef76f48f6aad27c31888b3a2
parentbe8812203998042783b4ea9850cd8cfa3fd26242 (diff)
parent37d75da266443dd4253ceedebd692ba77dd72e03 (diff)
Auto merge of #5769 - robojumper:match_like_matches_macro, r=phansch
new lint: match_like_matches_macro

Suggests using the `matches!` macro from `std` where appropriate.

`redundant_pattern_matching` has been moved into the `matches` pass to allow suppressing the suggestion where `is_some` and friends are a better replacement.

changelog: new lint: `match_like_matches_macro`
-rw-r--r--CHANGELOG.md1
-rw-r--r--clippy_lints/src/comparison_chain.rs5
-rw-r--r--clippy_lints/src/eq_op.rs30
-rw-r--r--clippy_lints/src/escape.rs5
-rw-r--r--clippy_lints/src/eta_reduction.rs5
-rw-r--r--clippy_lints/src/formatting.rs12
-rw-r--r--clippy_lints/src/functions.rs8
-rw-r--r--clippy_lints/src/lib.rs11
-rw-r--r--clippy_lints/src/lifetimes.rs16
-rw-r--r--clippy_lints/src/loops.rs10
-rw-r--r--clippy_lints/src/matches.rs392
-rw-r--r--clippy_lints/src/methods/mod.rs16
-rw-r--r--clippy_lints/src/misc.rs7
-rw-r--r--clippy_lints/src/misc_early.rs18
-rw-r--r--clippy_lints/src/missing_inline.rs9
-rw-r--r--clippy_lints/src/new_without_default.rs10
-rw-r--r--clippy_lints/src/non_copy_const.rs8
-rw-r--r--clippy_lints/src/precedence.rs10
-rw-r--r--clippy_lints/src/redundant_pattern_matching.rs260
-rw-r--r--clippy_lints/src/regex.rs7
-rw-r--r--clippy_lints/src/shadow.rs5
-rw-r--r--clippy_lints/src/temporary_assignment.rs8
-rw-r--r--clippy_lints/src/types.rs29
-rw-r--r--clippy_lints/src/unnamed_address.rs14
-rw-r--r--clippy_lints/src/use_self.rs6
-rwxr-xr-xclippy_lints/src/utils/ast_utils.rs5
-rw-r--r--clippy_lints/src/utils/mod.rs11
-rw-r--r--clippy_lints/src/utils/numeric_literal.rs2
-rw-r--r--src/driver.rs9
-rw-r--r--src/lintlist/mod.rs9
-rw-r--r--tests/ui/find_map.rs1
-rw-r--r--tests/ui/find_map.stderr2
-rw-r--r--tests/ui/match_expr_like_matches_macro.fixed36
-rw-r--r--tests/ui/match_expr_like_matches_macro.rs48
-rw-r--r--tests/ui/match_expr_like_matches_macro.stderr52
-rw-r--r--tests/ui/neg_cmp_op_on_partial_ord.rs2
-rw-r--r--tests/ui/redundant_pattern_matching.fixed8
-rw-r--r--tests/ui/redundant_pattern_matching.rs8
-rw-r--r--tests/ui/redundant_pattern_matching.stderr56
-rw-r--r--tests/ui/redundant_pattern_matching_const_result.fixed2
-rw-r--r--tests/ui/redundant_pattern_matching_const_result.rs2
41 files changed, 659 insertions, 496 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a081bb85fe..6261ca4879a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1513,6 +1513,7 @@ Released 2018-09-13
 [`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or
 [`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref
 [`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool
+[`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro
 [`match_on_vec_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_on_vec_items
 [`match_overlapping_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_overlapping_arm
 [`match_ref_pats`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_ref_pats
diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs
index 26476af4cb6..25ccabc1c88 100644
--- a/clippy_lints/src/comparison_chain.rs
+++ b/clippy_lints/src/comparison_chain.rs
@@ -122,8 +122,5 @@ impl<'tcx> LateLintPass<'tcx> for ComparisonChain {
 }
 
 fn kind_is_cmp(kind: BinOpKind) -> bool {
-    match kind {
-        BinOpKind::Lt | BinOpKind::Gt | BinOpKind::Eq => true,
-        _ => false,
-    }
+    matches!(kind, BinOpKind::Lt | BinOpKind::Gt | BinOpKind::Eq)
 }
diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs
index ca921dcfdfe..7839908fe4c 100644
--- a/clippy_lints/src/eq_op.rs
+++ b/clippy_lints/src/eq_op.rs
@@ -214,20 +214,20 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
 }
 
 fn is_valid_operator(op: BinOp) -> bool {
-    match op.node {
+    matches!(
+        op.node,
         BinOpKind::Sub
-        | BinOpKind::Div
-        | BinOpKind::Eq
-        | BinOpKind::Lt
-        | BinOpKind::Le
-        | BinOpKind::Gt
-        | BinOpKind::Ge
-        | BinOpKind::Ne
-        | BinOpKind::And
-        | BinOpKind::Or
-        | BinOpKind::BitXor
-        | BinOpKind::BitAnd
-        | BinOpKind::BitOr => true,
-        _ => false,
-    }
+            | BinOpKind::Div
+            | BinOpKind::Eq
+            | BinOpKind::Lt
+            | BinOpKind::Le
+            | BinOpKind::Gt
+            | BinOpKind::Ge
+            | BinOpKind::Ne
+            | BinOpKind::And
+            | BinOpKind::Or
+            | BinOpKind::BitXor
+            | BinOpKind::BitAnd
+            | BinOpKind::BitOr
+    )
 }
diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs
index b10181062ff..ceb3c40d869 100644
--- a/clippy_lints/src/escape.rs
+++ b/clippy_lints/src/escape.rs
@@ -105,10 +105,7 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool {
         _ => return false,
     }
 
-    match map.find(map.get_parent_node(id)) {
-        Some(Node::Param(_)) => true,
-        _ => false,
-    }
+    matches!(map.find(map.get_parent_node(id)), Some(Node::Param(_)))
 }
 
 impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs
index ceed6a74c4f..fb26b9fc27d 100644
--- a/clippy_lints/src/eta_reduction.rs
+++ b/clippy_lints/src/eta_reduction.rs
@@ -175,10 +175,7 @@ fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: def_id::DefId, self_a
 fn match_borrow_depth(lhs: Ty<'_>, rhs: Ty<'_>) -> bool {
     match (&lhs.kind, &rhs.kind) {
         (ty::Ref(_, t1, mut1), ty::Ref(_, t2, mut2)) => mut1 == mut2 && match_borrow_depth(&t1, &t2),
-        (l, r) => match (l, r) {
-            (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false,
-            (_, _) => true,
-        },
+        (l, r) => !matches!((l, r), (ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _))),
     }
 }
 
diff --git a/clippy_lints/src/formatting.rs b/clippy_lints/src/formatting.rs
index 156246fb8bb..1bd16e6cce5 100644
--- a/clippy_lints/src/formatting.rs
+++ b/clippy_lints/src/formatting.rs
@@ -305,18 +305,10 @@ fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
 }
 
 fn is_block(expr: &Expr) -> bool {
-    if let ExprKind::Block(..) = expr.kind {
-        true
-    } else {
-        false
-    }
+    matches!(expr.kind, ExprKind::Block(..))
 }
 
 /// Check if the expression is an `if` or `if let`
 fn is_if(expr: &Expr) -> bool {
-    if let ExprKind::If(..) = expr.kind {
-        true
-    } else {
-        false
-    }
+    matches!(expr.kind, ExprKind::If(..))
 }
diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs
index 3f030dd8422..63133a4872a 100644
--- a/clippy_lints/src/functions.rs
+++ b/clippy_lints/src/functions.rs
@@ -645,13 +645,7 @@ fn is_mutated_static(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {
     use hir::ExprKind::{Field, Index, Path};
 
     match e.kind {
-        Path(ref qpath) => {
-            if let Res::Local(_) = qpath_res(cx, qpath, e.hir_id) {
-                false
-            } else {
-                true
-            }
-        },
+        Path(ref qpath) => !matches!(qpath_res(cx, qpath, e.hir_id), Res::Local(_)),
         Field(ref inner, _) | Index(ref inner, _) => is_mutated_static(cx, inner),
         _ => false,
     }
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index fe34e4390d6..c4f1af8f4e4 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -277,7 +277,6 @@ mod question_mark;
 mod ranges;
 mod redundant_clone;
 mod redundant_field_names;
-mod redundant_pattern_matching;
 mod redundant_pub_crate;
 mod redundant_static_lifetimes;
 mod reference;
@@ -623,11 +622,13 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &matches::INFALLIBLE_DESTRUCTURING_MATCH,
         &matches::MATCH_AS_REF,
         &matches::MATCH_BOOL,
+        &matches::MATCH_LIKE_MATCHES_MACRO,
         &matches::MATCH_OVERLAPPING_ARM,
         &matches::MATCH_REF_PATS,
         &matches::MATCH_SINGLE_BINDING,
         &matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
         &matches::MATCH_WILD_ERR_ARM,
+        &matches::REDUNDANT_PATTERN_MATCHING,
         &matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
         &matches::SINGLE_MATCH,
         &matches::SINGLE_MATCH_ELSE,
@@ -757,7 +758,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &ranges::REVERSED_EMPTY_RANGES,
         &redundant_clone::REDUNDANT_CLONE,
         &redundant_field_names::REDUNDANT_FIELD_NAMES,
-        &redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING,
         &redundant_pub_crate::REDUNDANT_PUB_CRATE,
         &redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
         &reference::DEREF_ADDROF,
@@ -956,7 +956,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box missing_doc::MissingDoc::new());
     store.register_late_pass(|| box missing_inline::MissingInline);
     store.register_late_pass(|| box if_let_some_result::OkIfLet);
-    store.register_late_pass(|| box redundant_pattern_matching::RedundantPatternMatching);
     store.register_late_pass(|| box partialeq_ne_impl::PartialEqNeImpl);
     store.register_late_pass(|| box unused_io_amount::UnusedIoAmount);
     let enum_variant_size_threshold = conf.enum_variant_size_threshold;
@@ -1295,9 +1294,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&map_unit_fn::RESULT_MAP_UNIT_FN),
         LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH),
         LintId::of(&matches::MATCH_AS_REF),
+        LintId::of(&matches::MATCH_LIKE_MATCHES_MACRO),
         LintId::of(&matches::MATCH_OVERLAPPING_ARM),
         LintId::of(&matches::MATCH_REF_PATS),
         LintId::of(&matches::MATCH_SINGLE_BINDING),
+        LintId::of(&matches::REDUNDANT_PATTERN_MATCHING),
         LintId::of(&matches::SINGLE_MATCH),
         LintId::of(&matches::WILDCARD_IN_OR_PATTERNS),
         LintId::of(&mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
@@ -1387,7 +1388,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&ranges::REVERSED_EMPTY_RANGES),
         LintId::of(&redundant_clone::REDUNDANT_CLONE),
         LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
-        LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING),
         LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
         LintId::of(&reference::DEREF_ADDROF),
         LintId::of(&reference::REF_IN_DEREF),
@@ -1488,8 +1488,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
         LintId::of(&map_clone::MAP_CLONE),
         LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH),
+        LintId::of(&matches::MATCH_LIKE_MATCHES_MACRO),
         LintId::of(&matches::MATCH_OVERLAPPING_ARM),
         LintId::of(&matches::MATCH_REF_PATS),
+        LintId::of(&matches::REDUNDANT_PATTERN_MATCHING),
         LintId::of(&matches::SINGLE_MATCH),
         LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
         LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),
@@ -1526,7 +1528,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&ptr::PTR_ARG),
         LintId::of(&question_mark::QUESTION_MARK),
         LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
-        LintId::of(&redundant_pattern_matching::REDUNDANT_PATTERN_MATCHING),
         LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
         LintId::of(&regex::TRIVIAL_REGEX),
         LintId::of(&returns::NEEDLESS_RETURN),
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index a79f94855bd..168f9f953e4 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -129,10 +129,10 @@ fn check_fn_inner<'tcx>(
     }
 
     let mut bounds_lts = Vec::new();
-    let types = generics.params.iter().filter(|param| match param.kind {
-        GenericParamKind::Type { .. } => true,
-        _ => false,
-    });
+    let types = generics
+        .params
+        .iter()
+        .filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
     for typ in types {
         for bound in typ.bounds {
             let mut visitor = RefVisitor::new(cx);
@@ -337,10 +337,10 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
     fn collect_anonymous_lifetimes(&mut self, qpath: &QPath<'_>, ty: &Ty<'_>) {
         if let Some(ref last_path_segment) = last_path_segment(qpath).args {
             if !last_path_segment.parenthesized
-                && !last_path_segment.args.iter().any(|arg| match arg {
-                    GenericArg::Lifetime(_) => true,
-                    _ => false,
-                })
+                && !last_path_segment
+                    .args
+                    .iter()
+                    .any(|arg| matches!(arg, GenericArg::Lifetime(_)))
             {
                 let hir_id = ty.hir_id;
                 match self.cx.qpath_res(qpath, hir_id) {
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index b803d753b6d..396bb659109 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -2091,17 +2091,11 @@ fn var_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<HirId> {
 }
 
 fn is_loop(expr: &Expr<'_>) -> bool {
-    match expr.kind {
-        ExprKind::Loop(..) => true,
-        _ => false,
-    }
+    matches!(expr.kind, ExprKind::Loop(..))
 }
 
 fn is_conditional(expr: &Expr<'_>) -> bool {
-    match expr.kind {
-        ExprKind::Match(..) => true,
-        _ => false,
-    }
+    matches!(expr.kind, ExprKind::Match(..))
 }
 
 fn is_nested(cx: &LateContext<'_>, match_expr: &Expr<'_>, iter_expr: &Expr<'_>) -> bool {
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index a6cc1097441..bd474c20807 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -13,14 +13,14 @@ use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::CtorKind;
 use rustc_hir::{
-    Arm, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, Local, MatchSource, Mutability, Node, Pat, PatKind,
-    QPath, RangeEnd,
+    Arm, BindingAnnotation, Block, BorrowKind, Expr, ExprKind, Guard, Local, MatchSource, Mutability, Node, Pat,
+    PatKind, QPath, RangeEnd,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::source_map::Span;
+use rustc_span::source_map::{Span, Spanned};
 use std::cmp::Ordering;
 use std::collections::Bound;
 
@@ -409,6 +409,74 @@ declare_clippy_lint! {
     "a match on a struct that binds all fields but still uses the wildcard pattern"
 }
 
+declare_clippy_lint! {
+    /// **What it does:** Lint for redundant pattern matching over `Result` or
+    /// `Option`
+    ///
+    /// **Why is this bad?** It's more concise and clear to just use the proper
+    /// utility function
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// if let Ok(_) = Ok::<i32, i32>(42) {}
+    /// if let Err(_) = Err::<i32, i32>(42) {}
+    /// if let None = None::<()> {}
+    /// if let Some(_) = Some(42) {}
+    /// match Ok::<i32, i32>(42) {
+    ///     Ok(_) => true,
+    ///     Err(_) => false,
+    /// };
+    /// ```
+    ///
+    /// The more idiomatic use would be:
+    ///
+    /// ```rust
+    /// if Ok::<i32, i32>(42).is_ok() {}
+    /// if Err::<i32, i32>(42).is_err() {}
+    /// if None::<()>.is_none() {}
+    /// if Some(42).is_some() {}
+    /// Ok::<i32, i32>(42).is_ok();
+    /// ```
+    pub REDUNDANT_PATTERN_MATCHING,
+    style,
+    "use the proper utility function avoiding an `if let`"
+}
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for `match`  or `if let` expressions producing a
+    /// `bool` that could be written using `matches!`
+    ///
+    /// **Why is this bad?** Readability and needless complexity.
+    ///
+    /// **Known problems:** None
+    ///
+    /// **Example:**
+    /// ```rust
+    /// let x = Some(5);
+    ///
+    /// // Bad
+    /// let a = match x {
+    ///     Some(0) => true,
+    ///     _ => false,
+    /// };
+    ///
+    /// let a = if let Some(0) = x {
+    ///     true
+    /// } else {
+    ///     false
+    /// };
+    ///
+    /// // Good
+    /// let a = matches!(x, Some(0));
+    /// ```
+    pub MATCH_LIKE_MATCHES_MACRO,
+    style,
+    "a match that could be written with the matches! macro"
+}
+
 #[derive(Default)]
 pub struct Matches {
     infallible_destructuring_match_linted: bool,
@@ -427,7 +495,9 @@ impl_lint_pass!(Matches => [
     WILDCARD_IN_OR_PATTERNS,
     MATCH_SINGLE_BINDING,
     INFALLIBLE_DESTRUCTURING_MATCH,
-    REST_PAT_IN_FULLY_BOUND_STRUCTS
+    REST_PAT_IN_FULLY_BOUND_STRUCTS,
+    REDUNDANT_PATTERN_MATCHING,
+    MATCH_LIKE_MATCHES_MACRO
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Matches {
@@ -435,6 +505,10 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
         if in_external_macro(cx.sess(), expr.span) {
             return;
         }
+
+        redundant_pattern_match::check(cx, expr);
+        check_match_like_matches(cx, expr);
+
         if let ExprKind::Match(ref ex, ref arms, MatchSource::Normal) = expr.kind {
             check_single_match(cx, ex, arms, expr);
             check_match_bool(cx, ex, arms, expr);
@@ -808,13 +882,8 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
                     // Some simple checks for exhaustive patterns.
                     // There is a room for improvements to detect more cases,
                     // but it can be more expensive to do so.
-                    let is_pattern_exhaustive = |pat: &&Pat<'_>| {
-                        if let PatKind::Wild | PatKind::Binding(.., None) = pat.kind {
-                            true
-                        } else {
-                            false
-                        }
-                    };
+                    let is_pattern_exhaustive =
+                        |pat: &&Pat<'_>| matches!(pat.kind, PatKind::Wild | PatKind::Binding(.., None));
                     if patterns.iter().all(is_pattern_exhaustive) {
                         missing_variants.retain(|e| e.ctor_def_id != Some(p.res.def_id()));
                     }
@@ -995,6 +1064,79 @@ fn check_wild_in_or_pats(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
     }
 }
 
+/// Lint a `match` or `if let .. { .. } else { .. }` expr that could be replaced by `matches!`
+fn check_match_like_matches<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+    if let ExprKind::Match(ex, arms, ref match_source) = &expr.kind {
+        match match_source {
+            MatchSource::Normal => find_matches_sugg(cx, ex, arms, expr, false),
+            MatchSource::IfLetDesugar { .. } => find_matches_sugg(cx, ex, arms, expr, true),
+            _ => return,
+        }
+    }
+}
+
+/// Lint a `match` or desugared `if let` for replacement by `matches!`
+fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>, desugared: bool) {
+    if_chain! {
+        if arms.len() == 2;
+        if cx.tables().expr_ty(expr).is_bool();
+        if is_wild(&arms[1].pat);
+        if let Some(first) = find_bool_lit(&arms[0].body.kind, desugared);
+        if let Some(second) = find_bool_lit(&arms[1].body.kind, desugared);
+        if first != second;
+        then {
+            let mut applicability = Applicability::MachineApplicable;
+
+            let pat_and_guard = if let Some(Guard::If(g)) = arms[0].guard {
+                format!("{} if {}", snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability), snippet_with_applicability(cx, g.span, "..", &mut applicability))
+            } else {
+                format!("{}", snippet_with_applicability(cx, arms[0].pat.span, "..", &mut applicability))
+            };
+            span_lint_and_sugg(
+                cx,
+                MATCH_LIKE_MATCHES_MACRO,
+                expr.span,
+                &format!("{} expression looks like `matches!` macro", if desugared { "if let .. else" } else { "match" }),
+                "try this",
+                format!(
+                    "{}matches!({}, {})",
+                    if first { "" } else { "!" },
+                    snippet_with_applicability(cx, ex.span, "..", &mut applicability),
+                    pat_and_guard,
+                ),
+                applicability,
+            )
+        }
+    }
+}
+
+/// Extract a `bool` or `{ bool }`
+fn find_bool_lit(ex: &ExprKind<'_>, desugared: bool) -> Option<bool> {
+    match ex {
+        ExprKind::Lit(Spanned {
+            node: LitKind::Bool(b), ..
+        }) => Some(*b),
+        ExprKind::Block(
+            rustc_hir::Block {
+                stmts: &[],
+                expr: Some(exp),
+                ..
+            },
+            _,
+        ) if desugared => {
+            if let ExprKind::Lit(Spanned {
+                node: LitKind::Bool(b), ..
+            }) = exp.kind
+            {
+                Some(b)
+            } else {
+                None
+            }
+        },
+        _ => None,
+    }
+}
+
 fn check_match_single_binding<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) {
     if in_macro(expr.span) || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
         return;
@@ -1185,10 +1327,7 @@ fn is_unit_expr(expr: &Expr<'_>) -> bool {
 
 // Checks if arm has the form `None => None`
 fn is_none_arm(arm: &Arm<'_>) -> bool {
-    match arm.pat.kind {
-        PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => true,
-        _ => false,
-    }
+    matches!(arm.pat.kind, PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE))
 }
 
 // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
@@ -1299,6 +1438,229 @@ where
     None
 }
 
+mod redundant_pattern_match {
+    use super::REDUNDANT_PATTERN_MATCHING;
+    use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then};
+    use if_chain::if_chain;
+    use rustc_ast::ast::LitKind;
+    use rustc_errors::Applicability;
+    use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath};
+    use rustc_lint::LateContext;
+    use rustc_middle::ty;
+    use rustc_mir::const_eval::is_const_fn;
+    use rustc_span::source_map::Symbol;
+
+    pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if let ExprKind::Match(op, arms, ref match_source) = &expr.kind {
+            match match_source {
+                MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms),
+                MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"),
+                MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"),
+                _ => {},
+            }
+        }
+    }
+
+    fn find_sugg_for_if_let<'tcx>(
+        cx: &LateContext<'tcx>,
+        expr: &'tcx Expr<'_>,
+        op: &Expr<'_>,
+        arms: &[Arm<'_>],
+        keyword: &'static str,
+    ) {
+        fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> {
+            if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") {
+                return Some("is_ok()");
+            }
+            if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") {
+                return Some("is_err()");
+            }
+            if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") {
+                return Some("is_some()");
+            }
+            if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") {
+                return Some("is_none()");
+            }
+            None
+        }
+
+        let hir_id = expr.hir_id;
+        let good_method = match arms[0].pat.kind {
+            PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
+                if let PatKind::Wild = patterns[0].kind {
+                    find_suggestion(cx, hir_id, path)
+                } else {
+                    None
+                }
+            },
+            PatKind::Path(ref path) => find_suggestion(cx, hir_id, path),
+            _ => None,
+        };
+        let good_method = match good_method {
+            Some(method) => method,
+            None => return,
+        };
+
+        // check that `while_let_on_iterator` lint does not trigger
+        if_chain! {
+            if keyword == "while";
+            if let ExprKind::MethodCall(method_path, _, _, _) = op.kind;
+            if method_path.ident.name == sym!(next);
+            if match_trait_method(cx, op, &paths::ITERATOR);
+            then {
+                return;
+            }
+        }
+
+        span_lint_and_then(
+            cx,
+            REDUNDANT_PATTERN_MATCHING,
+            arms[0].pat.span,
+            &format!("redundant pattern matching, consider using `{}`", good_method),
+            |diag| {
+                // while let ... = ... { ... }
+                // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+                let expr_span = expr.span;
+
+                // while let ... = ... { ... }
+                //                 ^^^
+                let op_span = op.span.source_callsite();
+
+                // while let ... = ... { ... }
+                // ^^^^^^^^^^^^^^^^^^^
+                let span = expr_span.until(op_span.shrink_to_hi());
+                diag.span_suggestion(
+                    span,
+                    "try this",
+                    format!("{} {}.{}", keyword, snippet(cx, op_span, "_"), good_method),
+                    Applicability::MachineApplicable, // snippet
+                );
+            },
+        );
+    }
+
+    fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) {
+        if arms.len() == 2 {
+            let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
+
+            let hir_id = expr.hir_id;
+            let found_good_method = match node_pair {
+                (
+                    PatKind::TupleStruct(ref path_left, ref patterns_left, _),
+                    PatKind::TupleStruct(ref path_right, ref patterns_right, _),
+                ) if patterns_left.len() == 1 && patterns_right.len() == 1 => {
+                    if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) {
+                        find_good_method_for_match(
+                            arms,
+                            path_left,
+                            path_right,
+                            &paths::RESULT_OK,
+                            &paths::RESULT_ERR,
+                            "is_ok()",
+                            "is_err()",
+                            || can_suggest(cx, hir_id, sym!(result_type), "is_ok"),
+                            || can_suggest(cx, hir_id, sym!(result_type), "is_err"),
+                        )
+                    } else {
+                        None
+                    }
+                },
+                (PatKind::TupleStruct(ref path_left, ref patterns, _), PatKind::Path(ref path_right))
+                | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, ref patterns, _))
+                    if patterns.len() == 1 =>
+                {
+                    if let PatKind::Wild = patterns[0].kind {
+                        find_good_method_for_match(
+                            arms,
+                            path_left,
+                            path_right,
+                            &paths::OPTION_SOME,
+                            &paths::OPTION_NONE,
+                            "is_some()",
+                            "is_none()",
+                            || can_suggest(cx, hir_id, sym!(option_type), "is_some"),
+                            || can_suggest(cx, hir_id, sym!(option_type), "is_none"),
+                        )
+                    } else {
+                        None
+                    }
+                },
+                _ => None,
+            };
+
+            if let Some(good_method) = found_good_method {
+                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),
+                            Applicability::MaybeIncorrect, // snippet
+                        );
+                    },
+                );
+            }
+        }
+    }
+
+    #[allow(clippy::too_many_arguments)]
+    fn find_good_method_for_match<'a>(
+        arms: &[Arm<'_>],
+        path_left: &QPath<'_>,
+        path_right: &QPath<'_>,
+        expected_left: &[&str],
+        expected_right: &[&str],
+        should_be_left: &'a str,
+        should_be_right: &'a str,
+        can_suggest_left: impl Fn() -> bool,
+        can_suggest_right: impl Fn() -> bool,
+    ) -> Option<&'a str> {
+        let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) {
+            (&(*arms[0].body).kind, &(*arms[1].body).kind)
+        } else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) {
+            (&(*arms[1].body).kind, &(*arms[0].body).kind)
+        } else {
+            return None;
+        };
+
+        match body_node_pair {
+            (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) {
+                (LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left),
+                (LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right),
+                _ => None,
+            },
+            _ => None,
+        }
+    }
+
+    fn can_suggest(cx: &LateContext<'_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool {
+        if !in_constant(cx, hir_id) {
+            return true;
+        }
+
+        // Avoid suggesting calls to non-`const fn`s in const contexts, see #5697.
+        cx.tcx
+            .get_diagnostic_item(diag_item)
+            .and_then(|def_id| {
+                cx.tcx.inherent_impls(def_id).iter().find_map(|imp| {
+                    cx.tcx
+                        .associated_items(*imp)
+                        .in_definition_order()
+                        .find_map(|item| match item.kind {
+                            ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id),
+                            _ => None,
+                        })
+                })
+            })
+            .map_or(false, |def_id| is_const_fn(cx.tcx, def_id))
+    }
+}
+
 #[test]
 fn test_overlapping() {
     use rustc_span::source_map::DUMMY_SP;
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index f1c8894c0ee..4c595029ff7 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1844,10 +1844,10 @@ fn lint_expect_fun_call(
                         ty::Ref(ty::ReStatic, ..)
                     )
                 }),
-            hir::ExprKind::Path(ref p) => match cx.qpath_res(p, arg.hir_id) {
-                hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _) => true,
-                _ => false,
-            },
+            hir::ExprKind::Path(ref p) => matches!(
+                cx.qpath_res(p, arg.hir_id),
+                hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static, _)
+            ),
             _ => false,
         }
     }
@@ -2028,13 +2028,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Exp
                     .tables()
                     .expr_adjustments(arg)
                     .iter()
-                    .filter(|adj| {
-                        if let ty::adjustment::Adjust::Deref(_) = adj.kind {
-                            true
-                        } else {
-                            false
-                        }
-                    })
+                    .filter(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_)))
                     .count();
                 let derefs: String = iter::repeat('*').take(deref_count).collect();
                 snip = Some(("try dereferencing it", format!("{}{}", derefs, snippet)));
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index 3d4225f36a7..400f4b609af 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -694,12 +694,7 @@ fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
     use rustc_span::hygiene::MacroKind;
     if expr.span.from_expansion() {
         let data = expr.span.ctxt().outer_expn_data();
-
-        if let ExpnKind::Macro(MacroKind::Attr, _) = data.kind {
-            true
-        } else {
-            false
-        }
+        matches!(data.kind, ExpnKind::Macro(MacroKind::Attr, _))
     } else {
         false
     }
diff --git a/clippy_lints/src/misc_early.rs b/clippy_lints/src/misc_early.rs
index ad39e59d067..b84a1a3fe24 100644
--- a/clippy_lints/src/misc_early.rs
+++ b/clippy_lints/src/misc_early.rs
@@ -641,28 +641,22 @@ fn check_unneeded_wildcard_pattern(cx: &EarlyContext<'_>, pat: &Pat) {
             );
         }
 
-        #[allow(clippy::trivially_copy_pass_by_ref)]
-        fn is_wild<P: std::ops::Deref<Target = Pat>>(pat: &&P) -> bool {
-            if let PatKind::Wild = pat.kind {
-                true
-            } else {
-                false
-            }
-        }
-
         if let Some(rest_index) = patterns.iter().position(|pat| pat.is_rest()) {
             if let Some((left_index, left_pat)) = patterns[..rest_index]
                 .iter()
                 .rev()
-                .take_while(is_wild)
+                .take_while(|pat| matches!(pat.kind, PatKind::Wild))
                 .enumerate()
                 .last()
             {
                 span_lint(cx, left_pat.span.until(patterns[rest_index].span), left_index == 0);
             }
 
-            if let Some((right_index, right_pat)) =
-                patterns[rest_index + 1..].iter().take_while(is_wild).enumerate().last()
+            if let Some((right_index, right_pat)) = patterns[rest_index + 1..]
+                .iter()
+                .take_while(|pat| matches!(pat.kind, PatKind::Wild))
+                .enumerate()
+                .last()
             {
                 span_lint(
                     cx,
diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs
index bf80b62afe6..9c962673537 100644
--- a/clippy_lints/src/missing_inline.rs
+++ b/clippy_lints/src/missing_inline.rs
@@ -71,10 +71,11 @@ fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp
 fn is_executable(cx: &LateContext<'_>) -> bool {
     use rustc_session::config::CrateType;
 
-    cx.tcx.sess.crate_types().iter().any(|t: &CrateType| match t {
-        CrateType::Executable => true,
-        _ => false,
-    })
+    cx.tcx
+        .sess
+        .crate_types()
+        .iter()
+        .any(|t: &CrateType| matches!(t, CrateType::Executable))
 }
 
 declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);
diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs
index 2597f5f6f17..621ebdef2f0 100644
--- a/clippy_lints/src/new_without_default.rs
+++ b/clippy_lints/src/new_without_default.rs
@@ -80,10 +80,12 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                             // can't be implemented for unsafe new
                             return;
                         }
-                        if impl_item.generics.params.iter().any(|gen| match gen.kind {
-                            hir::GenericParamKind::Type { .. } => true,
-                            _ => false,
-                        }) {
+                        if impl_item
+                            .generics
+                            .params
+                            .iter()
+                            .any(|gen| matches!(gen.kind, hir::GenericParamKind::Type { .. }))
+                        {
                             // when the result of `new()` depends on a type parameter we should not require
                             // an
                             // impl of `Default`
diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs
index c11a2ff9ee0..a3521c31a6b 100644
--- a/clippy_lints/src/non_copy_const.rs
+++ b/clippy_lints/src/non_copy_const.rs
@@ -238,10 +238,10 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
 
             let ty = if needs_check_adjustment {
                 let adjustments = cx.tables().expr_adjustments(dereferenced_expr);
-                if let Some(i) = adjustments.iter().position(|adj| match adj.kind {
-                    Adjust::Borrow(_) | Adjust::Deref(_) => true,
-                    _ => false,
-                }) {
+                if let Some(i) = adjustments
+                    .iter()
+                    .position(|adj| matches!(adj.kind, Adjust::Borrow(_) | Adjust::Deref(_)))
+                {
                     if i == 0 {
                         cx.tables().expr_ty(dereferenced_expr)
                     } else {
diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs
index 7dce23dd223..04be96aa64c 100644
--- a/clippy_lints/src/precedence.rs
+++ b/clippy_lints/src/precedence.rs
@@ -148,17 +148,11 @@ fn is_arith_expr(expr: &Expr) -> bool {
 #[must_use]
 fn is_bit_op(op: BinOpKind) -> bool {
     use rustc_ast::ast::BinOpKind::{BitAnd, BitOr, BitXor, Shl, Shr};
-    match op {
-        BitXor | BitAnd | BitOr | Shl | Shr => true,
-        _ => false,
-    }
+    matches!(op, BitXor | BitAnd | BitOr | Shl | Shr)
 }
 
 #[must_use]
 fn is_arith_op(op: BinOpKind) -> bool {
     use rustc_ast::ast::BinOpKind::{Add, Div, Mul, Rem, Sub};
-    match op {
-        Add | Sub | Mul | Div | Rem => true,
-        _ => false,
-    }
+    matches!(op, Add | Sub | Mul | Div | Rem)
 }
diff --git a/clippy_lints/src/redundant_pattern_matching.rs b/clippy_lints/src/redundant_pattern_matching.rs
deleted file mode 100644
index d8d16efb978..00000000000
--- a/clippy_lints/src/redundant_pattern_matching.rs
+++ /dev/null
@@ -1,260 +0,0 @@
-use crate::utils::{in_constant, match_qpath, match_trait_method, paths, snippet, span_lint_and_then};
-use if_chain::if_chain;
-use rustc_ast::ast::LitKind;
-use rustc_errors::Applicability;
-use rustc_hir::{Arm, Expr, ExprKind, HirId, MatchSource, PatKind, QPath};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
-use rustc_mir::const_eval::is_const_fn;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Symbol;
-
-declare_clippy_lint! {
-    /// **What it does:** Lint for redundant pattern matching over `Result` or
-    /// `Option`
-    ///
-    /// **Why is this bad?** It's more concise and clear to just use the proper
-    /// utility function
-    ///
-    /// **Known problems:** None.
-    ///
-    /// **Example:**
-    ///
-    /// ```rust
-    /// if let Ok(_) = Ok::<i32, i32>(42) {}
-    /// if let Err(_) = Err::<i32, i32>(42) {}
-    /// if let None = None::<()> {}
-    /// if let Some(_) = Some(42) {}
-    /// match Ok::<i32, i32>(42) {
-    ///     Ok(_) => true,
-    ///     Err(_) => false,
-    /// };
-    /// ```
-    ///
-    /// The more idiomatic use would be:
-    ///
-    /// ```rust
-    /// if Ok::<i32, i32>(42).is_ok() {}
-    /// if Err::<i32, i32>(42).is_err() {}
-    /// if None::<()>.is_none() {}
-    /// if Some(42).is_some() {}
-    /// Ok::<i32, i32>(42).is_ok();
-    /// ```
-    pub REDUNDANT_PATTERN_MATCHING,
-    style,
-    "use the proper utility function avoiding an `if let`"
-}
-
-declare_lint_pass!(RedundantPatternMatching => [REDUNDANT_PATTERN_MATCHING]);
-
-impl<'tcx> LateLintPass<'tcx> for RedundantPatternMatching {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let ExprKind::Match(op, arms, ref match_source) = &expr.kind {
-            match match_source {
-                MatchSource::Normal => find_sugg_for_match(cx, expr, op, arms),
-                MatchSource::IfLetDesugar { .. } => find_sugg_for_if_let(cx, expr, op, arms, "if"),
-                MatchSource::WhileLetDesugar => find_sugg_for_if_let(cx, expr, op, arms, "while"),
-                _ => return,
-            }
-        }
-    }
-}
-
-fn find_sugg_for_if_let<'tcx>(
-    cx: &LateContext<'tcx>,
-    expr: &'tcx Expr<'_>,
-    op: &Expr<'_>,
-    arms: &[Arm<'_>],
-    keyword: &'static str,
-) {
-    fn find_suggestion(cx: &LateContext<'_>, hir_id: HirId, path: &QPath<'_>) -> Option<&'static str> {
-        if match_qpath(path, &paths::RESULT_OK) && can_suggest(cx, hir_id, sym!(result_type), "is_ok") {
-            return Some("is_ok()");
-        }
-        if match_qpath(path, &paths::RESULT_ERR) && can_suggest(cx, hir_id, sym!(result_type), "is_err") {
-            return Some("is_err()");
-        }
-        if match_qpath(path, &paths::OPTION_SOME) && can_suggest(cx, hir_id, sym!(option_type), "is_some") {
-            return Some("is_some()");
-        }
-        if match_qpath(path, &paths::OPTION_NONE) && can_suggest(cx, hir_id, sym!(option_type), "is_none") {
-            return Some("is_none()");
-        }
-        None
-    }
-
-    let hir_id = expr.hir_id;
-    let good_method = match arms[0].pat.kind {
-        PatKind::TupleStruct(ref path, ref patterns, _) if patterns.len() == 1 => {
-            if let PatKind::Wild = patterns[0].kind {
-                find_suggestion(cx, hir_id, path)
-            } else {
-                None
-            }
-        },
-        PatKind::Path(ref path) => find_suggestion(cx, hir_id, path),
-        _ => None,
-    };
-    let good_method = match good_method {
-        Some(method) => method,
-        None => return,
-    };
-
-    // check that `while_let_on_iterator` lint does not trigger
-    if_chain! {
-        if keyword == "while";
-        if let ExprKind::MethodCall(method_path, _, _, _) = op.kind;
-        if method_path.ident.name == sym!(next);
-        if match_trait_method(cx, op, &paths::ITERATOR);
-        then {
-            return;
-        }
-    }
-
-    span_lint_and_then(
-        cx,
-        REDUNDANT_PATTERN_MATCHING,
-        arms[0].pat.span,
-        &format!("redundant pattern matching, consider using `{}`", good_method),
-        |diag| {
-            // while let ... = ... { ... }
-            // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-            let expr_span = expr.span;
-
-            // while let ... = ... { ... }
-            //                 ^^^
-            let op_span = op.span.source_callsite();
-
-            // while let ... = ... { ... }
-            // ^^^^^^^^^^^^^^^^^^^
-            let span = expr_span.until(op_span.shrink_to_hi());
-            diag.span_suggestion(
-                span,
-                "try this",
-                format!("{} {}.{}", keyword, snippet(cx, op_span, "_"), good_method),
-                Applicability::MachineApplicable, // snippet
-            );
-        },
-    );
-}
-
-fn find_sugg_for_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) {
-    if arms.len() == 2 {
-        let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind);
-
-        let hir_id = expr.hir_id;
-        let found_good_method = match node_pair {
-            (
-                PatKind::TupleStruct(ref path_left, ref patterns_left, _),
-                PatKind::TupleStruct(ref path_right, ref patterns_right, _),
-            ) if patterns_left.len() == 1 && patterns_right.len() == 1 => {
-                if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) {
-                    find_good_method_for_match(
-                        arms,
-                        path_left,
-                        path_right,
-                        &paths::RESULT_OK,
-                        &paths::RESULT_ERR,
-                        "is_ok()",
-                        "is_err()",
-                        || can_suggest(cx, hir_id, sym!(result_type), "is_ok"),
-                        || can_suggest(cx, hir_id, sym!(result_type), "is_err"),
-                    )
-                } else {
-                    None
-                }
-            },
-            (PatKind::TupleStruct(ref path_left, ref patterns, _), PatKind::Path(ref path_right))
-            | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, ref patterns, _))
-                if patterns.len() == 1 =>
-            {
-                if let PatKind::Wild = patterns[0].kind {
-                    find_good_method_for_match(
-                        arms,
-                        path_left,
-                        path_right,
-                        &paths::OPTION_SOME,
-                        &paths::OPTION_NONE,
-                        "is_some()",
-                        "is_none()",
-                        || can_suggest(cx, hir_id, sym!(option_type), "is_some"),
-                        || can_suggest(cx, hir_id, sym!(option_type), "is_none"),
-                    )
-                } else {
-                    None
-                }
-            },
-            _ => None,
-        };
-
-        if let Some(good_method) = found_good_method {
-            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),
-                        Applicability::MaybeIncorrect, // snippet
-                    );
-                },
-            );
-        }
-    }
-}
-
-#[allow(clippy::too_many_arguments)]
-fn find_good_method_for_match<'a>(
-    arms: &[Arm<'_>],
-    path_left: &QPath<'_>,
-    path_right: &QPath<'_>,
-    expected_left: &[&str],
-    expected_right: &[&str],
-    should_be_left: &'a str,
-    should_be_right: &'a str,
-    can_suggest_left: impl Fn() -> bool,
-    can_suggest_right: impl Fn() -> bool,
-) -> Option<&'a str> {
-    let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) {
-        (&(*arms[0].body).kind, &(*arms[1].body).kind)
-    } else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) {
-        (&(*arms[1].body).kind, &(*arms[0].body).kind)
-    } else {
-        return None;
-    };
-
-    match body_node_pair {
-        (ExprKind::Lit(ref lit_left), ExprKind::Lit(ref lit_right)) => match (&lit_left.node, &lit_right.node) {
-            (LitKind::Bool(true), LitKind::Bool(false)) if can_suggest_left() => Some(should_be_left),
-            (LitKind::Bool(false), LitKind::Bool(true)) if can_suggest_right() => Some(should_be_right),
-            _ => None,
-        },
-        _ => None,
-    }
-}
-
-fn can_suggest(cx: &LateContext<'_>, hir_id: HirId, diag_item: Symbol, name: &str) -> bool {
-    if !in_constant(cx, hir_id) {
-        return true;
-    }
-
-    // Avoid suggesting calls to non-`const fn`s in const contexts, see #5697.
-    cx.tcx
-        .get_diagnostic_item(diag_item)
-        .and_then(|def_id| {
-            cx.tcx.inherent_impls(def_id).iter().find_map(|imp| {
-                cx.tcx
-                    .associated_items(*imp)
-                    .in_definition_order()
-                    .find_map(|item| match item.kind {
-                        ty::AssocKind::Fn if item.ident.name.as_str() == name => Some(item.def_id),
-                        _ => None,
-                    })
-            })
-        })
-        .map_or(false, |def_id| is_const_fn(cx.tcx, def_id))
-}
diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs
index d8c8eff2c85..f204a0ffb2c 100644
--- a/clippy_lints/src/regex.rs
+++ b/clippy_lints/src/regex.rs
@@ -99,12 +99,7 @@ fn is_trivial_regex(s: &regex_syntax::hir::Hir) -> Option<&'static str> {
     use regex_syntax::hir::Anchor::{EndText, StartText};
     use regex_syntax::hir::HirKind::{Alternation, Anchor, Concat, Empty, Literal};
 
-    let is_literal = |e: &[regex_syntax::hir::Hir]| {
-        e.iter().all(|e| match *e.kind() {
-            Literal(_) => true,
-            _ => false,
-        })
-    };
+    let is_literal = |e: &[regex_syntax::hir::Hir]| e.iter().all(|e| matches!(*e.kind(), Literal(_)));
 
     match *s.kind() {
         Empty | Anchor(_) => Some("the regex is unlikely to be useful as it is"),
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index 4cdff63f118..194786c5c41 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -165,10 +165,7 @@ fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: &
 
 fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool {
     let var_ty = cx.tables().node_type_opt(pat_id);
-    var_ty.map_or(false, |var_ty| match var_ty.kind {
-        ty::Adt(..) => false,
-        _ => true,
-    })
+    var_ty.map_or(false, |var_ty| !matches!(var_ty.kind, ty::Adt(..)))
 }
 
 fn check_pat<'tcx>(
diff --git a/clippy_lints/src/temporary_assignment.rs b/clippy_lints/src/temporary_assignment.rs
index 509bbfd27c1..1aeff1baa36 100644
--- a/clippy_lints/src/temporary_assignment.rs
+++ b/clippy_lints/src/temporary_assignment.rs
@@ -25,13 +25,7 @@ declare_clippy_lint! {
 fn is_temporary(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match &expr.kind {
         ExprKind::Struct(..) | ExprKind::Tup(..) => true,
-        ExprKind::Path(qpath) => {
-            if let Res::Def(DefKind::Const, ..) = cx.qpath_res(qpath, expr.hir_id) {
-                true
-            } else {
-                false
-            }
-        },
+        ExprKind::Path(qpath) => matches!(cx.qpath_res(qpath, expr.hir_id), Res::Def(DefKind::Const, ..)),
         _ => false,
     }
 }
diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs
index d6f31a99bb3..71207caecf5 100644
--- a/clippy_lints/src/types.rs
+++ b/clippy_lints/src/types.rs
@@ -775,11 +775,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitArg {
                     .iter()
                     .filter(|arg| {
                         if is_unit(cx.tables().expr_ty(arg)) && !is_unit_literal(arg) {
-                            if let ExprKind::Match(.., MatchSource::TryDesugar) = &arg.kind {
-                                false
-                            } else {
-                                true
-                            }
+                            !matches!(&arg.kind, ExprKind::Match(.., MatchSource::TryDesugar))
                         } else {
                             false
                         }
@@ -899,17 +895,11 @@ fn is_questionmark_desugar_marked_call(expr: &Expr<'_>) -> bool {
 }
 
 fn is_unit(ty: Ty<'_>) -> bool {
-    match ty.kind {
-        ty::Tuple(slice) if slice.is_empty() => true,
-        _ => false,
-    }
+    matches!(ty.kind, ty::Tuple(slice) if slice.is_empty())
 }
 
 fn is_unit_literal(expr: &Expr<'_>) -> bool {
-    match expr.kind {
-        ExprKind::Tup(ref slice) if slice.is_empty() => true,
-        _ => false,
-    }
+    matches!(expr.kind, ExprKind::Tup(ref slice) if slice.is_empty())
 }
 
 declare_clippy_lint! {
@@ -1154,10 +1144,7 @@ fn int_ty_to_nbits(typ: Ty<'_>, tcx: TyCtxt<'_>) -> u64 {
 }
 
 fn is_isize_or_usize(typ: Ty<'_>) -> bool {
-    match typ.kind {
-        ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => true,
-        _ => false,
-    }
+    matches!(typ.kind, ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize))
 }
 
 fn span_precision_loss_lint(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to_f64: bool) {
@@ -1737,10 +1724,10 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
 
             TyKind::TraitObject(ref param_bounds, _) => {
                 let has_lifetime_parameters = param_bounds.iter().any(|bound| {
-                    bound.bound_generic_params.iter().any(|gen| match gen.kind {
-                        GenericParamKind::Lifetime { .. } => true,
-                        _ => false,
-                    })
+                    bound
+                        .bound_generic_params
+                        .iter()
+                        .any(|gen| matches!(gen.kind, GenericParamKind::Lifetime { .. }))
                 });
                 if has_lifetime_parameters {
                     // complex trait bounds like A<'a, 'b>
diff --git a/clippy_lints/src/unnamed_address.rs b/clippy_lints/src/unnamed_address.rs
index b9aa202b328..25d136e564d 100644
--- a/clippy_lints/src/unnamed_address.rs
+++ b/clippy_lints/src/unnamed_address.rs
@@ -58,10 +58,10 @@ declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS, VTABLE_ADDRESS_COM
 impl LateLintPass<'_> for UnnamedAddress {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         fn is_comparison(binop: BinOpKind) -> bool {
-            match binop {
-                BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt => true,
-                _ => false,
-            }
+            matches!(
+                binop,
+                BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt
+            )
         }
 
         fn is_trait_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
@@ -72,11 +72,7 @@ impl LateLintPass<'_> for UnnamedAddress {
         }
 
         fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-            if let ty::FnDef(..) = cx.tables().expr_ty(expr).kind {
-                true
-            } else {
-                false
-            }
+            matches!(cx.tables().expr_ty(expr).kind, ty::FnDef(..))
         }
 
         if_chain! {
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index 39a8c020872..776c6bc57ca 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -169,10 +169,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
                 let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
                 let should_check = parameters.as_ref().map_or(
                     true,
-                    |params| !params.parenthesized && !params.args.iter().any(|arg| match arg {
-                        GenericArg::Lifetime(_) => true,
-                        _ => false,
-                    })
+                    |params| !params.parenthesized
+                        &&!params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
                 );
 
                 if should_check {
diff --git a/clippy_lints/src/utils/ast_utils.rs b/clippy_lints/src/utils/ast_utils.rs
index e19a79dd8da..58c1103da9f 100755
--- a/clippy_lints/src/utils/ast_utils.rs
+++ b/clippy_lints/src/utils/ast_utils.rs
@@ -387,10 +387,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
 }
 
 pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {
-    match (l, r) {
-        (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_)) => true,
-        _ => false,
-    }
+    matches!((l, r), (Defaultness::Final, Defaultness::Final) | (Defaultness::Default(_), Defaultness::Default(_)))
 }
 
 pub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 3a3b79925ff..0b4cba3fc42 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -102,11 +102,7 @@ pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool {
 #[must_use]
 pub fn in_macro(span: Span) -> bool {
     if span.from_expansion() {
-        if let ExpnKind::Desugaring(..) = span.ctxt().outer_expn_data().kind {
-            false
-        } else {
-            true
-        }
+        !matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
     } else {
         false
     }
@@ -127,10 +123,7 @@ pub fn is_present_in_source<T: LintContext>(cx: &T, span: Span) -> bool {
 
 /// Checks if given pattern is a wildcard (`_`)
 pub fn is_wild<'tcx>(pat: &impl std::ops::Deref<Target = Pat<'tcx>>) -> bool {
-    match pat.kind {
-        PatKind::Wild => true,
-        _ => false,
-    }
+    matches!(pat.kind, PatKind::Wild)
 }
 
 /// Checks if type is struct, enum or union type with the given def path.
diff --git a/clippy_lints/src/utils/numeric_literal.rs b/clippy_lints/src/utils/numeric_literal.rs
index 7a79741b30b..87cb454f654 100644
--- a/clippy_lints/src/utils/numeric_literal.rs
+++ b/clippy_lints/src/utils/numeric_literal.rs
@@ -51,7 +51,7 @@ impl<'a> NumericLiteral<'a> {
     pub fn from_lit_kind(src: &'a str, lit_kind: &LitKind) -> Option<NumericLiteral<'a>> {
         if lit_kind.is_numeric() && src.chars().next().map_or(false, |c| c.is_digit(10)) {
             let (unsuffixed, suffix) = split_suffix(&src, lit_kind);
-            let float = if let LitKind::Float(..) = lit_kind { true } else { false };
+            let float = matches!(lit_kind, LitKind::Float(..));
             Some(NumericLiteral::new(unsuffixed, suffix, float))
         } else {
             None
diff --git a/src/driver.rs b/src/driver.rs
index decd3a79cce..47315fa64cd 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -382,13 +382,8 @@ pub fn main() {
 
         let should_describe_lints = || {
             let args: Vec<_> = env::args().collect();
-            args.windows(2).any(|args| {
-                args[1] == "help"
-                    && match args[0].as_str() {
-                        "-W" | "-A" | "-D" | "-F" => true,
-                        _ => false,
-                    }
-            })
+            args.windows(2)
+                .any(|args| args[1] == "help" && matches!(args[0].as_str(), "-W" | "-A" | "-D" | "-F"))
         };
 
         if !wrapper_mode && should_describe_lints() {
diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs
index e681f47f949..888b4755484 100644
--- a/src/lintlist/mod.rs
+++ b/src/lintlist/mod.rs
@@ -1180,6 +1180,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "matches",
     },
     Lint {
+        name: "match_like_matches_macro",
+        group: "style",
+        desc: "a match that could be written with the matches! macro",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
         name: "match_on_vec_items",
         group: "pedantic",
         desc: "matching on vector elements can panic",
@@ -1856,7 +1863,7 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         group: "style",
         desc: "use the proper utility function avoiding an `if let`",
         deprecation: None,
-        module: "redundant_pattern_matching",
+        module: "matches",
     },
     Lint {
         name: "redundant_pub_crate",
diff --git a/tests/ui/find_map.rs b/tests/ui/find_map.rs
index c28cca144ca..88d3b0e7490 100644
--- a/tests/ui/find_map.rs
+++ b/tests/ui/find_map.rs
@@ -19,6 +19,7 @@ fn main() {
 
     let _: Option<i32> = a.iter().find(|s| s.parse::<i32>().is_ok()).map(|s| s.parse().unwrap());
 
+    #[allow(clippy::match_like_matches_macro)]
     let _: Option<Flavor> = desserts_of_the_week
         .iter()
         .find(|dessert| match *dessert {
diff --git a/tests/ui/find_map.stderr b/tests/ui/find_map.stderr
index 92f40fe6f1f..f279850fef8 100644
--- a/tests/ui/find_map.stderr
+++ b/tests/ui/find_map.stderr
@@ -8,7 +8,7 @@ LL |     let _: Option<i32> = a.iter().find(|s| s.parse::<i32>().is_ok()).map(|s
    = help: this is more succinctly expressed by calling `.find_map(..)` instead
 
 error: called `find(p).map(q)` on an `Iterator`
-  --> $DIR/find_map.rs:22:29
+  --> $DIR/find_map.rs:23:29
    |
 LL |       let _: Option<Flavor> = desserts_of_the_week
    |  _____________________________^
diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed
new file mode 100644
index 00000000000..f3e19092480
--- /dev/null
+++ b/tests/ui/match_expr_like_matches_macro.fixed
@@ -0,0 +1,36 @@
+// run-rustfix
+
+#![warn(clippy::match_like_matches_macro)]
+#![allow(unreachable_patterns)]
+
+fn main() {
+    let x = Some(5);
+
+    // Lint
+    let _y = matches!(x, Some(0));
+
+    // Lint
+    let _w = matches!(x, Some(_));
+
+    // Turn into is_none
+    let _z = x.is_none();
+
+    // Lint
+    let _zz = !matches!(x, Some(r) if r == 0);
+
+    // Lint
+    let _zzz = matches!(x, Some(5));
+
+    // No lint
+    let _a = match x {
+        Some(_) => false,
+        _ => false,
+    };
+
+    // No lint
+    let _ab = match x {
+        Some(0) => false,
+        _ => true,
+        None => false,
+    };
+}
diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs
new file mode 100644
index 00000000000..fbae7c18b92
--- /dev/null
+++ b/tests/ui/match_expr_like_matches_macro.rs
@@ -0,0 +1,48 @@
+// run-rustfix
+
+#![warn(clippy::match_like_matches_macro)]
+#![allow(unreachable_patterns)]
+
+fn main() {
+    let x = Some(5);
+
+    // Lint
+    let _y = match x {
+        Some(0) => true,
+        _ => false,
+    };
+
+    // Lint
+    let _w = match x {
+        Some(_) => true,
+        _ => false,
+    };
+
+    // Turn into is_none
+    let _z = match x {
+        Some(_) => false,
+        None => true,
+    };
+
+    // Lint
+    let _zz = match x {
+        Some(r) if r == 0 => false,
+        _ => true,
+    };
+
+    // Lint
+    let _zzz = if let Some(5) = x { true } else { false };
+
+    // No lint
+    let _a = match x {
+        Some(_) => false,
+        _ => false,
+    };
+
+    // No lint
+    let _ab = match x {
+        Some(0) => false,
+        _ => true,
+        None => false,
+    };
+}
diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr
new file mode 100644
index 00000000000..4668f8565a6
--- /dev/null
+++ b/tests/ui/match_expr_like_matches_macro.stderr
@@ -0,0 +1,52 @@
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:10:14
+   |
+LL |       let _y = match x {
+   |  ______________^
+LL | |         Some(0) => true,
+LL | |         _ => false,
+LL | |     };
+   | |_____^ help: try this: `matches!(x, Some(0))`
+   |
+   = note: `-D clippy::match-like-matches-macro` implied by `-D warnings`
+
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:16:14
+   |
+LL |       let _w = match x {
+   |  ______________^
+LL | |         Some(_) => true,
+LL | |         _ => false,
+LL | |     };
+   | |_____^ help: try this: `matches!(x, Some(_))`
+
+error: redundant pattern matching, consider using `is_none()`
+  --> $DIR/match_expr_like_matches_macro.rs:22:14
+   |
+LL |       let _z = match x {
+   |  ______________^
+LL | |         Some(_) => false,
+LL | |         None => true,
+LL | |     };
+   | |_____^ help: try this: `x.is_none()`
+   |
+   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
+
+error: match expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:28:15
+   |
+LL |       let _zz = match x {
+   |  _______________^
+LL | |         Some(r) if r == 0 => false,
+LL | |         _ => true,
+LL | |     };
+   | |_____^ help: try this: `!matches!(x, Some(r) if r == 0)`
+
+error: if let .. else expression looks like `matches!` macro
+  --> $DIR/match_expr_like_matches_macro.rs:34:16
+   |
+LL |     let _zzz = if let Some(5) = x { true } else { false };
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/neg_cmp_op_on_partial_ord.rs b/tests/ui/neg_cmp_op_on_partial_ord.rs
index ca70e3b7148..0cee0a28fc7 100644
--- a/tests/ui/neg_cmp_op_on_partial_ord.rs
+++ b/tests/ui/neg_cmp_op_on_partial_ord.rs
@@ -4,7 +4,7 @@
 
 use std::cmp::Ordering;
 
-#[allow(clippy::unnested_or_patterns)]
+#[allow(clippy::unnested_or_patterns, clippy::match_like_matches_macro)]
 #[warn(clippy::neg_cmp_op_on_partial_ord)]
 fn main() {
     let a_value = 1.0;
diff --git a/tests/ui/redundant_pattern_matching.fixed b/tests/ui/redundant_pattern_matching.fixed
index 8b4e2d21331..ce8582d2b22 100644
--- a/tests/ui/redundant_pattern_matching.fixed
+++ b/tests/ui/redundant_pattern_matching.fixed
@@ -2,7 +2,13 @@
 
 #![warn(clippy::all)]
 #![warn(clippy::redundant_pattern_matching)]
-#![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)]
+#![allow(
+    clippy::unit_arg,
+    unused_must_use,
+    clippy::needless_bool,
+    clippy::match_like_matches_macro,
+    deprecated
+)]
 
 fn main() {
     if Ok::<i32, i32>(42).is_ok() {}
diff --git a/tests/ui/redundant_pattern_matching.rs b/tests/ui/redundant_pattern_matching.rs
index b0904e41b6f..a3a9aa40e3b 100644
--- a/tests/ui/redundant_pattern_matching.rs
+++ b/tests/ui/redundant_pattern_matching.rs
@@ -2,7 +2,13 @@
 
 #![warn(clippy::all)]
 #![warn(clippy::redundant_pattern_matching)]
-#![allow(clippy::unit_arg, unused_must_use, clippy::needless_bool, deprecated)]
+#![allow(
+    clippy::unit_arg,
+    unused_must_use,
+    clippy::needless_bool,
+    clippy::match_like_matches_macro,
+    deprecated
+)]
 
 fn main() {
     if let Ok(_) = Ok::<i32, i32>(42) {}
diff --git a/tests/ui/redundant_pattern_matching.stderr b/tests/ui/redundant_pattern_matching.stderr
index 51a6f4350d3..25d1476062e 100644
--- a/tests/ui/redundant_pattern_matching.stderr
+++ b/tests/ui/redundant_pattern_matching.stderr
@@ -1,5 +1,5 @@
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:8:12
+  --> $DIR/redundant_pattern_matching.rs:14:12
    |
 LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
    |     -------^^^^^--------------------- help: try this: `if Ok::<i32, i32>(42).is_ok()`
@@ -7,67 +7,67 @@ LL |     if let Ok(_) = Ok::<i32, i32>(42) {}
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:10:12
+  --> $DIR/redundant_pattern_matching.rs:16: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:12:12
+  --> $DIR/redundant_pattern_matching.rs:18: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:14:12
+  --> $DIR/redundant_pattern_matching.rs:20: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:16:12
+  --> $DIR/redundant_pattern_matching.rs:22: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:15
+  --> $DIR/redundant_pattern_matching.rs:28: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:24:15
+  --> $DIR/redundant_pattern_matching.rs:30: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:26:15
+  --> $DIR/redundant_pattern_matching.rs:32: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:28:15
+  --> $DIR/redundant_pattern_matching.rs:34: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:30:15
+  --> $DIR/redundant_pattern_matching.rs:36: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:33:15
+  --> $DIR/redundant_pattern_matching.rs:39: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:49:5
+  --> $DIR/redundant_pattern_matching.rs:55:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -76,7 +76,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:54:5
+  --> $DIR/redundant_pattern_matching.rs:60:5
    |
 LL | /     match Ok::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -85,7 +85,7 @@ LL | |     };
    | |_____^ help: try this: `Ok::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_err()`
-  --> $DIR/redundant_pattern_matching.rs:59:5
+  --> $DIR/redundant_pattern_matching.rs:65:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => false,
@@ -94,7 +94,7 @@ LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_err()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:64:5
+  --> $DIR/redundant_pattern_matching.rs:70:5
    |
 LL | /     match Err::<i32, i32>(42) {
 LL | |         Ok(_) => true,
@@ -103,7 +103,7 @@ LL | |     };
    | |_____^ help: try this: `Err::<i32, i32>(42).is_ok()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching.rs:69:5
+  --> $DIR/redundant_pattern_matching.rs:75:5
    |
 LL | /     match Some(42) {
 LL | |         Some(_) => true,
@@ -112,7 +112,7 @@ LL | |     };
    | |_____^ help: try this: `Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:74:5
+  --> $DIR/redundant_pattern_matching.rs:80:5
    |
 LL | /     match None::<()> {
 LL | |         Some(_) => false,
@@ -121,7 +121,7 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching.rs:79:13
+  --> $DIR/redundant_pattern_matching.rs:85:13
    |
 LL |       let _ = match None::<()> {
    |  _____________^
@@ -131,61 +131,61 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_ok()`
-  --> $DIR/redundant_pattern_matching.rs:84:20
+  --> $DIR/redundant_pattern_matching.rs:90: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:87:20
+  --> $DIR/redundant_pattern_matching.rs:93: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:93:20
+  --> $DIR/redundant_pattern_matching.rs:99: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:95:19
+  --> $DIR/redundant_pattern_matching.rs:101: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:97:19
+  --> $DIR/redundant_pattern_matching.rs:103: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:99:19
+  --> $DIR/redundant_pattern_matching.rs:105: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:132:19
+  --> $DIR/redundant_pattern_matching.rs:138: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:133:16
+  --> $DIR/redundant_pattern_matching.rs:139: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:139:12
+  --> $DIR/redundant_pattern_matching.rs:145: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:140:15
+  --> $DIR/redundant_pattern_matching.rs:146:15
    |
 LL |     while let Some(_) = m!() {}
    |     ----------^^^^^^^------- help: try this: `while m!().is_some()`
diff --git a/tests/ui/redundant_pattern_matching_const_result.fixed b/tests/ui/redundant_pattern_matching_const_result.fixed
index 8a81e92f04a..de3fe00d5fa 100644
--- a/tests/ui/redundant_pattern_matching_const_result.fixed
+++ b/tests/ui/redundant_pattern_matching_const_result.fixed
@@ -2,7 +2,7 @@
 
 #![feature(const_result)]
 #![warn(clippy::redundant_pattern_matching)]
-#![allow(unused)]
+#![allow(clippy::match_like_matches_macro, unused)]
 
 // Test that results are linted with the feature enabled.
 
diff --git a/tests/ui/redundant_pattern_matching_const_result.rs b/tests/ui/redundant_pattern_matching_const_result.rs
index 1cd515441d1..b77969d53d9 100644
--- a/tests/ui/redundant_pattern_matching_const_result.rs
+++ b/tests/ui/redundant_pattern_matching_const_result.rs
@@ -2,7 +2,7 @@
 
 #![feature(const_result)]
 #![warn(clippy::redundant_pattern_matching)]
-#![allow(unused)]
+#![allow(clippy::match_like_matches_macro, unused)]
 
 // Test that results are linted with the feature enabled.