diff options
| author | bors <bors@rust-lang.org> | 2020-02-09 04:01:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-02-09 04:01:28 +0000 |
| commit | f8d830b4decaef5a6ae0f27baac14dfb48baa4c5 (patch) | |
| tree | a5e7a6a7f68e12dbd174c1313b4d0ab0e742dbdc /src/test/ui/pattern | |
| parent | a19edd6b161521a4f66716b3b45b8cf4d3f03f3a (diff) | |
| parent | d2b88b7050b0e21b136022c4cfe8d352c1425588 (diff) | |
| download | rust-f8d830b4decaef5a6ae0f27baac14dfb48baa4c5.tar.gz rust-f8d830b4decaef5a6ae0f27baac14dfb48baa4c5.zip | |
Auto merge of #68376 - Centril:move-ref-patterns, r=matthewjasper
Initial implementation of `#![feature(move_ref_pattern)]` Following up on #45600, under the gate `#![feature(move_ref_pattern)]`, `(ref x, mut y)` is allowed subject to restrictions necessary for soundness. The match checking implementation and tests for `#![feature(bindings_after_at)]` is also adjusted as necessary. Closes #45600. Tracking issue: #68354. r? @matthewjasper
Diffstat (limited to 'src/test/ui/pattern')
39 files changed, 2686 insertions, 636 deletions
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 75d7af58e70..c00296c34c4 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -3,33 +3,38 @@ // where one side is by-ref and the other is by-move. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] -struct X { x: () } +struct X { + x: (), +} fn main() { let x = Some(X { x: () }); match x { - Some(ref _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() + Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed + None => panic!(), } let x = Some(X { x: () }); match x { - Some(_z @ ref _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + Some(_z @ ref _y) => {} //~^ ERROR borrow of moved value - None => panic!() + //~| ERROR borrow of moved value + None => panic!(), } let mut x = Some(X { x: () }); match x { - Some(ref mut _y @ _z) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern - None => panic!() + Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed + None => panic!(), } let mut x = Some(X { x: () }); match x { - Some(_z @ ref mut _y) => { }, //~ ERROR cannot bind by-move with sub-bindings + Some(_z @ ref mut _y) => {} //~^ ERROR borrow of moved value - None => panic!() + //~| ERROR borrow of moved value + None => panic!(), } } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index 22d62ff4f00..026747c212a 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -1,37 +1,45 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:12:23 +error: cannot move out of value because it is borrowed + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14 | -LL | Some(ref _y @ _z) => { }, - | ---------^^ +LL | Some(ref _y @ _z) => {} + | ------^^^-- | | | - | | by-move pattern here - | by-ref pattern here + | | value moved into `_z` here + | value borrowed, by `_y`, here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:14 +error: borrow of moved value + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14 | -LL | Some(_z @ ref _y) => { }, - | ^^^^^^^^^^^ binds an already bound by-move value by moving it +LL | Some(_z @ ref _y) => {} + | --^^^------ + | | | + | | value borrowed here after move + | value moved into `_z` here + | move occurs because `_z` has type `X` which does implement the `Copy` trait -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:25:27 +error: cannot move out of value because it is borrowed + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14 | -LL | Some(ref mut _y @ _z) => { }, - | -------------^^ +LL | Some(ref mut _y @ _z) => {} + | ----------^^^-- | | | - | | by-move pattern here - | by-ref pattern here + | | value moved into `_z` here + | value borrowed, by `_y`, here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:14 +error: borrow of moved value + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14 | -LL | Some(_z @ ref mut _y) => { }, - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it +LL | Some(_z @ ref mut _y) => {} + | --^^^---------- + | | | + | | value borrowed here after move + | value moved into `_z` here + | move occurs because `_z` has type `X` which does implement the `Copy` trait error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:18:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:19 | -LL | Some(_z @ ref _y) => { }, +LL | Some(_z @ ref _y) => {} | -----^^^^^^ | | | | | value borrowed here after move @@ -40,9 +48,9 @@ LL | Some(_z @ ref _y) => { }, = note: move occurs because value has type `X`, which does not implement the `Copy` trait error[E0382]: borrow of moved value - --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:31:19 + --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:19 | -LL | Some(_z @ ref mut _y) => { }, +LL | Some(_z @ ref mut _y) => {} | -----^^^^^^^^^^ | | | | | value borrowed here after move @@ -52,5 +60,4 @@ LL | Some(_z @ ref mut _y) => { }, error: aborting due to 6 previous errors -Some errors have detailed explanations: E0007, E0009, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs index 86fb04e2edf..7a2e5128b85 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs @@ -1,14 +1,14 @@ // See issue #12534. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() {} struct A(Box<u8>); fn f(a @ A(u): A) -> Box<u8> { - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value drop(a); u } diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr index b039708fd3e..cfd978e1327 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr @@ -1,11 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:6 - | -LL | fn f(a @ A(u): A) -> Box<u8> { - | ^^^^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:12 + --> $DIR/bind-by-move-no-subbindings-fun-param.rs:10:12 | LL | fn f(a @ A(u): A) -> Box<u8> { | ------^- @@ -14,7 +8,6 @@ LL | fn f(a @ A(u): A) -> Box<u8> { | value moved here | move occurs because value has type `A`, which does not implement the `Copy` trait -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs index 2cd375da9a5..10865b92393 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -1,46 +1,34 @@ // Test that moving on both sides of an `@` pattern is not allowed. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct U; // Not copy! // Prevent promotion: - fn u() -> U { U } + fn u() -> U { + U + } - let a @ b = U; - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ b = U; //~ ERROR use of moved value - let a @ (b, c) = (U, U); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ (b, c) = (U, U); //~ ERROR use of moved value - let a @ (b, c) = (u(), u()); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + let a @ (b, c) = (u(), u()); //~ ERROR use of moved value match Ok(U) { - a @ Ok(b) | a @ Err(b) => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value - //~| ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value + //~^ ERROR use of moved value } - fn fun(a @ b: U) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + fn fun(a @ b: U) {} //~ ERROR use of moved value match [u(), u(), u(), u()] { - xs @ [a, .., b] => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + xs @ [a, .., b] => {} //~ ERROR use of moved value } match [u(), u(), u(), u()] { - xs @ [_, ys @ .., _] => {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + xs @ [_, ys @ .., _] => {} //~ ERROR use of moved value } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr index 12ebcb72af1..56613ee7618 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -1,53 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:11:9 - | -LL | let a @ b = U; - | ^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:15:9 - | -LL | let a @ (b, c) = (U, U); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:19:9 - | -LL | let a @ (b, c) = (u(), u()); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:24:9 - | -LL | a @ Ok(b) | a @ Err(b) => {} - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:24:21 - | -LL | a @ Ok(b) | a @ Err(b) => {} - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:36:9 - | -LL | xs @ [a, .., b] => {} - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:42:9 - | -LL | xs @ [_, ys @ .., _] => {} - | ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:31:12 - | -LL | fn fun(a @ b: U) {} - | ^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:11:13 + --> $DIR/borrowck-move-and-move.rs:14:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -56,7 +8,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:15:17 + --> $DIR/borrowck-move-and-move.rs:16:17 | LL | let a @ (b, c) = (U, U); | --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -65,7 +17,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:19:17 + --> $DIR/borrowck-move-and-move.rs:18:17 | LL | let a @ (b, c) = (u(), u()); | --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -74,7 +26,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:24:16 + --> $DIR/borrowck-move-and-move.rs:21:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait @@ -85,7 +37,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:24:29 + --> $DIR/borrowck-move-and-move.rs:21:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait @@ -96,7 +48,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:36:22 + --> $DIR/borrowck-move-and-move.rs:28:22 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -107,7 +59,7 @@ LL | xs @ [a, .., b] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:42:18 + --> $DIR/borrowck-move-and-move.rs:32:18 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -118,7 +70,7 @@ LL | xs @ [_, ys @ .., _] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:31:16 + --> $DIR/borrowck-move-and-move.rs:25:16 | LL | fn fun(a @ b: U) {} | ----^ @@ -127,7 +79,6 @@ LL | fn fun(a @ b: U) {} | value moved here | move occurs because value has type `main::U`, which does not implement the `Copy` trait -error: aborting due to 16 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index 092bd1133dd..271f4bca0fc 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -3,6 +3,7 @@ // Test `@` patterns combined with `box` patterns. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #![feature(box_patterns)] #[derive(Copy, Clone)] @@ -72,4 +73,14 @@ fn main() { } _ => {} } + + match Box::new([Ok(c()), Err(nc()), Ok(c())]) { + box [Ok(a), ref xs @ .., Err(b)] => {} + _ => {} + } + + match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { + [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} + _ => {} + } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index 3b2f598dc01..32c638bcbcc 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -1,61 +1,62 @@ // Test `@` patterns combined with `box` patterns. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #![feature(box_patterns)] #[derive(Copy, Clone)] struct C; -fn c() -> C { C } +fn c() -> C { + C +} struct NC; -fn nc() -> NC { NC } +fn nc() -> NC { + NC +} fn main() { let a @ box &b = Box::new(&C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value let a @ box b = Box::new(C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value fn f1(a @ box &b: Box<&C>) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value fn f2(a @ box b: Box<C>) {} - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value - match Box::new(C) { a @ box b => {} } - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + match Box::new(C) { + a @ box b => {} //~ ERROR use of moved value + } - let ref a @ box b = Box::new(NC); //~ ERROR cannot bind by-move and by-ref in the same pattern + let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of value because it is borrowed let ref a @ box ref mut b = Box::new(nc()); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = NC; let ref a @ box ref mut b = Box::new(NC); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = NC; drop(a); let ref mut a @ box ref b = Box::new(NC); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); fn f5(ref mut a @ box ref b: Box<NC>) { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); @@ -63,22 +64,10 @@ fn main() { match Box::new(nc()) { ref mut a @ box ref b => { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = Box::new(NC); drop(b); } } - - match Box::new([Ok(c()), Err(nc()), Ok(c())]) { - box [Ok(a), ref xs @ .., Err(b)] => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern - _ => {} - } - - match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { - [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern - _ => {} - } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index e96c15b0fa7..5534d0a75e6 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,125 +1,77 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:16:9 - | -LL | let a @ box &b = Box::new(&C); - | ^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:20:9 - | -LL | let a @ box b = Box::new(C); - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:32:25 - | -LL | match Box::new(C) { a @ box b => {} } - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:36:21 +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-at-and-box.rs:37:9 | LL | let ref a @ box b = Box::new(NC); - | ------------^ + | -----^^^^^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | value moved into `b` here + | value borrowed, by `a`, here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:38:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:39:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:40:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:41:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:42:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:43:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:45:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-at-and-box.rs:46:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:51:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:52:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:65:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:66:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:74:38 - | -LL | box [Ok(a), ref xs @ .., Err(b)] => {} - | ----------- ^ by-move pattern here - | | - | by-ref pattern here - -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:80:46 - | -LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} - | ----- ----------- ^ --------- by-ref pattern here - | | | | - | | | by-move pattern here - | | by-ref pattern here - | by-ref pattern here - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:24:11 - | -LL | fn f1(a @ box &b: Box<&C>) {} - | ^^^^^^^^^^ binds an already bound by-move value by moving it + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:28:11 - | -LL | fn f2(a @ box b: Box<C>) {} - | ^^^^^^^^^ binds an already bound by-move value by moving it - -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:57:11 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:58:11 | LL | fn f5(ref mut a @ box ref b: Box<NC>) { | ---------^^^^^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:16:18 + --> $DIR/borrowck-pat-at-and-box.rs:21:18 | LL | let a @ box &b = Box::new(&C); | ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait @@ -128,7 +80,7 @@ LL | let a @ box &b = Box::new(&C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:20:17 + --> $DIR/borrowck-pat-at-and-box.rs:24:17 | LL | let a @ box b = Box::new(C); | --------^ ----------- move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait @@ -137,17 +89,18 @@ LL | let a @ box b = Box::new(C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:32:33 + --> $DIR/borrowck-pat-at-and-box.rs:34:17 | -LL | match Box::new(C) { a @ box b => {} } - | ----------- --------^ - | | | | - | | | value used here after move - | | value moved here - | move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait +LL | match Box::new(C) { + | ----------- move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait +LL | a @ box b => {} + | --------^ + | | | + | | value used here after move + | value moved here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:45:21 + --> $DIR/borrowck-pat-at-and-box.rs:46:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -159,7 +112,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:51:25 + --> $DIR/borrowck-pat-at-and-box.rs:52:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -171,7 +124,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:65:25 + --> $DIR/borrowck-pat-at-and-box.rs:66:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -183,7 +136,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:24:20 + --> $DIR/borrowck-pat-at-and-box.rs:27:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -193,7 +146,7 @@ LL | fn f1(a @ box &b: Box<&C>) {} | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:28:19 + --> $DIR/borrowck-pat-at-and-box.rs:30:19 | LL | fn f2(a @ box b: Box<C>) {} | --------^ @@ -203,7 +156,7 @@ LL | fn f2(a @ box b: Box<C>) {} | move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:57:27 + --> $DIR/borrowck-pat-at-and-box.rs:58:27 | LL | fn f5(ref mut a @ box ref b: Box<NC>) { | ----------------^^^^^ @@ -214,7 +167,7 @@ LL | fn f5(ref mut a @ box ref b: Box<NC>) { LL | *a = Box::new(NC); | -- mutable borrow later used here -error: aborting due to 24 previous errors +error: aborting due to 17 previous errors -Some errors have detailed explanations: E0007, E0009, E0382, E0502. -For more information about an error, try `rustc --explain E0007`. +Some errors have detailed explanations: E0382, E0502. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs new file mode 100644 index 00000000000..14797917193 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs @@ -0,0 +1,10 @@ +// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented even with promotion. +// Currently this logic exists in HAIR match checking as opposed to borrowck. + +#![feature(bindings_after_at)] +#![feature(move_ref_pattern)] + +fn main() { + struct U; + let a @ ref b = U; //~ ERROR borrow of moved value +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr new file mode 100644 index 00000000000..91fdfd4f2ab --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr @@ -0,0 +1,12 @@ +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:9:9 + | +LL | let a @ ref b = U; + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs new file mode 100644 index 00000000000..7d9618c8df7 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs @@ -0,0 +1,98 @@ +// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented. + +#![feature(bindings_after_at)] +#![feature(move_ref_pattern)] + +fn main() { + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(a @ ref b: U) {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + + fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + + let a @ ref b = U; + //~^ ERROR borrow of moved value + let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + let a @ [ref mut b, ref c] = [U, U]; + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + let a @ ref b = u(); + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + let a @ [ref mut b, ref c] = [u(), u()]; + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + + match Some(U) { + a @ Some(ref b) => {} + //~^ ERROR borrow of moved value + None => {} + } + match Some((U, U)) { + a @ Some((mut b @ ref mut c, d @ ref e)) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + None => {} + } + match Some([U, U]) { + mut a @ Some([ref b, ref mut c]) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + None => {} + } + match Some(u()) { + a @ Some(ref b) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + None => {} + } + match Some((u(), u())) { + a @ Some((mut b @ ref mut c, d @ ref e)) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR borrow of moved value + //~| ERROR use of moved value + None => {} + } + match Some([u(), u()]) { + mut a @ Some([ref b, ref mut c]) => {} + //~^ ERROR borrow of moved value + //~| ERROR borrow of moved value + None => {} + } +} diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr new file mode 100644 index 00000000000..ec86692dc69 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -0,0 +1,503 @@ +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9 + | +LL | let a @ ref b = U; + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | -^^^^^^^^^^^^---------^^^^^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:14 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved into `b` here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `d` here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:9 + | +LL | let a @ [ref mut b, ref c] = [U, U]; + | -^^^^---------^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9 + | +LL | let a @ ref b = u(); + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:9 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | -^^^^^^^^^^^^---------^^^^^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:14 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved into `b` here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `d` here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:9 + | +LL | let a @ [ref mut b, ref c] = [u(), u()]; + | -^^^^---------^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9 + | +LL | a @ Some(ref b) => {} + | -^^^^^^^^-----^ + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:19 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved into `b` here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `d` here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:9 + | +LL | mut a @ Some([ref b, ref mut c]) => {} + | -----^^^^^^^^^-----^^---------^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9 + | +LL | a @ Some(ref b) => {} + | -^^^^^^^^-----^ + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:9 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `std::option::Option<(main::U, main::U)>` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:19 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----^^^--------- + | | | + | | value borrowed here after move + | value moved into `b` here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `d` here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:9 + | +LL | mut a @ Some([ref b, ref mut c]) => {} + | -----^^^^^^^^^-----^^---------^^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 + | +LL | fn f1(a @ ref b: U) {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:11 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | -----^^^^^^^^-----^^^^^^^^^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:20 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `b` here + | move occurs because `b` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | -----^^^----- + | | | + | | value borrowed here after move + | value moved into `d` here + | move occurs because `d` has type `main::U` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:11 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | -^^^^---------^^-----^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:22 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | ------------------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:37 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (U, U); + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:38:25 + | +LL | let a @ [ref mut b, ref c] = [U, U]; + | ----------------^^^^^- ------ move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:13 + | +LL | let a @ ref b = u(); + | ----^^^^^ --- move occurs because value has type `main::U`, which does not implement the `Copy` trait + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:22 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:33 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | ------------------------^^^^^^^^^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:37 + | +LL | let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:51:25 + | +LL | let a @ [ref mut b, ref c] = [u(), u()]; + | ----------------^^^^^- ---------- move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:27 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38 + | +LL | match Some((U, U)) { + | ------------ move occurs because value has type `std::option::Option<(main::U, main::U)>`, which does not implement the `Copy` trait +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----------------------------^^^^^^^^^-- + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:42 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:30 + | +LL | match Some([U, U]) { + | ------------ move occurs because value has type `std::option::Option<[main::U; 2]>`, which does not implement the `Copy` trait +LL | mut a @ Some([ref b, ref mut c]) => {} + | ---------------------^^^^^^^^^-- + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:18 + | +LL | match Some(u()) { + | --------- move occurs because value has type `std::option::Option<main::U>`, which does not implement the `Copy` trait +LL | a @ Some(ref b) => {} + | ---------^^^^^- + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:27 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | --------^^^^^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38 + | +LL | match Some((u(), u())) { + | ---------------- move occurs because value has type `std::option::Option<(main::U, main::U)>`, which does not implement the `Copy` trait +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | -----------------------------^^^^^^^^^-- + | | | + | | value used here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:42 + | +LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:30 + | +LL | match Some([u(), u()]) { + | ---------------- move occurs because value has type `std::option::Option<[main::U; 2]>`, which does not implement the `Copy` trait +LL | mut a @ Some([ref b, ref mut c]) => {} + | ---------------------^^^^^^^^^-- + | | | + | | value borrowed here after move + | value moved here + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:15 + | +LL | fn f1(a @ ref b: U) {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:24 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ----^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: use of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | --------------------^^^^^^^^^^^^^- + | | | + | | value used here after move + | value moved here + | move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:18:39 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | --------^^^^^ + | | | + | | value borrowed here after move + | value moved here + | + = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:25:27 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | ----------------^^^^^- + | | | + | | value borrowed here after move + | value moved here + | move occurs because value has type `[main::U; 2]`, which does not implement the `Copy` trait + +error: aborting due to 48 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs index abe5ed81b71..b7c8c8766c0 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -1,9 +1,74 @@ +// Test that `ref mut? @ pat_with_by_move_bindings` is prevented. + #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { - match Some("hi".to_string()) { - ref op_string_ref @ Some(s) => {}, - //~^ ERROR cannot bind by-move and by-ref in the same pattern [E0009] - None => {}, + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(ref a @ b: U) {} + //~^ ERROR cannot move out of value because it is borrowed + fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + //~^ ERROR cannot move out of value because it is borrowed + + let ref a @ b = U; + //~^ ERROR cannot move out of value because it is borrowed + let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + let ref mut a @ [b, mut c] = [U, U]; + //~^ ERROR cannot move out of value because it is borrowed + let ref a @ b = u(); + //~^ ERROR cannot move out of value because it is borrowed + let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + let ref mut a @ [b, mut c] = [u(), u()]; + //~^ ERROR cannot move out of value because it is borrowed + + match Some(U) { + ref a @ Some(b) => {} + //~^ ERROR cannot move out of value because it is borrowed + None => {} + } + match Some((U, U)) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + None => {} + } + match Some([U, U]) { + ref mut a @ Some([b, mut c]) => {} + //~^ ERROR cannot move out of value because it is borrowed + None => {} + } + match Some(u()) { + ref a @ Some(b) => {} + //~^ ERROR cannot move out of value because it is borrowed + None => {} + } + match Some((u(), u())) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + //~| ERROR cannot move out of value because it is borrowed + None => {} + } + match Some([u(), u()]) { + ref mut a @ Some([b, mut c]) => {} + //~^ ERROR cannot move out of value because it is borrowed + None => {} } } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 1f70a6c437e..e5419efa00b 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -1,12 +1,237 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-by-move-and-ref.rs:5:34 +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:23:9 | -LL | ref op_string_ref @ Some(s) => {}, - | -------------------------^- - | | | - | | by-move pattern here - | by-ref pattern here +LL | let ref a @ b = U; + | -----^^^- + | | | + | | value moved into `b` here + | value borrowed, by `a`, here -error: aborting due to previous error +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:25:9 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:25:18 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + | -----^^^----- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:25:33 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (U, U); + | -----^^^- + | | | + | | value moved into `e` here + | value borrowed, by `d`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:29:9 + | +LL | let ref mut a @ [b, mut c] = [U, U]; + | ---------^^^^-^^-----^ + | | | | + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:31:9 + | +LL | let ref a @ b = u(); + | -----^^^- + | | | + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:33:9 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:33:18 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + | -----^^^----- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:33:33 + | +LL | let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); + | -----^^^- + | | | + | | value moved into `e` here + | value borrowed, by `d`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:37:9 + | +LL | let ref mut a @ [b, mut c] = [u(), u()]; + | ---------^^^^-^^-----^ + | | | | + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:41:9 + | +LL | ref a @ Some(b) => {} + | -----^^^^^^^^-^ + | | | + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:46:9 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ + | | | | + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:46:23 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^----- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:46:38 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^- + | | | + | | value moved into `e` here + | value borrowed, by `d`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:53:9 + | +LL | ref mut a @ Some([b, mut c]) => {} + | ---------^^^^^^^^^-^^-----^^ + | | | | + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:58:9 + | +LL | ref a @ Some(b) => {} + | -----^^^^^^^^-^ + | | | + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:63:9 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^ + | | | | + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:63:23 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^----- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:63:38 + | +LL | ref a @ Some((ref b @ mut c, ref d @ e)) => {} + | -----^^^- + | | | + | | value moved into `e` here + | value borrowed, by `d`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:70:9 + | +LL | ref mut a @ Some([b, mut c]) => {} + | ---------^^^^^^^^^-^^-----^^ + | | | | + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 + | +LL | fn f1(ref a @ b: U) {} + | -----^^^- + | | | + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:16:11 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | -----^^^^^^^^^^^^-----^^^^^^^^^^-^ + | | | | + | | | value moved into `e` here + | | value moved into `c` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:16:20 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | -----^^^----- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:16:35 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | -----^^^- + | | | + | | value moved into `e` here + | value borrowed, by `d`, here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 + | +LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + | ---------^^^^-^^-----^ + | | | | + | | | value moved into `c` here + | | value moved into `b` here + | value borrowed, by `a`, here + +error: aborting due to 25 previous errors -For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index e8510dfa649..58d4a9b018c 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -1,4 +1,5 @@ #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] enum Option<T> { None, @@ -8,7 +9,7 @@ enum Option<T> { fn main() { match &mut Some(1) { ref mut z @ &mut Some(ref a) => { - //~^ ERROR cannot borrow `z` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable **z = None; println!("{}", *a); @@ -22,49 +23,52 @@ fn main() { fn u() -> U { U } fn f1(ref a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable fn f2(ref mut a @ ref b: U) {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + fn f4_also_moved(ref a @ ref mut b @ c: U) {} + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `b` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref mut a @ ref b = U; - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable let ref mut a @ (ref b, ref c) = (U, U); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable let ref mut a @ ref b = u(); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable *a = u(); drop(b); let ref a @ ref mut b = u(); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = u(); drop(a); let ref mut a @ ref b = U; - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable *a = U; drop(b); let ref a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; drop(a); match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable *a = Err(U); drop(b); } @@ -72,8 +76,8 @@ fn main() { match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = U; @@ -83,52 +87,52 @@ fn main() { match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard _ => {} } match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot assign to `*a`, as it is immutable for the pattern guard _ => {} } match Ok(U) { ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable - //~| ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable + //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot move out of `b` in pattern guard //~| ERROR cannot move out of `b` in pattern guard _ => {} } match Ok(U) { ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable - //~| ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable + //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable //~| ERROR cannot move out of `a` in pattern guard //~| ERROR cannot move out of `a` in pattern guard _ => {} } let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; *c = U; let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *b = U; drop(a); let ref a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable + //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable *b = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable *c = U; //~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable drop(a); let ref mut a @ (ref b, ref c) = (U, U); - //~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable + //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable } diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 0d7b703f181..8c6ca888e07 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,282 +1,301 @@ -error: cannot borrow `z` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `a`, occurs here + | mutable borrow, by `z`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ | | | | - | | | another mutable borrow occurs here - | | also borrowed as immutable here - | first mutable borrow occurs here + | | | another mutable borrow, by `c`, occurs here + | | also borrowed as immutable, by `b`, here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `b` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `c`, occurs here + | immutable borrow, by `b`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ | | | | - | | | immutable borrow occurs here - | | immutable borrow occurs here - | mutable borrow occurs here + | | | immutable borrow, by `c`, occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ | | | | - | | | mutable borrow occurs here - | | mutable borrow occurs here - | immutable borrow occurs here + | | | mutable borrow, by `c`, occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ | | | | - | | | immutable borrow occurs here - | | immutable borrow occurs here - | mutable borrow occurs here + | | | immutable borrow, by `c`, occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here -error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- | | | - | | immutable borrow occurs here - | mutable borrow occurs here + | | immutable borrow, by `b`, occurs here + | mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11 +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ | | | - | | mutable borrow occurs here - | immutable borrow occurs here + | | mutable borrow, by `mid`, occurs here + | immutable borrow, by `a`, occurs here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | -----^^^------------- + | | | | + | | | also moved into `c` here + | | mutable borrow, by `b`, occurs here + | immutable borrow, by `a`, occurs here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:30 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ---------^^^- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -288,7 +307,7 @@ LL | **z = None; | ---------- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -300,7 +319,7 @@ LL | *a = u(); | -------- mutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -312,7 +331,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -324,7 +343,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -336,7 +355,7 @@ LL | drop(a); | - immutable borrow later used here error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -344,7 +363,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } = note: variables bound in patterns are immutable until the end of the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -352,7 +371,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa = note: variables bound in patterns are immutable until the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -360,7 +379,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -368,7 +387,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait @@ -376,7 +395,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait @@ -384,7 +403,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -396,7 +415,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -408,7 +427,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -420,7 +439,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -431,7 +450,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); LL | drop(a); | - immutable borrow later used here -error: aborting due to 45 previous errors +error: aborting due to 47 previous errors Some errors have detailed explanations: E0502, E0507, E0594. For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index f425b35630d..f5c39a7ac52 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -1,6 +1,7 @@ // Test that `ref mut x @ ref mut y` and varieties of that are not allowed. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct U; @@ -8,39 +9,42 @@ fn main() { fn u() -> U { U } fn f1(ref mut a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time fn f2(ref mut a @ ref mut b: U) {} - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time fn f3( ref mut a @ [ - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time [ref b @ .., _], [_, ref mut mid @ ..], .., [..], ] : [[U; 4]; 5] ) {} + fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot move out of value because it is borrowed let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time drop(a); let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time drop(b); let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time *a = U; let ref mut a @ ref mut b = U; - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time *b = U; let ref mut a @ ( - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time ref mut b, [ ref mut c, @@ -50,7 +54,7 @@ fn main() { ) = (U, [U, U, U]); let ref mut a @ ( - //~^ ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time ref mut b, [ ref mut c, @@ -60,37 +64,37 @@ fn main() { ) = (u(), [u(), u(), u()]); let a @ (ref mut b, ref mut c) = (U, U); - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let mut val = (U, [U, U]); let a @ (b, [c, d]) = &mut val; // Same as ^-- - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let a @ &mut ref mut b = &mut U; - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value let a @ &mut (ref mut b, ref mut c) = &mut (U, U); - //~^ ERROR cannot bind by-move with sub-bindings + //~^ ERROR borrow of moved value //~| ERROR borrow of moved value match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time } } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time *b = U; } } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time *a = Err(U); @@ -101,8 +105,8 @@ fn main() { } match Ok(U) { ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { - //~^ ERROR cannot borrow `a` as mutable more than once at a time - //~| ERROR cannot borrow `a` as mutable more than once at a time + //~^ ERROR cannot borrow value as mutable more than once at a time + //~| ERROR cannot borrow value as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time //~| ERROR cannot borrow `_` as mutable more than once at a time drop(a); diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index d07ad140cc2..4e96c6e1669 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,226 +1,265 @@ -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:46:9 | LL | let ref mut a @ ( | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | ref mut b, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `b`, occurs here LL | | [ LL | | ref mut c, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `c`, occurs here LL | | ref mut d, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `d`, occurs here LL | | ref e, - | | ----- also borrowed as immutable here + | | ----- also borrowed as immutable, by `e`, here LL | | ] LL | | ) = (U, [U, U, U]); | |_____^ -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:52:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9 | LL | let ref mut a @ ( | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | ref mut b, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `b`, occurs here LL | | [ LL | | ref mut c, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `c`, occurs here LL | | ref mut d, - | | --------- another mutable borrow occurs here + | | --------- another mutable borrow, by `d`, occurs here LL | | ref e, - | | ----- also borrowed as immutable here + | | ----- also borrowed as immutable, by `e`, here LL | | ] LL | | ) = (u(), [u(), u(), u()]); | |_________^ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:62:9 +error: borrow of moved value + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | LL | let a @ (ref mut b, ref mut c) = (U, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 + | -^^^^---------^^---------^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait + +error: borrow of moved value + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- - | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^-^^^-^^-^^ + | | | | | + | | | | value borrowed here after move + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `&mut (main::U, [main::U; 2])` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 +error: borrow of moved value + --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 | LL | let a @ &mut ref mut b = &mut U; - | ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^^^^^--------- + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `&mut main::U` which does implement the `Copy` trait -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9 +error: borrow of moved value + --> $DIR/borrowck-pat-ref-mut-twice.rs:77:9 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it + | -^^^^^^^^^---------^^---------^ + | | | | + | | | value borrowed here after move + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `&mut (main::U, main::U)` which does implement the `Copy` trait -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:88:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:88:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- | | | - | | another mutable borrow occurs here - | first mutable borrow occurs here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here -error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9 +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 | LL | ref mut a @ [ | ^-------- | | - | _________first mutable borrow occurs here + | _________first mutable borrow, by `a`, occurs here | | LL | | LL | | [ref b @ .., _], - | | ---------- also borrowed as immutable here + | | ---------- also borrowed as immutable, by `b`, here LL | | [_, ref mut mid @ ..], - | | ---------------- another mutable borrow occurs here + | | ---------------- another mutable borrow, by `mid`, occurs here LL | | .., LL | | [..], LL | | ] : [[U; 4]; 5] | |_________^ +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:22 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ---------^^^------------- + | | | | + | | | also moved into `c` here + | | another mutable borrow, by `b`, occurs here + | first mutable borrow, by `a`, occurs here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:34 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ---------^^^- + | | | + | | value moved into `c` here + | value borrowed, by `b`, here + error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:24:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -232,7 +271,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:34:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -244,7 +283,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:62:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:25 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -253,7 +292,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:66:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:21 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait @@ -262,7 +301,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:70:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:74:18 | LL | let a @ &mut ref mut b = &mut U; | ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait @@ -271,7 +310,7 @@ LL | let a @ &mut ref mut b = &mut U; | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:73:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:77:30 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait @@ -280,7 +319,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | value moved here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -292,7 +331,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:95:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -304,7 +343,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -316,7 +355,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:107:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -327,7 +366,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | drop(a); | - first borrow later used here -error: aborting due to 32 previous errors +error: aborting due to 34 previous errors -Some errors have detailed explanations: E0007, E0382, E0499. -For more information about an error, try `rustc --explain E0007`. +Some errors have detailed explanations: E0382, E0499. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs index db5aabc7a14..821d4b42962 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs @@ -1,6 +1,7 @@ // Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] #[derive(Copy, Clone)] struct C; @@ -9,12 +10,9 @@ struct NC<A, B>(A, B); fn main() { let a @ NC(b, c) = NC(C, C); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value + //~^ ERROR use of moved value let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - //~^ ERROR cannot bind by-move with sub-bindings - //~| ERROR use of moved value - //~| ERROR cannot bind by-move with sub-bindings + //~^ ERROR use of moved value //~| ERROR use of moved value } diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr index cfc35d6c32a..7e89008a604 100644 --- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr +++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr @@ -1,23 +1,5 @@ -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:11:9 - | -LL | let a @ NC(b, c) = NC(C, C); - | ^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:15:9 - | -LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it - -error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/copy-and-move-mixed.rs:15:19 - | -LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); - | ^^^^^^^^^^^^ binds an already bound by-move value by moving it - error[E0382]: use of moved value - --> $DIR/copy-and-move-mixed.rs:11:19 + --> $DIR/copy-and-move-mixed.rs:12:19 | LL | let a @ NC(b, c) = NC(C, C); | ----------^- -------- move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait @@ -45,7 +27,6 @@ LL | let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); | = note: move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0007, E0382. -For more information about an error, try `rustc --explain E0007`. +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs index 1127d114145..b40c3e3358a 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -8,6 +8,7 @@ // this would create problems for the generalization aforementioned. #![feature(bindings_after_at)] +#![feature(move_ref_pattern)] fn main() { struct NotCopy; @@ -24,14 +25,26 @@ fn main() { let ref a @ b = &NotCopy; // OK let _: &&NotCopy = a; - let ref a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern - let ref mut a @ b = NotCopy; //~ ERROR cannot bind by-move and by-ref in the same pattern + let ref a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; + let ref mut a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed + //~^ ERROR cannot move out of `_` because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; match Ok(NotCopy) { - Ok(ref a @ b) | Err(ref a @ b) => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern + Ok(ref a @ b) | Err(b @ ref a) => { + //~^ ERROR cannot move out of value because it is borrowed + //~| ERROR borrow of moved value + let _a: &NotCopy = a; + let _b: NotCopy = b; + } } match NotCopy { - ref a @ b => {} - //~^ ERROR cannot bind by-move and by-ref in the same pattern + ref a @ b => { + //~^ ERROR cannot move out of value because it is borrowed + let _a: &NotCopy = a; + let _b: NotCopy = b; + } } } diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr index b6709a8a40e..697a8b96e63 100644 --- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr +++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr @@ -1,41 +1,61 @@ -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:27:17 +error: cannot move out of value because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:28:9 | LL | let ref a @ b = NotCopy; - | --------^ + | -----^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | value moved into `b` here + | value borrowed, by `a`, here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:28:21 +error: cannot move out of value because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:31:9 | LL | let ref mut a @ b = NotCopy; - | ------------^ + | ---------^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | value moved into `b` here + | value borrowed, by `a`, here + +error: cannot move out of value because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:36:12 + | +LL | Ok(ref a @ b) | Err(b @ ref a) => { + | -----^^^- + | | | + | | value moved into `b` here + | value borrowed, by `a`, here -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:30:20 +error: borrow of moved value + --> $DIR/default-binding-modes-both-sides-independent.rs:36:29 | -LL | Ok(ref a @ b) | Err(ref a @ b) => {} - | --------^ --------^ - | | | | | - | | | | by-move pattern here - | | | by-ref pattern here - | | by-move pattern here - | by-ref pattern here +LL | Ok(ref a @ b) | Err(b @ ref a) => { + | -^^^----- + | | | + | | value borrowed here after move + | value moved into `b` here + | move occurs because `b` has type `main::NotCopy` which does implement the `Copy` trait -error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/default-binding-modes-both-sides-independent.rs:34:17 +error: cannot move out of value because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:44:9 | -LL | ref a @ b => {} - | --------^ +LL | ref a @ b => { + | -----^^^- | | | - | | by-move pattern here - | by-ref pattern here + | | value moved into `b` here + | value borrowed, by `a`, here + +error[E0505]: cannot move out of `_` because it is borrowed + --> $DIR/default-binding-modes-both-sides-independent.rs:31:21 + | +LL | let ref mut a @ b = NotCopy; + | ------------^ + | | | + | | move out of value occurs here + | borrow of value occurs here +LL | +LL | let _a: &NotCopy = a; + | - borrow later used here -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0009`. +For more information about this error, try `rustc --explain E0505`. diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs new file mode 100644 index 00000000000..d2d4e61e049 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs @@ -0,0 +1,31 @@ +// check-pass + +#![feature(move_ref_pattern)] + +fn main() {} + +struct U; + +fn slice() { + let mut arr = [U, U, U, U, U, U, U, U]; + let [ref _x0, _x1, _, mut _x3, .., ref _x6, _x7] = arr; + _x3 = U; + let [ref mut _x0, _, ref _x2, _, _x4, ref mut _x5, _x6, _] = arr; + *_x5 = U; + let [_, _, _x2, _, _, _x5, _, _] = arr; + *_x0 = U; + let [ref _x0, ..] = arr; + let [_x0, ..] = arr; +} + +fn tuple() { + let mut tup = (U, U, U, U, U); + let (ref _x0, mut _x1, ref _x2, ..) = tup; + _x1 = U; + let (ref mut _x0, _, _, ref _x3, _x4) = tup; + let (_, _, _, _x3, _) = tup; + *_x0 = U; + drop(_x2); + drop(tup.2); + let (_x0, _, _, ..) = tup; +} diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs new file mode 100644 index 00000000000..3ee008fd84f --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs @@ -0,0 +1,50 @@ +#![feature(move_ref_pattern)] + +fn main() {} + +struct U; + +fn slice() { + let mut arr = [U, U, U, U, U]; + let hold_all = &arr; + let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; //~ ERROR cannot move out of `arr[..]` + _x1 = U; //~ ERROR cannot assign twice to immutable variable `_x1` + drop(hold_all); + let [_x0, ..] = arr; //~ ERROR cannot move out of `arr[..]` + drop(_x0_hold); + let [_, _, ref mut _x2, _x3, mut _x4] = arr; + //~^ ERROR cannot borrow `arr[..]` as mutable + //~| ERROR cannot move out of `arr[..]` because it is borrowed + //~| ERROR cannot move out of `arr[..]` because it is borrowed + drop(xs_hold); +} + +fn tuple() { + let mut tup = (U, U, U, U); + let (ref _x0, _x1, ref _x2, ..) = tup; + _x1 = U; //~ ERROR cannot assign twice to immutable variable + let _x0_hold = &mut tup.0; //~ ERROR cannot borrow `tup.0` as mutable because it is also + let (ref mut _x0_hold, ..) = tup; //~ ERROR cannot borrow `tup.0` as mutable because it is also + *_x0 = U; //~ ERROR cannot assign to `*_x0` which is behind a `&` reference + *_x2 = U; //~ ERROR cannot assign to `*_x2` which is behind a `&` reference + drop(tup.1); //~ ERROR use of moved value: `tup.1` + let _x1_hold = &tup.1; //~ ERROR borrow of moved value: `tup.1` + let (.., ref mut _x3) = tup; + let _x3_hold = &tup.3; //~ ERROR cannot borrow `tup.3` as immutable + let _x3_hold = &mut tup.3; //~ ERROR cannot borrow `tup.3` as mutable more + let (.., ref mut _x4_hold) = tup; //~ ERROR cannot borrow `tup.3` as mutable more + let (.., ref _x4_hold) = tup; //~ ERROR cannot borrow `tup.3` as immutable + drop(_x3); +} + +fn closure() { + let mut tup = (U, U, U); + let c1 = || { + let (ref _x0, _x1, _) = tup; + }; + let c2 = || { + //~^ ERROR use of moved value + let (ref mut _x0, _, _x2) = tup; + }; + drop(c1); +} diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr new file mode 100644 index 00000000000..d718ee29cf9 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -0,0 +1,208 @@ +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:10:24 + | +LL | let hold_all = &arr; + | ---- borrow of `arr` occurs here +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ^^^ move out of `arr[..]` occurs here +LL | _x1 = U; +LL | drop(hold_all); + | -------- borrow later used here + +error[E0384]: cannot assign twice to immutable variable `_x1` + --> $DIR/borrowck-move-ref-pattern.rs:11:5 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | --- + | | + | first assignment to `_x1` + | help: make this binding mutable: `mut _x1` +LL | _x1 = U; + | ^^^^^^^ cannot assign twice to immutable variable + +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:13:10 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ------------ borrow of `arr[..]` occurs here +... +LL | let [_x0, ..] = arr; + | ^^^ move out of `arr[..]` occurs here +LL | drop(_x0_hold); + | -------- borrow later used here + +error[E0502]: cannot borrow `arr[..]` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-move-ref-pattern.rs:15:16 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ---------------- immutable borrow occurs here +... +LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; + | ^^^^^^^^^^^ mutable borrow occurs here +... +LL | drop(xs_hold); + | ------- immutable borrow later used here + +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:15:29 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ---------------- borrow of `arr[..]` occurs here +... +LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; + | ^^^ move out of `arr[..]` occurs here +... +LL | drop(xs_hold); + | ------- borrow later used here + +error[E0505]: cannot move out of `arr[..]` because it is borrowed + --> $DIR/borrowck-move-ref-pattern.rs:15:34 + | +LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; + | ---------------- borrow of `arr[..]` occurs here +... +LL | let [_, _, ref mut _x2, _x3, mut _x4] = arr; + | ^^^^^^^ move out of `arr[..]` occurs here +... +LL | drop(xs_hold); + | ------- borrow later used here + +error[E0384]: cannot assign twice to immutable variable `_x1` + --> $DIR/borrowck-move-ref-pattern.rs:25:5 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | --- + | | + | first assignment to `_x1` + | help: make this binding mutable: `mut _x1` +LL | _x1 = U; + | ^^^^^^^ cannot assign twice to immutable variable + +error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-move-ref-pattern.rs:26:20 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- immutable borrow occurs here +LL | _x1 = U; +LL | let _x0_hold = &mut tup.0; + | ^^^^^^^^^^ mutable borrow occurs here +LL | let (ref mut _x0_hold, ..) = tup; +LL | *_x0 = U; + | -------- immutable borrow later used here + +error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-move-ref-pattern.rs:27:10 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- immutable borrow occurs here +... +LL | let (ref mut _x0_hold, ..) = tup; + | ^^^^^^^^^^^^^^^^ mutable borrow occurs here +LL | *_x0 = U; + | -------- immutable borrow later used here + +error[E0594]: cannot assign to `*_x0` which is behind a `&` reference + --> $DIR/borrowck-move-ref-pattern.rs:28:5 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- help: consider changing this to be a mutable reference: `ref mut _x0` +... +LL | *_x0 = U; + | ^^^^^^^^ `_x0` is a `&` reference, so the data it refers to cannot be written + +error[E0594]: cannot assign to `*_x2` which is behind a `&` reference + --> $DIR/borrowck-move-ref-pattern.rs:29:5 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | ------- help: consider changing this to be a mutable reference: `ref mut _x2` +... +LL | *_x2 = U; + | ^^^^^^^^ `_x2` is a `&` reference, so the data it refers to cannot be written + +error[E0382]: use of moved value: `tup.1` + --> $DIR/borrowck-move-ref-pattern.rs:30:10 + | +LL | let (ref _x0, _x1, ref _x2, ..) = tup; + | --- value moved here +... +LL | drop(tup.1); + | ^^^^^ value used here after move + | + = note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `tup.1` + --> $DIR/borrowck-move-ref-pattern.rs:31:20 + | +LL | drop(tup.1); + | ----- value moved here +LL | let _x1_hold = &tup.1; + | ^^^^^^ value borrowed here after move + | + = note: move occurs because `tup.1` has type `U`, which does not implement the `Copy` trait + +error[E0502]: cannot borrow `tup.3` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-move-ref-pattern.rs:33:20 + | +LL | let (.., ref mut _x3) = tup; + | ----------- mutable borrow occurs here +LL | let _x3_hold = &tup.3; + | ^^^^^^ immutable borrow occurs here +... +LL | drop(_x3); + | --- mutable borrow later used here + +error[E0499]: cannot borrow `tup.3` as mutable more than once at a time + --> $DIR/borrowck-move-ref-pattern.rs:34:20 + | +LL | let (.., ref mut _x3) = tup; + | ----------- first mutable borrow occurs here +LL | let _x3_hold = &tup.3; +LL | let _x3_hold = &mut tup.3; + | ^^^^^^^^^^ second mutable borrow occurs here +... +LL | drop(_x3); + | --- first borrow later used here + +error[E0499]: cannot borrow `tup.3` as mutable more than once at a time + --> $DIR/borrowck-move-ref-pattern.rs:35:14 + | +LL | let (.., ref mut _x3) = tup; + | ----------- first mutable borrow occurs here +... +LL | let (.., ref mut _x4_hold) = tup; + | ^^^^^^^^^^^^^^^^ second mutable borrow occurs here +LL | let (.., ref _x4_hold) = tup; +LL | drop(_x3); + | --- first borrow later used here + +error[E0502]: cannot borrow `tup.3` as immutable because it is also borrowed as mutable + --> $DIR/borrowck-move-ref-pattern.rs:36:14 + | +LL | let (.., ref mut _x3) = tup; + | ----------- mutable borrow occurs here +... +LL | let (.., ref _x4_hold) = tup; + | ^^^^^^^^^^^^ immutable borrow occurs here +LL | drop(_x3); + | --- mutable borrow later used here + +error[E0382]: use of moved value: `tup` + --> $DIR/borrowck-move-ref-pattern.rs:45:14 + | +LL | let mut tup = (U, U, U); + | ------- move occurs because `tup` has type `(U, U, U)`, which does not implement the `Copy` trait +LL | let c1 = || { + | -- value moved into closure here +LL | let (ref _x0, _x1, _) = tup; + | --- variable moved due to use in closure +LL | }; +LL | let c2 = || { + | ^^ value used here after move +LL | +LL | let (ref mut _x0, _, _x2) = tup; + | --- use occurs due to use in closure + +error: aborting due to 18 previous errors + +Some errors have detailed explanations: E0382, E0384, E0499, E0502, E0505, E0594. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs b/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs new file mode 100644 index 00000000000..08fb5cd2e16 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs @@ -0,0 +1,15 @@ +// When conflicts between by-move bindings in `by_move_1 @ has_by_move` patterns +// happen and that code is unreachable according to borrowck, we accept this code. +// In particular, we want to ensure here that an ICE does not happen, which it did originally. + +// check-pass + +#![feature(move_ref_pattern)] +#![feature(bindings_after_at)] + +fn main() { + return; + + struct S; + let a @ (b, c) = (S, S); +} diff --git a/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs new file mode 100644 index 00000000000..fb92eb1ba32 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs @@ -0,0 +1,23 @@ +fn main() { + #[derive(Clone)] + struct X { + x: (), + } + let mut tup = (X { x: () }, X { x: () }); + match Some(tup.clone()) { + Some((y, ref z)) => {} + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + None => panic!(), + } + + let (ref a, b) = tup.clone(); + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + + let (a, mut b) = &tup; + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + //~| ERROR cannot move out of a shared reference + + let (mut a, b) = &mut tup; + //~^ ERROR binding by-move and by-ref in the same pattern is unstable + //~| ERROR cannot move out of a mutable reference +} diff --git a/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr new file mode 100644 index 00000000000..8aef220c375 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr @@ -0,0 +1,66 @@ +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:8:15 + | +LL | Some((y, ref z)) => {} + | ^ ----- by-ref pattern here + | | + | by-move pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:13:17 + | +LL | let (ref a, b) = tup.clone(); + | ----- ^ by-move pattern here + | | + | by-ref pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:16:13 + | +LL | let (a, mut b) = &tup; + | - ^^^^^ by-move pattern here + | | + | by-ref pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0658]: binding by-move and by-ref in the same pattern is unstable + --> $DIR/feature-gate-move_ref_pattern.rs:20:10 + | +LL | let (mut a, b) = &mut tup; + | ^^^^^ - by-ref pattern here + | | + | by-move pattern here + | + = note: for more information, see https://github.com/rust-lang/rust/issues/68354 + = help: add `#![feature(move_ref_pattern)]` to the crate attributes to enable + +error[E0507]: cannot move out of a shared reference + --> $DIR/feature-gate-move_ref_pattern.rs:16:22 + | +LL | let (a, mut b) = &tup; + | ----- ^^^^ + | | + | data moved here + | move occurs because `b` has type `main::X`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of a mutable reference + --> $DIR/feature-gate-move_ref_pattern.rs:20:22 + | +LL | let (mut a, b) = &mut tup; + | ----- ^^^^^^^^ + | | + | data moved here + | move occurs because `a` has type `main::X`, which does not implement the `Copy` trait + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0507, E0658. +For more information about an error, try `rustc --explain E0507`. diff --git a/src/test/ui/pattern/move-ref-patterns/issue-53840.rs b/src/test/ui/pattern/move-ref-patterns/issue-53840.rs new file mode 100644 index 00000000000..ab7d10d9f83 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/issue-53840.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(move_ref_pattern)] + +enum E { + Foo(String, String, String), +} + +struct Bar { + a: String, + b: String, +} + +fn main() { + let bar = Bar { a: "1".to_string(), b: "2".to_string() }; + match E::Foo("".into(), "".into(), "".into()) { + E::Foo(a, b, ref c) => {} + } + match bar { + Bar { a, ref b } => {} + } +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs new file mode 100644 index 00000000000..4c3ca62e165 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs @@ -0,0 +1,122 @@ +#![feature(move_ref_pattern)] + +fn main() { + struct S; // Not `Copy`. + + let mut tup0 = (S, S); + let mut tup1 = (S, S, S); + let tup2 = (S, S); + let tup3 = (S, S, S); + let tup4 = (S, S); + let mut arr0 = [S, S, S]; + let mut arr1 = [S, S, S, S, S]; + let arr2 = [S, S, S]; + let arr3 = [S, S, S, S, S]; + + // The `mov` bindings require that we capture the scrutinees by-move. + let mut closure = || { + // Tuples... + let (ref mut borrow, mov) = tup0; + let (mov, _, ref mut borrow) = tup1; + let (ref borrow, mov) = tup2; + let (mov, _, ref borrow) = tup3; + let (ref borrow, mov) = tup4; + // Arrays... + let [mov @ .., ref borrow] = arr0; + let [_, ref mut borrow @ .., _, mov] = arr1; + let [mov @ .., ref borrow] = arr2; + let [_, ref borrow @ .., _, mov] = arr3; + }; + + // Now we try to borrow and move the captures, which should result in errors... + // ...for tuples: + drop(&tup0); //~ ERROR borrow of moved value: `tup0` + drop(&tup1); //~ ERROR borrow of moved value: `tup1` + drop(&tup2); //~ ERROR borrow of moved value: `tup2` + drop(&tup3); //~ ERROR borrow of moved value: `tup3` + // Ostensibly this should compile. + // However, because closures don't capture individual fields, which is changed in RFC 2229, + // this won't compile because the entire product is moved into the closure. + // The same applies to the array patterns below. + drop(&tup4.0); //~ ERROR borrow of moved value: `tup4` + // ...for arrays: + drop(&arr0); //~ ERROR borrow of moved value: `arr0` + let [_, mov1, mov2, mov3, _] = &arr1; //~ ERROR borrow of moved value: `arr1` + drop(&arr2); //~ ERROR borrow of moved value: `arr2` + let [_, mov1, mov2, mov3, _] = &arr3; //~ ERROR borrow of moved value: `arr3` + + // Let's redo ^--- with a `match` + sum type: + macro_rules! m { + ($p:pat = $s:expr) => { + match $s { + Some($p) => {} + _ => {} + } + }; + } + let mut tup0: Option<(S, S)> = None; + let mut tup1: Option<(S, S, S)> = None; + let tup2: Option<(S, S)> = None; + let tup3: Option<(S, S, S)> = None; + let tup4: Option<(S, S)> = None; + let mut arr0: Option<[S; 3]> = None; + let mut arr1: Option<[S; 5]> = None; + let arr2: Option<[S; 3]> = None; + let arr3: Option<[S; 5]> = None; + let mut closure = || { + m!((ref mut borrow, mov) = tup0); + m!((mov, _, ref mut borrow) = tup1); + m!((ref borrow, mov) = tup2); + m!((mov, _, ref borrow) = tup3); + m!((ref borrow, mov) = tup4); + m!([mov @ .., ref borrow] = arr0); + m!([_, ref mut borrow @ .., _, mov] = arr1); + m!([mov @ .., ref borrow] = arr2); + m!([_, ref borrow @ .., _, mov] = arr3); + }; + drop(&tup0); //~ ERROR borrow of moved value: `tup0` + drop(&tup1); //~ ERROR borrow of moved value: `tup1` + drop(&tup2); //~ ERROR borrow of moved value: `tup2` + drop(&tup3); //~ ERROR borrow of moved value: `tup3` + m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4` + drop(&arr0); //~ ERROR borrow of moved value: `arr0` + m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1` + drop(&arr2); //~ ERROR borrow of moved value: `arr2` + m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3` + + // Let's redo ^--- with `if let` (which may diverge from `match` in the future): + macro_rules! m { + ($p:pat = $s:expr) => { + if let Some($p) = $s {} + }; + } + let mut tup0: Option<(S, S)> = None; + let mut tup1: Option<(S, S, S)> = None; + let tup2: Option<(S, S)> = None; + let tup3: Option<(S, S, S)> = None; + let tup4: Option<(S, S)> = None; + let mut arr0: Option<[S; 3]> = None; + let mut arr1: Option<[S; 5]> = None; + let arr2: Option<[S; 3]> = None; + let arr3: Option<[S; 5]> = None; + let mut closure = || { + m!((ref mut borrow, mov) = tup0); + m!((mov, _, ref mut borrow) = tup1); + m!((ref borrow, mov) = tup2); + m!((mov, _, ref borrow) = tup3); + m!((ref borrow, mov) = tup4); + m!([mov @ .., ref borrow] = arr0); + m!([_, ref mut borrow @ .., _, mov] = arr1); + m!([mov @ .., ref borrow] = arr2); + m!([_, ref borrow @ .., _, mov] = arr3); + }; + drop(&tup0); //~ ERROR borrow of moved value: `tup0` + drop(&tup1); //~ ERROR borrow of moved value: `tup1` + drop(&tup2); //~ ERROR borrow of moved value: `tup2` + drop(&tup3); //~ ERROR borrow of moved value: `tup3` + m!((ref x, _) = &tup4); //~ ERROR borrow of moved value: `tup4` + drop(&arr0); //~ ERROR borrow of moved value: `arr0` + m!([_, mov1, mov2, mov3, _] = &arr1); //~ ERROR borrow of moved value: `arr1` + drop(&arr2); //~ ERROR borrow of moved value: `arr2` + m!([_, mov1, mov2, mov3, _] = &arr3); //~ ERROR borrow of moved value: `arr3` +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr new file mode 100644 index 00000000000..9159e3e2213 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.stderr @@ -0,0 +1,404 @@ +error[E0382]: borrow of moved value: `tup0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:33:10 + | +LL | let mut tup0 = (S, S); + | -------- move occurs because `tup0` has type `(main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | // Tuples... +LL | let (ref mut borrow, mov) = tup0; + | ---- variable moved due to use in closure +... +LL | drop(&tup0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:34:10 + | +LL | let mut tup1 = (S, S, S); + | -------- move occurs because `tup1` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (mov, _, ref mut borrow) = tup1; + | ---- variable moved due to use in closure +... +LL | drop(&tup1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:35:10 + | +LL | let tup2 = (S, S); + | ---- move occurs because `tup2` has type `(main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (ref borrow, mov) = tup2; + | ---- variable moved due to use in closure +... +LL | drop(&tup2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:36:10 + | +LL | let tup3 = (S, S, S); + | ---- move occurs because `tup3` has type `(main::S, main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (mov, _, ref borrow) = tup3; + | ---- variable moved due to use in closure +... +LL | drop(&tup3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup4` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:41:10 + | +LL | let tup4 = (S, S); + | ---- move occurs because `tup4` has type `(main::S, main::S)`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let (ref borrow, mov) = tup4; + | ---- variable moved due to use in closure +... +LL | drop(&tup4.0); + | ^^^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:43:10 + | +LL | let mut arr0 = [S, S, S]; + | -------- move occurs because `arr0` has type `[main::S; 3]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [mov @ .., ref borrow] = arr0; + | ---- variable moved due to use in closure +... +LL | drop(&arr0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:44:36 + | +LL | let mut arr1 = [S, S, S, S, S]; + | -------- move occurs because `arr1` has type `[main::S; 5]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [_, ref mut borrow @ .., _, mov] = arr1; + | ---- variable moved due to use in closure +... +LL | let [_, mov1, mov2, mov3, _] = &arr1; + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:45:10 + | +LL | let arr2 = [S, S, S]; + | ---- move occurs because `arr2` has type `[main::S; 3]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [mov @ .., ref borrow] = arr2; + | ---- variable moved due to use in closure +... +LL | drop(&arr2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:46:36 + | +LL | let arr3 = [S, S, S, S, S]; + | ---- move occurs because `arr3` has type `[main::S; 5]`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | let [_, ref borrow @ .., _, mov] = arr3; + | ---- variable moved due to use in closure +... +LL | let [_, mov1, mov2, mov3, _] = &arr3; + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:77:10 + | +LL | let mut tup0: Option<(S, S)> = None; + | -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); + | ---- variable moved due to use in closure +... +LL | drop(&tup0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:78:10 + | +LL | let mut tup1: Option<(S, S, S)> = None; + | -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); +LL | m!((mov, _, ref mut borrow) = tup1); + | ---- variable moved due to use in closure +... +LL | drop(&tup1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:79:10 + | +LL | let tup2: Option<(S, S)> = None; + | ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup2); + | ---- variable moved due to use in closure +... +LL | drop(&tup2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:80:10 + | +LL | let tup3: Option<(S, S, S)> = None; + | ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((mov, _, ref borrow) = tup3); + | ---- variable moved due to use in closure +... +LL | drop(&tup3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup4` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:81:21 + | +LL | let tup4: Option<(S, S)> = None; + | ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup4); + | ---- variable moved due to use in closure +... +LL | m!((ref x, _) = &tup4); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:82:10 + | +LL | let mut arr0: Option<[S; 3]> = None; + | -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr0); + | ---- variable moved due to use in closure +... +LL | drop(&arr0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:83:35 + | +LL | let mut arr1: Option<[S; 5]> = None; + | -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref mut borrow @ .., _, mov] = arr1); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:84:10 + | +LL | let arr2: Option<[S; 3]> = None; + | ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +LL | let arr3: Option<[S; 5]> = None; +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr2); + | ---- variable moved due to use in closure +... +LL | drop(&arr2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:85:35 + | +LL | let arr3: Option<[S; 5]> = None; + | ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref borrow @ .., _, mov] = arr3); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:113:10 + | +LL | let mut tup0: Option<(S, S)> = None; + | -------- move occurs because `tup0` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); + | ---- variable moved due to use in closure +... +LL | drop(&tup0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:114:10 + | +LL | let mut tup1: Option<(S, S, S)> = None; + | -------- move occurs because `tup1` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +LL | m!((ref mut borrow, mov) = tup0); +LL | m!((mov, _, ref mut borrow) = tup1); + | ---- variable moved due to use in closure +... +LL | drop(&tup1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:115:10 + | +LL | let tup2: Option<(S, S)> = None; + | ---- move occurs because `tup2` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup2); + | ---- variable moved due to use in closure +... +LL | drop(&tup2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:116:10 + | +LL | let tup3: Option<(S, S, S)> = None; + | ---- move occurs because `tup3` has type `std::option::Option<(main::S, main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((mov, _, ref borrow) = tup3); + | ---- variable moved due to use in closure +... +LL | drop(&tup3); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `tup4` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:117:21 + | +LL | let tup4: Option<(S, S)> = None; + | ---- move occurs because `tup4` has type `std::option::Option<(main::S, main::S)>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!((ref borrow, mov) = tup4); + | ---- variable moved due to use in closure +... +LL | m!((ref x, _) = &tup4); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr0` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:118:10 + | +LL | let mut arr0: Option<[S; 3]> = None; + | -------- move occurs because `arr0` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr0); + | ---- variable moved due to use in closure +... +LL | drop(&arr0); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr1` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:119:35 + | +LL | let mut arr1: Option<[S; 5]> = None; + | -------- move occurs because `arr1` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +... +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref mut borrow @ .., _, mov] = arr1); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr1); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr2` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:120:10 + | +LL | let arr2: Option<[S; 3]> = None; + | ---- move occurs because `arr2` has type `std::option::Option<[main::S; 3]>`, which does not implement the `Copy` trait +LL | let arr3: Option<[S; 5]> = None; +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([mov @ .., ref borrow] = arr2); + | ---- variable moved due to use in closure +... +LL | drop(&arr2); + | ^^^^^ value borrowed here after move + +error[E0382]: borrow of moved value: `arr3` + --> $DIR/move-ref-patterns-closure-captures-inside.rs:121:35 + | +LL | let arr3: Option<[S; 5]> = None; + | ---- move occurs because `arr3` has type `std::option::Option<[main::S; 5]>`, which does not implement the `Copy` trait +LL | let mut closure = || { + | -- value moved into closure here +... +LL | m!([_, ref borrow @ .., _, mov] = arr3); + | ---- variable moved due to use in closure +... +LL | m!([_, mov1, mov2, mov3, _] = &arr3); + | ^^^^^ value borrowed here after move + +error: aborting due to 27 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs new file mode 100644 index 00000000000..e1844d36e4a --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(move_ref_pattern)] + +fn main() { + struct U; + fn accept_fn_once(_: impl FnOnce()) {} + fn accept_fn_mut(_: impl FnMut()) {} + fn accept_fn(_: impl Fn()) {} + + let mut tup = (U, U, U); + let (ref _x0, _x1, ref mut _x2) = tup; + let c1 = || { + drop::<&U>(_x0); + drop::<U>(_x1); + drop::<&mut U>(_x2); + }; + accept_fn_once(c1); + + let c2 = || { + drop::<&U>(_x0); + drop::<&mut U>(_x2); + }; + accept_fn_mut(c2); + + let c3 = || { + drop::<&U>(_x0); + }; + accept_fn(c3); +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs new file mode 100644 index 00000000000..7f1c02c05cb --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs @@ -0,0 +1,34 @@ +#![feature(move_ref_pattern)] + +fn main() { + struct U; + fn accept_fn_once(_: &impl FnOnce()) {} + fn accept_fn_mut(_: &impl FnMut()) {} + fn accept_fn(_: &impl Fn()) {} + + let mut tup = (U, U, U); + let (ref _x0, _x1, ref mut _x2) = tup; + let c1 = || { + //~^ ERROR expected a closure that implements the `FnMut` + //~| ERROR expected a closure that implements the `Fn` + drop::<&U>(_x0); + drop::<U>(_x1); + drop::<&mut U>(_x2); + }; + accept_fn_once(&c1); + accept_fn_mut(&c1); + accept_fn(&c1); + + let c2 = || { + //~^ ERROR expected a closure that implements the `Fn` + drop::<&U>(_x0); + drop::<&mut U>(_x2); + }; + accept_fn_mut(&c2); + accept_fn(&c2); + + let c3 = || { + drop::<&U>(_x0); + }; + accept_fn(&c3); +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr new file mode 100644 index 00000000000..ca82353c1c9 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr @@ -0,0 +1,39 @@ +error[E0525]: expected a closure that implements the `FnMut` trait, but this closure only implements `FnOnce` + --> $DIR/move-ref-patterns-closure-captures.rs:11:14 + | +LL | let c1 = || { + | ^^ this closure implements `FnOnce`, not `FnMut` +... +LL | drop::<U>(_x1); + | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment +... +LL | accept_fn_mut(&c1); + | ------------- the requirement to implement `FnMut` derives from here + +error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce` + --> $DIR/move-ref-patterns-closure-captures.rs:11:14 + | +LL | let c1 = || { + | ^^ this closure implements `FnOnce`, not `Fn` +... +LL | drop::<U>(_x1); + | --- closure is `FnOnce` because it moves the variable `_x1` out of its environment +... +LL | accept_fn(&c1); + | --------- the requirement to implement `Fn` derives from here + +error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut` + --> $DIR/move-ref-patterns-closure-captures.rs:22:14 + | +LL | let c2 = || { + | ^^ this closure implements `FnMut`, not `Fn` +... +LL | drop::<&mut U>(_x2); + | --- closure is `FnMut` because it mutates the variable `_x2` here +... +LL | accept_fn(&c2); + | --------- the requirement to implement `Fn` derives from here + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0525`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs new file mode 100644 index 00000000000..5c51c47d979 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs @@ -0,0 +1,16 @@ +#![feature(move_ref_pattern)] + +fn main() { + struct U; + + // A tuple is a "non-reference pattern". + // A `mut` binding pattern resets the binding mode to by-value. + + let p = (U, U); + let (a, mut b) = &p; + //~^ ERROR cannot move out of a shared reference + + let mut p = (U, U); + let (a, mut b) = &mut p; + //~^ ERROR cannot move out of a mutable reference +} diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr new file mode 100644 index 00000000000..fe7f71e6c46 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr @@ -0,0 +1,21 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/move-ref-patterns-default-binding-modes.rs:10:22 + | +LL | let (a, mut b) = &p; + | ----- ^^ + | | + | data moved here + | move occurs because `b` has type `main::U`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of a mutable reference + --> $DIR/move-ref-patterns-default-binding-modes.rs:14:22 + | +LL | let (a, mut b) = &mut p; + | ----- ^^^^^^ + | | + | data moved here + | move occurs because `b` has type `main::U`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs new file mode 100644 index 00000000000..c78695390b5 --- /dev/null +++ b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs @@ -0,0 +1,81 @@ +// run-pass + +// This test checks the dynamic semantics and drop order of pattern matching +// where a product pattern has both a by-move and by-ref binding. + +#![feature(move_ref_pattern)] + +use std::cell::RefCell; +use std::rc::Rc; + +struct X { + x: Box<usize>, + d: DropOrderListPtr, +} + +type DropOrderListPtr = Rc<RefCell<Vec<usize>>>; + +impl Drop for X { + fn drop(&mut self) { + self.d.borrow_mut().push(*self.x); + } +} + +enum DoubleOption<T, U> { + Some2(T, U), + _None2, +} + +fn main() { + let d: DropOrderListPtr = <_>::default(); + { + let mk = |v| X { x: Box::new(v), d: d.clone() }; + let check = |a1: &X, a2, b1: &X, b2| { + assert_eq!(*a1.x, a2); + assert_eq!(*b1.x, b2); + }; + + let x = DoubleOption::Some2(mk(1), mk(2)); + match x { + DoubleOption::Some2(ref a, b) => check(a, 1, &b, 2), + DoubleOption::_None2 => panic!(), + } + let x = DoubleOption::Some2(mk(3), mk(4)); + match x { + DoubleOption::Some2(a, ref b) => check(&a, 3, b, 4), + DoubleOption::_None2 => panic!(), + } + match DoubleOption::Some2(mk(5), mk(6)) { + DoubleOption::Some2(ref a, b) => check(a, 5, &b, 6), + DoubleOption::_None2 => panic!(), + } + match DoubleOption::Some2(mk(7), mk(8)) { + DoubleOption::Some2(a, ref b) => check(&a, 7, b, 8), + DoubleOption::_None2 => panic!(), + } + { + let (a, ref b) = (mk(9), mk(10)); + let (ref c, d) = (mk(11), mk(12)); + check(&a, 9, b, 10); + check(c, 11, &d, 12); + } + fn fun([a, ref mut b, ref xs @ .., ref c, d]: [X; 6]) { + assert_eq!(*a.x, 13); + assert_eq!(*b.x, 14); + assert_eq!(&[*xs[0].x, *xs[1].x], &[15, 16]); + assert_eq!(*c.x, 17); + assert_eq!(*d.x, 18); + } + fun([mk(13), mk(14), mk(15), mk(16), mk(17), mk(18)]); + + let lam = |(a, ref b, c, ref mut d): (X, X, X, X)| { + assert_eq!(*a.x, 19); + assert_eq!(*b.x, 20); + assert_eq!(*c.x, 21); + assert_eq!(*d.x, 22); + }; + lam((mk(19), mk(20), mk(21), mk(22))); + } + let expected = [2, 3, 6, 5, 7, 8, 12, 11, 9, 10, 18, 13, 14, 15, 16, 17, 21, 19, 20, 22, 4, 1]; + assert_eq!(&*d.borrow(), &expected); +} diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs index 31620216e82..84552f2e733 100644 --- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs +++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs @@ -2,7 +2,7 @@ // outside of slice (+ ident patterns witin those), tuple, // and tuple struct patterns and that duplicates are caught in these contexts. -#![feature(slice_patterns, box_patterns)] +#![feature(box_patterns)] fn main() {} |
