]> git.lizzy.rs Git - rust.git/commitdiff
move_ref_patterns: introduce tests
authorMazdak Farrokhzad <twingoow@gmail.com>
Sun, 19 Jan 2020 01:47:01 +0000 (02:47 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Sun, 2 Feb 2020 13:13:07 +0000 (14:13 +0100)
bindings_after_at: harden tests

51 files changed:
src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs [deleted file]
src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr [deleted file]
src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs [deleted file]
src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr [deleted file]
src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs [deleted file]
src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr [deleted file]
src/test/ui/drop/dynamic-drop-async.rs
src/test/ui/drop/dynamic-drop.rs
src/test/ui/error-codes/E0009.rs [deleted file]
src/test/ui/error-codes/E0009.stderr [deleted file]
src/test/ui/issues/issue-53840.rs [deleted file]
src/test/ui/issues/issue-53840.stderr [deleted file]
src/test/ui/moves/move-out-of-slice-2.rs
src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs
src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs
src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs [new file with mode: 0644]
src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr [new file with mode: 0644]
src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs [new file with mode: 0644]
src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr [new file with mode: 0644]
src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs
src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.stderr [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/issue-53840.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.stderr [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.stderr [new file with mode: 0644]
src/test/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs [new file with mode: 0644]
src/test/ui/pattern/rest-pat-semantic-disallowed.rs
src/test/ui/rfc-2005-default-binding-mode/for.rs
src/test/ui/rfc-2005-default-binding-mode/for.stderr

diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.rs
deleted file mode 100644 (file)
index 238f2d9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-struct X { x: (), }
-
-impl Drop for X {
-    fn drop(&mut self) {
-        println!("destructor runs");
-    }
-}
-
-fn main() {
-    let x = Some((X { x: () }, X { x: () }));
-    match x {
-        Some((ref _y, _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
-        None => panic!()
-    }
-}
diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-2.stderr
deleted file mode 100644 (file)
index ff00aa8..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-2.rs:12:23
-   |
-LL |         Some((ref _y, _z)) => { },
-   |               ------  ^^ by-move pattern here
-   |               |
-   |               by-ref pattern here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0009`.
diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.rs
deleted file mode 100644 (file)
index e8357e9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-struct X { x: (), }
-
-impl Drop for X {
-    fn drop(&mut self) {
-        println!("destructor runs");
-    }
-}
-
-enum DoubleOption<T,U> { Some2(T,U), None2 }
-
-fn main() {
-    let x = DoubleOption::Some2(X { x: () }, X { x: () });
-    match x {
-        DoubleOption::Some2(ref _y, _z) => { },
-        //~^ ERROR cannot bind by-move and by-ref in the same pattern
-        DoubleOption::None2 => panic!()
-    }
-}
diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-3.stderr
deleted file mode 100644 (file)
index 3e8358d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-3.rs:14:37
-   |
-LL |         DoubleOption::Some2(ref _y, _z) => { },
-   |                             ------  ^^ by-move pattern here
-   |                             |
-   |                             by-ref pattern here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0009`.
diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.rs
deleted file mode 100644 (file)
index 41dafd2..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-struct X { x: (), }
-
-impl Drop for X {
-    fn drop(&mut self) {
-        println!("destructor runs");
-    }
-}
-
-fn main() {
-    let x = Some((X { x: () }, X { x: () }));
-    match x {
-        Some((_y, ref _z)) => { }, //~ ERROR cannot bind by-move and by-ref in the same pattern
-        None => panic!()
-    }
-}
diff --git a/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr b/src/test/ui/bind-by-move/bind-by-move-neither-can-live-while-the-other-survives-4.stderr
deleted file mode 100644 (file)
index 00e0c70..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-4.rs:12:15
-   |
-LL |         Some((_y, ref _z)) => { },
-   |               ^^  ------ by-ref pattern here
-   |               |
-   |               by-move pattern here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0009`.
index 30a896059449373fe6dd5c37f0b44e3b2b6b5dd9..88d36ab6aa66469c59dd3b2e86868642ba52a97d 100644 (file)
@@ -7,6 +7,8 @@
 // edition:2018
 // ignore-wasm32-bare compiled with panic=abort by default
 
+#![feature(move_ref_pattern)]
+
 #![allow(unused)]
 
 use std::{
@@ -227,6 +229,12 @@ async fn subslice_pattern_reassign(a: Rc<Allocator>) {
     a.alloc().await;
 }
 
+async fn move_ref_pattern(a: Rc<Allocator>) {
+    let mut tup = (a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await);
+    let (ref _a, ref mut _b, _c, mut _d) = tup;
+    a.alloc().await;
+}
+
 fn run_test<F, G>(cx: &mut Context<'_>, ref f: F)
 where
     F: Fn(Rc<Allocator>) -> G,
@@ -322,4 +330,6 @@ fn main() {
     run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true));
     run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false));
     run_test(context, |a| subslice_pattern_reassign(a));
+
+    run_test(context, |a| move_ref_pattern(a));
 }
index b4406204a5db9f214d60c1ea01c1a995e380d4dc..208a743ed1815d010013a17ce209a0cb944c0350 100644 (file)
@@ -2,6 +2,7 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(generators, generator_trait, untagged_unions)]
+#![feature(move_ref_pattern)]
 
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
@@ -290,6 +291,11 @@ fn subslice_mixed_min_lengths(a: &Allocator, c: i32) {
     }
 }
 
+fn move_ref_pattern(a: &Allocator) {
+    let mut tup = (a.alloc(), a.alloc(), a.alloc(), a.alloc());
+    let (ref _a, ref mut _b, _c, mut _d) = tup;
+}
+
 fn panic_after_return(a: &Allocator) -> Ptr<'_> {
     // Panic in the drop of `p` or `q` can leak
     let exceptions = vec![8, 9];
@@ -453,6 +459,8 @@ fn main() {
     run_test(|a| subslice_mixed_min_lengths(a, 6));
     run_test(|a| subslice_mixed_min_lengths(a, 7));
 
+    run_test(|a| move_ref_pattern(a));
+
     run_test(|a| {
         panic_after_return(a);
     });
diff --git a/src/test/ui/error-codes/E0009.rs b/src/test/ui/error-codes/E0009.rs
deleted file mode 100644 (file)
index 0610d03..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-fn main() {
-    struct X { x: (), }
-    let x = Some((X { x: () }, X { x: () }));
-    match x {
-        Some((y, ref z)) => {},
-        //~^ ERROR E0009
-        None => panic!()
-    }
-}
diff --git a/src/test/ui/error-codes/E0009.stderr b/src/test/ui/error-codes/E0009.stderr
deleted file mode 100644 (file)
index 446a436..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/E0009.rs:5:15
-   |
-LL |         Some((y, ref z)) => {},
-   |               ^  ----- by-ref pattern here
-   |               |
-   |               by-move pattern here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0009`.
diff --git a/src/test/ui/issues/issue-53840.rs b/src/test/ui/issues/issue-53840.rs
deleted file mode 100644 (file)
index e854d24..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-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) => {}
-//~^ ERROR cannot bind by-move and by-ref in the same pattern
-    }
-    match bar {
-        Bar {a, ref b} => {}
-//~^ ERROR cannot bind by-move and by-ref in the same pattern
-    }
-}
diff --git a/src/test/ui/issues/issue-53840.stderr b/src/test/ui/issues/issue-53840.stderr
deleted file mode 100644 (file)
index 9cb034e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/issue-53840.rs:13:16
-   |
-LL |         E::Foo(a, b, ref c) => {}
-   |                ^  ^  ----- by-ref pattern here
-   |                |  |
-   |                |  by-move pattern here
-   |                by-move pattern here
-
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/issue-53840.rs:17:14
-   |
-LL |         Bar {a, ref b} => {}
-   |              ^  ----- by-ref pattern here
-   |              |
-   |              by-move pattern here
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0009`.
index e460246193e5b88d58e46a4c514cf0294f10b649..5c1a61eb375a43a98a80910c26b38a0493f2079c 100644 (file)
@@ -1,4 +1,4 @@
-#![feature(slice_patterns, unsized_locals)]
+#![feature(unsized_locals)]
 
 struct A;
 #[derive(Clone, Copy)]
index 75d7af58e706db60c96578aa07edd27cb9a09dd4..1cad8223826770c2f2bf9841c624377c18860091 100644 (file)
@@ -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 `_y` 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 `_y` 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!(),
     }
 }
index 22d62ff4f003f1bdbf311413b208151dc3f00387..6ad0248fc6b2f45d0cecd9b62e97543f6624af2e 100644 (file)
@@ -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 `_y` 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
+   |              |        move out of `_y` occurs here
+   |              borrow of `_y` occurs 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: `_z`
+  --> $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 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 `_y` 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
+   |              |            move out of `_y` occurs here
+   |              borrow of `_y` occurs 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: `_z`
+  --> $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 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`.
index 86fb04e2edf5bb4d19a07ad90f6be2cf47b3b225..7a2e5128b85377452e9edb08bd6c2ecb0a5aad1f 100644 (file)
@@ -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
 }
index b039708fd3e0a4c85be7c583ef15feff261bbf30..cfd978e13270987ce60896fc14f7b524f977715b 100644 (file)
@@ -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`.
index 2cd375da9a56fd5bba460a082a2fec86a8274736..10865b92393b6ceb45cce0d0ac94c69203e12dc8 100644 (file)
@@ -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
     }
 }
index 12ebcb72af11cba13fb6ff6885e69862355ffdc6..56613ee7618b467cfb3c8d5d7241554d52d73333 100644 (file)
@@ -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`.
index 092bd1133dd624692aa7e966222a3eacacc1a81a..271f4bca0fcb8f46a0527213d74c8332043f8ffe 100644 (file)
@@ -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 f4(ref a @ box ref b: Box<NC>) { // OK.
         }
         _ => {}
     }
+
+    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)] => {}
+        _ => {}
+    }
 }
index 3b2f598dc0157f89b39e75e46001ab846b9b3112..e90aeab2edb0b3994d7cd11e27d0d4f4e4993d9e 100644 (file)
@@ -1,39 +1,40 @@
 // 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 `a` 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
@@ -69,16 +70,4 @@ fn f5(ref mut a @ box ref b: Box<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
-        _ => {}
-    }
 }
index e96c15b0fa7ddd604ce2a95994c78f97e30437a8..50185c1a017d3c25d042c4173425a3ef07c12247 100644 (file)
@@ -1,32 +1,14 @@
-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 `a` 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
+   |         |           move out of `a` occurs here
+   |         borrow of `a` occurs here
 
 error: cannot borrow `a` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-at-and-box.rs:38:9
+  --> $DIR/borrowck-pat-at-and-box.rs:39:9
    |
 LL |     let ref a @ box ref mut b = Box::new(nc());
    |         -----^^^^^^^---------
@@ -35,7 +17,7 @@ LL |     let ref a @ box ref mut b = Box::new(nc());
    |         immutable borrow occurs here
 
 error: cannot borrow `a` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-at-and-box.rs:40:9
+  --> $DIR/borrowck-pat-at-and-box.rs:41:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
    |         -----^^^^^^^---------
@@ -44,7 +26,7 @@ LL |     let ref a @ box ref mut b = Box::new(NC);
    |         immutable borrow occurs here
 
 error: cannot borrow `a` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-at-and-box.rs:42:9
+  --> $DIR/borrowck-pat-at-and-box.rs:43:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
    |         -----^^^^^^^---------
@@ -53,7 +35,7 @@ LL |     let ref a @ box ref mut b = Box::new(NC);
    |         immutable borrow occurs here
 
 error: cannot borrow `a` as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-at-and-box.rs:45:9
+  --> $DIR/borrowck-pat-at-and-box.rs:46:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
    |         -----^^^^^^^---------
@@ -62,7 +44,7 @@ LL |     let ref a @ box ref mut b = Box::new(NC);
    |         immutable borrow occurs here
 
 error: cannot borrow `a` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-at-and-box.rs:51:9
+  --> $DIR/borrowck-pat-at-and-box.rs:52:9
    |
 LL |     let ref mut a @ box ref b = Box::new(NC);
    |         ---------^^^^^^^-----
@@ -71,7 +53,7 @@ LL |     let ref mut a @ box ref b = Box::new(NC);
    |         mutable borrow occurs here
 
 error: cannot borrow `a` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-at-and-box.rs:65:9
+  --> $DIR/borrowck-pat-at-and-box.rs:66:9
    |
 LL |         ref mut a @ box ref b => {
    |         ---------^^^^^^^-----
@@ -79,38 +61,8 @@ 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
-
-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
+  --> $DIR/borrowck-pat-at-and-box.rs:58:11
    |
 LL |     fn f5(ref mut a @ box ref b: Box<NC>) {
    |           ---------^^^^^^^-----
@@ -119,7 +71,7 @@ LL |     fn f5(ref mut a @ box ref b: Box<NC>) {
    |           mutable borrow 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 (file)
index 0000000..1479791
--- /dev/null
@@ -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 (file)
index 0000000..dc9201d
--- /dev/null
@@ -0,0 +1,12 @@
+error: borrow of moved value: `a`
+  --> $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 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 (file)
index 0000000..7d9618c
--- /dev/null
@@ -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 (file)
index 0000000..0c502ce
--- /dev/null
@@ -0,0 +1,503 @@
+error: borrow of moved value: `a`
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:29:9
+   |
+LL |     let a @ ref b = U;
+   |         -^^^-----
+   |         |   |
+   |         |   value borrowed here after move
+   |         value moved here
+   |         move occurs because `a` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |         move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+
+error: borrow of moved value: `b`
+  --> $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 here
+   |              move occurs because `b` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `d`
+  --> $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 here
+   |                                 move occurs because `d` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |         move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:41:9
+   |
+LL |     let a @ ref b = u();
+   |         -^^^-----
+   |         |   |
+   |         |   value borrowed here after move
+   |         value moved here
+   |         move occurs because `a` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |         move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+
+error: borrow of moved value: `b`
+  --> $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 here
+   |              move occurs because `b` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `d`
+  --> $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 here
+   |                                 move occurs because `d` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |         move occurs because `a` has type `[main::U; 2]` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:56:9
+   |
+LL |         a @ Some(ref b) => {}
+   |         -^^^^^^^^-----^
+   |         |        |
+   |         |        value borrowed here after move
+   |         value moved here
+   |         move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 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: `b`
+  --> $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 here
+   |                   move occurs because `b` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `d`
+  --> $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 here
+   |                                      move occurs because `d` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |         move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:9
+   |
+LL |         a @ Some(ref b) => {}
+   |         -^^^^^^^^-----^
+   |         |        |
+   |         |        value borrowed here after move
+   |         value moved here
+   |         move occurs because `a` has type `std::option::Option<main::U>` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 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: `b`
+  --> $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 here
+   |                   move occurs because `b` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `d`
+  --> $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 here
+   |                                      move occurs because `d` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |         move occurs because `a` has type `std::option::Option<[main::U; 2]>` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |           move occurs because `a` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 here
+   |           move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
+
+error: borrow of moved value: `b`
+  --> $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 here
+   |                    move occurs because `b` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `d`
+  --> $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 here
+   |                               move occurs because `d` has type `main::U` which does implement the `Copy` trait
+
+error: borrow of moved value: `a`
+  --> $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 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`.
index abe5ed81b71a240b8088ad1e44d03d8f51ec9a4d..4ece55b07b080242eb612993d0f226ea993ccf74 100644 (file)
@@ -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 `a` because it is borrowed
+    fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
+    //~^ ERROR cannot move out of `a` because it is borrowed
+    //~| ERROR cannot move out of `b` because it is borrowed
+    //~| ERROR cannot move out of `d` because it is borrowed
+    fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
+    //~^ ERROR cannot move out of `a` because it is borrowed
+
+    let ref a @ b = U;
+    //~^ ERROR cannot move out of `a` because it is borrowed
+    let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
+    //~^ ERROR cannot move out of `a` because it is borrowed
+    //~| ERROR cannot move out of `b` because it is borrowed
+    //~| ERROR cannot move out of `d` because it is borrowed
+    let ref mut a @ [b, mut c] = [U, U];
+    //~^ ERROR cannot move out of `a` because it is borrowed
+    let ref a @ b = u();
+    //~^ ERROR cannot move out of `a` because it is borrowed
+    let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
+    //~^ ERROR cannot move out of `a` because it is borrowed
+    //~| ERROR cannot move out of `b` because it is borrowed
+    //~| ERROR cannot move out of `d` because it is borrowed
+    let ref mut a @ [b, mut c] = [u(), u()];
+    //~^ ERROR cannot move out of `a` because it is borrowed
+
+    match Some(U) {
+        ref a @ Some(b) => {}
+        //~^ ERROR cannot move out of `a` because it is borrowed
+        None => {}
+    }
+    match Some((U, U)) {
+        ref a @ Some((ref b @ mut c, ref d @ e)) => {}
+        //~^ ERROR cannot move out of `a` because it is borrowed
+        //~| ERROR cannot move out of `b` because it is borrowed
+        //~| ERROR cannot move out of `d` because it is borrowed
+        None => {}
+    }
+    match Some([U, U]) {
+        ref mut a @ Some([b, mut c]) => {}
+        //~^ ERROR cannot move out of `a` because it is borrowed
+        None => {}
+    }
+    match Some(u()) {
+        ref a @ Some(b) => {}
+        //~^ ERROR cannot move out of `a` because it is borrowed
+        None => {}
+    }
+    match Some((u(), u())) {
+        ref a @ Some((ref b @ mut c, ref d @ e)) => {}
+        //~^ ERROR cannot move out of `a` because it is borrowed
+        //~| ERROR cannot move out of `b` because it is borrowed
+        //~| ERROR cannot move out of `d` because it is borrowed
+        None => {}
+    }
+    match Some([u(), u()]) {
+        ref mut a @ Some([b, mut c]) => {}
+        //~^ ERROR cannot move out of `a` because it is borrowed
+        None => {}
     }
 }
index 1f70a6c437e92e61aa2357490ebf85e9e39328ba..607bbd5f991c082917a5242bce5c628d6674e1c7 100644 (file)
-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 `a` 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;
+   |         -----^^^-
+   |         |       |
+   |         |       move out of `a` occurs here
+   |         borrow of `a` occurs here
 
-error: aborting due to previous error
+error: cannot move out of `a` 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);
+   |         -----^^^^^^^^^^^^-----^^^^^^^^^^-^
+   |         |                |              |
+   |         |                |              move out of `a` occurs here
+   |         |                move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `b` 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);
+   |                  -----^^^-----
+   |                  |       |
+   |                  |       move out of `b` occurs here
+   |                  borrow of `b` occurs here
+
+error: cannot move out of `d` 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);
+   |                                 -----^^^-
+   |                                 |       |
+   |                                 |       move out of `d` occurs here
+   |                                 borrow of `d` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:29:9
+   |
+LL |     let ref mut a @ [b, mut c] = [U, U];
+   |         ---------^^^^-^^-----^
+   |         |            |  |
+   |         |            |  move out of `a` occurs here
+   |         |            move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:31:9
+   |
+LL |     let ref a @ b = u();
+   |         -----^^^-
+   |         |       |
+   |         |       move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` 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());
+   |         -----^^^^^^^^^^^^-----^^^^^^^^^^-^
+   |         |                |              |
+   |         |                |              move out of `a` occurs here
+   |         |                move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `b` 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());
+   |                  -----^^^-----
+   |                  |       |
+   |                  |       move out of `b` occurs here
+   |                  borrow of `b` occurs here
+
+error: cannot move out of `d` 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());
+   |                                 -----^^^-
+   |                                 |       |
+   |                                 |       move out of `d` occurs here
+   |                                 borrow of `d` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:37:9
+   |
+LL |     let ref mut a @ [b, mut c] = [u(), u()];
+   |         ---------^^^^-^^-----^
+   |         |            |  |
+   |         |            |  move out of `a` occurs here
+   |         |            move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:41:9
+   |
+LL |         ref a @ Some(b) => {}
+   |         -----^^^^^^^^-^
+   |         |            |
+   |         |            move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` 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)) => {}
+   |         -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
+   |         |                     |              |
+   |         |                     |              move out of `a` occurs here
+   |         |                     move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `b` 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)) => {}
+   |                       -----^^^-----
+   |                       |       |
+   |                       |       move out of `b` occurs here
+   |                       borrow of `b` occurs here
+
+error: cannot move out of `d` 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)) => {}
+   |                                      -----^^^-
+   |                                      |       |
+   |                                      |       move out of `d` occurs here
+   |                                      borrow of `d` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:53:9
+   |
+LL |         ref mut a @ Some([b, mut c]) => {}
+   |         ---------^^^^^^^^^-^^-----^^
+   |         |                 |  |
+   |         |                 |  move out of `a` occurs here
+   |         |                 move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:58:9
+   |
+LL |         ref a @ Some(b) => {}
+   |         -----^^^^^^^^-^
+   |         |            |
+   |         |            move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` 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)) => {}
+   |         -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
+   |         |                     |              |
+   |         |                     |              move out of `a` occurs here
+   |         |                     move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `b` 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)) => {}
+   |                       -----^^^-----
+   |                       |       |
+   |                       |       move out of `b` occurs here
+   |                       borrow of `b` occurs here
+
+error: cannot move out of `d` 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)) => {}
+   |                                      -----^^^-
+   |                                      |       |
+   |                                      |       move out of `d` occurs here
+   |                                      borrow of `d` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:70:9
+   |
+LL |         ref mut a @ Some([b, mut c]) => {}
+   |         ---------^^^^^^^^^-^^-----^^
+   |         |                 |  |
+   |         |                 |  move out of `a` occurs here
+   |         |                 move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11
+   |
+LL |     fn f1(ref a @ b: U) {}
+   |           -----^^^-
+   |           |       |
+   |           |       move out of `a` occurs here
+   |           borrow of `a` occurs here
+
+error: cannot move out of `a` 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)) {}
+   |           -----^^^^^^^^^^^^-----^^^^^^^^^^-^
+   |           |                |              |
+   |           |                |              move out of `a` occurs here
+   |           |                move out of `a` occurs here
+   |           borrow of `a` occurs here
+
+error: cannot move out of `b` 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)) {}
+   |                    -----^^^-----
+   |                    |       |
+   |                    |       move out of `b` occurs here
+   |                    borrow of `b` occurs here
+
+error: cannot move out of `d` 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)) {}
+   |                                   -----^^^-
+   |                                   |       |
+   |                                   |       move out of `d` occurs here
+   |                                   borrow of `d` occurs here
+
+error: cannot move out of `a` 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]) {}
+   |           ---------^^^^-^^-----^
+   |           |            |  |
+   |           |            |  move out of `a` occurs here
+   |           |            move out of `a` occurs here
+   |           borrow of `a` occurs here
+
+error: aborting due to 25 previous errors
 
