about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVishnunarayan K I <appukuttancr@gmail.com>2020-11-02 00:05:55 +0530
committerVishnunarayan K I <appukuttancr@gmail.com>2020-11-02 00:05:55 +0530
commitc93d25b6af6849f726bc52332fb993e8d6898a00 (patch)
tree045deab92a6d79873568e7f5ad9453bbb7db439c
parent0d33ab7af4aebe786410b4c10367eb6ddf13af0b (diff)
downloadrust-c93d25b6af6849f726bc52332fb993e8d6898a00.tar.gz
rust-c93d25b6af6849f726bc52332fb993e8d6898a00.zip
reverse binding order in matches ...
... to allow the subbinding of copyable fields in bindings after `@`

Fixes #69971
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs15
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs4
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr36
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs2
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr13
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs12
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr110
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs16
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr120
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs28
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr313
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs14
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr222
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs23
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr208
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs15
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr144
-rw-r--r--src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs6
-rw-r--r--src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr32
-rw-r--r--src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs2
-rw-r--r--src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr15
21 files changed, 641 insertions, 709 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index e46274770be..296051b173e 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -131,7 +131,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             PatKind::Binding { name, mutability, mode, var, ty, ref subpattern, is_primary: _ } => {
-                candidate.bindings.push(Binding {
+                // issue #69971: the binding order should be right to left if there are more
+                // bindings after `@` to please the borrow checker
+                // Ex
+                // struct NonCopyStruct {
+                //     copy_field: u32,
+                // }
+                //
+                // fn foo1(x: NonCopyStruct) {
+                //     let y @ NonCopyStruct { copy_field: z } = x;
+                //     // the above should turn into
+                //     let z = x.copy_field;
+                //     let y = x;
+                // }
+                candidate.bindings.insert(0, Binding {
                     name,
                     mutability,
                     span: match_pair.pattern.span,
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs
index ba9543bf738..71503ecf262 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs
@@ -12,6 +12,7 @@ fn main() {
     let x = Some(X { x: () });
     match x {
         Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of moved value
         None => panic!(),
     }
 
@@ -19,13 +20,13 @@ fn main() {
     match x {
         Some(_z @ ref _y) => {}
         //~^ ERROR borrow of moved value
-        //~| ERROR borrow of moved value
         None => panic!(),
     }
 
     let mut x = Some(X { x: () });
     match x {
         Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of moved value
         None => panic!(),
     }
 
@@ -33,7 +34,6 @@ fn main() {
     match x {
         Some(_z @ ref mut _y) => {}
         //~^ ERROR borrow of moved value
-        //~| ERROR borrow of moved value
         None => panic!(),
     }
 }
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
index 44dbcb9a754..e50ae3e7eeb 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
@@ -8,7 +8,7 @@ LL |         Some(ref _y @ _z) => {}
    |              value borrowed, by `_y`, here
 
 error: borrow of moved value
-  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:20:14
+  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14
    |
 LL |         Some(_z @ ref _y) => {}
    |              --^^^------
@@ -27,7 +27,7 @@ LL |         Some(ref mut _y @ _z) => {}
    |              value borrowed, by `_y`, here
 
 error: borrow of moved value
-  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:34:14
+  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14
    |
 LL |         Some(_z @ ref mut _y) => {}
    |              --^^^----------
@@ -37,34 +37,34 @@ LL |         Some(_z @ ref mut _y) => {}
    |              move occurs because `_z` 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:20:19
+  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:14:14
    |
-LL |         Some(_z @ ref _y) => {}
-   |              -----^^^^^^
-   |              |    |
-   |              |    value borrowed here after move
-   |              value moved here
+LL |         Some(ref _y @ _z) => {}
+   |              ^^^^^^^^^--
+   |              |        |
+   |              |        value moved here
+   |              value borrowed here after move
    |
    = note: move occurs because value has type `X`, which does not implement the `Copy` trait
 help: borrow this field in the pattern to avoid moving `x.0`
    |
-LL |         Some(ref _z @ ref _y) => {}
-   |              ^^^
+LL |         Some(ref _y @ ref _z) => {}
+   |                       ^^^
 
 error[E0382]: borrow of moved value
-  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:34:19
+  --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:28:14
    |
-LL |         Some(_z @ ref mut _y) => {}
-   |              -----^^^^^^^^^^
-   |              |    |
-   |              |    value borrowed here after move
-   |              value moved here
+LL |         Some(ref mut _y @ _z) => {}
+   |              ^^^^^^^^^^^^^--
+   |              |            |
+   |              |            value moved here
+   |              value borrowed here after move
    |
    = note: move occurs because value has type `X`, which does not implement the `Copy` trait
 help: borrow this field in the pattern to avoid moving `x.0`
    |
-LL |         Some(ref _z @ ref mut _y) => {}
-   |              ^^^
+LL |         Some(ref mut _y @ ref _z) => {}
+   |                           ^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs
index 3ab6f40725c..08240db4472 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs
@@ -7,7 +7,7 @@ fn main() {}
 struct A(Box<u8>);
 
 fn f(a @ A(u): A) -> Box<u8> {
-    //~^ ERROR use of moved value
+    //~^ ERROR use of partially moved value
     drop(a);
     u
 }
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
index f25d5a2d9b8..a77b866d837 100644
--- a/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.stderr
@@ -1,12 +1,13 @@
-error[E0382]: use of moved value
-  --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:12
+error[E0382]: use of partially moved value
+  --> $DIR/bind-by-move-no-subbindings-fun-param.rs:9:6
    |
 LL | fn f(a @ A(u): A) -> Box<u8> {
-   |      ------^-
+   |      ^^^^^^-^
    |      |     |
-   |      |     value used here after move
-   |      value moved here
-   |      move occurs because value has type `A`, which does not implement the `Copy` trait
+   |      |     value partially moved here
+   |      value used here after partial move
+   |
+   = note: partial move occurs because value has type `Box<u8>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
index d014c9828da..83f9b82b242 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
@@ -12,22 +12,22 @@ fn main() {
 
     let a @ b = U; //~ ERROR use of moved value
 
-    let a @ (b, c) = (U, U); //~ ERROR use of moved value
+    let a @ (b, c) = (U, U); //~ ERROR use of partially moved value
 
-    let a @ (b, c) = (u(), u()); //~ ERROR use of moved value
+    let a @ (b, c) = (u(), u()); //~ ERROR use of partially moved value
 
     match Ok(U) {
-        a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value
-                                     //~^ ERROR use of moved value
+        a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of partially moved value
+                                     //~^ ERROR use of partially moved value
     }
 
     fn fun(a @ b: U) {} //~ ERROR use of moved value
 
     match [u(), u(), u(), u()] {
-        xs @ [a, .., b] => {} //~ ERROR use of moved value
+        xs @ [a, .., b] => {} //~ ERROR use of partially moved value
     }
 
     match [u(), u(), u(), u()] {
-        xs @ [_, ys @ .., _] => {} //~ ERROR use of moved value
+        xs @ [_, ys @ .., _] => {} //~ ERROR use of partially moved value
     }
 }
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
index 5039f580ff6..b9be8968823 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
@@ -1,82 +1,94 @@
 error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:13:13
+  --> $DIR/borrowck-move-and-move.rs:13:9
    |
 LL |     let a @ b = U;
-   |         ----^   - move occurs because value has type `U`, which does not implement the `Copy` trait
+   |         ^^^^-   - move occurs because value has type `U`, which does not implement the `Copy` trait
    |         |   |
-   |         |   value used here after move
-   |         value moved here
+   |         |   value moved here
+   |         value used here after move
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:15:17
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:15:9
    |
 LL |     let a @ (b, c) = (U, U);
-   |         --------^-   ------ move occurs because value has type `(U, U)`, which does not implement the `Copy` trait
-   |         |       |
-   |         |       value used here after move
-   |         value moved here
+   |         ^^^^^-^^^^
+   |         |    |
+   |         |    value partially moved here
+   |         value used here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:17:17
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:17:9
    |
 LL |     let a @ (b, c) = (u(), u());
-   |         --------^-   ---------- move occurs because value has type `(U, U)`, which does not implement the `Copy` trait
-   |         |       |
-   |         |       value used here after move
-   |         value moved here
+   |         ^^^^^-^^^^
+   |         |    |
+   |         |    value partially moved here
+   |         value used here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:20:16
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:20:9
    |
-LL |     match Ok(U) {
-   |           ----- move occurs because value has type `std::result::Result<U, U>`, which does not implement the `Copy` trait
 LL |         a @ Ok(b) | a @ Err(b) => {}
-   |         -------^-
+   |         ^^^^^^^-^
    |         |      |
-   |         |      value used here after move
-   |         value moved here
+   |         |      value partially moved here
+   |         value used here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         a @ Ok(ref b) | a @ Err(b) => {}
+   |                ^^^
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:20:29
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:20:21
    |
-LL |     match Ok(U) {
-   |           ----- move occurs because value has type `std::result::Result<U, U>`, which does not implement the `Copy` trait
 LL |         a @ Ok(b) | a @ Err(b) => {}
-   |                     --------^-
+   |                     ^^^^^^^^-^
    |                     |       |
-   |                     |       value used here after move
-   |                     value moved here
+   |                     |       value partially moved here
+   |                     value used here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         a @ Ok(b) | a @ Err(ref b) => {}
+   |                             ^^^
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:27:22
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:27:9
    |
-LL |     match [u(), u(), u(), u()] {
-   |           -------------------- move occurs because value has type `[U; 4]`, which does not implement the `Copy` trait
 LL |         xs @ [a, .., b] => {}
-   |         -------------^-
-   |         |            |
-   |         |            value used here after move
-   |         value moved here
+   |         ^^^^^^-^^^^^^^^
+   |         |     |
+   |         |     value partially moved here
+   |         value used here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:31:18
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:31:9
    |
-LL |     match [u(), u(), u(), u()] {
-   |           -------------------- move occurs because value has type `[U; 4]`, which does not implement the `Copy` trait
 LL |         xs @ [_, ys @ .., _] => {}
-   |         ---------^^^^^^^----
+   |         ^^^^^^^^^-------^^^^
    |         |        |
-   |         |        value used here after move
-   |         value moved here
+   |         |        value partially moved here
+   |         value used here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:24:16
+  --> $DIR/borrowck-move-and-move.rs:24:12
    |
 LL |     fn fun(a @ b: U) {}
-   |            ----^
+   |            ^^^^-
    |            |   |
-   |            |   value used here after move
-   |            value moved here
+   |            |   value moved here
+   |            value used here after move
    |            move occurs because value has type `U`, which does not implement the `Copy` trait
 
 error: aborting due to 8 previous errors
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
index 236710ed854..07fac1d3631 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
@@ -18,22 +18,19 @@ fn nc() -> NC {
 
 fn main() {
     let a @ box &b = Box::new(&C);
-    //~^ ERROR use of moved value
 
     let a @ box b = Box::new(C);
-    //~^ ERROR use of moved value
 
     fn f1(a @ box &b: Box<&C>) {}
-    //~^ ERROR use of moved value
 
     fn f2(a @ box b: Box<C>) {}
-    //~^ ERROR use of moved value
 
     match Box::new(C) {
-        a @ box b => {} //~ ERROR use of moved value
+        a @ box b => {}
     }
 
     let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
 
     let ref a @ box ref mut b = Box::new(nc());
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
@@ -41,22 +38,23 @@ fn main() {
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
     let ref a @ box ref mut b = Box::new(NC);
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
     *b = NC;
     let ref a @ box ref mut b = Box::new(NC);
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
-    //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
     *b = NC;
     drop(a);
 
     let ref mut a @ box ref b = Box::new(NC);
     //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
-    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+    //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
     *a = Box::new(NC);
     drop(b);
 
     fn f5(ref mut a @ box ref b: Box<NC>) {
         //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
-        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
         *a = Box::new(NC);
         drop(b);
     }
@@ -64,7 +62,7 @@ fn main() {
     match Box::new(nc()) {
         ref mut a @ box ref b => {
             //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
-            //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+            //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
             *a = Box::new(NC);
             drop(b);
         }
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
index d9a8bbfb6b1..83da16a72a7 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
@@ -1,5 +1,5 @@
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-at-and-box.rs:36:9
+  --> $DIR/borrowck-pat-at-and-box.rs:32:9
    |
 LL |     let ref a @ box b = Box::new(NC);
    |         -----^^^^^^^-
@@ -8,7 +8,7 @@ LL |     let ref a @ box b = Box::new(NC);
    |         value borrowed, by `a`, here
 
 error: cannot borrow value 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:35:9
    |
 LL |     let ref a @ box ref mut b = Box::new(nc());
    |         -----^^^^^^^---------
@@ -17,7 +17,7 @@ LL |     let ref a @ box ref mut b = Box::new(nc());
    |         immutable borrow, by `a`, occurs here
 
 error: cannot borrow value 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:37:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
    |         -----^^^^^^^---------
@@ -26,7 +26,7 @@ LL |     let ref a @ box ref mut b = Box::new(NC);
    |         immutable borrow, by `a`, occurs here
 
 error: cannot borrow value 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:39:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
    |         -----^^^^^^^---------
@@ -35,7 +35,7 @@ LL |     let ref a @ box ref mut b = Box::new(NC);
    |         immutable borrow, by `a`, occurs here
 
 error: cannot borrow value 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:43:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
    |         -----^^^^^^^---------
@@ -44,7 +44,7 @@ LL |     let ref a @ box ref mut b = Box::new(NC);
    |         immutable borrow, by `a`, occurs here
 
 error: cannot borrow value 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:49:9
    |
 LL |     let ref mut a @ box ref b = Box::new(NC);
    |         ---------^^^^^^^-----
@@ -53,7 +53,7 @@ LL |     let ref mut a @ box ref b = Box::new(NC);
    |         mutable borrow, by `a`, occurs here
 
 error: cannot borrow value 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:63:9
    |
 LL |         ref mut a @ box ref b => {
    |         ---------^^^^^^^-----
@@ -62,7 +62,7 @@ LL |         ref mut a @ box ref b => {
    |         mutable borrow, by `a`, occurs here
 
 error: cannot borrow value 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:55:11
    |
 LL |     fn f5(ref mut a @ box ref b: Box<NC>) {
    |           ---------^^^^^^^-----
@@ -70,104 +70,78 @@ LL |     fn f5(ref mut a @ box ref b: Box<NC>) {
    |           |               immutable borrow, by `b`, occurs here
    |           mutable borrow, by `a`, occurs here
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-at-and-box.rs:20:18
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-at-and-box.rs:32:9
    |
-LL |     let a @ box &b = Box::new(&C);
-   |         ---------^   ------------ move occurs because value has type `Box<&C>`, which does not implement the `Copy` trait
-   |         |        |
-   |         |        value used here after move
-   |         value moved here
-
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-at-and-box.rs:23:17
+LL |     let ref a @ box b = Box::new(NC);
+   |         ^^^^^^^^^^^^-
+   |         |           |
+   |         |           value moved here
+   |         value borrowed here after move
    |
-LL |     let a @ box b = Box::new(C);
-   |         --------^   ----------- move occurs because value has type `Box<C>`, which does not implement the `Copy` trait
-   |         |       |
-   |         |       value used here after move
-   |         value moved here
+   = note: move occurs because value has type `NC`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-at-and-box.rs:33:17
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-at-and-box.rs:39:9
    |
-LL |     match Box::new(C) {
-   |           ----------- move occurs because value has type `Box<C>`, which does not implement the `Copy` trait
-LL |         a @ box b => {}
-   |         --------^
-   |         |       |
-   |         |       value used here after move
-   |         value moved here
+LL |     let ref a @ box ref mut b = Box::new(NC);
+   |         ^^^^^^^^^^^^---------
+   |         |           |
+   |         |           mutable borrow occurs here
+   |         immutable borrow occurs here
+...
+LL |     *b = NC;
+   |     ------- mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-at-and-box.rs:45:21
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-at-and-box.rs:43:9
    |
 LL |     let ref a @ box ref mut b = Box::new(NC);
-   |         ------------^^^^^^^^^
+   |         ^^^^^^^^^^^^---------
    |         |           |
    |         |           mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-LL |     drop(a);
-   |          - immutable borrow later used here
+LL |     *b = NC;
+   |     ------- mutable borrow later used here
 
-error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-at-and-box.rs:51:25
+error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-pat-at-and-box.rs:49:9
    |
 LL |     let ref mut a @ box ref b = Box::new(NC);
-   |         ----------------^^^^^
+   |         ^^^^^^^^^^^^^^^^-----
    |         |               |
    |         |               immutable borrow occurs here
    |         mutable borrow occurs here
 ...
-LL |     *a = Box::new(NC);
-   |     -- mutable borrow later used here
+LL |     drop(b);
+   |          - immutable borrow later used here
 
-error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-at-and-box.rs:65:25
+error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-pat-at-and-box.rs:63:9
    |
 LL |         ref mut a @ box ref b => {
-   |         ----------------^^^^^
+   |         ^^^^^^^^^^^^^^^^-----
    |         |               |
    |         |               immutable borrow occurs here
    |         mutable borrow occurs here
 ...
-LL |             *a = Box::new(NC);
-   |             -- mutable borrow later used here
+LL |             drop(b);
+   |                  - immutable borrow later used here
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-at-and-box.rs:26:20
-   |
-LL |     fn f1(a @ box &b: Box<&C>) {}
-   |           ---------^
-   |           |        |
-   |           |        value used here after move
-   |           value moved here
-   |           move occurs because value has type `Box<&C>`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-at-and-box.rs:29:19
-   |
-LL |     fn f2(a @ box b: Box<C>) {}
-   |           --------^
-   |           |       |
-   |           |       value used here after move
-   |           value moved here
-   |           move occurs because value has type `Box<C>`, which does not implement the `Copy` trait
-
-error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-at-and-box.rs:57:27
+error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-pat-at-and-box.rs:55:11
    |
 LL |     fn f5(ref mut a @ box ref b: Box<NC>) {
-   |           ----------------^^^^^
+   |           ^^^^^^^^^^^^^^^^-----
    |           |               |
    |           |               immutable borrow occurs here
    |           mutable borrow occurs here
 ...
-LL |         *a = Box::new(NC);
-   |         -- mutable borrow later used here
+LL |         drop(b);
+   |              - immutable borrow later used here
 
-error: aborting due to 17 previous errors
+error: aborting due to 14 previous errors
 
 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.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs
index 3e5a543c4c3..e75ff78abd7 100644
--- 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
@@ -12,18 +12,14 @@ fn main() {
 
     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
+    //~| ERROR use of partially 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
@@ -31,25 +27,18 @@ fn main() {
     //~^ 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
+    //~| ERROR use of partially 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
+    //~| ERROR use of partially 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) => {}
@@ -61,21 +50,17 @@ fn main() {
         //~^ 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
+        //~| ERROR use of partially 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())) {
@@ -83,15 +68,12 @@ fn main() {
         //~^ 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
+        //~| ERROR use of partially 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
index 282031aeb07..4a126a22192 100644
--- 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
@@ -1,5 +1,5 @@
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:28:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9
    |
 LL |     let a @ ref b = U;
    |         -^^^-----
@@ -9,7 +9,7 @@ LL |     let a @ ref b = U;
    |         move occurs because `a` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:30:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:26:9
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |         -^^^^^^^^^^^^---------^^^^^^-----^
@@ -20,7 +20,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |         move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:30:14
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:26:14
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |              -----^^^---------
@@ -30,7 +30,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |              move occurs because `b` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:30:33
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:26:33
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |                                 -^^^-----
@@ -40,7 +40,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |                                 move occurs because `d` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:37:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:31:9
    |
 LL |     let a @ [ref mut b, ref c] = [U, U];
    |         -^^^^---------^^-----^
@@ -51,7 +51,7 @@ LL |     let a @ [ref mut b, ref c] = [U, U];
    |         move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:40:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:33:9
    |
 LL |     let a @ ref b = u();
    |         -^^^-----
@@ -61,7 +61,7 @@ LL |     let a @ ref b = u();
    |         move occurs because `a` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:43:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:35:9
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |         -^^^^^^^^^^^^---------^^^^^^-----^
@@ -72,7 +72,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |         move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:43:14
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:35:14
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |              -----^^^---------
@@ -82,7 +82,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |              move occurs because `b` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:43:33
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:35:33
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |                                 -^^^-----
@@ -92,7 +92,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |                                 move occurs because `d` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:50:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:40:9
    |
 LL |     let a @ [ref mut b, ref c] = [u(), u()];
    |         -^^^^---------^^-----^
@@ -103,7 +103,7 @@ LL |     let a @ [ref mut b, ref c] = [u(), u()];
    |         move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:44:9
    |
 LL |         a @ Some(ref b) => {}
    |         -^^^^^^^^-----^
@@ -113,7 +113,7 @@ LL |         a @ Some(ref b) => {}
    |         move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:49:9
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^
@@ -124,7 +124,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:19
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:49:19
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   -----^^^---------
@@ -134,7 +134,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   move occurs because `b` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:38
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:49:38
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      -^^^-----
@@ -144,7 +144,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      move occurs because `d` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:70:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:57:9
    |
 LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         -----^^^^^^^^^-----^^---------^^
@@ -155,7 +155,7 @@ LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:76:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:62:9
    |
 LL |         a @ Some(ref b) => {}
    |         -^^^^^^^^-----^
@@ -165,7 +165,7 @@ LL |         a @ Some(ref b) => {}
    |         move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:82:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         -^^^^^^^^^^^^^^^^^---------^^^^^^-----^^
@@ -176,7 +176,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:82:19
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:19
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   -----^^^---------
@@ -186,7 +186,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   move occurs because `b` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:82:38
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      -^^^-----
@@ -196,7 +196,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      move occurs because `d` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:92:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:9
    |
 LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         -----^^^^^^^^^-----^^---------^^
@@ -217,7 +217,7 @@ LL |     fn f1(a @ ref b: U) {}
    |           move occurs because `a` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:17:11
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:16:11
    |
 LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |           -----^^^^^^^^-----^^^^^^^^^^-----^
@@ -228,7 +228,7 @@ LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |           move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:17:20
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:16:20
    |
 LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |                    -^^^-----
@@ -238,7 +238,7 @@ LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |                    move occurs because `b` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:17:31
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:16:31
    |
 LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |                               -----^^^-----
@@ -248,7 +248,7 @@ LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |                               move occurs because `d` has type `U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:11
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:21:11
    |
 LL |     fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
    |           -^^^^---------^^-----^
@@ -258,262 +258,69 @@ LL |     fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
    |           value moved into `a` here
    |           move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
 
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:30: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 `U`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:30:33
-   |
-LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
-   |         ------------------------^^^^^^^^^-   ------ move occurs because value has type `(U, 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:30:37
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:26:9
    |
 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 `U`, which does not implement the `Copy` trait
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:37:25
-   |
-LL |     let a @ [ref mut b, ref c] = [U, U];
-   |         ----------------^^^^^-   ------ move occurs because value has type `[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:40:13
-   |
-LL |     let a @ ref b = u();
-   |         ----^^^^^   --- move occurs because value has type `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:43:22
+   |         ^^^^^-----------------^^^^^^^^^^^^
+   |         |    |
+   |         |    value partially moved here
+   |         value used here after partial move
    |
-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 `U`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:43:33
-   |
-LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
-   |         ------------------------^^^^^^^^^-   ---------- move occurs because value has type `(U, U)`, which does not implement the `Copy` trait
-   |         |                       |
-   |         |                       value used here after move
-   |         value moved here
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:43:37
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:35:9
    |
 LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
-   |                                 ----^^^^^
-   |                                 |   |
-   |                                 |   value borrowed here after move
-   |                                 value moved here
+   |         ^^^^^-----------------^^^^^^^^^^^^
+   |         |    |
+   |         |    value partially moved here
+   |         value used here after partial move
    |
-   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:50:25
-   |
-LL |     let a @ [ref mut b, ref c] = [u(), u()];
-   |         ----------------^^^^^-   ---------- move occurs because value has type `[U; 2]`, which does not implement the `Copy` trait
-   |         |               |
-   |         |               value borrowed here after move
-   |         value moved here
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:27
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:49:9
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
-   |                   --------^^^^^^^^^
-   |                   |       |
-   |                   |       value borrowed here after move
-   |                   value moved here
+   |         ^^^^^^^^^^-----------------^^^^^^^^^^^^^
+   |         |         |
+   |         |         value partially moved here
+   |         value used here after partial move
    |
-   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 help: borrow this field in the pattern to avoid moving the value
    |
 LL |         a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
    |                   ^^^
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:38
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9
    |
-LL |     match Some((U, U)) {
-   |           ------------ move occurs because value has type `Option<(U, 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:60:42
+   |         ^^^^^^^^^^-----------------^^^^^^^^^^^^^
+   |         |         |
+   |         |         value partially moved here
+   |         value used here after partial move
    |
-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 `U`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving the value
-   |
-LL |         a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
-   |                                      ^^^
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:70:30
-   |
-LL |     match Some([U, U]) {
-   |           ------------ move occurs because value has type `Option<[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:76:18
-   |
-LL |     match Some(u()) {
-   |           --------- move occurs because value has type `Option<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:82: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 `U`, which does not implement the `Copy` trait
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 help: borrow this field in the pattern to avoid moving the value
    |
 LL |         a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
    |                   ^^^
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:82:38
-   |
-LL |     match Some((u(), u())) {
-   |           ---------------- move occurs because value has type `Option<(U, 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:82: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 `U`, which does not implement the `Copy` trait
-help: borrow this field in the pattern to avoid moving the value
-   |
-LL |         a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
-   |                                      ^^^
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:92:30
-   |
-LL |     match Some([u(), u()]) {
-   |           ---------------- move occurs because value has type `Option<[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:13:15
-   |
-LL |     fn f1(a @ ref b: U) {}
-   |           ----^^^^^
-   |           |   |
-   |           |   value borrowed here after move
-   |           value moved here
-   |           move occurs because value has type `U`, which does not implement the `Copy` trait
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:17: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 `U`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:17:31
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:16:11
    |
 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 `(U, U)`, which does not implement the `Copy` trait
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:17:39
+   |           ^^^^^^^^^---------^^^^^^^^^^^^^^^^
+   |           |        |
+   |           |        value partially moved here
+   |           value used here after partial move
    |
-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 `U`, which does not implement the `Copy` trait
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24: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 `[U; 2]`, which does not implement the `Copy` trait
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error: aborting due to 48 previous errors
+error: aborting due to 30 previous errors
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
index 42c3290ddfb..691d0a32fa8 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
@@ -12,12 +12,16 @@ fn main() {
 
     fn f1(ref a @ b: U) {}
     //~^ ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
     //~^ ERROR cannot move out of value because it is borrowed
     //~| ERROR cannot move out of value because it is borrowed
     //~| ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
+    //~| ERROR borrow of moved value
     fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
     //~^ ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of partially moved value
 
     let ref a @ b = U;
     //~^ ERROR cannot move out of value because it is borrowed
@@ -27,14 +31,19 @@ fn main() {
     //~| ERROR cannot move out of value because it is borrowed
     let ref mut a @ [b, mut c] = [U, U];
     //~^ ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of partially moved value
     let ref a @ b = u();
     //~^ ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
     //~^ ERROR cannot move out of value because it is borrowed
     //~| ERROR cannot move out of value because it is borrowed
     //~| ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
+    //~| ERROR borrow of moved value
     let ref mut a @ [b, mut c] = [u(), u()];
     //~^ ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of partially moved value
 
     match Some(U) {
         ref a @ Some(b) => {}
@@ -51,11 +60,13 @@ fn main() {
     match Some([U, U]) {
         ref mut a @ Some([b, mut c]) => {}
         //~^ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of partially moved value
         None => {}
     }
     match Some(u()) {
         ref a @ Some(b) => {}
         //~^ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of partially moved value
         None => {}
     }
     match Some((u(), u())) {
@@ -63,11 +74,14 @@ fn main() {
         //~^ ERROR cannot move out of value because it is borrowed
         //~| ERROR cannot move out of value because it is borrowed
         //~| ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of moved value
+        //~| ERROR borrow of moved value
         None => {}
     }
     match Some([u(), u()]) {
         ref mut a @ Some([b, mut c]) => {}
         //~^ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of partially moved value
         None => {}
     }
 }
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
index a275705b193..9113821d746 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
@@ -1,5 +1,5 @@
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:22:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:26:9
    |
 LL |     let ref a @ b = U;
    |         -----^^^-
@@ -8,7 +8,7 @@ LL |     let ref a @ b = U;
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:24:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:28:9
    |
 LL |     let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
    |         -----^^^^^^^^^^^^-----^^^^^^^^^^-^
@@ -18,7 +18,7 @@ LL |     let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:24:18
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:28:18
    |
 LL |     let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
    |                  -----^^^-----
@@ -27,7 +27,7 @@ LL |     let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
    |                  value borrowed, by `b`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:24:33
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:28:33
    |
 LL |     let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
    |                                 -----^^^-
@@ -36,7 +36,7 @@ LL |     let ref a @ (ref b @ mut c, ref d @ e) = (U, U);
    |                                 value borrowed, by `d`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:28:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:32:9
    |
 LL |     let ref mut a @ [b, mut c] = [U, U];
    |         ---------^^^^-^^-----^
@@ -46,7 +46,7 @@ LL |     let ref mut a @ [b, mut c] = [U, U];
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:30:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:35:9
    |
 LL |     let ref a @ b = u();
    |         -----^^^-
@@ -55,7 +55,7 @@ LL |     let ref a @ b = u();
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:32:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:38:9
    |
 LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
    |         -----^^^^^^^^^^^^-----^^^^^^^^^^-^
@@ -65,7 +65,7 @@ LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:32:18
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:38:18
    |
 LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
    |                  -----^^^-----
@@ -74,7 +74,7 @@ LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
    |                  value borrowed, by `b`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:32:33
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:38:33
    |
 LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
    |                                 -----^^^-
@@ -83,7 +83,7 @@ LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
    |                                 value borrowed, by `d`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:36:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:44:9
    |
 LL |     let ref mut a @ [b, mut c] = [u(), u()];
    |         ---------^^^^-^^-----^
@@ -93,7 +93,7 @@ LL |     let ref mut a @ [b, mut c] = [u(), u()];
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:40:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:49:9
    |
 LL |         ref a @ Some(b) => {}
    |         -----^^^^^^^^-^
@@ -102,7 +102,7 @@ LL |         ref a @ Some(b) => {}
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:45:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:54:9
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |         -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
@@ -112,7 +112,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:45:23
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:54:23
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       -----^^^-----
@@ -121,7 +121,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       value borrowed, by `b`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:45:38
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:54:38
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      -----^^^-
@@ -130,7 +130,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      value borrowed, by `d`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:52:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:61:9
    |
 LL |         ref mut a @ Some([b, mut c]) => {}
    |         ---------^^^^^^^^^-^^-----^^
@@ -140,7 +140,7 @@ LL |         ref mut a @ Some([b, mut c]) => {}
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:57:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:67:9
    |
 LL |         ref a @ Some(b) => {}
    |         -----^^^^^^^^-^
@@ -149,7 +149,7 @@ LL |         ref a @ Some(b) => {}
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:62:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:73:9
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |         -----^^^^^^^^^^^^^^^^^-----^^^^^^^^^^-^^
@@ -159,7 +159,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |         value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:62:23
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:73:23
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       -----^^^-----
@@ -168,7 +168,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       value borrowed, by `b`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:62:38
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:73:38
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      -----^^^-
@@ -177,7 +177,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      value borrowed, by `d`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:69:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:82:9
    |
 LL |         ref mut a @ Some([b, mut c]) => {}
    |         ---------^^^^^^^^^-^^-----^^
@@ -196,7 +196,7 @@ LL |     fn f1(ref a @ b: U) {}
    |           value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:15:11
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:16:11
    |
 LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
    |           -----^^^^^^^^^^^^-----^^^^^^^^^^-^
@@ -206,7 +206,7 @@ LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
    |           value borrowed, by `a`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:15:20
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:16:20
    |
 LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
    |                    -----^^^-----
@@ -215,7 +215,7 @@ LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
    |                    value borrowed, by `b`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:15:35
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:16:35
    |
 LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
    |                                   -----^^^-
@@ -224,7 +224,7 @@ LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
    |                                   value borrowed, by `d`, here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:19:11
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:22:11
    |
 LL |     fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
    |           ---------^^^^-^^-----^
@@ -233,5 +233,177 @@ LL |     fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
    |           |            value moved into `b` here
    |           value borrowed, by `a`, here
 
-error: aborting due to 25 previous errors
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:32:9
+   |
+LL |     let ref mut a @ [b, mut c] = [U, U];
+   |         ^^^^^^^^^^^^^-^^^^^^^^
+   |         |            |
+   |         |            value partially moved here
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:35:9
+   |
+LL |     let ref a @ b = u();
+   |         ^^^^^^^^-   --- move occurs because value has type `U`, which does not implement the `Copy` trait
+   |         |       |
+   |         |       value moved here
+   |         value borrowed here after move
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:38:18
+   |
+LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
+   |                  ^^^^^^^^-----
+   |                  |       |
+   |                  |       value moved here
+   |                  value borrowed here after move
+   |
+   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:38:33
+   |
+LL |     let ref a @ (ref b @ mut c, ref d @ e) = (u(), u());
+   |                                 ^^^^^^^^-
+   |                                 |       |
+   |                                 |       value moved here
+   |                                 value borrowed here after move
+   |
+   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:44:9
+   |
+LL |     let ref mut a @ [b, mut c] = [u(), u()];
+   |         ^^^^^^^^^^^^^-^^^^^^^^
+   |         |            |
+   |         |            value partially moved here
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:61:9
+   |
+LL |         ref mut a @ Some([b, mut c]) => {}
+   |         ^^^^^^^^^^^^^^^^^^-^^^^^^^^^
+   |         |                 |
+   |         |                 value partially moved here
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         ref mut a @ Some([ref b, mut c]) => {}
+   |                           ^^^
+
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:67:9
+   |
+LL |         ref a @ Some(b) => {}
+   |         ^^^^^^^^^^^^^-^
+   |         |            |
+   |         |            value partially moved here
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         ref a @ Some(ref b) => {}
+   |                      ^^^
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:73:23
+   |
+LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
+   |                       ^^^^^^^^-----
+   |                       |       |
+   |                       |       value moved here
+   |                       value borrowed here after move
+   |
+   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         ref a @ Some((ref b @ ref mut c, ref d @ e)) => {}
+   |                               ^^^
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:73:38
+   |
+LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
+   |                                      ^^^^^^^^-
+   |                                      |       |
+   |                                      |       value moved here
+   |                                      value borrowed here after move
+   |
+   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         ref a @ Some((ref b @ mut c, ref d @ ref e)) => {}
+   |                                              ^^^
+
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:82:9
+   |
+LL |         ref mut a @ Some([b, mut c]) => {}
+   |         ^^^^^^^^^^^^^^^^^^-^^^^^^^^^
+   |         |                 |
+   |         |                 value partially moved here
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving the value
+   |
+LL |         ref mut a @ Some([ref b, mut c]) => {}
+   |                           ^^^
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:13:11
+   |
+LL |     fn f1(ref a @ b: U) {}
+   |           ^^^^^^^^-
+   |           |       |
+   |           |       value moved here
+   |           value borrowed here after move
+   |           move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:16:20
+   |
+LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
+   |                    ^^^^^^^^-----
+   |                    |       |
+   |                    |       value moved here
+   |                    value borrowed here after move
+   |
+   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:16:35
+   |
+LL |     fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {}
+   |                                   ^^^^^^^^-
+   |                                   |       |
+   |                                   |       value moved here
+   |                                   value borrowed here after move
+   |
+   = note: move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:22:11
+   |
+LL |     fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
+   |           ^^^^^^^^^^^^^-^^^^^^^^
+   |           |            |
+   |           |            value partially moved here
+   |           value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+
+error: aborting due to 39 previous errors
 
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
index f67cd45ca95..f543eaece80 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
@@ -9,7 +9,7 @@ fn main() {
     match &mut Some(1) {
         ref mut z @ &mut Some(ref a) => {
         //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
-        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
             **z = None;
             println!("{}", *a);
         }
@@ -30,6 +30,7 @@ fn main() {
     fn f4_also_moved(ref a @ ref mut b @ c: U) {}
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
     //~| ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
 
     let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
     //~^ ERROR cannot borrow value as mutable more than once at a time
@@ -46,12 +47,12 @@ fn main() {
 
     let ref mut a @ ref b = u();
     //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
-    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+    //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
     *a = u();
     drop(b);
     let ref a @ ref mut b = u();
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
-    //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
     *b = u();
     drop(a);
 
@@ -77,8 +78,8 @@ fn main() {
         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
             //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
-            //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
-            //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+            //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+            //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
             *b = U;
             drop(a);
         }
@@ -89,6 +90,8 @@ fn main() {
         //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
         //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
         //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
         _ => {}
     }
     match Ok(U) {
@@ -102,6 +105,8 @@ fn main() {
         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
         //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
         //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
         //~| ERROR cannot move out of `b` in pattern guard
         //~| ERROR cannot move out of `b` in pattern guard
         _ => {}
@@ -117,20 +122,20 @@ fn main() {
 
     let ref a @ (ref mut b, ref mut c) = (U, U);
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
     *b = U;
     *c = U;
 
     let ref a @ (ref mut b, ref mut c) = (U, U);
     //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
-    //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
-    //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
     *b = U;
     drop(a);
 
     let ref a @ (ref mut b, ref mut c) = (U, U);
-    //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
     *b = U; //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
-    *c = U; //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+    *c = U;
     drop(a);
     let ref mut a @ (ref b, ref c) = (U, U);
     //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
index e6231dd49ba..d9b59504419 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
@@ -8,7 +8,7 @@ LL |         ref mut z @ &mut Some(ref a) => {
    |         mutable borrow, by `z`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:34: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:34: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, by `b`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:38: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:40: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:42: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, by `a`, occurs here
 
 error: cannot borrow value 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: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:47: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:52: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:58: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:62: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:68: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:68: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:77: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:77: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:88: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:88: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:95:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:98: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:95:33
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:98: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:102:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:105: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:102:33
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:105: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:110:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:110:33
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:118:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:129: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, by `a`, occurs here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:130:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:135: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, by `a`, occurs here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:135:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:140:9
    |
 LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         ---------^^^^-----^^-----^
@@ -294,68 +294,86 @@ LL |     fn f4_also_moved(ref a @ ref mut b @ c: U) {}
    |                              |           value moved into `c` here
    |                              value borrowed, by `b`, here
 
-error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31
+error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9
    |
 LL |         ref mut z @ &mut Some(ref a) => {
-   |         ----------------------^^^^^-
+   |         ^^^^^^^^^^^^^^^^^^^^^^-----^
    |         |                     |
    |         |                     immutable borrow occurs here
    |         mutable borrow occurs here
 ...
-LL |             **z = None;
-   |             ---------- mutable borrow later used here
+LL |             println!("{}", *a);
+   |                            -- immutable borrow later used here
 
-error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:47:21
+error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:48:9
    |
 LL |     let ref mut a @ ref b = u();
-   |         ------------^^^^^
+   |         ^^^^^^^^^^^^-----
    |         |           |
    |         |           immutable borrow occurs here
    |         mutable borrow occurs here
 ...
-LL |     *a = u();
-   |     -------- mutable borrow later used here
+LL |     drop(b);
+   |          - immutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:52:17
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:53:9
    |
 LL |     let ref a @ ref mut b = u();
-   |         --------^^^^^^^^^
+   |         ^^^^^^^^---------
    |         |       |
    |         |       mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-LL |     drop(a);
-   |          - immutable borrow later used here
+LL |     *b = u();
+   |     -------- mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:77:20
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:9
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
-   |         -----------^^^^^^^^^-
+   |         ^^^^^^^^^^^---------^
    |         |          |
    |         |          mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - immutable borrow later used here
+LL |             *b = U;
+   |             ------ mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:77:45
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:33
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
-   |                                 ------------^^^^^^^^^-
+   |                                 ^^^^^^^^^^^^---------^
    |                                 |           |
    |                                 |           mutable borrow occurs here
    |                                 immutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - immutable borrow later used here
+LL |             *b = U;
+   |             ------ mutable borrow later used here
+
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:9
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
+   |         ^^^^^^^^^^^---------^                               ------ mutable borrow later used here
+   |         |          |
+   |         |          mutable borrow occurs here
+   |         immutable borrow occurs here
+
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:89:33
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
+   |                                 ^^^^^^^^^^^^---------^      ------ mutable borrow later used here
+   |                                 |           |
+   |                                 |           mutable borrow occurs here
+   |                                 immutable borrow occurs here
 
 error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:88: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
@@ -363,15 +381,33 @@ 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:95:61
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:98:61
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |                                                             ^^^^^^^^^^^ cannot assign
    |
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:105:9
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
+   |         ^^^^^^^^^^^---------^                                    - mutable borrow later used here
+   |         |          |
+   |         |          mutable borrow occurs here
+   |         immutable borrow occurs here
+
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:105:33
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
+   |                                 ^^^^^^^^^^^^---------^           - mutable borrow later used here
+   |                                 |           |
+   |                                 |           mutable borrow occurs here
+   |                                 immutable borrow occurs here
+
 error[E0507]: cannot move out of `b` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:102:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:105: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 U`, which does not implement the `Copy` trait
@@ -379,7 +415,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:102:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:105: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 U`, which does not implement the `Copy` trait
@@ -387,7 +423,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:110:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115: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<U, U>`, which does not implement the `Copy` trait
@@ -395,62 +431,60 @@ 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:110:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115: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<U, U>`, which does not implement the `Copy` trait
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:18
-   |
-LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         ---------^^^^^^^^^------------
-   |         |        |
-   |         |        mutable borrow occurs here
-   |         immutable borrow occurs here
-...
-LL |     drop(a);
-   |          - immutable borrow later used here
-
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:29
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         --------------------^^^^^^^^^-
+   |         ^^^^^^^^^^^^^^^^^^^^---------^
    |         |                   |
    |         |                   mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-LL |     drop(a);
-   |          - immutable borrow later used here
+LL |     *c = U;
+   |     ------ mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:130:18
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         ---------^^^^^^^^^------------
+   |         ^^^^^^^^^---------^^^^^^^^^^^^
    |         |        |
    |         |        mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-LL |     drop(a);
-   |          - immutable borrow later used here
+LL |     *b = U;
+   |     ------ mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:130:29
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:135:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         --------------------^^^^^^^^^-
+   |         ^^^^^^^^^^^^^^^^^^^^---------^
    |         |                   |
    |         |                   mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-LL |     drop(a);
-   |          - immutable borrow later used here
+LL |     *c = U;
+   |     ------ mutable borrow later used here
+
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:30:30
+   |
+LL |     fn f4_also_moved(ref a @ ref mut b @ c: U) {}
+   |                      --------^^^^^^^^^^^^-
+   |                      |       |           |
+   |                      |       |           value moved here
+   |                      |       value borrowed here after move
+   |                      move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error: aborting due to 47 previous errors
+error: aborting due to 51 previous errors
 
-Some errors have detailed explanations: E0502, E0507, E0594.
-For more information about an error, try `rustc --explain E0502`.
+Some errors have detailed explanations: E0382, E0502, E0507, E0594.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
index 8faaa1c881f..c58f0413499 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
@@ -23,23 +23,24 @@ fn main() {
     fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
     //~^ ERROR cannot borrow value as mutable more than once at a time
     //~| ERROR cannot move out of value because it is borrowed
+    //~| ERROR borrow of moved value
 
     let ref mut a @ ref mut b = U;
     //~^ ERROR cannot borrow value as mutable more than once at a time
-    //~| ERROR cannot borrow value as mutable more than once at a time
     drop(a);
     let ref mut a @ ref mut b = U;
     //~^ ERROR cannot borrow value as mutable more than once at a time
+    //~| ERROR cannot borrow value as mutable more than once at a time
     drop(b);
     let ref mut a @ ref mut b = U;
     //~^ ERROR cannot borrow value as mutable more than once at a time
 
     let ref mut a @ ref mut b = U;
     //~^ ERROR cannot borrow value as mutable more than once at a time
-    //~| ERROR cannot borrow value as mutable more than once at a time
     *a = U;
     let ref mut a @ ref mut b = U;
     //~^ ERROR cannot borrow value as mutable more than once at a time
+    //~| ERROR cannot borrow value as mutable more than once at a time
     *b = U;
 
     let ref mut a @ (
@@ -64,18 +65,14 @@ fn main() {
 
     let a @ (ref mut b, ref mut c) = (U, U);
     //~^ 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 borrow of moved value
-    //~| ERROR borrow of moved value
 
     let a @ &mut ref mut b = &mut U;
     //~^ ERROR borrow of moved value
-    //~| ERROR borrow of moved value
     let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
     //~^ ERROR borrow of moved value
-    //~| ERROR borrow of moved value
 
     match Ok(U) {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
@@ -87,6 +84,8 @@ fn main() {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable more than once at a time
             //~| ERROR cannot borrow value as mutable more than once at a time
+            //~| ERROR cannot borrow value as mutable more than once at a time
+            //~| ERROR cannot borrow value as mutable more than once at a time
             *b = U;
         }
     }
@@ -94,8 +93,6 @@ fn main() {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable more than once at a time
             //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
             *a = Err(U);
 
             // FIXME: The binding name value used above makes for problematic diagnostics.
@@ -106,8 +103,6 @@ fn main() {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable more than once at a time
             //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
             drop(a);
         }
     }
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
index 2e0f5fcabdd..5ae71c2a9fd 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
@@ -1,5 +1,5 @@
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:27:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:28: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, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:34: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, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:37:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:38: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, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:45: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 value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:55:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:56:9
    |
 LL |       let ref mut a @ (
    |           ^--------
@@ -88,7 +88,7 @@ LL | |         ) = (u(), [u(), u(), u()]);
    | |_________^
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:65:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9
    |
 LL |     let a @ (ref mut b, ref mut c) = (U, U);
    |         -^^^^---------^^---------^
@@ -111,7 +111,7 @@ LL |     let a @ (b, [c, d]) = &mut val; // Same as ^--
    |         move occurs because `a` has type `&mut (U, [U; 2])` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:72:9
    |
 LL |     let a @ &mut ref mut b = &mut U;
    |         -^^^^^^^^---------
@@ -121,7 +121,7 @@ LL |     let a @ &mut ref mut b = &mut U;
    |         move occurs because `a` has type `&mut U` which does not implement the `Copy` trait
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:76:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9
    |
 LL |     let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
    |         -^^^^^^^^^---------^^---------^
@@ -132,7 +132,7 @@ LL |     let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
    |         move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:81:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -141,7 +141,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:81:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -150,7 +150,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:87:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -159,7 +159,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:87:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -168,7 +168,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:94:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:93:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -177,7 +177,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:94:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:93:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -186,7 +186,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:106:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------^^^^^^---------^
@@ -195,7 +195,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         first mutable borrow, by `a`, occurs here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:106:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ---------^^^^^^^---------^
@@ -259,114 +259,64 @@ LL |     fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
    |                                  value borrowed, by `b`, here
 
 error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:27:21
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9
    |
 LL |     let ref mut a @ ref mut b = U;
-   |         ------------^^^^^^^^^
+   |         ^^^^^^^^^^^^---------
    |         |           |
-   |         |           second mutable borrow occurs here
-   |         first mutable borrow occurs here
+   |         |           first mutable borrow occurs here
+   |         second mutable borrow occurs here
 ...
-LL |     drop(a);
+LL |     drop(b);
    |          - first borrow later used here
 
 error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:37:21
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:41:9
    |
 LL |     let ref mut a @ ref mut b = U;
-   |         ------------^^^^^^^^^
+   |         ^^^^^^^^^^^^---------
    |         |           |
-   |         |           second mutable borrow occurs here
-   |         first mutable borrow occurs here
+   |         |           first mutable borrow occurs here
+   |         second mutable borrow occurs here
 ...
-LL |     *a = U;
+LL |     *b = U;
    |     ------ first borrow later used here
 
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:65:25
-   |
-LL |     let a @ (ref mut b, ref mut c) = (U, U);
-   |         ----------------^^^^^^^^^-   ------ move occurs because value has type `(U, 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-ref-mut-twice.rs:69:21
-   |
-LL |     let a @ (b, [c, d]) = &mut val; // Same as ^--
-   |         ------------^--   -------- move occurs because value has type `&mut (U, [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-ref-mut-twice.rs:73:18
-   |
-LL |     let a @ &mut ref mut b = &mut U;
-   |         ---------^^^^^^^^^   ------ move occurs because value has type `&mut 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-ref-mut-twice.rs:76:30
-   |
-LL |     let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
-   |         ---------------------^^^^^^^^^-   ----------- move occurs because value has type `&mut (U, U)`, which does not implement the `Copy` trait
-   |         |                    |
-   |         |                    value borrowed here after move
-   |         value moved here
-
 error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:94:24
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |         ---------------^^^^^^^^^-
+   |         ^^^^^^^^^^^^^^^---------^
    |         |              |
-   |         |              second mutable borrow occurs here
-   |         first mutable borrow occurs here
+   |         |              first mutable borrow occurs here
+   |         second mutable borrow occurs here
 ...
-LL |             *a = Err(U);
-   |             ----------- first borrow later used here
+LL |             *b = U;
+   |             ------ first borrow later used here
 
 error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:94:53
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |                                     ----------------^^^^^^^^^-
+   |                                     ^^^^^^^^^^^^^^^^---------^
    |                                     |               |
-   |                                     |               second mutable borrow occurs here
-   |                                     first mutable borrow occurs here
-...
-LL |             *a = Err(U);
-   |             ----------- first borrow later used here
-
-error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:106:24
-   |
-LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |         ---------------^^^^^^^^^-
-   |         |              |
-   |         |              second mutable borrow occurs here
-   |         first mutable borrow occurs here
+   |                                     |               first mutable borrow occurs here
+   |                                     second mutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - first borrow later used here
+LL |             *b = U;
+   |             ------ first borrow later used here
 
-error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:106:53
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:23:34
    |
-LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |                                     ----------------^^^^^^^^^-
-   |                                     |               |
-   |                                     |               second mutable borrow occurs here
-   |                                     first mutable borrow occurs here
-...
-LL |             drop(a);
-   |                  - first borrow later used here
+LL |     fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
+   |                      ------------^^^^^^^^^^^^-
+   |                      |           |           |
+   |                      |           |           value moved here
+   |                      |           value borrowed here after move
+   |                      move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error: aborting due to 34 previous errors
+error: aborting due to 29 previous errors
 
 Some errors have detailed explanations: E0382, E0499.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
index 3954d17e1c2..1dc9716f54b 100644
--- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
+++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs
@@ -8,10 +8,6 @@ struct C;
 struct NC<A, B>(A, B);
 
 fn main() {
-    let a @ NC(b, c) = NC(C, C);
-    //~^ ERROR use of moved value
-
     let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
-    //~^ ERROR use of moved value
-    //~| ERROR use of moved value
+    //~^ ERROR use of partially moved value
 }
diff --git a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
index cc2786a13f4..9ffbadf36a6 100644
--- a/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
+++ b/src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.stderr
@@ -1,32 +1,14 @@
-error[E0382]: use of moved value
-  --> $DIR/copy-and-move-mixed.rs:11: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
-   |         |         |
-   |         |         value used here after move
-   |         value moved here
-
-error[E0382]: use of moved value
-  --> $DIR/copy-and-move-mixed.rs:14:19
+error[E0382]: use of partially moved value
+  --> $DIR/copy-and-move-mixed.rs:11:9
    |
 LL |     let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
-   |         ----------^^^^^^^^^^^^-   --------------- move occurs because value has type `NC<C, NC<C, C>>`, which does not implement the `Copy` trait
+   |         ^^^^^^^^^^------------^
    |         |         |
-   |         |         value used here after move
-   |         value moved here
-
-error[E0382]: use of moved value
-  --> $DIR/copy-and-move-mixed.rs:14:29
-   |
-LL |     let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C));
-   |                   ----------^-
-   |                   |         |
-   |                   |         value used here after move
-   |                   value moved here
+   |         |         value partially moved here
+   |         value used here after partial move
    |
-   = note: move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
+   = note: partial move occurs because value has type `NC<C, C>`, which does not implement the `Copy` trait
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs
index 276088b9a9e..c15167e7175 100644
--- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs
+++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs
@@ -28,7 +28,7 @@ fn main() {
     let _a: &NotCopy = a;
     let _b: NotCopy = b;
     let ref mut a @ b = NotCopy; //~ ERROR cannot move out of value because it is borrowed
-    //~^ ERROR cannot move out of value because it is borrowed
+    //~^ ERROR borrow of moved value
     let _a: &NotCopy = a;
     let _b: NotCopy = b;
     match Ok(NotCopy) {
diff --git a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
index 11d5e24f34e..a41fec7a3f8 100644
--- a/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
+++ b/src/test/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
@@ -44,18 +44,15 @@ LL |         ref a @ b => {
    |         |       value moved into `b` here
    |         value borrowed, by `a`, here
 
-error[E0505]: cannot move out of value because it is borrowed
-  --> $DIR/default-binding-modes-both-sides-independent.rs:30:21
+error[E0382]: borrow of moved value
+  --> $DIR/default-binding-modes-both-sides-independent.rs:30:9
    |
 LL |     let ref mut a @ b = NotCopy;
-   |         ------------^
+   |         ^^^^^^^^^^^^-   ------- move occurs because value has type `NotCopy`, which does not implement the `Copy` trait
    |         |           |
-   |         |           move out of value occurs here
-   |         borrow of value occurs here
-LL |
-LL |     let _a: &NotCopy = a;
-   |                        - borrow later used here
+   |         |           value moved here
+   |         value borrowed here after move
 
 error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0505`.
+For more information about this error, try `rustc --explain E0382`.