about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/matches/infallible_destructuring_match.rs7
-rw-r--r--tests/ui/infallible_destructuring_match.fixed12
-rw-r--r--tests/ui/infallible_destructuring_match.rs14
-rw-r--r--tests/ui/infallible_destructuring_match.stderr16
4 files changed, 42 insertions, 7 deletions
diff --git a/clippy_lints/src/matches/infallible_destructuring_match.rs b/clippy_lints/src/matches/infallible_destructuring_match.rs
index 2472acb6f6e..d18c92caba2 100644
--- a/clippy_lints/src/matches/infallible_destructuring_match.rs
+++ b/clippy_lints/src/matches/infallible_destructuring_match.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
 use rustc_errors::Applicability;
-use rustc_hir::{ExprKind, Local, MatchSource, PatKind, QPath};
+use rustc_hir::{ByRef, ExprKind, Local, MatchSource, PatKind, QPath};
 use rustc_lint::LateContext;
 
 use super::INFALLIBLE_DESTRUCTURING_MATCH;
@@ -16,7 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
         if let PatKind::TupleStruct(
             QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
         if args.len() == 1;
-        if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
+        if let PatKind::Binding(binding, arg, ..) = strip_pat_refs(&args[0]).kind;
         let body = peel_blocks(arms[0].body);
         if path_to_local_id(body, arg);
 
@@ -30,8 +30,9 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
                 Consider using `let`",
                 "try this",
                 format!(
-                    "let {}({}) = {};",
+                    "let {}({}{}) = {};",
                     snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
+                    if binding.0 == ByRef::Yes { "ref " } else { "" },
                     snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
                     snippet_with_applicability(cx, target.span, "..", &mut applicability),
                 ),
diff --git a/tests/ui/infallible_destructuring_match.fixed b/tests/ui/infallible_destructuring_match.fixed
index b8e40d99553..61985e56b76 100644
--- a/tests/ui/infallible_destructuring_match.fixed
+++ b/tests/ui/infallible_destructuring_match.fixed
@@ -9,6 +9,9 @@ enum SingleVariantEnum {
 
 struct TupleStruct(i32);
 
+struct NonCopy;
+struct TupleStructWithNonCopy(NonCopy);
+
 enum EmptyEnum {}
 
 macro_rules! match_enum {
@@ -71,6 +74,15 @@ fn infallible_destructuring_match_struct() {
     let TupleStruct(data) = wrapper;
 }
 
+fn infallible_destructuring_match_struct_with_noncopy() {
+    let wrapper = TupleStructWithNonCopy(NonCopy);
+
+    // This should lint! (keeping `ref` in the suggestion)
+    let TupleStructWithNonCopy(ref data) = wrapper;
+
+    let TupleStructWithNonCopy(ref data) = wrapper;
+}
+
 macro_rules! match_never_enum {
     ($param:expr) => {
         let data = match $param {
diff --git a/tests/ui/infallible_destructuring_match.rs b/tests/ui/infallible_destructuring_match.rs
index 106cd438b90..f2768245bbc 100644
--- a/tests/ui/infallible_destructuring_match.rs
+++ b/tests/ui/infallible_destructuring_match.rs
@@ -9,6 +9,9 @@ enum SingleVariantEnum {
 
 struct TupleStruct(i32);
 
+struct NonCopy;
+struct TupleStructWithNonCopy(NonCopy);
+
 enum EmptyEnum {}
 
 macro_rules! match_enum {
@@ -75,6 +78,17 @@ fn infallible_destructuring_match_struct() {
     let TupleStruct(data) = wrapper;
 }
 
+fn infallible_destructuring_match_struct_with_noncopy() {
+    let wrapper = TupleStructWithNonCopy(NonCopy);
+
+    // This should lint! (keeping `ref` in the suggestion)
+    let data = match wrapper {
+        TupleStructWithNonCopy(ref n) => n,
+    };
+
+    let TupleStructWithNonCopy(ref data) = wrapper;
+}
+
 macro_rules! match_never_enum {
     ($param:expr) => {
         let data = match $param {
diff --git a/tests/ui/infallible_destructuring_match.stderr b/tests/ui/infallible_destructuring_match.stderr
index 1b78db42014..f8a50f0223d 100644
--- a/tests/ui/infallible_destructuring_match.stderr
+++ b/tests/ui/infallible_destructuring_match.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
-  --> $DIR/infallible_destructuring_match.rs:26:5
+  --> $DIR/infallible_destructuring_match.rs:29:5
    |
 LL | /     let data = match wrapper {
 LL | |         SingleVariantEnum::Variant(i) => i,
@@ -9,7 +9,7 @@ LL | |     };
    = note: `-D clippy::infallible-destructuring-match` implied by `-D warnings`
 
 error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
-  --> $DIR/infallible_destructuring_match.rs:58:5
+  --> $DIR/infallible_destructuring_match.rs:61:5
    |
 LL | /     let data = match wrapper {
 LL | |         TupleStruct(i) => i,
@@ -17,12 +17,20 @@ LL | |     };
    | |______^ help: try this: `let TupleStruct(data) = wrapper;`
 
 error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
-  --> $DIR/infallible_destructuring_match.rs:90:5
+  --> $DIR/infallible_destructuring_match.rs:85:5
+   |
+LL | /     let data = match wrapper {
+LL | |         TupleStructWithNonCopy(ref n) => n,
+LL | |     };
+   | |______^ help: try this: `let TupleStructWithNonCopy(ref data) = wrapper;`
+
+error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`
+  --> $DIR/infallible_destructuring_match.rs:104:5
    |
 LL | /     let data = match wrapper {
 LL | |         Ok(i) => i,
 LL | |     };
    | |______^ help: try this: `let Ok(data) = wrapper;`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors