mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Rollup merge of #115172 - matthewjasper:if-let-guard-tests, r=cjgillot
Add more tests for if_let_guard Adds tests for borrow checking, name shadowing and interaction with macros. cc #51114
This commit is contained in:
commit
0c1f9c8c4f
18
tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
Normal file
18
tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
Normal file
@ -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 => {}
|
||||
}
|
||||
}
|
35
tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
Normal file
35
tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
Normal file
@ -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`.
|
15
tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
Normal file
15
tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
Normal file
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
15
tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
Normal file
15
tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
Normal file
@ -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`.
|
16
tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
Normal file
16
tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
Normal file
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
14
tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
Normal file
14
tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
Normal file
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -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`.
|
14
tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
Normal file
14
tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
Normal file
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -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`.
|
16
tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
Normal file
16
tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
Normal file
@ -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)) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
13
tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
Normal file
13
tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
Normal file
@ -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
|
||||
|
27
tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
Normal file
27
tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
Normal file
@ -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
|
||||
}
|
||||
}
|
52
tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
Normal file
52
tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
Normal file
@ -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
|
||||
|
@ -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))] => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
23
tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
Normal file
23
tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
Normal file
@ -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;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user