about summary refs log tree commit diff
path: root/tests/ui/pattern/deref-patterns/usefulness
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-04-20 23:57:09 -0700
committerdianne <diannes.gm@gmail.com>2025-05-06 18:53:55 -0700
commitfb261a179d2c210785b6e9005201e262dac801b5 (patch)
tree17a709e679f327bb95f013ed4c2f5a825637bc1a /tests/ui/pattern/deref-patterns/usefulness
parentcf43bba1e5ec87838fca248f36d940f2923576c2 (diff)
error early when mixing deref patterns with normal constructors
Without adding proper support for mixed exhaustiveness, mixing deref
patterns with normal constructors would either violate
`ConstructorSet::split`'s invariant 4 or 7. We'd either be ignoring rows
with normal constructors or we'd have problems in unspecialization from
non-disjoint constructors. Checking mixed exhaustivenss similarly to how
unions are currently checked should work, but the diagnostics for unions
are confusing. Since mixing deref patterns with normal constructors is
pretty niche (currently it only makes sense for `Cow`), emitting an
error lets us avoid committing to supporting mixed exhaustiveness
without a good answer for the diagnostics.
Diffstat (limited to 'tests/ui/pattern/deref-patterns/usefulness')
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs48
-rw-r--r--tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr43
2 files changed, 91 insertions, 0 deletions
diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs
new file mode 100644
index 00000000000..f567dc07bb5
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.rs
@@ -0,0 +1,48 @@
+//! Test matches with a mix of ADT constructors and deref patterns. Currently, usefulness analysis
+//! doesn't support this, so make sure we catch it beforehand. As a consequence, it takes priority
+//! over non-exhaustive match and unreachable pattern errors.
+#![feature(deref_patterns)]
+#![expect(incomplete_features)]
+#![deny(unreachable_patterns)]
+
+use std::borrow::Cow;
+
+fn main() {
+    let cow: Cow<'static, bool> = Cow::Borrowed(&false);
+
+    match cow {
+        true => {}
+        //~v ERROR mix of deref patterns and normal constructors
+        false => {}
+        Cow::Borrowed(_) => {}
+    }
+
+    match cow {
+        Cow::Owned(_) => {}
+        Cow::Borrowed(_) => {}
+        true => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+
+    match cow {
+        _ => {}
+        Cow::Owned(_) => {}
+        false => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+
+    match (cow, 0) {
+        (Cow::Owned(_), 0) => {}
+        (Cow::Borrowed(_), 0) => {}
+        (true, 0) => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+
+    match (0, cow) {
+        (0, Cow::Owned(_)) => {}
+        (0, Cow::Borrowed(_)) => {}
+        _ => {}
+        (1, true) => {}
+        //~^ ERROR mix of deref patterns and normal constructors
+    }
+}
diff --git a/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr
new file mode 100644
index 00000000000..5ad24164b98
--- /dev/null
+++ b/tests/ui/pattern/deref-patterns/usefulness/mixed-constructors.stderr
@@ -0,0 +1,43 @@
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:16:9
+   |
+LL |         false => {}
+   |         ^^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+LL |         Cow::Borrowed(_) => {}
+   |         ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:22:9
+   |
+LL |         Cow::Borrowed(_) => {}
+   |         ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         true => {}
+   |         ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:29:9
+   |
+LL |         Cow::Owned(_) => {}
+   |         ^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         false => {}
+   |         ^^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:36:10
+   |
+LL |         (Cow::Borrowed(_), 0) => {}
+   |          ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         (true, 0) => {}
+   |          ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: mix of deref patterns and normal constructors
+  --> $DIR/mixed-constructors.rs:43:13
+   |
+LL |         (0, Cow::Borrowed(_)) => {}
+   |             ^^^^^^^^^^^^^^^^ matches directly on `Cow<'_, bool>`
+LL |         _ => {}
+LL |         (1, true) => {}
+   |             ^^^^ matches on the result of dereferencing `Cow<'_, bool>`
+
+error: aborting due to 5 previous errors
+