about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/enum_variants.rs2
-rw-r--r--clippy_lints/src/int_plus_one.rs28
-rw-r--r--clippy_lints/src/len_zero.rs3
-rw-r--r--clippy_lints/src/needless_borrowed_ref.rs108
-rw-r--r--clippy_lints/src/unsafe_removed_from_name.rs2
-rw-r--r--clippy_utils/src/consts.rs22
-rw-r--r--clippy_utils/src/hir_utils.rs16
-rw-r--r--tests/ui/match_expr_like_matches_macro.fixed7
-rw-r--r--tests/ui/match_expr_like_matches_macro.rs7
-rw-r--r--tests/ui/match_expr_like_matches_macro.stderr28
-rw-r--r--tests/ui/needless_borrowed_ref.fixed67
-rw-r--r--tests/ui/needless_borrowed_ref.rs67
-rw-r--r--tests/ui/needless_borrowed_ref.stderr113
13 files changed, 356 insertions, 114 deletions
diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs
index b019d07d53d..7add358e8e4 100644
--- a/clippy_lints/src/enum_variants.rs
+++ b/clippy_lints/src/enum_variants.rs
@@ -250,7 +250,7 @@ impl LateLintPass<'_> for EnumVariantNames {
         let item_name = item.ident.name.as_str();
         let item_camel = to_camel_case(item_name);
         if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
