diff options
| author | bors <bors@rust-lang.org> | 2023-01-03 17:08:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-01-03 17:08:17 +0000 |
| commit | ab10908e8c32c4350b07fc6892b9e5f7e9ffa881 (patch) | |
| tree | 79e8cbf6f4fa1d69911edb883cae3c13a0a8268c /src/test | |
| parent | 312c9a37f26d1f0a98fc410109abb961e945b85e (diff) | |
| parent | e2f7108459baf3e3af1b7ed7d02c9100b2a413d8 (diff) | |
| download | rust-ab10908e8c32c4350b07fc6892b9e5f7e9ffa881.tar.gz rust-ab10908e8c32c4350b07fc6892b9e5f7e9ffa881.zip | |
Auto merge of #106409 - matthiaskrgr:rollup-b58z1hz, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #104552 (warn newer available version of the x tool) - #105681 (some fixes/improvements to mir::visit module) - #106005 (Test the borrowck behavior of if-let guards) - #106356 (clean: Remove `ctor_kind` from `VariantStruct`.) - #106365 (Grammar : Missing "is" in format specifier diagnostic) - #106388 (rustdoc: remove legacy box-sizing CSS) - #106392 (`has_overflow` only if value is *not* within limit) - #106402 (Fix dupe word typos) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'src/test')
33 files changed, 655 insertions, 72 deletions
diff --git a/src/test/ui/borrowck/borrowck-drop-from-guard.rs b/src/test/ui/borrowck/borrowck-drop-from-guard.rs index 4995029a70f..0f320af2657 100644 --- a/src/test/ui/borrowck/borrowck-drop-from-guard.rs +++ b/src/test/ui/borrowck/borrowck-drop-from-guard.rs @@ -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] + } } diff --git a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr index eaf4bb38bc5..9fa28efd855 100644 --- a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr +++ b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr @@ -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`. diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs index 9cbceeb945c..d80a9e81576 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs @@ -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() {} diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr index 6d05e97252d..dbb3272fdc3 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr @@ -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`. diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.rs b/src/test/ui/borrowck/issue-31287-drop-in-guard.rs index 07125b98a1f..5b824adc6e2 100644 --- a/src/test/ui/borrowck/issue-31287-drop-in-guard.rs +++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.rs @@ -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` + }; } diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr index ad898fcabd9..18f371c2073 100644 --- a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr +++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr @@ -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`. diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr index a8a2a47fe46..c2619d6df58 100644 --- a/src/test/ui/fmt/ifmt-bad-arg.stderr +++ b/src/test/ui/fmt/ifmt-bad-arg.stderr @@ -170,7 +170,7 @@ LL | format!("foo %s baz", "bar"); | | | help: format specifiers use curly braces: `{}` | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: invalid format string: expected `'}'`, found `'t'` --> $DIR/ifmt-bad-arg.rs:75:1 diff --git a/src/test/ui/fmt/issue-89173.rs b/src/test/ui/fmt/issue-89173.rs index 96277d4d0d9..fc99af40859 100644 --- a/src/test/ui/fmt/issue-89173.rs +++ b/src/test/ui/fmt/issue-89173.rs @@ -10,5 +10,5 @@ fn main() { //~| NOTE: argument never used //~| NOTE: argument never used //~| NOTE: format specifiers use curly braces, and you have to use a positional or named parameter for the width - //~| NOTE: printf formatting not supported + //~| NOTE: printf formatting is not supported } diff --git a/src/test/ui/fmt/issue-89173.stderr b/src/test/ui/fmt/issue-89173.stderr index 7b21e0a4fc8..ddeb769eadc 100644 --- a/src/test/ui/fmt/issue-89173.stderr +++ b/src/test/ui/fmt/issue-89173.stderr @@ -12,7 +12,7 @@ note: format specifiers use curly braces, and you have to use a positional or na | LL | print!("%0*x", width, num); | ^^^^ - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29723.rs b/src/test/ui/issues/issue-29723.rs index ce91022f093..399e9ba0df7 100644 --- a/src/test/ui/issues/issue-29723.rs +++ b/src/test/ui/issues/issue-29723.rs @@ -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` + }; } diff --git a/src/test/ui/issues/issue-29723.stderr b/src/test/ui/issues/issue-29723.stderr index 92ee5cf22b7..044d8a9b5dd 100644 --- a/src/test/ui/issues/issue-29723.stderr +++ b/src/test/ui/issues/issue-29723.stderr @@ -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`. diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index ff5236dc949..7971c2ab2b9 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -8,7 +8,7 @@ LL | println!("%.*3$s %s!\n", "Hello,", "World", 4); | | argument never used | multiple missing formatting specifiers | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | LL | println!("{:.2$} {}!\n", "Hello,", "World", 4); @@ -22,7 +22,7 @@ LL | println!("%1$*2$.*3$f", 123.456); | | | help: format specifiers use curly braces: `{0:1$.2$}` | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: multiple unused formatting arguments --> $DIR/format-foreign.rs:6:7 @@ -37,7 +37,7 @@ LL | | "###, "Hello,", "World", 4); | |____| argument never used | multiple missing formatting specifiers | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | LL ~ println!(r###"{:.2$} @@ -60,7 +60,7 @@ LL | println!("Hi there, $NAME.", NAME="Tim"); | | | help: format specifiers use curly braces: `{NAME}` | - = note: shell formatting not supported; see the documentation for `std::fmt` + = note: shell formatting is not supported; see the documentation for `std::fmt` error: multiple unused formatting arguments --> $DIR/format-foreign.rs:15:32 @@ -72,7 +72,7 @@ LL | println!("$1 $0 $$ $NAME", 1, 2, NAME=3); | | argument never used | multiple missing formatting specifiers | - = note: shell formatting not supported; see the documentation for `std::fmt` + = note: shell formatting is not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | LL | println!("{1} {0} $$ {NAME}", 1, 2, NAME=3); diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr index 7423c7b7c8b..fad87fa2aee 100644 --- a/src/test/ui/macros/format-unused-lables.stderr +++ b/src/test/ui/macros/format-unused-lables.stderr @@ -44,7 +44,7 @@ LL | "things" LL | , UNUSED="args"); | ^^^^^^ named argument never used | - = note: shell formatting not supported; see the documentation for `std::fmt` + = note: shell formatting is not supported; see the documentation for `std::fmt` error: aborting due to 4 previous errors diff --git a/src/test/ui/macros/issue-92267.stderr b/src/test/ui/macros/issue-92267.stderr index d2d66c81198..5359f68cd55 100644 --- a/src/test/ui/macros/issue-92267.stderr +++ b/src/test/ui/macros/issue-92267.stderr @@ -10,7 +10,7 @@ note: format specifiers use curly braces, and the conversion specifier ` | LL | pub fn main() { println!("🦀%%%", 0) } | ^^ - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: aborting due to previous error diff --git a/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs index 7253d35ed2d..ccfc8937fd7 100644 --- a/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs +++ b/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs @@ -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 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() { diff --git a/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs b/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs index 4109c10e2e4..85feda5824b 100644 --- a/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs +++ b/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs @@ -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 => {} + _ => {} + } } diff --git a/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr index 9be1a927999..ae797800457 100644 --- a/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr +++ b/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr @@ -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`. diff --git a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs index afa0ba780de..833ca8afd61 100644 --- a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs +++ b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs @@ -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), + } } diff --git a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr index a0d32616f83..45119018d4e 100644 --- a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr +++ b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr @@ -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`. diff --git a/src/test/ui/nll/issue-27282-mutation-in-guard.rs b/src/test/ui/nll/issue-27282-mutation-in-guard.rs index 395c7d214d0..4f41fc23fc3 100644 --- a/src/test/ui/nll/issue-27282-mutation-in-guard.rs +++ b/src/test/ui/nll/issue-27282-mutation-in-guard.rs @@ -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(_) => {}, + } } diff --git a/src/test/ui/nll/issue-27282-mutation-in-guard.stderr b/src/test/ui/nll/issue-27282-mutation-in-guard.stderr index c4ce7e62fda..1ba696593af 100644 --- a/src/test/ui/nll/issue-27282-mutation-in-guard.stderr +++ b/src/test/ui/nll/issue-27282-mutation-in-guard.stderr @@ -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`. diff --git a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs index 82d8b9e9ed9..ac06b2b0102 100644 --- a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs +++ b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs @@ -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 => {}, + _ => {}, + } } diff --git a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr index 48433432de1..5eb7a25bf9f 100644 --- a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr +++ b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr @@ -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`. diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs index 252f7f8ba07..1afc7931a6b 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.rs +++ b/src/test/ui/nll/match-cfg-fake-edges.rs @@ -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() {} diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index f72ed3af718..a6261345cea 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -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`. diff --git a/src/test/ui/nll/match-guards-always-borrow.rs b/src/test/ui/nll/match-guards-always-borrow.rs index 87dba187ba2..ff63cc09273 100644 --- a/src/test/ui/nll/match-guards-always-borrow.rs +++ b/src/test/ui/nll/match-guards-always-borrow.rs @@ -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), } } diff --git a/src/test/ui/nll/match-guards-always-borrow.stderr b/src/test/ui/nll/match-guards-always-borrow.stderr index c0fb5f65382..fa01d3a6fd1 100644 --- a/src/test/ui/nll/match-guards-always-borrow.stderr +++ b/src/test/ui/nll/match-guards-always-borrow.stderr @@ -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`. diff --git a/src/test/ui/nll/match-guards-partially-borrow.rs b/src/test/ui/nll/match-guards-partially-borrow.rs index 81ae19ebf8a..3a9e1654b1c 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.rs +++ b/src/test/ui/nll/match-guards-partially-borrow.rs @@ -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() {} diff --git a/src/test/ui/nll/match-guards-partially-borrow.stderr b/src/test/ui/nll/match-guards-partially-borrow.stderr index 48e3a7c6993..60b8dee71a8 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.stderr +++ b/src/test/ui/nll/match-guards-partially-borrow.stderr @@ -1,5 +1,5 @@ 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 @@ -7,8 +7,26 @@ LL | match q { 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 @@ -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: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 @@ -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,16 @@ 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 +... +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 @@ -81,7 +164,7 @@ LL | match b { 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`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs index d1f685f3e7a..6f0d2b04591 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs @@ -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 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])); } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr index 6c3d1caf807..a749361bf30 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr @@ -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`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs index 571f51c9001..827335f6a84 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs @@ -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 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); } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr index d1204bc2601..9285492b224 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr @@ -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`. |