-For more information about this error, try `rustc --explain E0009`.
index e8510dfa649990a3aef693dc92f9ff52f78bdc07..a921ad056d81f5917814b3ac88b349dea2bd1503 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(bindings_after_at)]
+#![feature(move_ref_pattern)]
 
 enum Option<T> {
     None,
@@ -27,6 +28,9 @@ fn f2(ref mut a @ ref b: U) {}
     //~^ ERROR cannot borrow `a` 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
+    fn f4_also_moved(ref a @ ref mut b @ c: U) {}
+    //~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
+    //~| ERROR cannot move out of `b` 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
index 0d7b703f1816b4aa31bc511e3c26bc0f3075af9c..4652fffe36a4204553ad1bb45d6674fef57a7e80 100644 (file)
@@ -1,5 +1,5 @@
 error: cannot borrow `z` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9
    |
 LL |         ref mut z @ &mut Some(ref a) => {
    |         ---------^^^^^^^^^^^^^-----^
@@ -8,7 +8,7 @@ LL |         ref mut z @ &mut Some(ref a) => {
    |         mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9
    |
 LL |     let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
    |         ---------^^^^-----------------^
@@ -18,7 +18,7 @@ LL |     let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
    |         first mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:22
    |
 LL |     let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
    |                      -----^^^---------
@@ -27,7 +27,7 @@ LL |     let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
    |                      immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
    |
 LL |     let ref a @ ref mut b = U;
    |         -----^^^---------
@@ -36,7 +36,7 @@ LL |     let ref a @ ref mut b = U;
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
    |
 LL |     let ref mut a @ ref b = U;
    |         ---------^^^-----
@@ -45,7 +45,7 @@ LL |     let ref mut a @ ref b = U;
    |         mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:43:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         -----^^^^---------^^---------^
@@ -55,7 +55,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9
    |
 LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         ---------^^^^-----^^-----^
@@ -65,7 +65,7 @@ LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9
    |
 LL |     let ref mut a @ ref b = u();
    |         ---------^^^-----
@@ -74,7 +74,7 @@ LL |     let ref mut a @ ref b = u();
    |         mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9
    |
 LL |     let ref a @ ref mut b = u();
    |         -----^^^---------
@@ -83,7 +83,7 @@ LL |     let ref a @ ref mut b = u();
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9
    |
 LL |     let ref mut a @ ref b = U;
    |         ---------^^^-----
@@ -92,7 +92,7 @@ LL |     let ref mut a @ ref b = U;
    |         mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:63:9
    |
 LL |     let ref a @ ref mut b = U;
    |         -----^^^---------
@@ -101,7 +101,7 @@ LL |     let ref a @ ref mut b = U;
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:9
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
    |         ---------^^^^^^-----^
@@ -110,7 +110,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
    |         mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:69:33
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
    |                                 ---------^^^^^^^-----^
@@ -119,7 +119,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
    |                                 mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
    |         -----^^^^^^---------^
@@ -128,7 +128,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
    |                                 -----^^^^^^^---------^
@@ -137,7 +137,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
    |                                 immutable borrow 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
+  --> $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 } => {}
    |         -----^^^^^^---------^
@@ -146,7 +146,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
    |         immutable borrow 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
+  --> $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 } => {}
    |                                 -----^^^^^^^---------^
@@ -155,7 +155,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
    |                                 immutable borrow 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
+  --> $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 } => {}
    |         ---------^^^^^^-----^