-            if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
+            if let Some((mod_name, mod_camel)) = self.modules.last() {
                 // constants don't have surrounding modules
                 if !mod_camel.is_empty() {
                     if mod_name == &item.ident.name {
diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs
index 33491da3fc5..51757592c02 100644
--- a/clippy_lints/src/int_plus_one.rs
+++ b/clippy_lints/src/int_plus_one.rs
@@ -62,58 +62,54 @@ impl IntPlusOne {
     fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option<String> {
         match (binop, &lhs.kind, &rhs.kind) {
             // case where `x - 1 >= ...` or `-1 + x >= ...`
-            (BinOpKind::Ge, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) => {
+            (BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => {
                 match (lhskind.node, &lhslhs.kind, &lhsrhs.kind) {
                     // `-1 + x`
-                    (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if Self::check_lit(lit, -1) => {
+                    (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
                         Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
                     },
                     // `x - 1`
-                    (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+                    (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
                         Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
                     },
                     _ => None,
                 }
             },
             // case where `... >= y + 1` or `... >= 1 + y`
-            (BinOpKind::Ge, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs))
-                if rhskind.node == BinOpKind::Add =>
-            {
+            (BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => {
                 match (&rhslhs.kind, &rhsrhs.kind) {
                     // `y + 1` and `1 + y`
-                    (&ExprKind::Lit(ref lit), _) if Self::check_lit(lit, 1) => {
+                    (ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
                         Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
                     },
-                    (_, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+                    (_, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
                         Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
                     },
                     _ => None,
                 }
             },
             // case where `x + 1 <= ...` or `1 + x <= ...`
-            (BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _)
-                if lhskind.node == BinOpKind::Add =>
-            {
+            (BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => {
                 match (&lhslhs.kind, &lhsrhs.kind) {
                     // `1 + x` and `x + 1`
-                    (&ExprKind::Lit(ref lit), _) if Self::check_lit(lit, 1) => {
+                    (ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
                         Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
                     },
-                    (_, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+                    (_, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
                         Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
                     },
                     _ => None,
                 }
             },
             // case where `... >= y - 1` or `... >= -1 + y`
-            (BinOpKind::Le, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) => {
+            (BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => {
                 match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) {
                     // `-1 + y`
-                    (BinOpKind::Add, &ExprKind::Lit(ref lit), _) if Self::check_lit(lit, -1) => {
+                    (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
                         Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
                     },
                     // `y - 1`
-                    (BinOpKind::Sub, _, &ExprKind::Lit(ref lit)) if Self::check_lit(lit, 1) => {
+                    (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
                         Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
                     },
                     _ => None,
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 3a563736fb0..76b0c21327c 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -366,8 +366,7 @@ fn check_for_is_empty<'tcx>(
 }
 
 fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
-    if let (&ExprKind::MethodCall(method_path, receiver, args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind)
-    {
+    if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {
         // check if we are in an is_empty() method
         if let Some(name) = get_item_name(cx, method) {
             if name.as_str() == "is_empty" {
diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs
index 10c3ff026b6..498e1408e52 100644
--- a/clippy_lints/src/needless_borrowed_ref.rs
+++ b/clippy_lints/src/needless_borrowed_ref.rs
@@ -36,14 +36,14 @@ declare_clippy_lint! {
 declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);
 
 impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
-    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
-        if pat.span.from_expansion() {
+    fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) {
+        if ref_pat.span.from_expansion() {
             // OK, simple enough, lints doesn't check in macro.
             return;
         }
 
         // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms
-        for (_, node) in cx.tcx.hir().parent_iter(pat.hir_id) {
+        for (_, node) in cx.tcx.hir().parent_iter(ref_pat.hir_id) {
             let Node::Pat(pat) = node else { break };
 
             if matches!(pat.kind, PatKind::Or(_)) {
@@ -52,20 +52,20 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
         }
 
         // Only lint immutable refs, because `&mut ref T` may be useful.
-        let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind else { return };
+        let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind else { return };
 
-        match sub_pat.kind {
+        match pat.kind {
             // Check sub_pat got a `ref` keyword (excluding `ref mut`).
             PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
                 span_lint_and_then(
                     cx,
                     NEEDLESS_BORROWED_REFERENCE,
-                    pat.span,
+                    ref_pat.span,
                     "this pattern takes a reference on something that is being dereferenced",
                     |diag| {
                         // `&ref ident`
                         //  ^^^^^
-                        let span = pat.span.until(ident.span);
+                        let span = ref_pat.span.until(ident.span);
                         diag.span_suggestion_verbose(
                             span,
                             "try removing the `&ref` part",
@@ -84,41 +84,71 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
                 }),
                 after,
             ) => {
-                let mut suggestions = Vec::new();
-
-                for element_pat in itertools::chain(before, after) {
-                    if let PatKind::Binding(BindingAnnotation::REF, _, ident, None) = element_pat.kind {
-                        // `&[..., ref ident, ...]`
-                        //         ^^^^
-                        let span = element_pat.span.until(ident.span);
-                        suggestions.push((span, String::new()));
-                    } else {
-                        return;
-                    }
-                }
+                check_subpatterns(
+                    cx,
+                    "dereferencing a slice pattern where every element takes a reference",
+                    ref_pat,
+                    pat,
+                    itertools::chain(before, after),
+                );
+            },
+            PatKind::Tuple(subpatterns, _) | PatKind::TupleStruct(_, subpatterns, _) => {
+                check_subpatterns(
+                    cx,
+                    "dereferencing a tuple pattern where every element takes a reference",
+                    ref_pat,
+                    pat,
+                    subpatterns,
+                );
+            },
+            PatKind::Struct(_, fields, _) => {
+                check_subpatterns(
+                    cx,
+                    "dereferencing a struct pattern where every field's pattern takes a reference",
+                    ref_pat,
+                    pat,
+                    fields.iter().map(|field| field.pat),
+                );
+            },
+            _ => {},
+        }
+    }
+}
 
-                if !suggestions.is_empty() {
-                    span_lint_and_then(
-                        cx,
-                        NEEDLESS_BORROWED_REFERENCE,
-                        pat.span,
-                        "dereferencing a slice pattern where every element takes a reference",
-                        |diag| {
-                            // `&[...]`
-                            //  ^
-                            let span = pat.span.until(sub_pat.span);
-                            suggestions.push((span, String::new()));
+fn check_subpatterns<'tcx>(
+    cx: &LateContext<'tcx>,
+    message: &str,
+    ref_pat: &Pat<'_>,
+    pat: &Pat<'_>,
+    subpatterns: impl IntoIterator<Item = &'tcx Pat<'tcx>>,
+) {
+    let mut suggestions = Vec::new();
 
-                            diag.multipart_suggestion(
-                                "try removing the `&` and `ref` parts",
-                                suggestions,
-                                Applicability::MachineApplicable,
-                            );
-                        },
-                    );
-                }
+    for subpattern in subpatterns {
+        match subpattern.kind {
+            PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
+                // `ref ident`
+                //  ^^^^
+                let span = subpattern.span.until(ident.span);
+                suggestions.push((span, String::new()));
             },
-            _ => {},
+            PatKind::Wild => {},
+            _ => return,
         }
     }
+
+    if !suggestions.is_empty() {
+        span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, ref_pat.span, message, |diag| {
+            // `&pat`
+            //  ^
+            let span = ref_pat.span.until(pat.span);
+            suggestions.push((span, String::new()));
+
+            diag.multipart_suggestion(
+                "try removing the `&` and `ref` parts",
+                suggestions,
+                Applicability::MachineApplicable,
+            );
+        });
+    }
 }
diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs
index 32cd4681201..95258652768 100644
--- a/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/clippy_lints/src/unsafe_removed_from_name.rs
@@ -50,7 +50,7 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
         },
         UseTreeKind::Simple(None, ..) | UseTreeKind::Glob => {},
         UseTreeKind::Nested(ref nested_use_tree) => {
-            for &(ref use_tree, _) in nested_use_tree {
+            for (use_tree, _) in nested_use_tree {
                 check_use_tree(use_tree, cx, span);
             }
         },
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index f01afda72b2..315aea9aa09 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -51,8 +51,8 @@ pub enum Constant {
 impl PartialEq for Constant {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
-            (&Self::Str(ref ls), &Self::Str(ref rs)) => ls == rs,
-            (&Self::Binary(ref l), &Self::Binary(ref r)) => l == r,
+            (Self::Str(ls), Self::Str(rs)) => ls == rs,
+            (Self::Binary(l), Self::Binary(r)) => l == r,
             (&Self::Char(l), &Self::Char(r)) => l == r,
             (&Self::Int(l), &Self::Int(r)) => l == r,
             (&Self::F64(l), &Self::F64(r)) => {
@@ -69,8 +69,8 @@ impl PartialEq for Constant {
             },
             (&Self::Bool(l), &Self::Bool(r)) => l == r,
             (&Self::Vec(ref l), &Self::Vec(ref r)) | (&Self::Tuple(ref l), &Self::Tuple(ref r)) => l == r,
-            (&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => ls == rs && lv == rv,
-            (&Self::Ref(ref lb), &Self::Ref(ref rb)) => *lb == *rb,
+            (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => ls == rs && lv == rv,
+            (Self::Ref(lb), Self::Ref(rb)) => *lb == *rb,
             // TODO: are there inter-type equalities?
             _ => false,
         }
@@ -126,8 +126,8 @@ impl Hash for Constant {
 impl Constant {
     pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {
         match (left, right) {
-            (&Self::Str(ref ls), &Self::Str(ref rs)) => Some(ls.cmp(rs)),
-            (&Self::Char(ref l), &Self::Char(ref r)) => Some(l.cmp(r)),
+            (Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),
+            (Self::Char(l), Self::Char(r)) => Some(l.cmp(r)),
             (&Self::Int(l), &Self::Int(r)) => match *cmp_type.kind() {
                 ty::Int(int_ty) => Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty))),
                 ty::Uint(_) => Some(l.cmp(&r)),
@@ -135,8 +135,8 @@ impl Constant {
             },
             (&Self::F64(l), &Self::F64(r)) => l.partial_cmp(&r),
             (&Self::F32(l), &Self::F32(r)) => l.partial_cmp(&r),
-            (&Self::Bool(ref l), &Self::Bool(ref r)) => Some(l.cmp(r)),
-            (&Self::Tuple(ref l), &Self::Tuple(ref r)) if l.len() == r.len() => match *cmp_type.kind() {
+            (Self::Bool(l), Self::Bool(r)) => Some(l.cmp(r)),
+            (Self::Tuple(l), Self::Tuple(r)) if l.len() == r.len() => match *cmp_type.kind() {
                 ty::Tuple(tys) if tys.len() == l.len() => l
                     .iter()
                     .zip(r)
@@ -146,7 +146,7 @@ impl Constant {
                     .unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
                 _ => None,
             },
-            (&Self::Vec(ref l), &Self::Vec(ref r)) => {
+            (Self::Vec(l), Self::Vec(r)) => {
                 let (ty::Array(cmp_type, _) | ty::Slice(cmp_type)) = *cmp_type.kind() else {
                     return None
                 };
@@ -155,7 +155,7 @@ impl Constant {
                     .find(|r| r.map_or(true, |o| o != Ordering::Equal))
                     .unwrap_or_else(|| Some(l.len().cmp(&r.len())))
             },
-            (&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => {
+            (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {
                 match Self::partial_cmp(
                     tcx,
                     match *cmp_type.kind() {
@@ -169,7 +169,7 @@ impl Constant {
                     x => x,
                 }
             },
-            (&Self::Ref(ref lb), &Self::Ref(ref rb)) => Self::partial_cmp(
+            (Self::Ref(lb), Self::Ref(rb)) => Self::partial_cmp(
                 tcx,
                 match *cmp_type.kind() {
                     ty::Ref(_, ty, _) => ty,
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index da8c976c952..0231a51adf4 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -266,7 +266,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Let(l), &ExprKind::Let(r)) => {
                 self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
             },
-            (&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
+            (ExprKind::Lit(l), ExprKind::Lit(r)) => l.node == r.node,
             (&ExprKind::Loop(lb, ref ll, ref lls, _), &ExprKind::Loop(rb, ref rl, ref rls, _)) => {
                 lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
             },
@@ -291,8 +291,8 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
                 self.eq_expr(le, re) && self.eq_array_length(ll, rl)
             },
-            (&ExprKind::Ret(ref l), &ExprKind::Ret(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
-            (&ExprKind::Path(ref l), &ExprKind::Path(ref r)) => self.eq_qpath(l, r),
+            (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l, r, |l, r| self.eq_expr(l, r)),
+            (ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r),
             (&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
                 self.eq_qpath(l_path, r_path)
                     && both(lo, ro, |l, r| self.eq_expr(l, r))
@@ -362,7 +362,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 }
                 eq
             },
-            (&PatKind::Path(ref l), &PatKind::Path(ref r)) => self.eq_qpath(l, r),
+            (PatKind::Path(l), PatKind::Path(r)) => self.eq_qpath(l, r),
             (&PatKind::Lit(l), &PatKind::Lit(r)) => self.eq_expr(l, r),
             (&PatKind::Tuple(l, ls), &PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)),
             (&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => {
@@ -429,13 +429,11 @@ impl HirEqInterExpr<'_, '_, '_> {
         match (&left.kind, &right.kind) {
             (&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),
             (&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl),
-            (&TyKind::Ptr(ref l_mut), &TyKind::Ptr(ref r_mut)) => {
-                l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty)
-            },
-            (&TyKind::Rptr(_, ref l_rmut), &TyKind::Rptr(_, ref r_rmut)) => {
+            (TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),
+            (TyKind::Rptr(_, l_rmut), TyKind::Rptr(_, r_rmut)) => {
                 l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)
             },
-            (&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r),
+            (TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
             (&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),
             (&TyKind::Infer, &TyKind::Infer) => true,
             _ => false,
diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed
index 2498007694c..968f462f8a0 100644
--- a/tests/ui/match_expr_like_matches_macro.fixed
+++ b/tests/ui/match_expr_like_matches_macro.fixed
@@ -2,7 +2,12 @@
 
 #![feature(custom_inner_attributes)]
 #![warn(clippy::match_like_matches_macro)]
-#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
+#![allow(
+    unreachable_patterns,
+    dead_code,
+    clippy::equatable_if_let,
+    clippy::needless_borrowed_reference
+)]
 
 fn main() {
     let x = Some(5);
diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs
index b4e48499bd0..c6b479e27c5 100644
--- a/tests/ui/match_expr_like_matches_macro.rs
+++ b/tests/ui/match_expr_like_matches_macro.rs
@@ -2,7 +2,12 @@
 
 #![feature(custom_inner_attributes)]
 #![warn(clippy::match_like_matches_macro)]
-#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
+#![allow(
+    unreachable_patterns,
+    dead_code,
+    clippy::equatable_if_let,
+    clippy::needless_borrowed_reference
+)]
 
 fn main() {
     let x = Some(5);
diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr
index f1d1c23aeb0..a4df8008ac2 100644
--- a/tests/ui/match_expr_like_matches_macro.stderr
+++ b/tests/ui/match_expr_like_matches_macro.stderr
@@ -1,5 +1,5 @@
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:11:14
+  --> $DIR/match_expr_like_matches_macro.rs:16:14
    |
 LL |       let _y = match x {
    |  ______________^
@@ -11,7 +11,7 @@ LL | |     };
    = 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:17:14
+  --> $DIR/match_expr_like_matches_macro.rs:22:14
    |
 LL |       let _w = match x {
    |  ______________^
@@ -21,7 +21,7 @@ LL | |     };
    | |_____^ help: try this: `matches!(x, Some(_))`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/match_expr_like_matches_macro.rs:23:14
+  --> $DIR/match_expr_like_matches_macro.rs:28:14
    |
 LL |       let _z = match x {
    |  ______________^
@@ -33,7 +33,7 @@ LL | |     };
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:29:15
+  --> $DIR/match_expr_like_matches_macro.rs:34:15
    |
 LL |       let _zz = match x {
    |  _______________^
@@ -43,13 +43,13 @@ 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:35:16
+  --> $DIR/match_expr_like_matches_macro.rs:40:16
    |
 LL |     let _zzz = if let Some(5) = x { true } else { false };
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `matches!(x, Some(5))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:59:20
+  --> $DIR/match_expr_like_matches_macro.rs:64:20
    |
 LL |           let _ans = match x {
    |  ____________________^
@@ -60,7 +60,7 @@ LL | |         };
    | |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:69:20
+  --> $DIR/match_expr_like_matches_macro.rs:74:20
    |
 LL |           let _ans = match x {
    |  ____________________^
@@ -73,7 +73,7 @@ LL | |         };
    | |_________^ help: try this: `matches!(x, E::A(_) | E::B(_))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:79:20
+  --> $DIR/match_expr_like_matches_macro.rs:84:20
    |
 LL |           let _ans = match x {
    |  ____________________^
@@ -84,7 +84,7 @@ LL | |         };
    | |_________^ help: try this: `!matches!(x, E::B(_) | E::C)`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:139:18
+  --> $DIR/match_expr_like_matches_macro.rs:144:18
    |
 LL |           let _z = match &z {
    |  __________________^
@@ -94,7 +94,7 @@ LL | |         };
    | |_________^ help: try this: `matches!(z, Some(3))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:148:18
+  --> $DIR/match_expr_like_matches_macro.rs:153:18
    |
 LL |           let _z = match &z {
    |  __________________^
@@ -104,7 +104,7 @@ LL | |         };
    | |_________^ help: try this: `matches!(&z, Some(3))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:165:21
+  --> $DIR/match_expr_like_matches_macro.rs:170:21
    |
 LL |               let _ = match &z {
    |  _____________________^
@@ -114,7 +114,7 @@ LL | |             };
    | |_____________^ help: try this: `matches!(&z, AnEnum::X)`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:179:20
+  --> $DIR/match_expr_like_matches_macro.rs:184:20
    |
 LL |           let _res = match &val {
    |  ____________________^
@@ -124,7 +124,7 @@ LL | |         };
    | |_________^ help: try this: `matches!(&val, &Some(ref _a))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:191:20
+  --> $DIR/match_expr_like_matches_macro.rs:196:20
    |
 LL |           let _res = match &val {
    |  ____________________^
@@ -134,7 +134,7 @@ LL | |         };
    | |_________^ help: try this: `matches!(&val, &Some(ref _a))`
 
 error: match expression looks like `matches!` macro
-  --> $DIR/match_expr_like_matches_macro.rs:251:14
+  --> $DIR/match_expr_like_matches_macro.rs:256:14
    |
 LL |       let _y = match Some(5) {
    |  ______________^
diff --git a/tests/ui/needless_borrowed_ref.fixed b/tests/ui/needless_borrowed_ref.fixed
index bcb4eb2dd48..0c47ceb7b67 100644
--- a/tests/ui/needless_borrowed_ref.fixed
+++ b/tests/ui/needless_borrowed_ref.fixed
@@ -1,11 +1,32 @@
 // run-rustfix
 
 #![warn(clippy::needless_borrowed_reference)]
-#![allow(unused, clippy::needless_borrow)]
+#![allow(
+    unused,
+    irrefutable_let_patterns,
+    non_shorthand_field_patterns,
+    clippy::needless_borrow
+)]
 
 fn main() {}
 
-fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+struct Struct {
+    a: usize,
+    b: usize,
+    c: usize,
+}
+
+struct TupleStruct(u8, u8, u8);
+
+fn should_lint(
+    array: [u8; 4],
+    slice: &[u8],
+    slice_of_refs: &[&u8],
+    vec: Vec<u8>,
+    tuple: (u8, u8, u8),
+    tuple_struct: TupleStruct,
+    s: Struct,
+) {
     let mut v = Vec::<String>::new();
     let _ = v.iter_mut().filter(|a| a.is_empty());
 
@@ -24,16 +45,54 @@ fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>
     if let [a, b, ..] = slice {}
     if let [a, .., b] = slice {}
     if let [.., a, b] = slice {}
+
+    if let [a, _] = slice {}
+
+    if let (a, b, c) = &tuple {}
+    if let (a, _, c) = &tuple {}
+    if let (a, ..) = &tuple {}
+
+    if let TupleStruct(a, ..) = &tuple_struct {}
+
+    if let Struct {
+        a,
+        b: b,
+        c: renamed,
+    } = &s
+    {}
+
+    if let Struct { a, b: _, .. } = &s {}
 }
 
-fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+fn should_not_lint(
+    array: [u8; 4],
+    slice: &[u8],
+    slice_of_refs: &[&u8],
+    vec: Vec<u8>,
+    tuple: (u8, u8, u8),
+    tuple_struct: TupleStruct,
+    s: Struct,
+) {
     if let [ref a] = slice {}
     if let &[ref a, b] = slice {}
     if let &[ref a, .., b] = slice {}
 
+    if let &(ref a, b, ..) = &tuple {}
+    if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
+    if let &Struct { ref a, b, .. } = &s {}
+
     // must not be removed as variables must be bound consistently across | patterns
     if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
 
+    // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
+    // the lint name
+    if let &[] = slice {}
+    if let &[_] = slice {}
+    if let &[..] = slice {}
+    if let &(..) = &tuple {}
+    if let &TupleStruct(..) = &tuple_struct {}
+    if let &Struct { .. } = &s {}
+
     let mut var2 = 5;
     let thingy2 = Some(&mut var2);
     if let Some(&mut ref mut v) = thingy2 {
@@ -59,6 +118,6 @@ fn foo(a: &Animal, b: &Animal) {
         // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
         (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
         //                  ^    and   ^ should **not** be linted
-        (&Animal::Dog(ref a), &Animal::Dog(_)) => (), //              ^ should **not** be linted
+        (Animal::Dog(a), &Animal::Dog(_)) => (),
     }
 }
diff --git a/tests/ui/needless_borrowed_ref.rs b/tests/ui/needless_borrowed_ref.rs
index f6de1a6d83d..f883bb0c889 100644
--- a/tests/ui/needless_borrowed_ref.rs
+++ b/tests/ui/needless_borrowed_ref.rs
@@ -1,11 +1,32 @@
 // run-rustfix
 
 #![warn(clippy::needless_borrowed_reference)]
-#![allow(unused, clippy::needless_borrow)]
+#![allow(
+    unused,
+    irrefutable_let_patterns,
+    non_shorthand_field_patterns,
+    clippy::needless_borrow
+)]
 
 fn main() {}
 
-fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+struct Struct {
+    a: usize,
+    b: usize,
+    c: usize,
+}
+
+struct TupleStruct(u8, u8, u8);
+
+fn should_lint(
+    array: [u8; 4],
+    slice: &[u8],
+    slice_of_refs: &[&u8],
+    vec: Vec<u8>,
+    tuple: (u8, u8, u8),
+    tuple_struct: TupleStruct,
+    s: Struct,
+) {
     let mut v = Vec::<String>::new();
     let _ = v.iter_mut().filter(|&ref a| a.is_empty());
 
@@ -24,16 +45,54 @@ fn should_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>
     if let &[ref a, ref b, ..] = slice {}
     if let &[ref a, .., ref b] = slice {}
     if let &[.., ref a, ref b] = slice {}
+
+    if let &[ref a, _] = slice {}
+
+    if let &(ref a, ref b, ref c) = &tuple {}
+    if let &(ref a, _, ref c) = &tuple {}
+    if let &(ref a, ..) = &tuple {}
+
+    if let &TupleStruct(ref a, ..) = &tuple_struct {}
+
+    if let &Struct {
+        ref a,
+        b: ref b,
+        c: ref renamed,
+    } = &s
+    {}
+
+    if let &Struct { ref a, b: _, .. } = &s {}
 }
 
-fn should_not_lint(array: [u8; 4], slice: &[u8], slice_of_refs: &[&u8], vec: Vec<u8>) {
+fn should_not_lint(
+    array: [u8; 4],
+    slice: &[u8],
+    slice_of_refs: &[&u8],
+    vec: Vec<u8>,
+    tuple: (u8, u8, u8),
+    tuple_struct: TupleStruct,
+    s: Struct,
+) {
     if let [ref a] = slice {}
     if let &[ref a, b] = slice {}
     if let &[ref a, .., b] = slice {}
 
+    if let &(ref a, b, ..) = &tuple {}
+    if let &TupleStruct(ref a, b, ..) = &tuple_struct {}
+    if let &Struct { ref a, b, .. } = &s {}
+
     // must not be removed as variables must be bound consistently across | patterns
     if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}
 
+    // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match
+    // the lint name
+    if let &[] = slice {}
+    if let &[_] = slice {}
+    if let &[..] = slice {}
+    if let &(..) = &tuple {}
+    if let &TupleStruct(..) = &tuple_struct {}
+    if let &Struct { .. } = &s {}
+
     let mut var2 = 5;
     let thingy2 = Some(&mut var2);
     if let Some(&mut ref mut v) = thingy2 {
@@ -59,6 +118,6 @@ fn foo(a: &Animal, b: &Animal) {
         // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63
         (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),
         //                  ^    and   ^ should **not** be linted
-        (&Animal::Dog(ref a), &Animal::Dog(_)) => (), //              ^ should **not** be linted
+        (Animal::Dog(a), &Animal::Dog(_)) => (),
     }
 }
diff --git a/tests/ui/needless_borrowed_ref.stderr b/tests/ui/needless_borrowed_ref.stderr
index 7453542e673..8d0f0c258dd 100644
--- a/tests/ui/needless_borrowed_ref.stderr
+++ b/tests/ui/needless_borrowed_ref.stderr
@@ -1,5 +1,5 @@
 error: this pattern takes a reference on something that is being dereferenced
-  --> $DIR/needless_borrowed_ref.rs:10:34
+  --> $DIR/needless_borrowed_ref.rs:31:34
    |
 LL |     let _ = v.iter_mut().filter(|&ref a| a.is_empty());
    |                                  ^^^^^^
@@ -12,7 +12,7 @@ LL +     let _ = v.iter_mut().filter(|a| a.is_empty());
    |
 
 error: this pattern takes a reference on something that is being dereferenced
-  --> $DIR/needless_borrowed_ref.rs:14:17
+  --> $DIR/needless_borrowed_ref.rs:35:17
    |
 LL |     if let Some(&ref v) = thingy {}
    |                 ^^^^^^
@@ -24,7 +24,7 @@ LL +     if let Some(v) = thingy {}
    |
 
 error: this pattern takes a reference on something that is being dereferenced
-  --> $DIR/needless_borrowed_ref.rs:16:14
+  --> $DIR/needless_borrowed_ref.rs:37:14
    |
 LL |     if let &[&ref a, ref b] = slice_of_refs {}
    |              ^^^^^^
@@ -36,7 +36,7 @@ LL +     if let &[a, ref b] = slice_of_refs {}
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:18:9
+  --> $DIR/needless_borrowed_ref.rs:39:9
    |
 LL |     let &[ref a, ..] = &array;
    |         ^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL +     let [a, ..] = &array;
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:19:9
+  --> $DIR/needless_borrowed_ref.rs:40:9
    |
 LL |     let &[ref a, ref b, ..] = &array;
    |         ^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL +     let [a, b, ..] = &array;
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:21:12
+  --> $DIR/needless_borrowed_ref.rs:42:12
    |
 LL |     if let &[ref a, ref b] = slice {}
    |            ^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL +     if let [a, b] = slice {}
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:22:12
+  --> $DIR/needless_borrowed_ref.rs:43:12
    |
 LL |     if let &[ref a, ref b] = &vec[..] {}
    |            ^^^^^^^^^^^^^^^
@@ -84,7 +84,7 @@ LL +     if let [a, b] = &vec[..] {}
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:24:12
+  --> $DIR/needless_borrowed_ref.rs:45:12
    |
 LL |     if let &[ref a, ref b, ..] = slice {}
    |            ^^^^^^^^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL +     if let [a, b, ..] = slice {}
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:25:12
+  --> $DIR/needless_borrowed_ref.rs:46:12
    |
 LL |     if let &[ref a, .., ref b] = slice {}
    |            ^^^^^^^^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL +     if let [a, .., b] = slice {}
    |
 
 error: dereferencing a slice pattern where every element takes a reference
-  --> $DIR/needless_borrowed_ref.rs:26:12
+  --> $DIR/needless_borrowed_ref.rs:47:12
    |
 LL |     if let &[.., ref a, ref b] = slice {}
    |            ^^^^^^^^^^^^^^^^^^^
@@ -119,5 +119,96 @@ LL -     if let &[.., ref a, ref b] = slice {}
 LL +     if let [.., a, b] = slice {}
    |
 
-error: aborting due to 10 previous errors
+error: dereferencing a slice pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:49:12
+   |
+LL |     if let &[ref a, _] = slice {}
+   |            ^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &[ref a, _] = slice {}
+LL +     if let [a, _] = slice {}
+   |
+
+error: dereferencing a tuple pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:51:12
+   |
+LL |     if let &(ref a, ref b, ref c) = &tuple {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &(ref a, ref b, ref c) = &tuple {}
+LL +     if let (a, b, c) = &tuple {}
+   |
+
+error: dereferencing a tuple pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:52:12
+   |
+LL |     if let &(ref a, _, ref c) = &tuple {}
+   |            ^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &(ref a, _, ref c) = &tuple {}
+LL +     if let (a, _, c) = &tuple {}
+   |
+
+error: dereferencing a tuple pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:53:12
+   |
+LL |     if let &(ref a, ..) = &tuple {}
+   |            ^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &(ref a, ..) = &tuple {}
+LL +     if let (a, ..) = &tuple {}
+   |
+
+error: dereferencing a tuple pattern where every element takes a reference
+  --> $DIR/needless_borrowed_ref.rs:55:12
+   |
+LL |     if let &TupleStruct(ref a, ..) = &tuple_struct {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &TupleStruct(ref a, ..) = &tuple_struct {}
+LL +     if let TupleStruct(a, ..) = &tuple_struct {}
+   |
+
+error: dereferencing a struct pattern where every field's pattern takes a reference
+  --> $DIR/needless_borrowed_ref.rs:57:12
+   |
+LL |       if let &Struct {
+   |  ____________^
+LL | |         ref a,
+LL | |         b: ref b,
+LL | |         c: ref renamed,
+LL | |     } = &s
+   | |_____^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL ~     if let Struct {
+LL ~         a,
+LL ~         b: b,
+LL ~         c: renamed,
+   |
+
+error: dereferencing a struct pattern where every field's pattern takes a reference
+  --> $DIR/needless_borrowed_ref.rs:64:12
+   |
+LL |     if let &Struct { ref a, b: _, .. } = &s {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try removing the `&` and `ref` parts
+   |
+LL -     if let &Struct { ref a, b: _, .. } = &s {}
+LL +     if let Struct { a, b: _, .. } = &s {}
+   |
+
+error: aborting due to 17 previous errors