about summary refs log tree commit diff
path: root/tests/ui/pattern/never_patterns.rs
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2023-11-22 02:30:43 +0100
committerNadrieril <nadrieril+git@gmail.com>2023-11-29 03:58:29 +0100
commita3838c855064f55485147c66e0e50b039875613e (patch)
treef390c4580092b09a4c93c276bc06c681281e1f1c /tests/ui/pattern/never_patterns.rs
parent1bcbb7c93b96828092e83e52d592faa046183d6c (diff)
downloadrust-a3838c855064f55485147c66e0e50b039875613e.tar.gz
rust-a3838c855064f55485147c66e0e50b039875613e.zip
Add `never_patterns` feature gate
Diffstat (limited to 'tests/ui/pattern/never_patterns.rs')
-rw-r--r--tests/ui/pattern/never_patterns.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/tests/ui/pattern/never_patterns.rs b/tests/ui/pattern/never_patterns.rs
new file mode 100644
index 00000000000..e2e17e0e9a7
--- /dev/null
+++ b/tests/ui/pattern/never_patterns.rs
@@ -0,0 +1,99 @@
+#![feature(never_patterns)]
+#![allow(incomplete_features)]
+
+enum Void {}
+
+fn main() {}
+
+// The classic use for empty types.
+fn safe_unwrap_result<T>(res: Result<T, Void>) {
+    let Ok(_x) = res;
+    // FIXME(never_patterns): These should be allowed
+    let (Ok(_x) | Err(!)) = &res;
+    //~^ ERROR: is not bound in all patterns
+    let (Ok(_x) | Err(&!)) = res.as_ref();
+    //~^ ERROR: is not bound in all patterns
+}
+
+// Check we only accept `!` where we want to.
+fn never_pattern_location(void: Void) {
+    // FIXME(never_patterns): Don't accept on a non-empty type.
+    match Some(0) {
+        None => {}
+        Some(!) => {}
+    }
+    // FIXME(never_patterns): Don't accept on an arbitrary type, even if there are no more branches.
+    match () {
+        () => {}
+        ! => {}
+    }
+    // FIXME(never_patterns): Don't accept even on an empty branch.
+    match None::<Void> {
+        None => {}
+        ! => {}
+    }
+    // FIXME(never_patterns): Let alone if the emptiness is behind a reference.
+    match None::<&Void> {
+        None => {}
+        ! => {}
+    }
+    // Participate in match ergonomics.
+    match &void {
+        ! => {}
+    }
+    match &&void {
+        ! => {}
+    }
+    match &&void {
+        &! => {}
+    }
+    match &None::<Void> {
+        None => {}
+        Some(!) => {}
+    }
+    match None::<&Void> {
+        None => {}
+        Some(!) => {}
+    }
+    // Accept on a composite empty type.
+    match None::<&(u32, Void)> {
+        None => {}
+        Some(&!) => {}
+    }
+    // Accept on an simple empty type.
+    match None::<Void> {
+        None => {}
+        Some(!) => {}
+    }
+    match None::<&Void> {
+        None => {}
+        Some(&!) => {}
+    }
+    match None::<&(u32, Void)> {
+        None => {}
+        Some(&(_, !)) => {}
+    }
+}
+
+fn never_and_bindings() {
+    let x: Result<bool, &(u32, Void)> = Ok(false);
+
+    // FIXME(never_patterns): Never patterns in or-patterns don't need to share the same bindings.
+    match x {
+        Ok(_x) | Err(&!) => {}
+        //~^ ERROR: is not bound in all patterns
+    }
+    let (Ok(_x) | Err(&!)) = x;
+        //~^ ERROR: is not bound in all patterns
+
+    // FIXME(never_patterns): A never pattern mustn't have bindings.
+    match x {
+        Ok(_) => {}
+        Err(&(_b, !)) => {}
+    }
+    match x {
+        Ok(_a) | Err(&(_b, !)) => {}
+        //~^ ERROR: is not bound in all patterns
+        //~| ERROR: is not bound in all patterns
+    }
+}