@@ -164,7 +164,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    |         mutable borrow 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
+  --> $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 } => {}
    |                                 ---------^^^^^^^-----^
@@ -173,7 +173,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    |                                 mutable borrow 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
+  --> $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 } => {}
    |         -----^^^^^^---------^
@@ -182,7 +182,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    |         immutable borrow 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
+  --> $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 } => {}
    |                                 -----^^^^^^^---------^
@@ -191,7 +191,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    |                                 immutable borrow 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
+  --> $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 } => {}
    |         ---------^^^^^^-----^
@@ -200,7 +200,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    |         mutable borrow 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
+  --> $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 } => {}
    |                                 ---------^^^^^^^-----^
@@ -209,7 +209,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    |                                 mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         -----^^^^---------^^---------^
@@ -219,7 +219,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:124:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         -----^^^^---------^^---------^
@@ -229,7 +229,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         -----^^^^---------^^---------^
@@ -239,7 +239,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:136:9
    |
 LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         ---------^^^^-----^^-----^
@@ -249,7 +249,7 @@ LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11
    |
 LL |     fn f1(ref a @ ref mut b: U) {}
    |           -----^^^---------
@@ -258,7 +258,7 @@ LL |     fn f1(ref a @ ref mut b: U) {}
    |           immutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11
    |
 LL |     fn f2(ref mut a @ ref b: U) {}
    |           ---------^^^-----
