about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-11-05 13:26:08 +0000
committerbors <bors@rust-lang.org>2020-11-05 13:26:08 +0000
commitb1d9f31e043d0ba2782a4bb7416f18c4ba1c9044 (patch)
tree42842aa22ca61789dfcfbdfe5b784994fc2af5cb
parentf7801d6c7cc19ab22bdebcc8efa894a564c53469 (diff)
parent5827fbadf6feaa3da42d7223ac9f10148c827a89 (diff)
downloadrust-b1d9f31e043d0ba2782a4bb7416f18c4ba1c9044.tar.gz
rust-b1d9f31e043d0ba2782a4bb7416f18c4ba1c9044.zip
Auto merge of #78638 - vn-ki:bindigs-after-at-issue-69971, r=oli-obk
reverse binding order in matches to allow the subbinding of copyable fields in bindings after @

Fixes #69971

### TODO

- [x] Regression tests

r? `@oli-obk`
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs44
-rw-r--r--src/test/ui/pattern/bindings-after-at/bind-by-copy.rs49
-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.rs8
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr68
-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.rs21
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr264
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs11
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr177
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs13
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr146
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs9
-rw-r--r--src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr108
-rw-r--r--src/test/ui/pattern/bindings-after-at/copy-and-move-mixed.rs5
-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
22 files changed, 568 insertions, 595 deletions
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 375f19f8755..705266d4a0b 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -43,12 +43,36 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         candidate: &mut Candidate<'pat, 'tcx>,
     ) -> bool {
         // repeatedly simplify match pairs until fixed point is reached
+        debug!(?candidate, "simplify_candidate");
+
+        // existing_bindings and new_bindings exists to keep the semantics in order.
+        // Reversing the binding order for bindings after `@` changes the binding order in places
+        // it shouldn't be changed, for example `let (Some(a), Some(b)) = (x, y)`
+        //
+        // To avoid this, the binding occurs in the following manner:
+        // * the bindings for one iteration of the following loop occurs in order (i.e. left to
+        // right)
+        // * the bindings from the previous iteration of the loop is prepended to the bindings from
+        // the current iteration (in the implementation this is done by mem::swap and extend)
+        // * after all iterations, these new bindings are then appended to the bindings that were
+        // prexisting (i.e. `candidate.binding` when the function was called).
+        //
+        // example:
+        // candidate.bindings = [1, 2, 3]
+        // binding in iter 1: [4, 5]
+        // binding in iter 2: [6, 7]
+        //
+        // final binding: [1, 2, 3, 6, 7, 4, 5]
+        let mut existing_bindings = mem::take(&mut candidate.bindings);
+        let mut new_bindings = Vec::new();
         loop {
             let match_pairs = mem::take(&mut candidate.match_pairs);
 
             if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, place }] =
                 *match_pairs
             {
+                existing_bindings.extend_from_slice(&new_bindings);
+                mem::swap(&mut candidate.bindings, &mut existing_bindings);
                 candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
                 return true;
             }
@@ -64,13 +88,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     }
                 }
             }
+            // Avoid 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.extend_from_slice(&new_bindings);
+            mem::swap(&mut candidate.bindings, &mut new_bindings);
+            candidate.bindings.clear();
+
             if !changed {
+                existing_bindings.extend_from_slice(&new_bindings);
+                mem::swap(&mut candidate.bindings, &mut existing_bindings);
                 // Move or-patterns to the end, because they can result in us
                 // creating additional candidates, so we want to test them as
                 // late as possible.
                 candidate
                     .match_pairs
                     .sort_by_key(|pair| matches!(*pair.pattern.kind, PatKind::Or { .. }));
+                debug!(simplified = ?candidate, "simplify_candidate");
                 return false; // if we were not able to simplify any, done.
             }
         }
diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-copy.rs b/src/test/ui/pattern/bindings-after-at/bind-by-copy.rs
new file mode 100644
index 00000000000..508e486afec
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/bind-by-copy.rs
@@ -0,0 +1,49 @@
+// run-pass
+
+// Test copy
+
+#![feature(bindings_after_at)]
+
+struct A { a: i32, b: i32 }
+struct B { a: i32, b: C }
+struct D { a: i32, d: C }
+#[derive(Copy,Clone)]
+struct C { c: i32 }
+
+pub fn main() {
+    match (A {a: 10, b: 20}) {
+        x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); }
+        A {b: _b, ..} => { panic!(); }
+    }
+
+    let mut x@B {b, ..} = B {a: 10, b: C {c: 20}};
+    assert_eq!(x.a, 10);
+    x.b.c = 30;
+    assert_eq!(b.c, 20);
+    let mut y@D {d, ..} = D {a: 10, d: C {c: 20}};
+    assert_eq!(y.a, 10);
+    y.d.c = 30;
+    assert_eq!(d.c, 20);
+
+    let some_b = Some(B { a: 10, b: C { c: 20 } });
+
+    // in irrefutable pattern
+    if let Some(x @ B { b, .. }) = some_b {
+        assert_eq!(x.b.c, 20);
+        assert_eq!(b.c, 20);
+    } else {
+        unreachable!();
+    }
+
+    let some_b = Some(B { a: 10, b: C { c: 20 } });
+
+    if let Some(x @ B { b: mut b @ C { c }, .. }) = some_b {
+        assert_eq!(x.b.c, 20);
+        assert_eq!(b.c, 20);
+        b.c = 30;
+        assert_eq!(b.c, 30);
+        assert_eq!(c, 20);
+    } else {
+        unreachable!();
+    }
+}
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..bce43f9df85 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,9 +12,9 @@ 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
@@ -24,10 +24,10 @@ fn main() {
     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..bfb7b479731 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,29 +1,33 @@
 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
@@ -47,36 +51,36 @@ LL |         a @ Ok(b) | a @ Err(b) => {}
    |                     |       value used here after move
    |                     value moved here
 
-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..8a574f880ed 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,8 +50,6 @@ 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
         None => {}
     }
@@ -83,8 +70,6 @@ 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
         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..79addf9d574 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:63: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:69: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:69: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:69: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:77: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,112 +258,30 @@ 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
