about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2023-08-24 09:41:30 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2023-08-24 16:29:08 +0100
commitd3c3c17abb3a4cb38be0fec3ea2cb62bdd452e06 (patch)
treecf7bbb8671b65c9220e5e5fa97fdc3a7cf503224
parentb4d09f3b811cf9bb73288c054557f2c2436bb37d (diff)
downloadrust-d3c3c17abb3a4cb38be0fec3ea2cb62bdd452e06.tar.gz
rust-d3c3c17abb3a4cb38be0fec3ea2cb62bdd452e06.zip
Add more tests for if_let_guard
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs18
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr35
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs15
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs16
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs14
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs14
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs16
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs27
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr52
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs18
-rw-r--r--tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs23
15 files changed, 298 insertions, 0 deletions
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
new file mode 100644
index 00000000000..b4eb541398c
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
@@ -0,0 +1,18 @@
+#![feature(if_let_guard)]
+#![allow(irrefutable_let_patterns)]
+
+fn match_option(x: Option<u32>) {
+    match x {
+        //~^ ERROR non-exhaustive patterns: `None` not covered
+        Some(_) => {}
+        None if let y = x => {}
+    }
+}
+
+fn main() {
+    let x = ();
+    match x {
+        //~^ ERROR non-exhaustive patterns: `()` not covered
+        y if let z = y => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
new file mode 100644
index 00000000000..ddd08854ff7
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
@@ -0,0 +1,35 @@
+error[E0004]: non-exhaustive patterns: `None` not covered
+  --> $DIR/exhaustive.rs:5:11
+   |
+LL |     match x {
+   |           ^ pattern `None` not covered
+   |
+note: `Option<u32>` defined here
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: not covered
+   = note: the matched value is of type `Option<u32>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         None if let y = x => {},
+LL +         None => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `()` not covered
+  --> $DIR/exhaustive.rs:14:11
+   |
+LL |     match x {
+   |           ^ pattern `()` not covered
+   |
+   = note: the matched value is of type `()`
+   = note: match arms with guards don't count towards exhaustivity
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~         y if let z = y => {},
+LL +         () => todo!()
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
new file mode 100644
index 00000000000..792225e656f
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
@@ -0,0 +1,15 @@
+// References to by-move bindings in an if-let guard *cannot* be used after the guard.
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let x: Option<Option<String>> = Some(Some(String::new()));
+    match x {
+        Some(mut y) if let Some(ref z) = y => {
+            //~^ ERROR: cannot move out of `x.0` because it is borrowed
+            let _z: &String = z;
+            let _y: Option<String> = y;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
new file mode 100644
index 00000000000..b8e1bb324b1
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
@@ -0,0 +1,15 @@
+error[E0505]: cannot move out of `x.0` because it is borrowed
+  --> $DIR/guard-lifetime-1.rs:8:14
+   |
+LL |         Some(mut y) if let Some(ref z) = y => {
+   |              ^^^^^
+   |              |
+   |              move out of `x.0` occurs here
+   |              borrow of `x.0` occurs here
+LL |
+LL |             let _z: &String = z;
+   |                               - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
new file mode 100644
index 00000000000..aa2154e3e9e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
@@ -0,0 +1,16 @@
+// References to by-mutable-ref bindings in an if-let guard *can* be used after the guard.
+
+// check-pass
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let mut x: Option<Option<String>> = Some(Some(String::new()));
+    match x {
+        Some(ref mut y) if let Some(ref z) = *y => {
+            let _z: &String = z;
+            let _y: &mut Option<String> = y;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
new file mode 100644
index 00000000000..9353c9d92f8
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
@@ -0,0 +1,14 @@
+// Check mutable bindings cannot be mutated by an if-let guard.
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let x: Option<Option<i32>> = Some(Some(6));
+    match x {
+        Some(mut y) if let Some(ref mut z) = y => {
+            //~^ ERROR cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+            let _: &mut i32 = z;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr
new file mode 100644
index 00000000000..009d153387e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+  --> $DIR/guard-mutability-1.rs:8:33
+   |
+LL |         Some(mut y) if let Some(ref mut z) = y => {
+   |                                 ^^^^^^^^^ cannot borrow as mutable
+   |
+   = note: variables bound in patterns are immutable until the end of the pattern guard
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
new file mode 100644
index 00000000000..4efa02f57a6
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
@@ -0,0 +1,14 @@
+// Check mutable reference bindings cannot be mutated by an if-let guard.
+
+#![feature(if_let_guard)]
+
+fn main() {
+    let mut x: Option<Option<i32>> = Some(Some(6));
+    match x {
+        Some(ref mut y) if let Some(ref mut z) = *y => {
+            //~^ ERROR cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+            let _: &mut i32 = z;
+        }
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr
new file mode 100644
index 00000000000..07e7c6a2c07
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr
@@ -0,0 +1,11 @@
+error[E0596]: cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
+  --> $DIR/guard-mutability-2.rs:8:37
+   |
+LL |         Some(ref mut y) if let Some(ref mut z) = *y => {
+   |                                     ^^^^^^^^^ cannot borrow as mutable
+   |
+   = note: variables bound in patterns are immutable until the end of the pattern guard
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
new file mode 100644
index 00000000000..423a2cd53fc
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
@@ -0,0 +1,16 @@
+// Expression macros can't expand to a let match guard.
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+macro_rules! m {
+    ($e:expr) => { let Some(x) = $e }
+    //~^ ERROR expected expression, found `let` statement
+}
+
+fn main() {
+    match () {
+        () if m!(Some(5)) => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
new file mode 100644
index 00000000000..41a20bf8ae1
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
@@ -0,0 +1,13 @@
+error: expected expression, found `let` statement
+  --> $DIR/macro-expanded.rs:7:20
+   |
+LL |     ($e:expr) => { let Some(x) = $e }
+   |                    ^^^
+...
+LL |         () if m!(Some(5)) => {}
+   |               ----------- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
new file mode 100644
index 00000000000..9cb27c73b14
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
@@ -0,0 +1,27 @@
+// Parenthesised let "expressions" are not allowed in guards
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+#[cfg(FALSE)]
+fn un_cfged() {
+    match () {
+        () if let 0 = 1 => {}
+        () if (let 0 = 1) => {}
+        //~^ ERROR expected expression, found `let` statement
+        () if (((let 0 = 1))) => {}
+        //~^ ERROR expected expression, found `let` statement
+    }
+}
+
+fn main() {
+    match () {
+        () if let 0 = 1 => {}
+        () if (let 0 = 1) => {}
+        //~^ ERROR expected expression, found `let` statement
+        //~| ERROR `let` expressions are not supported here
+        () if (((let 0 = 1))) => {}
+        //~^ ERROR expected expression, found `let` statement
+        //~| ERROR `let` expressions are not supported here
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
new file mode 100644
index 00000000000..85df360daab
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
@@ -0,0 +1,52 @@
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:10:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:12:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:20:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/parens.rs:23:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^
+
+error: `let` expressions are not supported here
+  --> $DIR/parens.rs:20:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/parens.rs:20:16
+   |
+LL |         () if (let 0 = 1) => {}
+   |                ^^^^^^^^^
+
+error: `let` expressions are not supported here
+  --> $DIR/parens.rs:23:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+note: `let`s wrapped in parentheses are not supported in a context with let chains
+  --> $DIR/parens.rs:23:18
+   |
+LL |         () if (((let 0 = 1))) => {}
+   |                  ^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs
new file mode 100644
index 00000000000..d91b3a358da
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs
@@ -0,0 +1,18 @@
+// Macros can be used for (parts of) the pattern and expression in an if let guard
+// check-pass
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+macro_rules! m {
+    (pattern $i:ident) => { Some($i) };
+    (expression $e:expr) => { $e };
+}
+
+fn main() {
+    match () {
+        () if let m!(pattern x) = m!(expression Some(4)) => {}
+        () if let [m!(pattern y)] = [Some(8 + m!(expression 4))] => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
new file mode 100644
index 00000000000..dba292ef9e2
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
@@ -0,0 +1,23 @@
+// Check shadowing in if let guards works as expected.
+// check-pass
+
+#![feature(if_let_guard)]
+#![feature(let_chains)]
+
+fn main() {
+    let x: Option<Option<i32>> = Some(Some(6));
+    match x {
+        Some(x) if let Some(x) = x => {
+            let _: i32 = x;
+        }
+        _ => {}
+    }
+
+    let y: Option<Option<Option<i32>>> = Some(Some(Some(-24)));
+    match y {
+        Some(y) if let Some(y) = y && let Some(y) = y => {
+            let _: i32 = y;
+        }
+        _ => {}
+    }
+}