Skip to content

Commit 0c1f9c8

Browse files
authored
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
2 parents c996197 + d3c3c17 commit 0c1f9c8

15 files changed

+298
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(if_let_guard)]
2+
#![allow(irrefutable_let_patterns)]
3+
4+
fn match_option(x: Option<u32>) {
5+
match x {
6+
//~^ ERROR non-exhaustive patterns: `None` not covered
7+
Some(_) => {}
8+
None if let y = x => {}
9+
}
10+
}
11+
12+
fn main() {
13+
let x = ();
14+
match x {
15+
//~^ ERROR non-exhaustive patterns: `()` not covered
16+
y if let z = y => {}
17+
}
18+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0004]: non-exhaustive patterns: `None` not covered
2+
--> $DIR/exhaustive.rs:5:11
3+
|
4+
LL | match x {
5+
| ^ pattern `None` not covered
6+
|
7+
note: `Option<u32>` defined here
8+
--> $SRC_DIR/core/src/option.rs:LL:COL
9+
::: $SRC_DIR/core/src/option.rs:LL:COL
10+
|
11+
= note: not covered
12+
= note: the matched value is of type `Option<u32>`
13+
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
14+
|
15+
LL ~ None if let y = x => {},
16+
LL + None => todo!()
17+
|
18+
19+
error[E0004]: non-exhaustive patterns: `()` not covered
20+
--> $DIR/exhaustive.rs:14:11
21+
|
22+
LL | match x {
23+
| ^ pattern `()` not covered
24+
|
25+
= note: the matched value is of type `()`
26+
= note: match arms with guards don't count towards exhaustivity
27+
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
28+
|
29+
LL ~ y if let z = y => {},
30+
LL + () => todo!()
31+
|
32+
33+
error: aborting due to 2 previous errors
34+
35+
For more information about this error, try `rustc --explain E0004`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// References to by-move bindings in an if-let guard *cannot* be used after the guard.
2+
3+
#![feature(if_let_guard)]
4+
5+
fn main() {
6+
let x: Option<Option<String>> = Some(Some(String::new()));
7+
match x {
8+
Some(mut y) if let Some(ref z) = y => {
9+
//~^ ERROR: cannot move out of `x.0` because it is borrowed
10+
let _z: &String = z;
11+
let _y: Option<String> = y;
12+
}
13+
_ => {}
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0505]: cannot move out of `x.0` because it is borrowed
2+
--> $DIR/guard-lifetime-1.rs:8:14
3+
|
4+
LL | Some(mut y) if let Some(ref z) = y => {
5+
| ^^^^^
6+
| |
7+
| move out of `x.0` occurs here
8+
| borrow of `x.0` occurs here
9+
LL |
10+
LL | let _z: &String = z;
11+
| - borrow later used here
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0505`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// References to by-mutable-ref bindings in an if-let guard *can* be used after the guard.
2+
3+
// check-pass
4+
5+
#![feature(if_let_guard)]
6+
7+
fn main() {
8+
let mut x: Option<Option<String>> = Some(Some(String::new()));
9+
match x {
10+
Some(ref mut y) if let Some(ref z) = *y => {
11+
let _z: &String = z;
12+
let _y: &mut Option<String> = y;
13+
}
14+
_ => {}
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Check mutable bindings cannot be mutated by an if-let guard.
2+
3+
#![feature(if_let_guard)]
4+
5+
fn main() {
6+
let x: Option<Option<i32>> = Some(Some(6));
7+
match x {
8+
Some(mut y) if let Some(ref mut z) = y => {
9+
//~^ ERROR cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
10+
let _: &mut i32 = z;
11+
}
12+
_ => {}
13+
}
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0596]: cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
2+
--> $DIR/guard-mutability-1.rs:8:33
3+
|
4+
LL | Some(mut y) if let Some(ref mut z) = y => {
5+
| ^^^^^^^^^ cannot borrow as mutable
6+
|
7+
= note: variables bound in patterns are immutable until the end of the pattern guard
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0596`.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Check mutable reference bindings cannot be mutated by an if-let guard.
2+
3+
#![feature(if_let_guard)]
4+
5+
fn main() {
6+
let mut x: Option<Option<i32>> = Some(Some(6));
7+
match x {
8+
Some(ref mut y) if let Some(ref mut z) = *y => {
9+
//~^ ERROR cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
10+
let _: &mut i32 = z;
11+
}
12+
_ => {}
13+
}
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0596]: cannot borrow `y.0` as mutable, as it is immutable for the pattern guard
2+
--> $DIR/guard-mutability-2.rs:8:37
3+
|
4+
LL | Some(ref mut y) if let Some(ref mut z) = *y => {
5+
| ^^^^^^^^^ cannot borrow as mutable
6+
|
7+
= note: variables bound in patterns are immutable until the end of the pattern guard
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0596`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Expression macros can't expand to a let match guard.
2+
3+
#![feature(if_let_guard)]
4+
#![feature(let_chains)]
5+
6+
macro_rules! m {
7+
($e:expr) => { let Some(x) = $e }
8+
//~^ ERROR expected expression, found `let` statement
9+
}
10+
11+
fn main() {
12+
match () {
13+
() if m!(Some(5)) => {}
14+
_ => {}
15+
}
16+
}

0 commit comments

Comments
 (0)