+#![feature(if_let_guard)]
+
fn foo(_:String) {}
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]
+ }
}
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
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`.
+#![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 {
}
}
-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() {}
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
| ^^^^^^^^^^^^^^^^^^ 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`.
+#![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`
+ };
}
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
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`.
// test for https://github.com/rust-lang/rust/issues/29723
+#![feature(if_let_guard)]
+
fn main() {
let s = String::new();
let _s = match 0 {
//~^ 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`
+ };
}
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
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`.
// 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();
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() {
// 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 {
&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 => {}
+ _ => {}
+ }
}
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
| |
| 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`.
// 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 => {},
//~^ 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),
+ }
}
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
|
= 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`.
+#![feature(if_let_guard)]
+
fn main() {
match Some(&4) {
None => {},
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(_) => {},
+ }
}
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
|
= 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`.
// 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;
&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 => {},
+ _ => {},
+ }
}
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
|
= 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`.
// 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
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) {
} => 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) {
}
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() {}
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
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
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`.
+#![feature(if_let_guard)]
+
// Here is arielb1's basic example from rust-lang/rust#27282
// that AST borrowck is flummoxed by:
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
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),
}
}
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),
}
}
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
|
= 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`.
// 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 } => (),
}
}
-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 {
_ => (),
}
}
-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 {
_ => (),
}
}
-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 {
}
}
-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 {
}
}
-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 => (),
}
}
-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 {
}
}
-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 {
}
}
-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 => (),
}
}
-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
}
}
-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 {
}
}
-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 {
}
}
-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 {
}
}
-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 {
}
}
+fn bad_indirect_mutation_in_if_let_guard4(mut b: &bool) {
+ match b {
+ &_ => (),
+ &_ if let Some(()) = {
+ b = &true; //~ ERROR
+ None
+ } => (),
+ &b => (),
+ }
+}
+
fn main() {}
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
+...
+LL | q = true;
+ | ^^^^^^^^ cannot assign
+
+error[E0510]: cannot assign `r` in match guard
+ --> $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:67:13
+ --> $DIR/match-guards-partially-borrow.rs:135:13
|
LL | match r {
| - value is immutable in match guard
| ^^^^^^^^ 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
| ^^^^^^^^ 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
| ^^^^^^^^^ 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
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: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:128:13
+ --> $DIR/match-guards-partially-borrow.rs:257:13
|
LL | match *y {
| -- value is immutable in match guard
| ^^^^^^^^^ 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
| ^^^^^^^^^ 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
| ^^^^^^^^^ 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
+...
+LL | b = &true;
+ | ^^^^^^^^^ cannot assign
+
+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 9 previous errors
+error: aborting due to 18 previous errors
Some errors have detailed explanations: E0506, E0510.
For more information about an error, try `rustc --explain E0506`.
+#![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
}
}
+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() {
- foo(VecWrapper::A(vec![107]));
+ if_guard(VecWrapper::A(vec![107]));
+ if_let_guard(VecWrapper::A(vec![107]));
}
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`.
+#![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,
};
}
+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() {
- foo(107);
+ if_guard(107);
+ if_let_guard(107);
}
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`.