+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);
-   |         ------------------------^^^^^^^^^-   ------ 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
+   |         |                       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
+   = 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: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
+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
-   |
-   = 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
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:43:37
+   |         |                       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]: 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
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60: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
-help: borrow this field in the pattern to avoid moving the value
-   |
-LL |         a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
-   |                   ^^^
+   = note: partial 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:60:38
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:49:38
    |
 LL |     match Some((U, U)) {
    |           ------------ move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
@@ -374,22 +292,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         value moved here
 
 error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60: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:70:30
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:57:30
    |
 LL |     match Some([U, U]) {
    |           ------------ move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
@@ -400,7 +303,7 @@ LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         value moved here
 
 error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:76:18
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:63:18
    |
 LL |     match Some(u()) {
    |           --------- move occurs because value has type `Option<U>`, which does not implement the `Copy` trait
@@ -410,23 +313,8 @@ 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
-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
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:69:38
    |
 LL |     match Some((u(), u())) {
    |           ---------------- move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
@@ -437,22 +325,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         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
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:77:30
    |
 LL |     match Some([u(), u()]) {
    |           ---------------- move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
@@ -462,58 +335,17 @@ 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 33 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..b9235eabd88 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) => {}
@@ -63,6 +72,8 @@ 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()]) {
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..50b2f8929f2 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:66: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:71: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:71: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:71: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:80: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,132 @@ 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 moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:71: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:71: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 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 36 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..2d391cd7d07 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
@@ -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);
 
@@ -117,20 +118,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..00136c25764 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:96:9
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |         ---------^^^^^^-----^
@@ -164,7 +164,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    |         mutable borrow, 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:96:33
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |                                 ---------^^^^^^^-----^
@@ -173,7 +173,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    |                                 mutable borrow, 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:103:9
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |         -----^^^^^^---------^
@@ -182,7 +182,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    |         immutable borrow, 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:103:33
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |                                 -----^^^^^^^---------^
@@ -191,7 +191,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    |                                 immutable borrow, 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:111:9
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |         ---------^^^^^^-----^
@@ -200,7 +200,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    |         mutable borrow, 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:111:33
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |                                 ---------^^^^^^^-----^
@@ -209,7 +209,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    |                                 mutable borrow, 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:119:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         -----^^^^---------^^---------^
@@ -219,7 +219,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         immutable borrow, 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:125: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:131:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         -----^^^^---------^^---------^
@@ -239,7 +239,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         immutable borrow, 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:136:9
    |
 LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         ---------^^^^-----^^-----^
@@ -306,32 +306,32 @@ LL |         ref mut z @ &mut Some(ref a) => {
 LL |             **z = None;
    |             ---------- 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: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
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:20
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
    |         -----------^^^^^^^^^-
@@ -343,7 +343,7 @@ 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:77:45
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:78:45
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
    |                                 ------------^^^^^^^^^-
@@ -355,7 +355,7 @@ LL |             drop(a);
    |                  - immutable borrow later used here
 
 error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs: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,7 +363,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
 error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:95:61
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:61
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |                                                             ^^^^^^^^^^^ cannot assign
@@ -371,7 +371,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
 error[E0507]: cannot move out of `b` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:102:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |                                                                  ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait
@@ -379,7 +379,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error[E0507]: cannot move out of `b` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:102:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |                                                                  ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait
@@ -387,7 +387,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error[E0507]: cannot move out of `a` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:110:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:111:66
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |                                                                  ^ move occurs because `a` has type `&mut std::result::Result<U, U>`, which does not implement the `Copy` trait
@@ -395,62 +395,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:111:66
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |                                                                  ^ move occurs because `a` has type `&mut std::result::Result<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
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:119:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         ---------^^^^^^^^^------------
+   |         ^^^^^^^^^---------^^^^^^^^^^^^
    |         |        |
    |         |        mutable borrow occurs here
    |         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:123:29
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:125:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         --------------------^^^^^^^^^-
-   |         |                   |
-   |         |                   mutable borrow occurs here
+   |         ^^^^^^^^^---------^^^^^^^^^^^^
+   |         |        |
+   |         |        mutable borrow occurs here
    |         immutable borrow occurs here
 ...
-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:18
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:131:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
-   |         ---------^^^^^^^^^------------
+   |         ^^^^^^^^^---------^^^^^^^^^^^^
    |         |        |
    |         |        mutable borrow occurs here
    |         immutable borrow occurs here
-...
-LL |     drop(a);
-   |          - immutable borrow later used here
+LL |
+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[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:30:30
    |
-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 |     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
 
-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..339814e1e31 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) => {
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..0370037f242 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:91: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:91: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,67 +259,31 @@ 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:91:24
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------------^^^^^^^^^-
@@ -331,7 +295,7 @@ 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:94:53
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ----------------^^^^^^^^^-
@@ -343,7 +307,7 @@ 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
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ---------------^^^^^^^^^-
@@ -355,7 +319,7 @@ LL |             drop(a);
    |                  - 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
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ----------------^^^^^^^^^-
@@ -366,7 +330,17 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
 LL |             drop(a);
    |                  - first borrow later used here
 
-error: aborting due to 34 previous errors
+error[E0382]: borrow of moved value
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:23:34
+   |
+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 31 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..f731aa2e963 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,9 @@ struct C;
 struct NC<A, B>(A, B);
 
 fn main() {
+    // this compiles
     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..183a37176ec 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:14: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`.