@@ -267,7 +267,7 @@ LL |     fn f2(ref mut a @ ref b: U) {}
    |           mutable borrow 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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11
    |
 LL |     fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
    |           -----^^^^^^^^^^^----------------^^^^^^^^
@@ -275,8 +275,27 @@ LL |     fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
    |           |               mutable borrow occurs here
    |           immutable borrow occurs here
 
+error: cannot borrow `a` 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 here
+   |                      |       mutable borrow occurs here
+   |                      immutable borrow occurs here
+
+error: cannot move out of `b` 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) {}
+   |                              ---------^^^-
+   |                              |           |
+   |                              |           move out of `b` occurs here
+   |                              borrow of `b` occurs 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`.
index f425b35630d17565ace97e2472251e6f12912aad..77cd779d7167fadcab81e8f5f0a497164b7cec05 100644 (file)
@@ -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;
@@ -20,6 +21,9 @@ fn f3(
             [..],
         ] : [[U; 4]; 5]
     ) {}
+    fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
+    //~^ ERROR cannot borrow `a` as mutable more than once at a time
+    //~| ERROR cannot move out of `b` because it is borrowed
 
     let ref mut a @ ref mut b = U;
     //~^ ERROR cannot borrow `a` as mutable more than once at a time
@@ -60,18 +64,18 @@ fn f3(
         ) = (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) {
index d07ad140cc23a72366d6e0eed73f25b842416bbe..a6d6678736475002e360e2c867ba22133612bbe9 100644 (file)
@@ -1,5 +1,5 @@
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9
    |
 LL |     let ref mut a @ ref mut b = U;
    |         ---------^^^---------
@@ -8,7 +8,7 @@ LL |     let ref mut a @ ref mut b = U;
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9
    |
 LL |     let ref mut a @ ref mut b = U;
    |         ---------^^^---------
@@ -17,7 +17,7 @@ LL |     let ref mut a @ ref mut b = U;
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9
    |
 LL |     let ref mut a @ ref mut b = U;
    |         ---------^^^---------
@@ -26,7 +26,7 @@ LL |     let ref mut a @ ref mut b = U;
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9
    |
 LL |     let ref mut a @ ref mut b = U;
    |         ---------^^^---------
@@ -35,7 +35,7 @@ LL |     let ref mut a @ ref mut b = U;
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9
    |
 LL |     let ref mut a @ ref mut b = U;
    |         ---------^^^---------
@@ -44,7 +44,7 @@ LL |     let ref mut a @ ref mut b = U;
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:46:9
    |
 LL |       let ref mut a @ (
    |           ^--------
@@ -66,7 +66,7 @@ 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
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9
    |
 LL |       let ref mut a @ (
    |           ^--------
@@ -87,32 +87,52 @@ 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: `a`
+  --> $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
+   |         -^^^^---------^^---------^
+   |         |    |          |
+   |         |    |          value borrowed here after move
+   |         |    value borrowed here after move
+   |         value moved here
+   |         move occurs because `a` has type `(main::U, main::U)` which does implement the `Copy` trait
 
-error[E0007]: cannot bind by-move with sub-bindings
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9
+error: borrow of moved value: `a`
+  --> $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 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: `a`
+  --> $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 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: `a`
+  --> $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 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
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -121,7 +141,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -130,7 +150,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:88:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -139,7 +159,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:88:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -148,7 +168,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:95:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -157,7 +177,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:95:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -166,7 +186,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:107:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -175,7 +195,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:107:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -184,7 +204,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11
    |
 LL |     fn f1(ref mut a @ ref mut b: U) {}
    |           ---------^^^---------
@@ -193,7 +213,7 @@ LL |     fn f1(ref mut a @ ref mut b: U) {}
    |           first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11
    |
 LL |     fn f2(ref mut a @ ref mut b: U) {}
    |           ---------^^^---------
@@ -202,7 +222,7 @@ LL |     fn f2(ref mut a @ ref mut b: U) {}
    |           first mutable borrow occurs here
 
 error: cannot borrow `a` as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9
    |
 LL |           ref mut a @ [
    |           ^--------
@@ -219,8 +239,27 @@ LL | |             [..],
 LL | |         ] : [[U; 4]; 5]
    | |_________^
 
+error: cannot borrow `a` 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 here
+   |                      |           another mutable borrow occurs here
+   |                      first mutable borrow occurs here
+
+error: cannot move out of `b` 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) {}
+   |                                  ---------^^^-
+   |                                  |           |
+   |                                  |           move out of `b` occurs here
+   |                                  borrow of `b` occurs 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`.
index db5aabc7a145309da7fd2099fd70c6561faeef0d..821d4b42962bf4cabce11ec47c50851a18423330 100644 (file)
@@ -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 @@
 
 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
 }
