Test the borrowck behavior of if-let guards
This commit is contained in:
parent
1d12c3cea3
commit
56aaf749b6
@ -1,3 +1,5 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn foo(_:String) {}
|
||||
|
||||
fn main()
|
||||
@ -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]
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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`.
|
||||
|
@ -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 {
|
||||
@ -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() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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
|
||||
@ -7,7 +7,7 @@ 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
|
||||
@ -15,6 +15,23 @@ LL | match x {
|
||||
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`.
|
||||
|
@ -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`
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
@ -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`.
|
||||
|
@ -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 {
|
||||
@ -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`
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
@ -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`.
|
||||
|
@ -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();
|
||||
@ -23,6 +25,12 @@ fn compare(a: &u8, b: &mut u8) -> bool {
|
||||
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() {
|
||||
|
@ -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 {
|
||||
@ -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 => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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`.
|
||||
|
@ -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 => {},
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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`.
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
@ -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(_) => {},
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -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`.
|
||||
|
@ -3,7 +3,9 @@
|
||||
// It reborrows instead of moving the `ref mut` pattern borrow. This
|
||||
// means that our conservative check for mutation in guards will
|
||||
// reject it. But I want to make sure that we continue to reject it
|
||||
// (under NLL) even when that conservaive check goes away.
|
||||
// (under NLL) even when that conservative check goes away.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn main() {
|
||||
let mut b = &mut true;
|
||||
@ -15,4 +17,14 @@ 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 mut b = &mut true;
|
||||
match b {
|
||||
&mut false => {},
|
||||
ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })();
|
||||
//~^ ERROR cannot borrow `r` as mutable, as it is immutable for the pattern guard
|
||||
None } => { &mut *r; },
|
||||
&mut true => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
|
||||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25
|
||||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:14:25
|
||||
|
|
||||
LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
|
||||
| ^^ -- mutable borrow occurs due to use of `r` in closure
|
||||
@ -8,6 +8,16 @@ LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
|
||||
|
|
||||
= note: variables bound in patterns are immutable until the end of the pattern guard
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
|
||||
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:24:40
|
||||
|
|
||||
LL | ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })();
|
||||
| ^^ -- mutable borrow occurs due to use of `r` in closure
|
||||
| |
|
||||
| cannot borrow as mutable
|
||||
|
|
||||
= note: variables bound in patterns are immutable until the end of the pattern guard
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0596`.
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Test that we have enough false edges to avoid exposing the exact matching
|
||||
// algorithm in borrow checking.
|
||||
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn guard_always_precedes_arm(y: i32) {
|
||||
let mut x;
|
||||
// x should always be initialized, as the only way to reach the arm is
|
||||
@ -9,6 +11,12 @@ fn guard_always_precedes_arm(y: i32) {
|
||||
0 | 2 if { x = 2; true } => x,
|
||||
_ => 2,
|
||||
};
|
||||
|
||||
let mut x;
|
||||
match y {
|
||||
0 | 2 if let Some(()) = { x = 2; Some(()) } => x,
|
||||
_ => 2,
|
||||
};
|
||||
}
|
||||
|
||||
fn guard_may_be_skipped(y: i32) {
|
||||
@ -23,6 +31,16 @@ fn guard_may_be_skipped(y: i32) {
|
||||
} => 2,
|
||||
_ => 3,
|
||||
};
|
||||
|
||||
let x;
|
||||
match y {
|
||||
_ if let Some(()) = { x = 2; Some(()) } => 1,
|
||||
_ if let Some(()) = {
|
||||
x; //~ ERROR E0381
|
||||
None
|
||||
} => 2,
|
||||
_ => 3,
|
||||
};
|
||||
}
|
||||
|
||||
fn guard_may_be_taken(y: bool) {
|
||||
@ -37,6 +55,16 @@ fn guard_may_be_taken(y: bool) {
|
||||
}
|
||||
false => 3,
|
||||
};
|
||||
|
||||
let x = String::new();
|
||||
match y {
|
||||
false if let Some(()) = { drop(x); Some(()) } => 1,
|
||||
true => {
|
||||
x; //~ ERROR use of moved value: `x`
|
||||
2
|
||||
}
|
||||
false => 3,
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:21:13
|
||||
--> $DIR/match-cfg-fake-edges.rs:29:13
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
@ -15,8 +15,25 @@ help: consider assigning a value
|
||||
LL | let x = 0;
|
||||
| +++
|
||||
|
||||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/match-cfg-fake-edges.rs:39:13
|
||||
|
|
||||
LL | let x;
|
||||
| - binding declared here but left uninitialized
|
||||
LL | match y {
|
||||
LL | _ if let Some(()) = { x = 2; Some(()) } => 1,
|
||||
| ----- binding initialized here in some conditions
|
||||
LL | _ if let Some(()) = {
|
||||
LL | x;
|
||||
| ^ `x` used here but it isn't initialized
|
||||
|
|
||||
help: consider assigning a value
|
||||
|
|
||||
LL | let x = 0;
|
||||
| +++
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:35:13
|
||||
--> $DIR/match-cfg-fake-edges.rs:53:13
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
@ -32,7 +49,24 @@ help: consider cloning the value if the performance cost is acceptable
|
||||
LL | false if { drop(x.clone()); true } => 1,
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/match-cfg-fake-edges.rs:63:13
|
||||
|
|
||||
LL | let x = String::new();
|
||||
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
|
||||
LL | match y {
|
||||
LL | false if let Some(()) = { drop(x); Some(()) } => 1,
|
||||
| - value moved here
|
||||
LL | true => {
|
||||
LL | x;
|
||||
| ^ value used here after move
|
||||
|
|
||||
help: consider cloning the value if the performance cost is acceptable
|
||||
|
|
||||
LL | false if let Some(()) = { drop(x.clone()); Some(()) } => 1,
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0381, E0382.
|
||||
For more information about an error, try `rustc --explain E0381`.
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
// Here is arielb1's basic example from rust-lang/rust#27282
|
||||
// that AST borrowck is flummoxed by:
|
||||
|
||||
@ -10,6 +12,15 @@ fn should_reject_destructive_mutate_in_guard() {
|
||||
false } => { },
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo if let Some(()) = {
|
||||
(|| { let bar = foo; bar.take() })();
|
||||
//~^ ERROR cannot move out of `foo` in pattern guard [E0507]
|
||||
None } => { },
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
|
||||
// Here below is a case that needs to keep working: we only use the
|
||||
@ -18,7 +29,13 @@ fn should_reject_destructive_mutate_in_guard() {
|
||||
fn allow_mutate_in_arm_body() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo if foo.is_some() && false => { foo.take(); () }
|
||||
ref mut foo if foo.is_some() => { foo.take(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
ref mut foo if let Some(_) = foo => { foo.take(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
@ -29,7 +46,13 @@ fn allow_mutate_in_arm_body() {
|
||||
fn allow_move_into_arm_body() {
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
mut foo if foo.is_some() && false => { foo.take(); () }
|
||||
mut foo if foo.is_some() => { foo.unwrap(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
|
||||
match Some(&4) {
|
||||
None => {},
|
||||
mut foo if let Some(_) = foo => { foo.unwrap(); () }
|
||||
Some(s) => std::process::exit(*s),
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0507]: cannot move out of `foo` in pattern guard
|
||||
--> $DIR/match-guards-always-borrow.rs:8:14
|
||||
--> $DIR/match-guards-always-borrow.rs:10:14
|
||||
|
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
|
||||
@ -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/match-guards-always-borrow.rs:19:14
|
||||
|
|
||||
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`.
|
||||
|
@ -5,7 +5,9 @@
|
||||
// Test that we don't allow mutating the value being matched on in a way that
|
||||
// changes which patterns it matches, until we have chosen an arm.
|
||||
|
||||
fn ok_mutation_in_guard(mut q: i32) {
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
fn ok_mutation_in_if_guard(mut q: i32) {
|
||||
match q {
|
||||
// OK, mutation doesn't change which patterns g matches
|
||||
_ if { q = 1; false } => (),
|
||||
@ -13,7 +15,15 @@ fn ok_mutation_in_guard(mut q: i32) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_guard2(mut u: bool) {
|
||||
fn ok_mutation_in_if_let_guard(mut q: i32) {
|
||||
match q {
|
||||
// OK, mutation doesn't change which patterns g matches
|
||||
_ if let Some(()) = { q = 1; None } => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_if_guard2(mut u: bool) {
|
||||
// OK value of u is unused before modification
|
||||
match u {
|
||||
_ => (),
|
||||
@ -25,7 +35,19 @@ fn ok_mutation_in_guard2(mut u: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_guard4(mut w: (&mut bool,)) {
|
||||
fn ok_mutation_in_if_let_guard2(mut u: bool) {
|
||||
// OK value of u is unused before modification
|
||||
match u {
|
||||
_ => (),
|
||||
_ if let Some(()) = {
|
||||
u = true;
|
||||
None
|
||||
} => (),
|
||||
x => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_mutation_in_if_guard4(mut w: (&mut bool,)) {
|
||||
// OK value of u is unused before modification
|
||||
match w {
|
||||
_ => (),
|
||||
@ -37,7 +59,19 @@ fn ok_mutation_in_guard4(mut w: (&mut bool,)) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_indirect_mutation_in_guard(mut p: &bool) {
|
||||
fn ok_mutation_in_if_let_guard4(mut w: (&mut bool,)) {
|
||||
// OK value of u is unused before modification
|
||||
match w {
|
||||
_ => (),
|
||||
_ if let Some(()) = {
|
||||
*w.0 = true;
|
||||
None
|
||||
} => (),
|
||||
x => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_indirect_mutation_in_if_guard(mut p: &bool) {
|
||||
match *p {
|
||||
// OK, mutation doesn't change which patterns s matches
|
||||
_ if {
|
||||
@ -48,7 +82,18 @@ fn ok_indirect_mutation_in_guard(mut p: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_pattern_in_guard(mut q: bool) {
|
||||
fn ok_indirect_mutation_in_if_let_guard(mut p: &bool) {
|
||||
match *p {
|
||||
// OK, mutation doesn't change which patterns s matches
|
||||
_ if let Some(()) = {
|
||||
p = &true;
|
||||
None
|
||||
} => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_pattern_in_if_guard(mut q: bool) {
|
||||
match q {
|
||||
// q doesn't match the pattern with the guard by the end of the guard.
|
||||
false if {
|
||||
@ -59,7 +104,18 @@ fn mutation_invalidates_pattern_in_guard(mut q: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) {
|
||||
fn mutation_invalidates_pattern_in_if_let_guard(mut q: bool) {
|
||||
match q {
|
||||
// q doesn't match the pattern with the guard by the end of the guard.
|
||||
false if let Some(()) = {
|
||||
q = true; //~ ERROR
|
||||
Some(())
|
||||
} => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn mutation_invalidates_previous_pattern_in_if_guard(mut r: bool) {
|
||||
match r {
|
||||
// r matches a previous pattern by the end of the guard.
|
||||
true => (),
|
||||
@ -71,7 +127,19 @@ fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn match_on_borrowed_early_end(mut s: bool) {
|
||||
fn mutation_invalidates_previous_pattern_in_if_let_guard(mut r: bool) {
|
||||
match r {
|
||||
// r matches a previous pattern by the end of the guard.
|
||||
true => (),
|
||||
_ if let Some(()) = {
|
||||
r = true; //~ ERROR
|
||||
Some(())
|
||||
} => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn match_on_borrowed_early_end_if_guard(mut s: bool) {
|
||||
let h = &mut s;
|
||||
// OK value of s is unused before modification.
|
||||
match s {
|
||||
@ -84,7 +152,20 @@ fn match_on_borrowed_early_end(mut s: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_guard(mut t: bool) {
|
||||
fn match_on_borrowed_early_end_if_let_guard(mut s: bool) {
|
||||
let h = &mut s;
|
||||
// OK value of s is unused before modification.
|
||||
match s {
|
||||
_ if let Some(()) = {
|
||||
*h = !*h;
|
||||
None
|
||||
} => (),
|
||||
true => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_if_guard(mut t: bool) {
|
||||
match t {
|
||||
true => (),
|
||||
false if {
|
||||
@ -95,7 +176,18 @@ fn bad_mutation_in_guard(mut t: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_guard2(mut x: Option<Option<&i32>>) {
|
||||
fn bad_mutation_in_if_let_guard(mut t: bool) {
|
||||
match t {
|
||||
true => (),
|
||||
false if let Some(()) = {
|
||||
t = true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_if_guard2(mut x: Option<Option<&i32>>) {
|
||||
// Check that nested patterns are checked.
|
||||
match x {
|
||||
None => (),
|
||||
@ -111,7 +203,23 @@ fn bad_mutation_in_guard2(mut x: Option<Option<&i32>>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_guard3(mut t: bool) {
|
||||
fn bad_mutation_in_if_let_guard2(mut x: Option<Option<&i32>>) {
|
||||
// Check that nested patterns are checked.
|
||||
match x {
|
||||
None => (),
|
||||
Some(None) => (),
|
||||
_ if let Some(()) = {
|
||||
match x {
|
||||
Some(ref mut r) => *r = None, //~ ERROR
|
||||
_ => return,
|
||||
};
|
||||
None
|
||||
} => (),
|
||||
Some(Some(r)) => println!("{}", r),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_mutation_in_if_guard3(mut t: bool) {
|
||||
match t {
|
||||
s if {
|
||||
t = !t; //~ ERROR
|
||||
@ -121,7 +229,17 @@ fn bad_mutation_in_guard3(mut t: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard(mut y: &bool) {
|
||||
fn bad_mutation_in_if_let_guard3(mut t: bool) {
|
||||
match t {
|
||||
s if let Some(()) = {
|
||||
t = !t; //~ ERROR
|
||||
None
|
||||
} => (), // What value should `s` have in the arm?
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard(mut y: &bool) {
|
||||
match *y {
|
||||
true => (),
|
||||
false if {
|
||||
@ -132,7 +250,18 @@ fn bad_indirect_mutation_in_guard(mut y: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard2(mut z: &bool) {
|
||||
fn bad_indirect_mutation_in_if_let_guard(mut y: &bool) {
|
||||
match *y {
|
||||
true => (),
|
||||
false if let Some(()) = {
|
||||
y = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard2(mut z: &bool) {
|
||||
match z {
|
||||
&true => (),
|
||||
&false if {
|
||||
@ -143,8 +272,19 @@ fn bad_indirect_mutation_in_guard2(mut z: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard3(mut a: &bool) {
|
||||
// Same as bad_indirect_mutation_in_guard2, but using match ergonomics
|
||||
fn bad_indirect_mutation_in_if_let_guard2(mut z: &bool) {
|
||||
match z {
|
||||
&true => (),
|
||||
&false if let Some(()) = {
|
||||
z = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
&false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard3(mut a: &bool) {
|
||||
// Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics
|
||||
match a {
|
||||
true => (),
|
||||
false if {
|
||||
@ -155,7 +295,19 @@ fn bad_indirect_mutation_in_guard3(mut a: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_guard4(mut b: &bool) {
|
||||
fn bad_indirect_mutation_in_if_let_guard3(mut a: &bool) {
|
||||
// Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics
|
||||
match a {
|
||||
true => (),
|
||||
false if let Some(()) = {
|
||||
a = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
false => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_guard4(mut b: &bool) {
|
||||
match b {
|
||||
&_ => (),
|
||||
&_ if {
|
||||
@ -166,4 +318,15 @@ fn bad_indirect_mutation_in_guard4(mut b: &bool) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bad_indirect_mutation_in_if_let_guard4(mut b: &bool) {
|
||||
match b {
|
||||
&_ => (),
|
||||
&_ if let Some(()) = {
|
||||
b = &true; //~ ERROR
|
||||
None
|
||||
} => (),
|
||||
&b => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,14 @@
|
||||
error[E0510]: cannot assign `q` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:55:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:100:13
|
||||
|
|
||||
LL | match q {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | q = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `q` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:111:13
|
||||
|
|
||||
LL | match q {
|
||||
| - value is immutable in match guard
|
||||
@ -8,7 +17,16 @@ LL | q = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `r` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:67:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:123:13
|
||||
|
|
||||
LL | match r {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | r = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `r` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:135:13
|
||||
|
|
||||
LL | match r {
|
||||
| - value is immutable in match guard
|
||||
@ -17,7 +35,16 @@ LL | r = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `t` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:91:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:172:13
|
||||
|
|
||||
LL | match t {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | t = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `t` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:183:13
|
||||
|
|
||||
LL | match t {
|
||||
| - value is immutable in match guard
|
||||
@ -26,7 +53,16 @@ LL | t = true;
|
||||
| ^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot mutably borrow `x.0` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:105:22
|
||||
--> $DIR/match-guards-partially-borrow.rs:197:22
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | Some(ref mut r) => *r = None,
|
||||
| ^^^^^^^^^ cannot mutably borrow
|
||||
|
||||
error[E0510]: cannot mutably borrow `x.0` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:213:22
|
||||
|
|
||||
LL | match x {
|
||||
| - value is immutable in match guard
|
||||
@ -35,7 +71,7 @@ LL | Some(ref mut r) => *r = None,
|
||||
| ^^^^^^^^^ cannot mutably borrow
|
||||
|
||||
error[E0506]: cannot assign to `t` because it is borrowed
|
||||
--> $DIR/match-guards-partially-borrow.rs:117:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:225:13
|
||||
|
|
||||
LL | s if {
|
||||
| - borrow of `t` occurs here
|
||||
@ -45,8 +81,28 @@ LL | false
|
||||
LL | } => (), // What value should `s` have in the arm?
|
||||
| - borrow later used here
|
||||
|
||||
error[E0506]: cannot assign to `t` because it is borrowed
|
||||
--> $DIR/match-guards-partially-borrow.rs:235:13
|
||||
|
|
||||
LL | s if let Some(()) = {
|
||||
| - borrow of `t` occurs here
|
||||
LL | t = !t;
|
||||
| ^^^^^^ assignment to borrowed `t` occurs here
|
||||
LL | None
|
||||
LL | } => (), // What value should `s` have in the arm?
|
||||
| - borrow later used here
|
||||
|
||||
error[E0510]: cannot assign `y` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:128:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:246:13
|
||||
|
|
||||
LL | match *y {
|
||||
| -- value is immutable in match guard
|
||||
...
|
||||
LL | y = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `y` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:257:13
|
||||
|
|
||||
LL | match *y {
|
||||
| -- value is immutable in match guard
|
||||
@ -55,7 +111,16 @@ LL | y = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `z` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:139:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:268:13
|
||||
|
|
||||
LL | match z {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | z = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `z` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:279:13
|
||||
|
|
||||
LL | match z {
|
||||
| - value is immutable in match guard
|
||||
@ -64,7 +129,16 @@ LL | z = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `a` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:151:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:291:13
|
||||
|
|
||||
LL | match a {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | a = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `a` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:303:13
|
||||
|
|
||||
LL | match a {
|
||||
| - value is immutable in match guard
|
||||
@ -73,7 +147,7 @@ LL | a = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error[E0510]: cannot assign `b` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:162:13
|
||||
--> $DIR/match-guards-partially-borrow.rs:314:13
|
||||
|
|
||||
LL | match b {
|
||||
| - value is immutable in match guard
|
||||
@ -81,7 +155,16 @@ LL | match b {
|
||||
LL | b = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error[E0510]: cannot assign `b` in match guard
|
||||
--> $DIR/match-guards-partially-borrow.rs:325:13
|
||||
|
|
||||
LL | match b {
|
||||
| - value is immutable in match guard
|
||||
...
|
||||
LL | b = &true;
|
||||
| ^^^^^^^^^ cannot assign
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0506, E0510.
|
||||
For more information about an error, try `rustc --explain E0506`.
|
||||
|
@ -1,6 +1,8 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
enum VecWrapper { A(Vec<i32>) }
|
||||
|
||||
fn foo(x: VecWrapper) -> usize {
|
||||
fn if_guard(x: VecWrapper) -> usize {
|
||||
match x {
|
||||
VecWrapper::A(v) if { drop(v); false } => 1,
|
||||
//~^ ERROR cannot move out of `v` in pattern guard
|
||||
@ -8,6 +10,15 @@ fn foo(x: VecWrapper) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(VecWrapper::A(vec![107]));
|
||||
fn if_let_guard(x: VecWrapper) -> usize {
|
||||
match x {
|
||||
VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1,
|
||||
//~^ ERROR cannot move out of `v` in pattern guard
|
||||
VecWrapper::A(v) => v.len()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if_guard(VecWrapper::A(vec![107]));
|
||||
if_let_guard(VecWrapper::A(vec![107]));
|
||||
}
|
||||
|
@ -1,11 +1,19 @@
|
||||
error[E0507]: cannot move out of `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-across-arms.rs:5:36
|
||||
--> $DIR/rfc-reject-double-move-across-arms.rs:7:36
|
||||
|
|
||||
LL | VecWrapper::A(v) if { drop(v); false } => 1,
|
||||
| ^ move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= 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 `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-across-arms.rs:15:51
|
||||
|
|
||||
LL | VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1,
|
||||
| ^ move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= 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`.
|
||||
|
@ -1,6 +1,8 @@
|
||||
#![feature(if_let_guard)]
|
||||
|
||||
struct A { a: Box<i32> }
|
||||
|
||||
fn foo(n: i32) {
|
||||
fn if_guard(n: i32) {
|
||||
let x = A { a: Box::new(n) };
|
||||
let _y = match x {
|
||||
A { a: v } if { drop(v); true } => v,
|
||||
@ -9,6 +11,16 @@ fn foo(n: i32) {
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(107);
|
||||
fn if_let_guard(n: i32) {
|
||||
let x = A { a: Box::new(n) };
|
||||
let _y = match x {
|
||||
A { a: v } if let Some(()) = { drop(v); Some(()) } => v,
|
||||
//~^ ERROR cannot move out of `v` in pattern guard
|
||||
_ => Box::new(0),
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if_guard(107);
|
||||
if_let_guard(107);
|
||||
}
|
||||
|
@ -1,11 +1,19 @@
|
||||
error[E0507]: cannot move out of `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-in-first-arm.rs:6:30
|
||||
--> $DIR/rfc-reject-double-move-in-first-arm.rs:8:30
|
||||
|
|
||||
LL | A { a: v } if { drop(v); true } => v,
|
||||
| ^ move occurs because `v` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= 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 `v` in pattern guard
|
||||
--> $DIR/rfc-reject-double-move-in-first-arm.rs:17:45
|
||||
|
|
||||
LL | A { a: v } if let Some(()) = { drop(v); Some(()) } => v,
|
||||
| ^ move occurs because `v` has type `Box<i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
= 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…
Reference in New Issue
Block a user