about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/matches/single_match.rs21
-rw-r--r--tests/ui/single_match_else_deref_patterns.fixed7
-rw-r--r--tests/ui/single_match_else_deref_patterns.rs11
-rw-r--r--tests/ui/single_match_else_deref_patterns.stderr16
4 files changed, 47 insertions, 8 deletions
diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs
index 08c0caa4266..811455c25e4 100644
--- a/clippy_lints/src/matches/single_match.rs
+++ b/clippy_lints/src/matches/single_match.rs
@@ -152,21 +152,26 @@ fn report_single_pattern(
             }) if lit.node.is_str() || lit.node.is_bytestr() => pat_ref_count + 1,
             _ => pat_ref_count,
         };
-        // References are only implicitly added to the pattern, so no overflow here.
-        // e.g. will work: match &Some(_) { Some(_) => () }
-        // will not: match Some(_) { &Some(_) => () }
-        let ref_count_diff = ty_ref_count - pat_ref_count;
 
-        // Try to remove address of expressions first.
-        let (ex, removed) = peel_n_hir_expr_refs(ex, ref_count_diff);
-        let ref_count_diff = ref_count_diff - removed;
+        // References are implicitly removed when `deref_patterns` are used.
+        // They are implicitly added when match ergonomics are used.
+        let (ex, ref_or_deref_adjust) = if ty_ref_count > pat_ref_count {
+            let ref_count_diff = ty_ref_count - pat_ref_count;
+
+            // Try to remove address of expressions first.
+            let (ex, removed) = peel_n_hir_expr_refs(ex, ref_count_diff);
+
+            (ex, "&".repeat(ref_count_diff - removed))
+        } else {
+            (ex, "*".repeat(pat_ref_count - ty_ref_count))
+        };
 
         let msg = "you seem to be trying to use `match` for an equality check. Consider using `if`";
         let sugg = format!(
             "if {} == {}{} {}{els_str}",
             snippet_with_context(cx, ex.span, ctxt, "..", &mut app).0,
             // PartialEq for different reference counts may not exist.
-            "&".repeat(ref_count_diff),
+            ref_or_deref_adjust,
             snippet_with_applicability(cx, arm.pat.span, "..", &mut app),
             expr_block(cx, arm.body, ctxt, "..", Some(expr.span), &mut app),
         );
diff --git a/tests/ui/single_match_else_deref_patterns.fixed b/tests/ui/single_match_else_deref_patterns.fixed
new file mode 100644
index 00000000000..c83e8c4a18f
--- /dev/null
+++ b/tests/ui/single_match_else_deref_patterns.fixed
@@ -0,0 +1,7 @@
+#![feature(deref_patterns)]
+#![allow(incomplete_features, clippy::eq_op)]
+#![warn(clippy::single_match_else)]
+
+fn string() {
+    if *"" == *"" {}
+}
diff --git a/tests/ui/single_match_else_deref_patterns.rs b/tests/ui/single_match_else_deref_patterns.rs
new file mode 100644
index 00000000000..c7dbfb4e465
--- /dev/null
+++ b/tests/ui/single_match_else_deref_patterns.rs
@@ -0,0 +1,11 @@
+#![feature(deref_patterns)]
+#![allow(incomplete_features, clippy::eq_op)]
+#![warn(clippy::single_match_else)]
+
+fn string() {
+    match *"" {
+        //~^ single_match
+        "" => {},
+        _ => {},
+    }
+}
diff --git a/tests/ui/single_match_else_deref_patterns.stderr b/tests/ui/single_match_else_deref_patterns.stderr
new file mode 100644
index 00000000000..17959ce9a0c
--- /dev/null
+++ b/tests/ui/single_match_else_deref_patterns.stderr
@@ -0,0 +1,16 @@
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+  --> tests/ui/single_match_else_deref_patterns.rs:6:5
+   |
+LL | /     match *"" {
+LL | |
+LL | |         "" => {},
+LL | |         _ => {},
+LL | |     }
+   | |_____^ help: try: `if *"" == *"" {}`
+   |
+   = note: you might want to preserve the comments from inside the `match`
+   = note: `-D clippy::single-match` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::single_match)]`
+
+error: aborting due to 1 previous error
+