diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /tests/ui/rfcs/rfc-2294-if-let-guard | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/rfcs/rfc-2294-if-let-guard')
22 files changed, 608 insertions, 259 deletions
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/const-expr.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/const-expr.rs new file mode 100644 index 000000000..5c42c0d8b --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/const-expr.rs @@ -0,0 +1,26 @@ +// Ensure if let guards can be used in constant expressions. +// build-pass + +#![feature(if_let_guard)] + +const fn match_if_let(x: Option<i32>, y: Option<i32>) -> i32 { + match x { + None if let Some(a @ 5) = y => a, + Some(z) if let (Some(_), 12) = (y, z) => 2, + _ => 3, + } +} + +const ASSERTS: usize = { + assert!(match_if_let(None, Some(5)) == 5); + assert!(match_if_let(Some(12), Some(3)) == 2); + assert!(match_if_let(None, Some(4)) == 3); + assert!(match_if_let(Some(11), Some(3)) == 3); + assert!(match_if_let(Some(12), None) == 3); + assert!(match_if_let(None, None) == 3); + 0 +}; + +fn main() { + let _: [(); ASSERTS]; +} 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 000000000..b4eb54139 --- /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 000000000..ddd08854f --- /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/feature-gate.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs index 3beb20f0a..b8c0eb3e6 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs @@ -8,14 +8,10 @@ fn _if_let_guard() { //~^ ERROR `if let` guards are experimental () if (let 0 = 1) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if (((let 0 = 1))) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if true && let 0 = 1 => {} //~^ ERROR `if let` guards are experimental @@ -26,36 +22,22 @@ fn _if_let_guard() { //~| ERROR `let` expressions in this position are unstable () if (let 0 = 1) && true => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if true && (let 0 = 1) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement () if (let 0 = 1) && (let 0 = 1) => {} - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable + //~^ ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} //~^ ERROR `if let` guards are experimental //~| ERROR `let` expressions in this position are unstable //~| ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable - //~| ERROR `let` expressions in this position are unstable //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here - //~| ERROR `let` expressions are not supported here () if let Range { start: _, end: _ } = (true..true) && false => {} @@ -76,13 +58,9 @@ fn _macros() { } } use_expr!((let 0 = 1 && 0 == 0)); - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement use_expr!((let 0 = 1)); - //~^ ERROR `let` expressions in this position are unstable - //~| ERROR expected expression, found `let` statement - //~| ERROR `let` expressions are not supported here + //~^ ERROR expected expression, found `let` statement match () { #[cfg(FALSE)] () if let 0 = 1 => {} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr index dc182ce46..62534b555 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr @@ -2,87 +2,6 @@ error: expected expression, found `let` statement --> $DIR/feature-gate.rs:10:16 | LL | () if (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:15:18 - | -LL | () if (((let 0 = 1))) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:28:16 - | -LL | () if (let 0 = 1) && true => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:33:24 - | -LL | () if true && (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:38:16 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:38:31 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:46:42 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:46:55 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:46:68 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:78:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^ - -error: expected expression, found `let` statement - --> $DIR/feature-gate.rs:82:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^ - -error: no rules expected the token `let` - --> $DIR/feature-gate.rs:92:15 - | -LL | macro_rules! use_expr { - | --------------------- when calling this macro -... -LL | use_expr!(let 0 = 1); - | ^^^ no rules expected this token in macro call - | -note: while trying to match meta-variable `$e:expr` - --> $DIR/feature-gate.rs:71:10 - | -LL | ($e:expr) => { - | ^^^^^^^ - -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:10:16 - | -LL | () if (let 0 = 1) => {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions @@ -92,135 +11,140 @@ note: `let`s wrapped in parentheses are not supported in a context with let chai LL | () if (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:15:18 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:13: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/feature-gate.rs:15:18 + --> $DIR/feature-gate.rs:13:18 | LL | () if (((let 0 = 1))) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:28:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:24:16 | LL | () if (let 0 = 1) && true => {} | ^^^^^^^^^ | = 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/feature-gate.rs:28:16 + --> $DIR/feature-gate.rs:24:16 | LL | () if (let 0 = 1) && true => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:33:24 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:27:24 | LL | () if true && (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/feature-gate.rs:33:24 + --> $DIR/feature-gate.rs:27:24 | LL | () if true && (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:38:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:30:16 | LL | () if (let 0 = 1) && (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/feature-gate.rs:38:16 + --> $DIR/feature-gate.rs:30:16 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:38:31 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:30:31 | LL | () if (let 0 = 1) && (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/feature-gate.rs:38:31 + --> $DIR/feature-gate.rs:30:31 | LL | () if (let 0 = 1) && (let 0 = 1) => {} | ^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:46:42 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ | = 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/feature-gate.rs:46:42 + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:46:55 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:34:55 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ | = 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/feature-gate.rs:46:42 + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:46:68 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:34:68 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ | = 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/feature-gate.rs:46:42 + --> $DIR/feature-gate.rs:34:42 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:78:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:60:16 | LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^ + | ^^^ | = 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/feature-gate.rs:78:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^^^^^^^^^^^ -error: `let` expressions are not supported here - --> $DIR/feature-gate.rs:82:16 +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:62:16 | LL | use_expr!((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/feature-gate.rs:82:16 + +error: no rules expected the token `let` + --> $DIR/feature-gate.rs:70:15 | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ +LL | macro_rules! use_expr { + | --------------------- when calling this macro +... +LL | use_expr!(let 0 = 1); + | ^^^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$e:expr` + --> $DIR/feature-gate.rs:53:10 + | +LL | ($e:expr) => { + | ^^^^^^^ error[E0658]: `if let` guards are experimental --> $DIR/feature-gate.rs:7:12 @@ -233,7 +157,7 @@ LL | () if let 0 = 1 => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:20:12 + --> $DIR/feature-gate.rs:16:12 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^^^^^^^^^^^^ @@ -243,7 +167,7 @@ LL | () if true && let 0 = 1 => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:24:12 + --> $DIR/feature-gate.rs:20:12 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +177,7 @@ LL | () if let 0 = 1 && true => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:46:12 + --> $DIR/feature-gate.rs:34:12 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +187,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:61:12 + --> $DIR/feature-gate.rs:43:12 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -273,7 +197,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:88:12 + --> $DIR/feature-gate.rs:66:12 | LL | () if let 0 = 1 => {} | ^^^^^^^^^^^^ @@ -283,25 +207,7 @@ LL | () if let 0 = 1 => {} = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:10:16 - | -LL | () if (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:15:18 - | -LL | () if (((let 0 = 1))) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:20:23 + --> $DIR/feature-gate.rs:16:23 | LL | () if true && let 0 = 1 => {} | ^^^^^^^^^ @@ -310,7 +216,7 @@ LL | () if true && let 0 = 1 => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:24:15 + --> $DIR/feature-gate.rs:20:15 | LL | () if let 0 = 1 && true => {} | ^^^^^^^^^ @@ -319,43 +225,7 @@ LL | () if let 0 = 1 && true => {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:28:16 - | -LL | () if (let 0 = 1) && true => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:33:24 - | -LL | () if true && (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:38:16 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:38:31 - | -LL | () if (let 0 = 1) && (let 0 = 1) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:15 + --> $DIR/feature-gate.rs:34:15 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -364,7 +234,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:28 + --> $DIR/feature-gate.rs:34:28 | LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} | ^^^^^^^^^ @@ -373,34 +243,7 @@ LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:42 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:55 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:46:68 - | -LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:61:15 + --> $DIR/feature-gate.rs:43:15 | LL | () if let Range { start: _, end: _ } = (true..true) && false => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -408,24 +251,6 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:78:16 - | -LL | use_expr!((let 0 = 1 && 0 == 0)); - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:82:16 - | -LL | use_expr!((let 0 = 1)); - | ^^^^^^^^^ - | - = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information - = help: add `#![feature(let_chains)]` to the crate attributes to enable - -error: aborting due to 45 previous errors +error: aborting due to 23 previous errors For more information about this error, try `rustc --explain E0658`. 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 000000000..792225e65 --- /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 000000000..b8e1bb324 --- /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 000000000..aa2154e3e --- /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 000000000..9353c9d92 --- /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 000000000..009d15338 --- /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 000000000..4efa02f57 --- /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 000000000..07e7c6a2c --- /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 000000000..423a2cd53 --- /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 000000000..00c1c303d --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr @@ -0,0 +1,14 @@ +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: only supported directly in conditions of `if` and `while` expressions + = 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/move-guard-if-let-chain.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs new file mode 100644 index 000000000..5c333cd77 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs @@ -0,0 +1,97 @@ +#![feature(if_let_guard)] +#![feature(let_chains)] +#![allow(irrefutable_let_patterns)] + +fn same_pattern(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x && c => (), + (1, 2) if let z = x => (), //~ ERROR use of moved value: `x` + _ => (), + } +} + +fn same_pattern_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if c && let y = x => (), + (1, 2) if let z = x => (), + _ => (), + } +} + +fn different_patterns(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) if let y = x && c => (), + (_, 2) if let z = x => (), //~ ERROR use of moved value: `x` + _ => (), + } +} + +fn different_patterns_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) if c && let y = x => (), + (_, 2) if let z = x => (), + _ => (), + } +} + +fn or_pattern(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) | (_, 2) if let y = x && c => (), //~ ERROR use of moved value: `x` + _ => (), + } +} + +fn or_pattern_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) | (_, 2) if c && let y = x => (), + _ => (), + } +} + +fn use_in_arm(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x && c => false, + _ => { *x == 1 }, //~ ERROR use of moved value: `x` + }; +} + +fn use_in_arm_ok(c: bool) { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if c && let y = x => false, + _ => { *x == 1 }, + }; +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr new file mode 100644 index 000000000..d27fde582 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr @@ -0,0 +1,67 @@ +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:12:27 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, 2) if let y = x && c => (), + | - value moved here +LL | (1, 2) if let z = x => (), + | ^ value used here after move + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, 2) if let ref y = x && c => (), + | +++ + +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:36:27 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, _) if let y = x && c => (), + | - value moved here +LL | (_, 2) if let z = x => (), + | ^ value used here after move + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, _) if let ref y = x && c => (), + | +++ + +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:59:36 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, _) | (_, 2) if let y = x && c => (), + | - ^ value used here after move + | | + | value moved here + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, _) | (_, 2) if let ref y = x && c => (), + | +++ + +error[E0382]: use of moved value: `x` + --> $DIR/move-guard-if-let-chain.rs:82:16 + | +LL | let x: Box<_> = Box::new(1); + | - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait +... +LL | (1, 2) if let y = x && c => false, + | - value moved here +LL | _ => { *x == 1 }, + | ^^ value used here after move + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | (1, 2) if let ref y = x && c => false, + | +++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs new file mode 100644 index 000000000..071b86e2e --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs @@ -0,0 +1,41 @@ +// Check that borrowck knows that moves in the pattern for if-let guards +// only happen when the pattern is matched. + +// build-pass + +#![feature(if_let_guard)] +#![allow(irrefutable_let_patterns)] + +fn same_pattern() { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x => (), + (1, 2) if let z = x => (), + _ => (), + } +} + +fn or_pattern() { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, _) | (_, 2) if let y = x => (), + _ => (), + } +} + +fn main() { + let x: Box<_> = Box::new(1); + + let v = (1, 2); + + match v { + (1, 2) if let y = x => false, + _ => { *x == 1 }, + }; +} 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 000000000..f12824db9 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs @@ -0,0 +1,25 @@ +// 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 + () if (((let 0 = 1))) => {} + //~^ ERROR expected expression, found `let` statement + } +} 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 000000000..0c16d9c54 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr @@ -0,0 +1,54 @@ +error: expected expression, found `let` statement + --> $DIR/parens.rs:10: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:10:16 + | +LL | () if (let 0 = 1) => {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $DIR/parens.rs:12: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:12:18 + | +LL | () if (((let 0 = 1))) => {} + | ^^^^^^^^^ + +error: expected expression, found `let` statement + --> $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: expected expression, found `let` statement + --> $DIR/parens.rs:22: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:22:18 + | +LL | () if (((let 0 = 1))) => {} + | ^^^^^^^^^ + +error: aborting due to 4 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 000000000..d91b3a358 --- /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 000000000..dba292ef9 --- /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; + } + _ => {} + } +} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs new file mode 100644 index 000000000..ef7a772e6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(if_let_guard)] + +struct S; + +fn get<T>() -> Option<T> { + None +} + +fn main() { + match get() { + x if let Some(S) = x => {} + _ => {} + } +} |