Skip to content

Test the borrowck behavior of if-let guards #106005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/test/ui/borrowck/borrowck-drop-from-guard.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![feature(if_let_guard)]

fn foo(_:String) {}

fn main()
Expand All @@ -8,4 +10,11 @@ fn main()
Some(_) => {}
None => { foo(my_str); } //~ ERROR [E0382]
}

let my_str = "hello".to_owned();
match Some(42) {
Some(_) if let Some(()) = { drop(my_str); None } => {}
Some(_) => {}
None => { foo(my_str); } //~ ERROR [E0382]
}
}
21 changes: 19 additions & 2 deletions src/test/ui/borrowck/borrowck-drop-from-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `my_str`
--> $DIR/borrowck-drop-from-guard.rs:9:23
--> $DIR/borrowck-drop-from-guard.rs:11:23
|
LL | let my_str = "hello".to_owned();
| ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait
Expand All @@ -15,6 +15,23 @@ help: consider cloning the value if the performance cost is acceptable
LL | Some(_) if { drop(my_str.clone()); false } => {}
| ++++++++

error: aborting due to previous error
error[E0382]: use of moved value: `my_str`
--> $DIR/borrowck-drop-from-guard.rs:18:23
|
LL | let my_str = "hello".to_owned();
| ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait
LL | match Some(42) {
LL | Some(_) if let Some(()) = { drop(my_str); None } => {}
| ------ value moved here
LL | Some(_) => {}
LL | None => { foo(my_str); }
| ^^^^^^ value used here after move
|
help: consider cloning the value if the performance cost is acceptable
|
LL | Some(_) if let Some(()) = { drop(my_str.clone()); None } => {}
| ++++++++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0382`.
19 changes: 16 additions & 3 deletions src/test/ui/borrowck/borrowck-mutate-in-guard.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#![feature(if_let_guard)]

enum Enum<'a> {
A(&'a isize),
B(bool),
}

fn foo() -> isize {
fn if_guard() -> isize {
let mut n = 42;
let mut x = Enum::A(&mut n);
match x {
Expand All @@ -16,6 +18,17 @@ fn foo() -> isize {
}
}

fn main() {
foo();
fn if_let_guard() -> isize {
let mut n = 42;
let mut x = Enum::A(&mut n);
match x {
Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1,
//~^ ERROR cannot assign `x` in match guard
Enum::A(_) if let Some(()) = { let y = &mut x; *y = Enum::B(false); None } => 1,
//~^ ERROR cannot mutably borrow `x` in match guard
Enum::A(p) => *p,
Enum::B(_) => 2,
}
}

fn main() {}
23 changes: 20 additions & 3 deletions src/test/ui/borrowck/borrowck-mutate-in-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
error[E0510]: cannot assign `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:10:25
--> $DIR/borrowck-mutate-in-guard.rs:12:25
|
LL | match x {
| - value is immutable in match guard
LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
| ^^^^^^^^^^^^^^^^^^ cannot assign

error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:12:33
--> $DIR/borrowck-mutate-in-guard.rs:14:33
|
LL | match x {
| - value is immutable in match guard
...
LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
| ^^^^^^ cannot mutably borrow

error: aborting due to 2 previous errors
error[E0510]: cannot assign `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:25:40
|
LL | match x {
| - value is immutable in match guard
LL | Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1,
| ^^^^^^^^^^^^^^^^^^ cannot assign

error[E0510]: cannot mutably borrow `x` in match guard
--> $DIR/borrowck-mutate-in-guard.rs:27:48
|
LL | match x {
| - value is immutable in match guard
...
LL | Enum::A(_) if let Some(()) = { let y = &mut x; *y = Enum::B(false); None } => 1,
| ^^^^^^ cannot mutably borrow

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0510`.
9 changes: 8 additions & 1 deletion src/test/ui/borrowck/issue-31287-drop-in-guard.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#![feature(if_let_guard)]

fn main() {
let a = Some("...".to_owned());
let b = match a {
Some(_) if { drop(a); false } => None,
x => x, //~ ERROR use of moved value: `a`
};
println!("{:?}", b);

let a = Some("...".to_owned());
let b = match a {
Some(_) if let Some(()) = { drop(a); None } => None,
x => x, //~ ERROR use of moved value: `a`
};
}
20 changes: 18 additions & 2 deletions src/test/ui/borrowck/issue-31287-drop-in-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `a`
--> $DIR/issue-31287-drop-in-guard.rs:5:9
--> $DIR/issue-31287-drop-in-guard.rs:7:9
|
LL | let a = Some("...".to_owned());
| - move occurs because `a` has type `Option<String>`, which does not implement the `Copy` trait
Expand All @@ -14,6 +14,22 @@ help: consider cloning the value if the performance cost is acceptable
LL | Some(_) if { drop(a.clone()); false } => None,
| ++++++++

error: aborting due to previous error
error[E0382]: use of moved value: `a`
--> $DIR/issue-31287-drop-in-guard.rs:13:9
|
LL | let a = Some("...".to_owned());
| - move occurs because `a` has type `Option<String>`, which does not implement the `Copy` trait
LL | let b = match a {
LL | Some(_) if let Some(()) = { drop(a); None } => None,
| - value moved here
LL | x => x,
| ^ value used here after move
|
help: consider cloning the value if the performance cost is acceptable
|
LL | Some(_) if let Some(()) = { drop(a.clone()); None } => None,
| ++++++++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0382`.
8 changes: 8 additions & 0 deletions src/test/ui/issues/issue-29723.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// test for https://github.com/rust-lang/rust/issues/29723

#![feature(if_let_guard)]

fn main() {
let s = String::new();
let _s = match 0 {
Expand All @@ -11,4 +13,10 @@ fn main() {
//~^ ERROR use of moved value: `s`
}
};

let s = String::new();
let _s = match 0 {
0 if let Some(()) = { drop(s); None } => String::from("oops"),
_ => s //~ ERROR use of moved value: `s`
};
}
20 changes: 18 additions & 2 deletions src/test/ui/issues/issue-29723.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `s`
--> $DIR/issue-29723.rs:10:13
--> $DIR/issue-29723.rs:12:13
|
LL | let s = String::new();
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
Expand All @@ -15,6 +15,22 @@ help: consider cloning the value if the performance cost is acceptable
LL | 0 if { drop(s.clone()); false } => String::from("oops"),
| ++++++++

error: aborting due to previous error
error[E0382]: use of moved value: `s`
--> $DIR/issue-29723.rs:20:14
|
LL | let s = String::new();
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
LL | let _s = match 0 {
LL | 0 if let Some(()) = { drop(s); None } => String::from("oops"),
| - value moved here
LL | _ => s
| ^ value used here after move
|
help: consider cloning the value if the performance cost is acceptable
|
LL | 0 if let Some(()) = { drop(s.clone()); None } => String::from("oops"),
| ++++++++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0382`.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// See further discussion on rust-lang/rust#24535,
// rust-lang/rfcs#1006, and rust-lang/rfcs#107

#![feature(if_let_guard)]

fn main() {
rust_issue_24535();
rfcs_issue_1006_1();
Expand All @@ -23,6 +25,12 @@ fn rust_issue_24535() {
3 if compare(&a, &mut 3) => (),
_ => panic!("nope"),
}

match a {
0 => panic!("nope"),
3 if let true = compare(&a, &mut 3) => (),
_ => panic!("nope"),
}
}

fn rfcs_issue_1006_1() {
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/nll/issue-27282-move-match-input-into-guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// reaches the panic code when executed, despite the compiler warning
// about that match arm being unreachable.

#![feature(if_let_guard)]

fn main() {
let b = &mut true;
match b {
Expand All @@ -17,4 +19,16 @@ fn main() {
&mut true => { println!("You might think we should get here"); },
_ => panic!("surely we could never get here, since rustc warns it is unreachable."),
}

let b = &mut true;
match b {
//~^ ERROR use of moved value: `b` [E0382]
&mut false => {}
_ if let Some(()) = {
(|| { let bar = b; *bar = false; })();
None
} => {}
&mut true => {}
_ => {}
}
}
17 changes: 15 additions & 2 deletions src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:12:5
--> $DIR/issue-27282-move-match-input-into-guard.rs:14:5
|
LL | let b = &mut true;
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
Expand All @@ -11,6 +11,19 @@ LL | _ if { (|| { let bar = b; *bar = false; })();
| |
| value moved into closure here

error: aborting due to previous error
error[E0382]: use of moved value: `b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:24:5
|
LL | let b = &mut true;
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
LL | match b {
| ^^^^^^^ value used here after move
...
LL | (|| { let bar = b; *bar = false; })();
| -- - variable moved due to use in closure
| |
| value moved into closure here

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0382`.
10 changes: 10 additions & 0 deletions src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// mutable borrows in match guards by hiding the mutable borrow in a
// guard behind a move (of the ref mut pattern id) within a closure.

#![feature(if_let_guard)]

fn main() {
match Some(&4) {
None => {},
Expand All @@ -10,4 +12,12 @@ fn main() {
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
Some(s) => std::process::exit(*s),
}

match Some(&4) {
None => {},
ref mut foo
if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
Some(s) => std::process::exit(*s),
}
}
14 changes: 12 additions & 2 deletions src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
|
LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
Expand All @@ -8,6 +8,16 @@ LL | if { (|| { let bar = foo; bar.take() })(); false } => {},
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

error: aborting due to previous error
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:19:34
|
LL | if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0507`.
13 changes: 13 additions & 0 deletions src/test/ui/nll/issue-27282-mutation-in-guard.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![feature(if_let_guard)]

fn main() {
match Some(&4) {
None => {},
Expand All @@ -10,4 +12,15 @@ fn main() {
Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
_ => println!("Here is some supposedly unreachable code."),
}

match Some(&4) {
None => {},
ref mut foo
if let Some(()) = {
(|| { let bar = foo; bar.take() })();
//~^ ERROR cannot move out of `foo` in pattern guard
None
} => {},
Some(_) => {},
}
}
14 changes: 12 additions & 2 deletions src/test/ui/nll/issue-27282-mutation-in-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-mutation-in-guard.rs:6:18
--> $DIR/issue-27282-mutation-in-guard.rs:8:18
|
LL | (|| { let bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
Expand All @@ -8,6 +8,16 @@ LL | (|| { let bar = foo; bar.take() })();
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

error: aborting due to previous error
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-mutation-in-guard.rs:20:18
|
LL | (|| { let bar = foo; bar.take() })();
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| move out of `foo` occurs here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0507`.
Loading