about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCameron Steffen <cam.steffen94@gmail.com>2021-08-01 19:18:50 -0500
committerCameron Steffen <cam.steffen94@gmail.com>2021-08-30 20:18:43 -0500
commit5b95df4bdc330f34213812ad65cae86ced90d80c (patch)
tree791b8ecd4a8e627a0d334319ebdb1c5a6044d161
parentdf9a2e0687895731e12f4a2651e8d70acd08872d (diff)
downloadrust-5b95df4bdc330f34213812ad65cae86ced90d80c.tar.gz
rust-5b95df4bdc330f34213812ad65cae86ced90d80c.zip
Add let-else tests
-rw-r--r--src/test/ui/let-else/let-else-bool-binop-init.fixed8
-rw-r--r--src/test/ui/let-else/let-else-bool-binop-init.rs8
-rw-r--r--src/test/ui/let-else/let-else-bool-binop-init.stderr24
-rw-r--r--src/test/ui/let-else/let-else-brace-before-else.fixed26
-rw-r--r--src/test/ui/let-else/let-else-brace-before-else.rs26
-rw-r--r--src/test/ui/let-else/let-else-brace-before-else.stderr46
-rw-r--r--src/test/ui/let-else/let-else-check.rs14
-rw-r--r--src/test/ui/let-else/let-else-check.stderr14
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.rs7
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.stderr12
-rw-r--r--src/test/ui/let-else/let-else-missing-semicolon.rs11
-rw-r--r--src/test/ui/let-else/let-else-missing-semicolon.stderr18
-rw-r--r--src/test/ui/let-else/let-else-non-diverging.rs13
-rw-r--r--src/test/ui/let-else/let-else-non-diverging.stderr44
-rw-r--r--src/test/ui/let-else/let-else-run-pass.rs35
-rw-r--r--src/test/ui/let-else/let-else-scope.rs7
-rw-r--r--src/test/ui/let-else/let-else-scope.stderr9
17 files changed, 322 insertions, 0 deletions
diff --git a/src/test/ui/let-else/let-else-bool-binop-init.fixed b/src/test/ui/let-else/let-else-bool-binop-init.fixed
new file mode 100644
index 00000000000..e47f7f23d7e
--- /dev/null
+++ b/src/test/ui/let-else/let-else-bool-binop-init.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+#![feature(let_else)]
+
+fn main() {
+    let true = (true && false) else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else`
+    let true = (true || false) else { return }; //~ ERROR a `||` expression cannot be directly assigned in `let...else`
+}
diff --git a/src/test/ui/let-else/let-else-bool-binop-init.rs b/src/test/ui/let-else/let-else-bool-binop-init.rs
new file mode 100644
index 00000000000..e443fb0d6a3
--- /dev/null
+++ b/src/test/ui/let-else/let-else-bool-binop-init.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+#![feature(let_else)]
+
+fn main() {
+    let true = true && false else { return }; //~ ERROR a `&&` expression cannot be directly assigned in `let...else`
+    let true = true || false else { return }; //~ ERROR a `||` expression cannot be directly assigned in `let...else`
+}
diff --git a/src/test/ui/let-else/let-else-bool-binop-init.stderr b/src/test/ui/let-else/let-else-bool-binop-init.stderr
new file mode 100644
index 00000000000..6551e24cc83
--- /dev/null
+++ b/src/test/ui/let-else/let-else-bool-binop-init.stderr
@@ -0,0 +1,24 @@
+error: a `&&` expression cannot be directly assigned in `let...else`
+  --> $DIR/let-else-bool-binop-init.rs:6:16
+   |
+LL |     let true = true && false else { return };
+   |                ^^^^^^^^^^^^^
+   |
+help: wrap the expression in parenthesis
+   |
+LL |     let true = (true && false) else { return };
+   |                +             +
+
+error: a `||` expression cannot be directly assigned in `let...else`
+  --> $DIR/let-else-bool-binop-init.rs:7:16
+   |
+LL |     let true = true || false else { return };
+   |                ^^^^^^^^^^^^^
+   |
+help: wrap the expression in parenthesis
+   |
+LL |     let true = (true || false) else { return };
+   |                +             +
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/let-else/let-else-brace-before-else.fixed b/src/test/ui/let-else/let-else-brace-before-else.fixed
new file mode 100644
index 00000000000..fb4fd77791e
--- /dev/null
+++ b/src/test/ui/let-else/let-else-brace-before-else.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+
+#![feature(let_else)]
+
+fn main() {
+    let Some(1) = ({ Some(1) }) else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+    let Some(1) = (loop { break Some(1) }) else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+    let 2 = 1 + (match 1 { n => n }) else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+    let Some(1) = (unsafe { unsafe_fn() }) else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+unsafe fn unsafe_fn<T>() -> T {
+    unimplemented!();
+}
diff --git a/src/test/ui/let-else/let-else-brace-before-else.rs b/src/test/ui/let-else/let-else-brace-before-else.rs
new file mode 100644
index 00000000000..c4c5a1ca28b
--- /dev/null
+++ b/src/test/ui/let-else/let-else-brace-before-else.rs
@@ -0,0 +1,26 @@
+// run-rustfix
+
+#![feature(let_else)]
+
+fn main() {
+    let Some(1) = { Some(1) } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+    let Some(1) = loop { break Some(1) } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+    let 2 = 1 + match 1 { n => n } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+    let Some(1) = unsafe { unsafe_fn() } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+unsafe fn unsafe_fn<T>() -> T {
+    unimplemented!();
+}
diff --git a/src/test/ui/let-else/let-else-brace-before-else.stderr b/src/test/ui/let-else/let-else-brace-before-else.stderr
new file mode 100644
index 00000000000..eac029c848b
--- /dev/null
+++ b/src/test/ui/let-else/let-else-brace-before-else.stderr
@@ -0,0 +1,46 @@
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/let-else-brace-before-else.rs:6:29
+   |
+LL |     let Some(1) = { Some(1) } else {
+   |                             ^
+   |
+help: try wrapping the expression in parenthesis
+   |
+LL |     let Some(1) = ({ Some(1) }) else {
+   |                   +           +
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/let-else-brace-before-else.rs:10:40
+   |
+LL |     let Some(1) = loop { break Some(1) } else {
+   |                                        ^
+   |
+help: try wrapping the expression in parenthesis
+   |
+LL |     let Some(1) = (loop { break Some(1) }) else {
+   |                   +                      +
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/let-else-brace-before-else.rs:14:34
+   |
+LL |     let 2 = 1 + match 1 { n => n } else {
+   |                                  ^
+   |
+help: try wrapping the expression in parenthesis
+   |
+LL |     let 2 = 1 + (match 1 { n => n }) else {
+   |                 +                  +
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/let-else-brace-before-else.rs:18:40
+   |
+LL |     let Some(1) = unsafe { unsafe_fn() } else {
+   |                                        ^
+   |
+help: try wrapping the expression in parenthesis
+   |
+LL |     let Some(1) = (unsafe { unsafe_fn() }) else {
+   |                   +                      +
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/let-else/let-else-check.rs b/src/test/ui/let-else/let-else-check.rs
new file mode 100644
index 00000000000..ab763447ef7
--- /dev/null
+++ b/src/test/ui/let-else/let-else-check.rs
@@ -0,0 +1,14 @@
+#![feature(let_else)]
+
+#![deny(unused_variables)]
+
+fn main() {
+    // type annotation, attributes
+    #[allow(unused_variables)]
+    let Some(_): Option<u32> = Some(Default::default()) else {
+        let x = 1; // OK
+        return;
+    };
+
+    let x = 1; //~ ERROR unused variable: `x`
+}
diff --git a/src/test/ui/let-else/let-else-check.stderr b/src/test/ui/let-else/let-else-check.stderr
new file mode 100644
index 00000000000..50e54d320b0
--- /dev/null
+++ b/src/test/ui/let-else/let-else-check.stderr
@@ -0,0 +1,14 @@
+error: unused variable: `x`
+  --> $DIR/let-else-check.rs:13:9
+   |
+LL |     let x = 1;
+   |         ^ help: if this is intentional, prefix it with an underscore: `_x`
+   |
+note: the lint level is defined here
+  --> $DIR/let-else-check.rs:3:9
+   |
+LL | #![deny(unused_variables)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/let-else/let-else-irrefutable.rs b/src/test/ui/let-else/let-else-irrefutable.rs
new file mode 100644
index 00000000000..b1e09a1248f
--- /dev/null
+++ b/src/test/ui/let-else/let-else-irrefutable.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+#![feature(let_else)]
+
+fn main() {
+    let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
+}
diff --git a/src/test/ui/let-else/let-else-irrefutable.stderr b/src/test/ui/let-else/let-else-irrefutable.stderr
new file mode 100644
index 00000000000..e030c50d45d
--- /dev/null
+++ b/src/test/ui/let-else/let-else-irrefutable.stderr
@@ -0,0 +1,12 @@
+warning: irrefutable `let...else` pattern
+  --> $DIR/let-else-irrefutable.rs:6:5
+   |
+LL |     let x = 1 else { return };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/let-else/let-else-missing-semicolon.rs b/src/test/ui/let-else/let-else-missing-semicolon.rs
new file mode 100644
index 00000000000..ed9d79f1ebd
--- /dev/null
+++ b/src/test/ui/let-else/let-else-missing-semicolon.rs
@@ -0,0 +1,11 @@
+#![feature(let_else)]
+
+fn main() {
+    let Some(x) = Some(1) else {
+        return;
+    } //~ ERROR expected `;`, found keyword `let`
+    let _ = "";
+    let Some(x) = Some(1) else {
+        panic!();
+    } //~ ERROR expected `;`, found `}`
+}
diff --git a/src/test/ui/let-else/let-else-missing-semicolon.stderr b/src/test/ui/let-else/let-else-missing-semicolon.stderr
new file mode 100644
index 00000000000..1818a0b1263
--- /dev/null
+++ b/src/test/ui/let-else/let-else-missing-semicolon.stderr
@@ -0,0 +1,18 @@
+error: expected `;`, found keyword `let`
+  --> $DIR/let-else-missing-semicolon.rs:6:6
+   |
+LL |     }
+   |      ^ help: add `;` here
+LL |     let _ = "";
+   |     --- unexpected token
+
+error: expected `;`, found `}`
+  --> $DIR/let-else-missing-semicolon.rs:10:6
+   |
+LL |     }
+   |      ^ help: add `;` here
+LL | }
+   | - unexpected token
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/let-else/let-else-non-diverging.rs b/src/test/ui/let-else/let-else-non-diverging.rs
new file mode 100644
index 00000000000..a1cee335aee
--- /dev/null
+++ b/src/test/ui/let-else/let-else-non-diverging.rs
@@ -0,0 +1,13 @@
+#![feature(let_else)]
+
+fn main() {
+    let Some(x) = Some(1) else { //~ ERROR does not diverge
+        Some(2)
+    };
+    let Some(x) = Some(1) else { //~ ERROR does not diverge
+        if 1 == 1 {
+            panic!();
+        }
+    };
+    let Some(x) = Some(1) else { Some(2) }; //~ ERROR does not diverge
+}
diff --git a/src/test/ui/let-else/let-else-non-diverging.stderr b/src/test/ui/let-else/let-else-non-diverging.stderr
new file mode 100644
index 00000000000..fd5a18ce7ea
--- /dev/null
+++ b/src/test/ui/let-else/let-else-non-diverging.stderr
@@ -0,0 +1,44 @@
+error[E0308]: `else` clause of `let...else` does not diverge
+  --> $DIR/let-else-non-diverging.rs:12:32
+   |
+LL |     let Some(x) = Some(1) else { Some(2) };
+   |                                ^^^^^^^^^^^ expected `!`, found enum `Option`
+   |
+   = note: expected type `!`
+              found type `Option<{integer}>`
+   = help: try adding a diverging expression, such as `return` or `panic!(..)`
+   = help: ...or use `match` instead of `let...else`
+
+error[E0308]: `else` clause of `let...else` does not diverge
+  --> $DIR/let-else-non-diverging.rs:7:32
+   |
+LL |       let Some(x) = Some(1) else {
+   |  ________________________________^
+LL | |         if 1 == 1 {
+LL | |             panic!();
+LL | |         }
+LL | |     };
+   | |_____^ expected `!`, found `()`
+   |
+   = note: expected type `!`
+              found type `()`
+   = help: try adding a diverging expression, such as `return` or `panic!(..)`
+   = help: ...or use `match` instead of `let...else`
+
+error[E0308]: `else` clause of `let...else` does not diverge
+  --> $DIR/let-else-non-diverging.rs:4:32
+   |
+LL |       let Some(x) = Some(1) else {
+   |  ________________________________^
+LL | |         Some(2)
+LL | |     };
+   | |_____^ expected `!`, found enum `Option`
+   |
+   = note: expected type `!`
+              found type `Option<{integer}>`
+   = help: try adding a diverging expression, such as `return` or `panic!(..)`
+   = help: ...or use `match` instead of `let...else`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/let-else/let-else-run-pass.rs b/src/test/ui/let-else/let-else-run-pass.rs
new file mode 100644
index 00000000000..5d96623236d
--- /dev/null
+++ b/src/test/ui/let-else/let-else-run-pass.rs
@@ -0,0 +1,35 @@
+// run-pass
+
+#![feature(let_else)]
+
+fn main() {
+    #[allow(dead_code)]
+    enum MyEnum {
+        A(String),
+        B { f: String },
+        C,
+    }
+    // ref binding to non-copy value and or-pattern
+    let (MyEnum::A(ref x) | MyEnum::B { f: ref x }) = (MyEnum::B { f: String::new() }) else {
+        panic!();
+    };
+    assert_eq!(x, "");
+
+    // nested let-else
+    let mut x = 1;
+    loop {
+        let 4 = x else {
+            let 3 = x else {
+                x += 1;
+                continue;
+            };
+            break;
+        };
+        panic!();
+    }
+    assert_eq!(x, 3);
+
+    // else return
+    let Some(1) = Some(2) else { return };
+    panic!();
+}
diff --git a/src/test/ui/let-else/let-else-scope.rs b/src/test/ui/let-else/let-else-scope.rs
new file mode 100644
index 00000000000..f17682db4c3
--- /dev/null
+++ b/src/test/ui/let-else/let-else-scope.rs
@@ -0,0 +1,7 @@
+#![feature(let_else)]
+
+fn main() {
+    let Some(x) = Some(2) else {
+        panic!("{}", x); //~ ERROR cannot find value `x` in this scope
+    };
+}
diff --git a/src/test/ui/let-else/let-else-scope.stderr b/src/test/ui/let-else/let-else-scope.stderr
new file mode 100644
index 00000000000..4b3936eac4b
--- /dev/null
+++ b/src/test/ui/let-else/let-else-scope.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/let-else-scope.rs:5:22
+   |
+LL |         panic!("{}", x);
+   |                      ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.