Skip to content

Commit

Permalink
Rollup merge of #115172 - matthewjasper:if-let-guard-tests, r=cjgillot
Browse files Browse the repository at this point in the history
Add more tests for if_let_guard

Adds tests for borrow checking, name shadowing and interaction with macros.

cc #51114
  • Loading branch information
weihanglo authored Aug 24, 2023
2 parents c996197 + d3c3c17 commit 0c1f9c8
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 0 deletions.
18 changes: 18 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-1.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-lifetime-2.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.rs
Original file line number Diff line number Diff line change
@@ -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;
}
_ => {}
}
}
11 changes: 11 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-1.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs
Original file line number Diff line number Diff line change
@@ -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;
}
_ => {}
}
}
11 changes: 11 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 13 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 27 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 52 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
Original file line number Diff line number Diff line change
@@ -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

18 changes: 18 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs
Original file line number Diff line number Diff line change
@@ -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;
}
_ => {}
}
}

0 comments on commit 0c1f9c8

Please sign in to comment.