index cfc35d6c32a7274d77b191028da22f47dfb50915..7e89008a604969ed1b6d7d1d0b2b9675c2d6cbe5 100644 (file)
@@ -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`.
index 1127d114145cd2d8b7dc0a6382d8e30e3885adfc..94becb9e8b8e3dd992d5f0a828d9dff8f74d3716 100644 (file)
@@ -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 f2(ref a @ b: &NotCopy) {
     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 `a` because it is borrowed
+    let _a: &NotCopy = a;
+    let _b: NotCopy = b;
+    let ref mut a @ b = NotCopy; //~ ERROR cannot move out of `a` 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 `a` because it is borrowed
+            //~| ERROR borrow of moved value: `b`
+            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 `a` because it is borrowed
+            let _a: &NotCopy = a;
+            let _b: NotCopy = b;
+        }
     }
 }
index b6709a8a40e2317b443aea2efd1353ce5cd5b1a5..dfc6e16600e2a9cfa45cfc6f56e755ea03e74e30 100644 (file)
@@ -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 `a` 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
+   |         |       move out of `a` occurs here
+   |         borrow of `a` occurs 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 `a` 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
+   |         |           move out of `a` occurs here
+   |         borrow of `a` occurs here
+
+error: cannot move out of `a` because it is borrowed
+  --> $DIR/default-binding-modes-both-sides-independent.rs:36:12
+   |
+LL |         Ok(ref a @ b) | Err(b @ ref a) => {
+   |            -----^^^-
+   |            |       |
+   |            |       move out of `a` occurs here
+   |            borrow of `a` occurs 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: `b`
+  --> $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 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 `a` 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
+   |         |       move out of `a` occurs here
+   |         borrow of `a` occurs 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 (file)
index 0000000..d2d4e61
--- /dev/null
@@ -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 (file)
index 0000000..3ee008f
--- /dev/null
@@ -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 (file)
index 0000000..d718ee2
--- /dev/null
@@ -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/feature-gate-move_ref_pattern.rs b/src/test/ui/pattern/move-ref-patterns/feature-gate-move_ref_pattern.rs
new file mode 100644 (file)
index 0000000..fb92eb1
--- /dev/null
@@ -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 (file)
index 0000000..8aef220
--- /dev/null
@@ -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 (file)
index 0000000..ab7d10d
--- /dev/null
@@ -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-pass.rs b/src/test/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
new file mode 100644 (file)
index 0000000..e1844d3
--- /dev/null
@@ -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 (file)
index 0000000..7f1c02c
--- /dev/null
@@ -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 (file)
index 0000000..ca82353
--- /dev/null
@@ -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 (file)
index 0000000..5c51c47
--- /dev/null
@@ -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 (file)
index 0000000..fe7f71e
--- /dev/null
@@ -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 (file)
index 0000000..c786953
--- /dev/null
@@ -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);
+}
index 31620216e82e1f19973da1169569adb0a6d6690c..84552f2e7331580a306292e947c733dadbf775b9 100644 (file)
@@ -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() {}
 
index 3bf053eb874ce62496ffc1ac6426596b1468d5b9..aa42c7bb9c2f1368dffeb1bb1f0ea8fe9965190e 100644 (file)
@@ -1,10 +1,11 @@
+#![feature(move_ref_pattern)]
+
 struct Foo {}
 
 pub fn main() {
-    let mut tups = vec![(Foo{}, Foo{})];
+    let mut tups = vec![(Foo {}, Foo {})];
     // The below desugars to &(ref n, mut m).
     for (n, mut m) in &tups {
-        //~^ ERROR cannot bind by-move and by-ref in the same pattern
-        //~| ERROR cannot move out of a shared reference
+        //~^ ERROR cannot move out of a shared reference
     }
 }
index ebc6ff5d8c3fe5e63dbb9832447bad3cbb0e1a5b..ef62431388081f478924fd19afe9427f28c235ba 100644 (file)
@@ -1,13 +1,5 @@
-error[E0009]: cannot bind by-move and by-ref in the same pattern
-  --> $DIR/for.rs:6:13
-   |
-LL |     for (n, mut m) in &tups {
-   |          -  ^^^^^ by-move pattern here
-   |          |
-   |          by-ref pattern here
-
 error[E0507]: cannot move out of a shared reference
-  --> $DIR/for.rs:6:23
+  --> $DIR/for.rs:8:23
    |
 LL |     for (n, mut m) in &tups {
    |             -----     ^^^^^
@@ -15,7 +7,6 @@ LL |     for (n, mut m) in &tups {
    |             data moved here
    |             move occurs because `m` has type `Foo`, 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: E0009, E0507.
-For more information about an error, try `rustc --explain E0009`.
+For more information about this error, try `rustc --explain E0507`.