about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/mir/mod.rs10
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs24
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs30
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs556
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs7
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs8
-rw-r--r--src/librustc_mir/util/borrowck_errors.rs12
-rw-r--r--src/test/ui/access-mode-in-closures.stderr15
-rw-r--r--src/test/ui/binop/binop-move-semantics.rs4
-rw-r--r--src/test/ui/binop/binop-move-semantics.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr12
-rw-r--r--src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs4
-rw-r--r--src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr12
-rw-r--r--src/test/ui/borrowck/borrowck-fn-in-const-a.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-fn-in-const-a.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.stderr33
-rw-r--r--src/test/ui/borrowck/borrowck-in-static.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-in-static.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-issue-2657-2.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr11
-rw-r--r--src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr11
-rw-r--r--src/test/ui/borrowck/borrowck-move-by-capture.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-move-error-with-note.rs3
-rw-r--r--src/test/ui/borrowck/borrowck-move-error-with-note.stderr35
-rw-r--r--src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-move-in-irrefut-pat.stderr31
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-overloaded-deref.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-static-item.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-static-item.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.stderr25
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.stderr25
-rw-r--r--src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-struct-update-with-dtor.stderr10
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs3
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr35
-rw-r--r--src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs2
-rw-r--r--src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr4
-rw-r--r--src/test/ui/borrowck/issue-51415.stderr14
-rw-r--r--src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs2
-rw-r--r--src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr4
-rw-r--r--src/test/ui/borrowck/move-in-static-initializer-issue-38520.stderr8
-rw-r--r--src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs2
-rw-r--r--src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr4
-rw-r--r--src/test/ui/by-move-pattern-binding.stderr11
-rw-r--r--src/test/ui/check-static-values-constraints.stderr4
-rw-r--r--src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.stderr7
-rw-r--r--src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.stderr11
-rw-r--r--src/test/ui/dst/dst-index.rs4
-rw-r--r--src/test/ui/dst/dst-index.stderr8
-rw-r--r--src/test/ui/dst/dst-rvalue.rs2
-rw-r--r--src/test/ui/dst/dst-rvalue.stderr9
-rw-r--r--src/test/ui/error-codes/E0507.stderr4
-rw-r--r--src/test/ui/error-codes/E0508-fail.stderr1
-rw-r--r--src/test/ui/error-codes/E0508.stderr1
-rw-r--r--src/test/ui/error-codes/E0509.stderr1
-rw-r--r--src/test/ui/functional-struct-update/functional-struct-update-noncopyable.stderr5
-rw-r--r--src/test/ui/issues/issue-17718-static-move.stderr4
-rw-r--r--src/test/ui/issues/issue-20801.rs8
-rw-r--r--src/test/ui/issues/issue-20801.stderr16
-rw-r--r--src/test/ui/issues/issue-2590.rs2
-rw-r--r--src/test/ui/issues/issue-2590.stderr4
-rw-r--r--src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs2
-rw-r--r--src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr12
-rw-r--r--src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.rs2
-rw-r--r--src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr4
-rw-r--r--src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.rs2
-rw-r--r--src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr8
-rw-r--r--src/test/ui/issues/issue-4335.stderr4
-rw-r--r--src/test/ui/moves/move-out-of-array-1.stderr5
-rw-r--r--src/test/ui/moves/move-out-of-slice-1.stderr11
-rw-r--r--src/test/ui/moves/moves-based-on-type-block-bad.rs1
-rw-r--r--src/test/ui/moves/moves-based-on-type-block-bad.stderr20
-rw-r--r--src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr4
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.stderr27
-rw-r--r--src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr1
-rw-r--r--src/test/ui/nll/issue-52086.stderr4
-rw-r--r--src/test/ui/nll/issue-52663-span-decl-captured-variable.rs2
-rw-r--r--src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr4
-rw-r--r--src/test/ui/nll/match-guards-always-borrow.rs2
-rw-r--r--src/test/ui/nll/match-guards-always-borrow.stderr12
-rw-r--r--src/test/ui/nll/move-errors.stderr93
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr4
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs2
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr6
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs2
-rw-r--r--src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr6
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/for.rs2
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/for.stderr11
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs2
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr4
-rw-r--r--src/test/ui/static/static-items-cant-move.stderr4
-rw-r--r--src/test/ui/std-uncopyable-atomics.rs8
-rw-r--r--src/test/ui/std-uncopyable-atomics.stderr16
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr66
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr342
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/simple.stderr772
-rw-r--r--src/test/ui/suggestions/option-content-move.fixed4
-rw-r--r--src/test/ui/suggestions/option-content-move.rs4
-rw-r--r--src/test/ui/suggestions/option-content-move.stderr8
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr16
-rw-r--r--src/test/ui/unop-move-semantics.rs4
-rw-r--r--src/test/ui/unop-move-semantics.stderr8
-rw-r--r--src/test/ui/unsized-locals/unsized-exprs2.stderr5
107 files changed, 1116 insertions, 1516 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 6213eda6514..c2b4a765c59 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -913,6 +913,16 @@ impl<'tcx> LocalDecl<'tcx> {
         }
     }
 
+    /// Returns `true` if this is a reference to a variable bound in a `match`
+    /// expression that is used to access said variable for the guard of the
+    /// match arm.
+    pub fn is_ref_for_guard(&self) -> bool {
+        match self.is_user_variable {
+            Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) => true,
+            _ => false,
+        }
+    }
+
     /// Returns `true` is the local is from a compiler desugaring, e.g.,
     /// `__next` from a `for` loop.
     #[inline]
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index e3a79b24cab..f8e73e838df 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -234,22 +234,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         );
                     }
                 }
-                if let Place::Base(PlaceBase::Local(local)) = place {
+                let span = if let Place::Base(PlaceBase::Local(local)) = place {
                     let decl = &self.mir.local_decls[*local];
-                    err.span_label(
-                        decl.source_info.span,
-                        format!(
-                            "move occurs because {} has type `{}`, \
-                                which does not implement the `Copy` trait",
-                            note_msg, ty,
-                    ));
+                    Some(decl.source_info.span)
                 } else {
-                    err.note(&format!(
-                        "move occurs because {} has type `{}`, \
-                         which does not implement the `Copy` trait",
-                        note_msg, ty
-                    ));
-                }
+                    None
+                };
+                self.note_type_does_not_implement_copy(
+                    &mut err,
+                    &note_msg,
+                    ty,
+                    span,
+                );
             }
 
             if let Some((_, mut old_err)) = self.move_error_reported
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 31af20fdb77..3f977ea198b 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -2,9 +2,9 @@ use rustc::hir;
 use rustc::hir::def::Namespace;
 use rustc::hir::def_id::DefId;
 use rustc::mir::{
-    AggregateKind, BindingForm, ClearCrossCrate, Constant, Field, Local,
-    LocalKind, Location, Operand, Place, PlaceBase, ProjectionElem, Rvalue,
-    Statement, StatementKind, Static, StaticKind, TerminatorKind,
+    AggregateKind, Constant, Field, Local, LocalKind, Location, Operand,
+    Place, PlaceBase, ProjectionElem, Rvalue, Statement, StatementKind, Static,
+    StaticKind, TerminatorKind,
 };
 use rustc::ty::{self, DefIdTree, Ty};
 use rustc::ty::layout::VariantIdx;
@@ -180,9 +180,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                                     &including_downcast,
                                 )?;
                             } else if let Place::Base(PlaceBase::Local(local)) = proj.base {
-                                if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
-                                    self.mir.local_decls[local].is_user_variable
-                                {
+                                if self.mir.local_decls[local].is_ref_for_guard() {
                                     self.append_place_to_string(
                                         &proj.base,
                                         buf,
@@ -383,6 +381,26 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             false
         }
     }
+
+    /// Add a note that a type does not implement `Copy`
+    pub(super) fn note_type_does_not_implement_copy(
+        &self,
+        err: &mut DiagnosticBuilder<'a>,
+        place_desc: &str,
+        ty: Ty<'tcx>,
+        span: Option<Span>,
+    ) {
+        let message = format!(
+            "move occurs because {} has type `{}`, which does not implement the `Copy` trait",
+            place_desc,
+            ty,
+        );
+        if let Some(span) = span {
+            err.span_label(span, message);
+        } else {
+            err.note(&message);
+        }
+    }
 }
 
 impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 63d5cd4372f..f892c159705 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -1,13 +1,13 @@
 use core::unicode::property::Pattern_White_Space;
-use std::fmt::{self, Display};
 
 use rustc::mir::*;
-use rustc::ty;
+use rustc::ty::{self, Ty, TyCtxt};
 use rustc_errors::{DiagnosticBuilder,Applicability};
 use syntax_pos::Span;
 
 use crate::borrow_check::MirBorrowckCtxt;
 use crate::borrow_check::prefixes::PrefixSet;
+use crate::borrow_check::error_reporting::UseSpans;
 use crate::dataflow::move_paths::{
     IllegalMoveOrigin, IllegalMoveOriginKind, InitLocation,
     LookupResult, MoveError, MovePathIndex,
@@ -50,25 +50,71 @@ enum GroupedMoveError<'tcx> {
     // Everything that isn't from pattern matching.
     OtherIllegalMove {
         original_path: Place<'tcx>,
-        span: Span,
+        use_spans: UseSpans,
         kind: IllegalMoveOriginKind<'tcx>,
     },
 }
 
-enum BorrowedContentSource {
-    Arc,
-    Rc,
+enum BorrowedContentSource<'tcx> {
     DerefRawPointer,
-    Other,
+    DerefMutableRef,
+    DerefSharedRef,
+    OverloadedDeref(Ty<'tcx>),
+    OverloadedIndex(Ty<'tcx>),
 }
 
-impl Display for BorrowedContentSource {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+impl BorrowedContentSource<'tcx> {
+    fn describe_for_unnamed_place(&self) -> String {
+        match *self {
+            BorrowedContentSource::DerefRawPointer => format!("a raw pointer"),
+            BorrowedContentSource::DerefSharedRef => format!("a shared reference"),
+            BorrowedContentSource::DerefMutableRef => {
+                format!("a mutable reference")
+            }
+            BorrowedContentSource::OverloadedDeref(ty) => {
+                if ty.is_rc() {
+                   format!("an `Rc`")
+                } else if ty.is_arc() {
+                    format!("an `Arc`")
+                } else {
+                    format!("dereference of `{}`", ty)
+                }
+            }
+            BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
+        }
+    }
+
+    fn describe_for_named_place(&self) -> Option<&'static str> {
         match *self {
-            BorrowedContentSource::Arc => write!(f, "an `Arc`"),
-            BorrowedContentSource::Rc => write!(f, "an `Rc`"),
-            BorrowedContentSource::DerefRawPointer => write!(f, "dereference of raw pointer"),
-            BorrowedContentSource::Other => write!(f, "borrowed content"),
+            BorrowedContentSource::DerefRawPointer => Some("raw pointer"),
+            BorrowedContentSource::DerefSharedRef => Some("shared reference"),
+            BorrowedContentSource::DerefMutableRef => Some("mutable reference"),
+            // Overloaded deref and index operators should be evaluated into a
+            // temporary. So we don't need a description here.
+            BorrowedContentSource::OverloadedDeref(_)
+            | BorrowedContentSource::OverloadedIndex(_) => None
+        }
+    }
+
+    fn from_call(func: Ty<'tcx>, tcx: TyCtxt<'_, '_, 'tcx>) -> Option<Self> {
+        match func.sty {
+            ty::FnDef(def_id, substs) => {
+                let trait_id = tcx.trait_of_item(def_id)?;
+
+                let lang_items = tcx.lang_items();
+                if Some(trait_id) == lang_items.deref_trait()
+                    || Some(trait_id) == lang_items.deref_mut_trait()
+                {
+                    Some(BorrowedContentSource::OverloadedDeref(substs.type_at(0)))
+                } else if Some(trait_id) == lang_items.index_trait()
+                    || Some(trait_id) == lang_items.index_mut_trait()
+                {
+                    Some(BorrowedContentSource::OverloadedIndex(substs.type_at(0)))
+                } else {
+                    None
+                }
+            }
+            _ => None,
         }
     }
 }
@@ -105,7 +151,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
             MoveError::IllegalMove {
                 cannot_move_out_of: IllegalMoveOrigin { location, kind },
             } => {
-                let stmt_source_info = self.mir.source_info(location);
                 // Note: that the only time we assign a place isn't a temporary
                 // to a user variable is when initializing it.
                 // If that ever stops being the case, then the ever initialized
@@ -133,6 +178,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                         pat_span: _,
                     }))) = local_decl.is_user_variable
                     {
+                        let stmt_source_info = self.mir.source_info(location);
                         self.append_binding_error(
                             grouped_errors,
                             kind,
@@ -146,8 +192,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                         return;
                     }
                 }
+
+                let move_spans = self.move_spans(&original_path, location);
                 grouped_errors.push(GroupedMoveError::OtherIllegalMove {
-                    span: stmt_source_info.span,
+                    use_spans: move_spans,
                     original_path,
                     kind,
                 });
@@ -243,114 +291,205 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
             let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) =
                 match error {
                     GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } |
-                    GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } |
-                    GroupedMoveError::OtherIllegalMove { span, ref original_path, ref kind } => {
+                    GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
                         (span, original_path, kind)
+                    }
+                    GroupedMoveError::OtherIllegalMove {
+                        use_spans,
+                        ref original_path,
+                        ref kind
+                    } => {
+                        (use_spans.args_or_use(), original_path, kind)
                     },
                 };
-            let origin = Origin::Mir;
             debug!("report: original_path={:?} span={:?}, kind={:?} \
                    original_path.is_upvar_field_projection={:?}", original_path, span, kind,
                    self.is_upvar_field_projection(original_path));
-            let err = match kind {
-                IllegalMoveOriginKind::Static => {
-                    self.infcx.tcx.cannot_move_out_of(span, "static item", origin)
-                }
-                IllegalMoveOriginKind::BorrowedContent { target_place: place } => {
-                    // Inspect the type of the content behind the
-                    // borrow to provide feedback about why this
-                    // was a move rather than a copy.
-                    let ty = place.ty(self.mir, self.infcx.tcx).ty;
-                    let is_upvar_field_projection =
-                        self.prefixes(&original_path, PrefixSet::All)
-                        .any(|p| self.is_upvar_field_projection(p).is_some());
-                    debug!("report: ty={:?}", ty);
-                    let mut err = match ty.sty {
-                        ty::Array(..) | ty::Slice(..) =>
-                            self.infcx.tcx.cannot_move_out_of_interior_noncopy(
-                                span, ty, None, origin
-                            ),
-                        ty::Closure(def_id, closure_substs)
-                            if def_id == self.mir_def_id && is_upvar_field_projection
-                        => {
-                            let closure_kind_ty =
-                                closure_substs.closure_kind_ty(def_id, self.infcx.tcx);
-                            let closure_kind = closure_kind_ty.to_opt_closure_kind();
-                            let place_description = match closure_kind {
-                                Some(ty::ClosureKind::Fn) => {
-                                    "captured variable in an `Fn` closure"
-                                }
-                                Some(ty::ClosureKind::FnMut) => {
-                                    "captured variable in an `FnMut` closure"
-                                }
-                                Some(ty::ClosureKind::FnOnce) => {
-                                    bug!("closure kind does not match first argument type")
-                                }
-                                None => bug!("closure kind not inferred by borrowck"),
-                            };
-                            debug!("report: closure_kind_ty={:?} closure_kind={:?} \
-                                    place_description={:?}", closure_kind_ty, closure_kind,
-                                    place_description);
-
-                            let mut diag = self.infcx.tcx.cannot_move_out_of(
-                                span, place_description, origin);
-
-                            for prefix in self.prefixes(&original_path, PrefixSet::All) {
-                                if let Some(field) = self.is_upvar_field_projection(prefix) {
-                                    let upvar_hir_id = self.upvars[field.index()].var_hir_id;
-                                    let upvar_span = self.infcx.tcx.hir().span_by_hir_id(
-                                        upvar_hir_id);
-                                    diag.span_label(upvar_span, "captured outer variable");
-                                    break;
-                                }
-                            }
-
-                            diag
-                        }
-                        _ => {
-                            let source = self.borrowed_content_source(place);
-                            self.infcx.tcx.cannot_move_out_of(
-                                span, &source.to_string(), origin
-                            )
-                        },
-                    };
-                    let orig_path_ty = format!(
-                        "{:?}",
-                        original_path.ty(self.mir, self.infcx.tcx).ty,
-                    );
-                    let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
-                    let is_option = orig_path_ty.starts_with("std::option::Option");
-                    let is_result = orig_path_ty.starts_with("std::result::Result");
-                    if  is_option || is_result {
-                        err.span_suggestion(
+            (
+                match kind {
+                    IllegalMoveOriginKind::Static => {
+                        self.report_cannot_move_from_static(original_path, span)
+                    }
+                    IllegalMoveOriginKind::BorrowedContent { target_place } => {
+                        self.report_cannot_move_from_borrowed_content(
+                            original_path,
+                            target_place,
                             span,
-                            &format!("consider borrowing the `{}`'s content", if is_option {
-                                "Option"
-                            } else {
-                                "Result"
-                            }),
-                            format!("{}.as_ref()", snippet),
-                            Applicability::MaybeIncorrect,
-                        );
+                        )
                     }
-                    err
-                }
-                IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
-                    self.infcx.tcx
-                        .cannot_move_out_of_interior_of_drop(span, ty, origin)
-                }
-                IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } =>
-                    self.infcx.tcx.cannot_move_out_of_interior_noncopy(
-                        span, ty, Some(*is_index), origin
-                    ),
-            };
-            (err, span)
+                    IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
+                        self.infcx.tcx
+                            .cannot_move_out_of_interior_of_drop(span, ty, Origin::Mir)
+                    }
+                    IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } =>
+                        self.infcx.tcx.cannot_move_out_of_interior_noncopy(
+                            span, ty, Some(*is_index), Origin::Mir
+                        ),
+                },
+                span,
+            )
         };
 
         self.add_move_hints(error, &mut err, err_span);
         err.buffer(&mut self.errors_buffer);
     }
 
+    fn report_cannot_move_from_static(
+        &mut self,
+        place: &Place<'tcx>,
+        span: Span
+    ) -> DiagnosticBuilder<'a> {
+        let mut base_static = place;
+        loop {
+            match base_static {
+                Place::Base(_) => break,
+                Place::Projection(box Projection { base, .. }) => base_static = base,
+            }
+        }
+
+        let description = if let Place::Base(_) = place {
+            format!("static item `{}`", self.describe_place(place).unwrap())
+        } else {
+            format!(
+                "`{:?}` as `{:?}` is a static item",
+                self.describe_place(place).unwrap(),
+                self.describe_place(base_static).unwrap(),
+            )
+        };
+
+        self.infcx.tcx.cannot_move_out_of(span, &description, Origin::Mir)
+    }
+
+    fn report_cannot_move_from_borrowed_content(
+        &mut self,
+        move_place: &Place<'tcx>,
+        deref_target_place: &Place<'tcx>,
+        span: Span,
+    ) -> DiagnosticBuilder<'a> {
+        let origin = Origin::Mir;
+
+        // Inspect the type of the content behind the
+        // borrow to provide feedback about why this
+        // was a move rather than a copy.
+        let ty = deref_target_place.ty(self.mir, self.infcx.tcx).ty;
+        let upvar_field = self.prefixes(&move_place, PrefixSet::All)
+            .find_map(|p| self.is_upvar_field_projection(p));
+
+        let deref_base = match deref_target_place {
+            Place::Projection(box Projection { base, elem: ProjectionElem::Deref }) => base,
+            _ => bug!("deref_target_place is not a deref projection"),
+        };
+
+        if let Place::Base(PlaceBase::Local(local)) = *deref_base {
+            let decl = &self.mir.local_decls[local];
+            if decl.is_ref_for_guard() {
+                let mut err = self.infcx.tcx.cannot_move_out_of(
+                    span,
+                    &format!("`{}` in pattern guard", decl.name.unwrap()),
+                    origin,
+                );
+                err.note(
+                    "variables bound in patterns cannot be moved from \
+                     until after the end of the pattern guard");
+                return err;
+            }
+        }
+
+        debug!("report: ty={:?}", ty);
+        let mut err = match ty.sty {
+            ty::Array(..) | ty::Slice(..) =>
+                self.infcx.tcx.cannot_move_out_of_interior_noncopy(
+                    span, ty, None, origin
+                ),
+            ty::Closure(def_id, closure_substs)
+                if def_id == self.mir_def_id && upvar_field.is_some()
+            => {
+                let closure_kind_ty = closure_substs.closure_kind_ty(def_id, self.infcx.tcx);
+                let closure_kind = closure_kind_ty.to_opt_closure_kind();
+                let capture_description = match closure_kind {
+                    Some(ty::ClosureKind::Fn) => {
+                        "captured variable in an `Fn` closure"
+                    }
+                    Some(ty::ClosureKind::FnMut) => {
+                        "captured variable in an `FnMut` closure"
+                    }
+                    Some(ty::ClosureKind::FnOnce) => {
+                        bug!("closure kind does not match first argument type")
+                    }
+                    None => bug!("closure kind not inferred by borrowck"),
+                };
+
+                let upvar = &self.upvars[upvar_field.unwrap().index()];
+                let upvar_hir_id = upvar.var_hir_id;
+                let upvar_name = upvar.name;
+                let upvar_span = self.infcx.tcx.hir().span_by_hir_id(upvar_hir_id);
+
+                let place_name = self.describe_place(move_place).unwrap();
+
+                let place_description = if self.is_upvar_field_projection(move_place).is_some() {
+                    format!("`{}`, a {}", place_name, capture_description)
+                } else {
+                    format!(
+                        "`{}`, as `{}` is a {}",
+                        place_name,
+                        upvar_name,
+                        capture_description,
+                    )
+                };
+
+                debug!(
+                    "report: closure_kind_ty={:?} closure_kind={:?} place_description={:?}",
+                    closure_kind_ty, closure_kind, place_description,
+                );
+
+                let mut diag = self.infcx.tcx.cannot_move_out_of(span, &place_description, origin);
+
+                diag.span_label(upvar_span, "captured outer variable");
+
+                diag
+            }
+            _ => {
+                let source = self.borrowed_content_source(deref_base);
+                match (self.describe_place(move_place), source.describe_for_named_place()) {
+                    (Some(place_desc), Some(source_desc)) => {
+                        self.infcx.tcx.cannot_move_out_of(
+                            span,
+                            &format!("`{}` which is behind a {}", place_desc, source_desc),
+                            origin,
+                        )
+                    }
+                    (_, _) => {
+                        self.infcx.tcx.cannot_move_out_of(
+                            span,
+                            &source.describe_for_unnamed_place(),
+                            origin,
+                        )
+                    }
+                }
+            },
+        };
+        let move_ty = format!(
+            "{:?}",
+            move_place.ty(self.mir, self.infcx.tcx).ty,
+        );
+        let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
+        let is_option = move_ty.starts_with("std::option::Option");
+        let is_result = move_ty.starts_with("std::result::Result");
+        if  is_option || is_result {
+            err.span_suggestion(
+                span,
+                &format!("consider borrowing the `{}`'s content", if is_option {
+                    "Option"
+                } else {
+                    "Result"
+                }),
+                format!("{}.as_ref()", snippet),
+                Applicability::MaybeIncorrect,
+            );
+        }
+        err
+    }
+
     fn add_move_hints(
         &self,
         error: GroupedMoveError<'tcx>,
@@ -391,9 +530,25 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                     );
                 }
 
-                binds_to.sort();
-                binds_to.dedup();
-                self.add_move_error_details(err, &binds_to);
+                if binds_to.is_empty() {
+                    let place_ty = move_from.ty(self.mir, self.infcx.tcx).ty;
+                    let place_desc = match self.describe_place(&move_from) {
+                        Some(desc) => format!("`{}`", desc),
+                        None => format!("value"),
+                    };
+
+                    self.note_type_does_not_implement_copy(
+                        err,
+                        &place_desc,
+                        place_ty,
+                        Some(span)
+                    );
+                } else {
+                    binds_to.sort();
+                    binds_to.dedup();
+
+                    self.add_move_error_details(err, &binds_to);
+                }
             }
             GroupedMoveError::MovesFromValue { mut binds_to, .. } => {
                 binds_to.sort();
@@ -402,7 +557,26 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 self.add_move_error_details(err, &binds_to);
             }
             // No binding. Nothing to suggest.
-            GroupedMoveError::OtherIllegalMove { .. } => (),
+            GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
+                let span = use_spans.var_or_use();
+                let place_ty = original_path.ty(self.mir, self.infcx.tcx).ty;
+                let place_desc = match self.describe_place(original_path) {
+                    Some(desc) => format!("`{}`", desc),
+                    None => format!("value"),
+                };
+                self.note_type_does_not_implement_copy(
+                    err,
+                    &place_desc,
+                    place_ty,
+                    Some(span),
+                );
+
+                use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc));
+                use_spans.var_span_label(
+                    err,
+                    format!("move occurs due to use{}", use_spans.describe()),
+                );
+            },
         }
     }
 
@@ -473,14 +647,11 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
             }
 
             if binds_to.len() == 1 {
-                err.span_note(
-                    binding_span,
-                    &format!(
-                        "move occurs because `{}` has type `{}`, \
-                            which does not implement the `Copy` trait",
-                        bind_to.name.unwrap(),
-                        bind_to.ty
-                    ),
+                self.note_type_does_not_implement_copy(
+                    err,
+                    &format!("`{}`", bind_to.name.unwrap()),
+                    bind_to.ty,
+                    Some(binding_span)
                 );
             } else {
                 noncopy_var_spans.push(binding_span);
@@ -496,105 +667,64 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn borrowed_content_source(&self, place: &Place<'tcx>) -> BorrowedContentSource {
-        // Look up the provided place and work out the move path index for it,
-        // we'll use this to work back through where this value came from and check whether it
-        // was originally part of an `Rc` or `Arc`.
-        let initial_mpi = match self.move_data.rev_lookup.find(place) {
-            LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => mpi,
-            _ => return BorrowedContentSource::Other,
-        };
+    fn borrowed_content_source(&self, deref_base: &Place<'tcx>) -> BorrowedContentSource<'tcx> {
+        let tcx = self.infcx.tcx;
 
-        let mut queue = vec![initial_mpi];
-        let mut visited = Vec::new();
-        debug!("borrowed_content_source: queue={:?}", queue);
-        while let Some(mpi) = queue.pop() {
-            debug!(
-                "borrowed_content_source: mpi={:?} queue={:?} visited={:?}",
-                mpi, queue, visited
-            );
-
-            // Don't visit the same path twice.
-            if visited.contains(&mpi) {
-                continue;
-            }
-            visited.push(mpi);
-
-            for i in &self.move_data.init_path_map[mpi] {
-                let init = &self.move_data.inits[*i];
-                debug!("borrowed_content_source: init={:?}", init);
-                // We're only interested in statements that initialized a value, not the
-                // initializations from arguments.
-                let loc = match init.location {
-                    InitLocation::Statement(stmt) => stmt,
-                    _ => continue,
-                };
+        // Look up the provided place and work out the move path index for it,
+        // we'll use this to check whether it was originally from an overloaded
+        // operator.
+        match self.move_data.rev_lookup.find(deref_base) {
+            LookupResult::Exact(mpi) | LookupResult::Parent(Some(mpi)) => {
+                debug!("borrowed_content_source: mpi={:?}", mpi);
+
+                for i in &self.move_data.init_path_map[mpi] {
+                    let init = &self.move_data.inits[*i];
+                    debug!("borrowed_content_source: init={:?}", init);
+                    // We're only interested in statements that initialized a value, not the
+                    // initializations from arguments.
+                    let loc = match init.location {
+                        InitLocation::Statement(stmt) => stmt,
+                        _ => continue,
+                    };
 
-                let bbd = &self.mir[loc.block];
-                let is_terminator = bbd.statements.len() == loc.statement_index;
-                debug!("borrowed_content_source: loc={:?} is_terminator={:?}", loc, is_terminator);
-                if !is_terminator {
-                    let stmt = &bbd.statements[loc.statement_index];
-                    debug!("borrowed_content_source: stmt={:?}", stmt);
-                    // We're only interested in assignments (in particular, where the
-                    // assignment came from - was it an `Rc` or `Arc`?).
-                    if let StatementKind::Assign(_, box Rvalue::Ref(_, _, source)) = &stmt.kind {
-                        let ty = source.ty(self.mir, self.infcx.tcx).ty;
-                        let ty = match ty.sty {
-                            ty::Ref(_, ty, _) => ty,
-                            _ => ty,
-                        };
-                        debug!("borrowed_content_source: ty={:?}", ty);
-
-                        if ty.is_arc() {
-                            return BorrowedContentSource::Arc;
-                        } else if ty.is_rc() {
-                            return BorrowedContentSource::Rc;
-                        } else {
-                            queue.push(init.path);
-                        }
-                    }
-                } else if let Some(Terminator {
-                    kind: TerminatorKind::Call { args, .. },
-                    ..
-                }) = &bbd.terminator {
-                    for arg in args {
-                        let source = match arg {
-                            Operand::Copy(place) | Operand::Move(place) => place,
-                            _ => continue,
-                        };
-
-                        let ty = source.ty(self.mir, self.infcx.tcx).ty;
-                        let ty = match ty.sty {
-                            ty::Ref(_, ty, _) => ty,
-                            _ => ty,
-                        };
-                        debug!("borrowed_content_source: ty={:?}", ty);
-
-                        if ty.is_arc() {
-                            return BorrowedContentSource::Arc;
-                        } else if ty.is_rc() {
-                            return BorrowedContentSource::Rc;
-                        } else {
-                            queue.push(init.path);
+                    let bbd = &self.mir[loc.block];
+                    let is_terminator = bbd.statements.len() == loc.statement_index;
+                    debug!(
+                        "borrowed_content_source: loc={:?} is_terminator={:?}",
+                        loc,
+                        is_terminator,
+                    );
+                    if !is_terminator {
+                        continue;
+                    } else if let Some(Terminator {
+                        kind: TerminatorKind::Call {
+                            ref func,
+                            from_hir_call: false,
+                            ..
+                        },
+                        ..
+                    }) = bbd.terminator {
+                        if let Some(source)
+                            = BorrowedContentSource::from_call(func.ty(self.mir, tcx), tcx)
+                        {
+                            return source;
                         }
                     }
                 }
             }
-        }
+            // Base is a `static` so won't be from an overloaded operator
+            _ => (),
+        };
 
-        // If we didn't find an `Arc` or an `Rc`, then check specifically for
-        // a dereference of a place that has the type of a raw pointer.
-        // We can't use `place.ty(..).to_ty(..)` here as that strips away the raw pointer.
-        if let Place::Projection(box Projection {
-            base,
-            elem: ProjectionElem::Deref,
-        }) = place {
-            if base.ty(self.mir, self.infcx.tcx).ty.is_unsafe_ptr() {
-                return BorrowedContentSource::DerefRawPointer;
-            }
+        // If we didn't find an overloaded deref or index, then assume it's a
+        // built in deref and check the type of the base.
+        let base_ty = deref_base.ty(self.mir, tcx).ty;
+        if base_ty.is_unsafe_ptr() {
+            BorrowedContentSource::DerefRawPointer
+        } else if base_ty.is_mutable_pointer() {
+            BorrowedContentSource::DerefMutableRef
+        } else {
+            BorrowedContentSource::DerefSharedRef
         }
-
-        BorrowedContentSource::Other
     }
 }
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index a292115707d..cbab84c2961 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -95,12 +95,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                     }
                 } else if {
                     if let Place::Base(PlaceBase::Local(local)) = *base {
-                        if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard))
-                            = self.mir.local_decls[local].is_user_variable {
-                                true
-                        } else {
-                            false
-                        }
+                        self.mir.local_decls[local].is_ref_for_guard()
                     } else {
                         false
                     }
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 685db7713ca..87e2118094c 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -503,13 +503,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 elem: ProjectionElem::Deref,
             }) => {
                 debug_assert!(
-                    if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
-                        this.local_decls[local].is_user_variable
-                    {
-                        true
-                    } else {
-                        false
-                    },
+                    this.local_decls[local].is_ref_for_guard(),
                     "Unexpected capture place",
                 );
                 this.local_decls[local].mutability
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index a5dfb736b81..37df368f3b7 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -399,7 +399,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
         move_from_desc: &str,
         o: Origin,
     ) -> DiagnosticBuilder<'cx> {
-        let mut err = struct_span_err!(
+        let err = struct_span_err!(
             self,
             move_from_span,
             E0507,
@@ -407,10 +407,6 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
             move_from_desc,
             OGN = o
         );
-        err.span_label(
-            move_from_span,
-            format!("cannot move out of {}", move_from_desc),
-        );
 
         self.cancel_if_wrong_origin(err, o)
     }
@@ -434,8 +430,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
             self,
             move_from_span,
             E0508,
-            "cannot move out of type `{}`, \
-             a non-copy {}{OGN}",
+            "cannot move out of type `{}`, a non-copy {}{OGN}",
             ty,
             type_name,
             OGN = o
@@ -455,8 +450,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
             self,
             move_from_span,
             E0509,
-            "cannot move out of type `{}`, \
-             which implements the `Drop` trait{OGN}",
+            "cannot move out of type `{}`, which implements the `Drop` trait{OGN}",
             container_ty,
             OGN = o
         );
diff --git a/src/test/ui/access-mode-in-closures.stderr b/src/test/ui/access-mode-in-closures.stderr
index 713eeba5459..424d7ebb374 100644
--- a/src/test/ui/access-mode-in-closures.stderr
+++ b/src/test/ui/access-mode-in-closures.stderr
@@ -1,17 +1,12 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `s.0` which is behind a shared reference
   --> $DIR/access-mode-in-closures.rs:8:15
    |
 LL |         match *s { S(v) => v }
-   |               ^^     - data moved here
-   |               |
-   |               cannot move out of borrowed content
+   |               ^^     -
+   |               |      |
+   |               |      data moved here
+   |               |      move occurs because `v` has type `std::vec::Vec<isize>`, which does not implement the `Copy` trait
    |               help: consider removing the `*`: `s`
-   |
-note: move occurs because `v` has type `std::vec::Vec<isize>`, which does not implement the `Copy` trait
-  --> $DIR/access-mode-in-closures.rs:8:22
-   |
-LL |         match *s { S(v) => v }
-   |                      ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/binop/binop-move-semantics.rs b/src/test/ui/binop/binop-move-semantics.rs
index 17dec594042..b5133ea7c92 100644
--- a/src/test/ui/binop/binop-move-semantics.rs
+++ b/src/test/ui/binop/binop-move-semantics.rs
@@ -27,9 +27,9 @@ fn illegal_dereference<T: Add<Output=()>>(mut x: T, y: T) {
     let m = &mut x;
     let n = &y;
 
-    *m  //~ ERROR: cannot move out of borrowed content
+    *m  //~ ERROR: cannot move
     +
-    *n;  //~ ERROR: cannot move out of borrowed content
+    *n;  //~ ERROR: cannot move
     use_imm(n); use_mut(m);
 }
 struct Foo;
diff --git a/src/test/ui/binop/binop-move-semantics.stderr b/src/test/ui/binop/binop-move-semantics.stderr
index 146e3781463..897607dc2d8 100644
--- a/src/test/ui/binop/binop-move-semantics.stderr
+++ b/src/test/ui/binop/binop-move-semantics.stderr
@@ -47,17 +47,17 @@ LL |     y;
 LL |     use_mut(n); use_imm(m);
    |             - borrow later used here
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*m` which is behind a mutable reference
   --> $DIR/binop-move-semantics.rs:30:5
    |
 LL |     *m
-   |     ^^ cannot move out of borrowed content
+   |     ^^ move occurs because `*m` has type `T`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*n` which is behind a shared reference
   --> $DIR/binop-move-semantics.rs:32:5
    |
 LL |     *n;
-   |     ^^ cannot move out of borrowed content
+   |     ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait
 
 error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
   --> $DIR/binop-move-semantics.rs:54:5
diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr
index 9059ef438d0..ebdacee7f65 100644
--- a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr
+++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr
@@ -1,8 +1,14 @@
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:17
+error[E0507]: cannot move out of `foo` in pattern guard
+  --> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
    |
 LL |                 (|| { let bar = foo; bar.take() })();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                  ^^             ---
+   |                  |              |
+   |                  |              move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait
+   |                  |              move occurs due to use in closure
+   |                  move out of `foo` occurs here
+   |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs
index 4eefc5859ff..a6f3905bebd 100644
--- a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs
+++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs
@@ -20,8 +20,8 @@ fn main() {
         ref mut foo
             if {
                 (|| { let bar = foo; bar.take() })();
-                //[zflag]~^ ERROR cannot move out of borrowed content [E0507]
-                //[edition]~^^ ERROR cannot move out of borrowed content [E0507]
+                //[zflag]~^ ERROR cannot move out of `foo` in pattern guard [E0507]
+                //[edition]~^^ ERROR cannot move out of `foo` in pattern guard [E0507]
                 false
             } => {},
         Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr
index 9059ef438d0..ebdacee7f65 100644
--- a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr
+++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr
@@ -1,8 +1,14 @@
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:17
+error[E0507]: cannot move out of `foo` in pattern guard
+  --> $DIR/borrowck-feature-nll-overrides-migrate.rs:22:18
    |
 LL |                 (|| { let bar = foo; bar.take() })();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                  ^^             ---
+   |                  |              |
+   |                  |              move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait
+   |                  |              move occurs due to use in closure
+   |                  move out of `foo` occurs here
+   |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-fn-in-const-a.rs b/src/test/ui/borrowck/borrowck-fn-in-const-a.rs
index faa56cc7f2a..d4ceae2963b 100644
--- a/src/test/ui/borrowck/borrowck-fn-in-const-a.rs
+++ b/src/test/ui/borrowck/borrowck-fn-in-const-a.rs
@@ -3,7 +3,7 @@
 
 const MOVE: fn(&String) -> String = {
     fn broken(x: &String) -> String {
-        return *x //~ ERROR cannot move out of borrowed content [E0507]
+        return *x //~ ERROR cannot move
     }
     broken
 };
diff --git a/src/test/ui/borrowck/borrowck-fn-in-const-a.stderr b/src/test/ui/borrowck/borrowck-fn-in-const-a.stderr
index fff28359c14..4c9cfa60ad4 100644
--- a/src/test/ui/borrowck/borrowck-fn-in-const-a.stderr
+++ b/src/test/ui/borrowck/borrowck-fn-in-const-a.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*x` which is behind a shared reference
   --> $DIR/borrowck-fn-in-const-a.rs:6:16
    |
 LL |         return *x
-   |                ^^ cannot move out of borrowed content
+   |                ^^ move occurs because `*x` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.stderr b/src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.stderr
index 08cafa7da7a..38e41f315fc 100644
--- a/src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.stderr
+++ b/src/test/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.stderr
@@ -1,47 +1,32 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:12:15
    |
 LL |     for &a in x.iter() {
-   |         --    ^^^^^^^^ cannot move out of borrowed content
+   |         --    ^^^^^^^^
    |         ||
    |         |data moved here
+   |         |move occurs because `a` has type `&mut i32`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `a`
-   |
-note: move occurs because `a` has type `&mut i32`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:12:10
-   |
-LL |     for &a in x.iter() {
-   |          ^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:18:15
    |
 LL |     for &a in &f.a {
-   |         --    ^^^^ cannot move out of borrowed content
+   |         --    ^^^^
    |         ||
    |         |data moved here
+   |         |move occurs because `a` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `a`
-   |
-note: move occurs because `a` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:18:10
-   |
-LL |     for &a in &f.a {
-   |          ^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:22:15
    |
 LL |     for &a in x.iter() {
-   |         --    ^^^^^^^^ cannot move out of borrowed content
+   |         --    ^^^^^^^^
    |         ||
    |         |data moved here
+   |         |move occurs because `a` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `a`
-   |
-note: move occurs because `a` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-for-loop-correct-cmt-for-pattern.rs:22:10
-   |
-LL |     for &a in x.iter() {
-   |          ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-in-static.rs b/src/test/ui/borrowck/borrowck-in-static.rs
index c468740bc3b..a45f7b18e07 100644
--- a/src/test/ui/borrowck/borrowck-in-static.rs
+++ b/src/test/ui/borrowck/borrowck-in-static.rs
@@ -2,7 +2,7 @@
 
 static FN : &'static (dyn Fn() -> (Box<dyn Fn()->Box<i32>>) + Sync) = &|| {
     let x = Box::new(0);
-    Box::new(|| x) //~ ERROR cannot move out of captured variable in an `Fn` closure
+    Box::new(|| x) //~ ERROR cannot move out of `x`, a captured variable in an `Fn` closure
 };
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-in-static.stderr b/src/test/ui/borrowck/borrowck-in-static.stderr
index da639a837aa..77d6d7c231d 100644
--- a/src/test/ui/borrowck/borrowck-in-static.stderr
+++ b/src/test/ui/borrowck/borrowck-in-static.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/borrowck-in-static.rs:5:17
    |
 LL |     let x = Box::new(0);
    |         - captured outer variable
 LL |     Box::new(|| x)
-   |                 ^ cannot move out of captured variable in an `Fn` closure
+   |                 ^ move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-issue-2657-2.stderr b/src/test/ui/borrowck/borrowck-issue-2657-2.stderr
index 4ef36df52df..908b2c0ff5e 100644
--- a/src/test/ui/borrowck/borrowck-issue-2657-2.stderr
+++ b/src/test/ui/borrowck/borrowck-issue-2657-2.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*y` which is behind a shared reference
   --> $DIR/borrowck-issue-2657-2.rs:7:18
    |
 LL |         let _b = *y;
    |                  ^^
    |                  |
-   |                  cannot move out of borrowed content
+   |                  move occurs because `*y` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
    |                  help: consider removing the `*`: `y`
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
index 461fb7d11a5..663164cfc2c 100644
--- a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
@@ -1,9 +1,14 @@
-warning[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-migrate-to-nll.rs:25:17
+warning[E0507]: cannot move out of `foo` in pattern guard
+  --> $DIR/borrowck-migrate-to-nll.rs:25:18
    |
 LL |                 (|| { let bar = foo; bar.take() })();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                  ^^             ---
+   |                  |              |
+   |                  |              move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait
+   |                  |              move occurs due to use in closure
+   |                  move out of `foo` occurs here
    |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
    = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
    = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
    = note: for more information, try `rustc --explain E0729`
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
index 461fb7d11a5..663164cfc2c 100644
--- a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
@@ -1,9 +1,14 @@
-warning[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-migrate-to-nll.rs:25:17
+warning[E0507]: cannot move out of `foo` in pattern guard
+  --> $DIR/borrowck-migrate-to-nll.rs:25:18
    |
 LL |                 (|| { let bar = foo; bar.take() })();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                  ^^             ---
+   |                  |              |
+   |                  |              move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait
+   |                  |              move occurs due to use in closure
+   |                  move out of `foo` occurs here
    |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
    = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
    = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
    = note: for more information, try `rustc --explain E0729`
diff --git a/src/test/ui/borrowck/borrowck-move-by-capture.stderr b/src/test/ui/borrowck/borrowck-move-by-capture.stderr
index 38f6ca7be75..0eceaf561b4 100644
--- a/src/test/ui/borrowck/borrowck-move-by-capture.stderr
+++ b/src/test/ui/borrowck/borrowck-move-by-capture.stderr
@@ -1,11 +1,15 @@
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-move-by-capture.rs:9:29
    |
 LL |     let bar: Box<_> = box 3;
    |         --- captured outer variable
 LL |     let _g = to_fn_mut(|| {
 LL |         let _h = to_fn_once(move || -> isize { *bar });
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of captured variable in an `FnMut` closure
+   |                             ^^^^^^^^^^^^^^^^    ---
+   |                             |                   |
+   |                             |                   move occurs because `bar` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+   |                             |                   move occurs due to use in closure
+   |                             move out of `bar` occurs here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-move-error-with-note.rs b/src/test/ui/borrowck/borrowck-move-error-with-note.rs
index b21f13a983c..7ef59f50c03 100644
--- a/src/test/ui/borrowck/borrowck-move-error-with-note.rs
+++ b/src/test/ui/borrowck/borrowck-move-error-with-note.rs
@@ -9,7 +9,6 @@ enum Foo {
 fn blah() {
     let f = &Foo::Foo1(box 1, box 2);
     match *f {             //~ ERROR cannot move out of
-                           //~| cannot move out
         Foo::Foo1(num1,
                   num2) => (),
         Foo::Foo2(num) => (),
@@ -28,7 +27,6 @@ impl Drop for S {
 fn move_in_match() {
     match (S {f: "foo".to_string(), g: "bar".to_string()}) {
         //~^ ERROR cannot move out of type `S`, which implements the `Drop` trait
-        //~| cannot move out of here
         S {
             f: _s,
             g: _t
@@ -46,7 +44,6 @@ fn free<T>(_: T) {}
 fn blah2() {
     let a = &A { a: box 1 };
     match a.a {           //~ ERROR cannot move out of
-                          //~| cannot move out
         n => {
             free(n)
         }
diff --git a/src/test/ui/borrowck/borrowck-move-error-with-note.stderr b/src/test/ui/borrowck/borrowck-move-error-with-note.stderr
index 8438320891c..13d3faab650 100644
--- a/src/test/ui/borrowck/borrowck-move-error-with-note.stderr
+++ b/src/test/ui/borrowck/borrowck-move-error-with-note.stderr
@@ -1,12 +1,8 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `f.0` which is behind a shared reference
   --> $DIR/borrowck-move-error-with-note.rs:11:11
    |
 LL |     match *f {
-   |           ^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `f`
-LL |
+   |           ^^ help: consider removing the `*`: `f`
 LL |         Foo::Foo1(num1,
    |                   ---- data moved here
 LL |                   num2) => (),
@@ -15,7 +11,7 @@ LL |         Foo::Foo2(num) => (),
    |                   --- ...and here
    |
 note: move occurs because these variables have types that don't implement the `Copy` trait
-  --> $DIR/borrowck-move-error-with-note.rs:13:19
+  --> $DIR/borrowck-move-error-with-note.rs:12:19
    |
 LL |         Foo::Foo1(num1,
    |                   ^^^^
@@ -25,7 +21,7 @@ LL |         Foo::Foo2(num) => (),
    |                   ^^^
 
 error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
-  --> $DIR/borrowck-move-error-with-note.rs:29:11
+  --> $DIR/borrowck-move-error-with-note.rs:28:11
    |
 LL |     match (S {f: "foo".to_string(), g: "bar".to_string()}) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
@@ -36,30 +32,23 @@ LL |             g: _t
    |                -- ...and here
    |
 note: move occurs because these variables have types that don't implement the `Copy` trait
-  --> $DIR/borrowck-move-error-with-note.rs:33:16
+  --> $DIR/borrowck-move-error-with-note.rs:31:16
    |
 LL |             f: _s,
    |                ^^
 LL |             g: _t
    |                ^^
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-move-error-with-note.rs:48:11
+error[E0507]: cannot move out of `a.a` which is behind a shared reference
+  --> $DIR/borrowck-move-error-with-note.rs:46:11
    |
 LL |     match a.a {
-   |           ^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider borrowing here: `&a.a`
-LL |
+   |           ^^^ help: consider borrowing here: `&a.a`
 LL |         n => {
-   |         - data moved here
-   |
-note: move occurs because `n` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-error-with-note.rs:50:9
-   |
-LL |         n => {
-   |         ^
+   |         -
+   |         |
+   |         data moved here
+   |         move occurs because `n` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.rs b/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.rs
index bf8ff9cf0a9..824da5ceb07 100644
--- a/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.rs
+++ b/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.rs
@@ -1,5 +1,5 @@
 unsafe fn foo(x: *const Box<isize>) -> Box<isize> {
-    let y = *x; //~ ERROR cannot move out of dereference of raw pointer
+    let y = *x; //~ ERROR cannot move out of `*x` which is behind a raw pointer
     return y;
 }
 
diff --git a/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr b/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr
index 615e3fd1800..6c806e0896b 100644
--- a/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr
+++ b/src/test/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of dereference of raw pointer
+error[E0507]: cannot move out of `*x` which is behind a raw pointer
   --> $DIR/borrowck-move-from-unsafe-ptr.rs:2:13
    |
 LL |     let y = *x;
    |             ^^
    |             |
-   |             cannot move out of dereference of raw pointer
+   |             move occurs because `*x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `x`
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-move-in-irrefut-pat.stderr b/src/test/ui/borrowck/borrowck-move-in-irrefut-pat.stderr
index d38c05ca36e..f0a490d359d 100644
--- a/src/test/ui/borrowck/borrowck-move-in-irrefut-pat.stderr
+++ b/src/test/ui/borrowck/borrowck-move-in-irrefut-pat.stderr
@@ -1,49 +1,32 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/borrowck-move-in-irrefut-pat.rs:3:13
    |
 LL | fn arg_item(&_x: &String) {}
    |             ^--
    |             ||
    |             |data moved here
-   |             cannot move out of borrowed content
+   |             |move occurs because `_x` has type `std::string::String`, which does not implement the `Copy` trait
    |             help: consider removing the `&`: `_x`
-   |
-note: move occurs because `_x` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-in-irrefut-pat.rs:3:14
-   |
-LL | fn arg_item(&_x: &String) {}
-   |              ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/borrowck-move-in-irrefut-pat.rs:7:11
    |
 LL |     with(|&_x| ())
    |           ^--
    |           ||
    |           |data moved here
-   |           cannot move out of borrowed content
+   |           |move occurs because `_x` has type `std::string::String`, which does not implement the `Copy` trait
    |           help: consider removing the `&`: `_x`
-   |
-note: move occurs because `_x` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-in-irrefut-pat.rs:7:12
-   |
-LL |     with(|&_x| ())
-   |            ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/borrowck-move-in-irrefut-pat.rs:12:15
    |
 LL |     let &_x = &"hi".to_string();
-   |         ---   ^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |         ---   ^^^^^^^^^^^^^^^^^
    |         ||
    |         |data moved here
+   |         |move occurs because `_x` has type `std::string::String`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `_x`
-   |
-note: move occurs because `_x` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-in-irrefut-pat.rs:12:10
-   |
-LL |     let &_x = &"hi".to_string();
-   |          ^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr b/src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr
index 7dc8e1749b5..8a94c85ef27 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.stderr
@@ -2,7 +2,7 @@ error[E0507]: cannot move out of an `Rc`
   --> $DIR/borrowck-move-out-of-overloaded-auto-deref.rs:4:14
    |
 LL |     let _x = Rc::new(vec![1, 2]).into_iter();
-   |              ^^^^^^^^^^^^^^^^^^^ cannot move out of an `Rc`
+   |              ^^^^^^^^^^^^^^^^^^^ move occurs because value has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-overloaded-deref.stderr b/src/test/ui/borrowck/borrowck-move-out-of-overloaded-deref.stderr
index e6af992c4d9..da3e5c54b75 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-overloaded-deref.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-overloaded-deref.stderr
@@ -4,7 +4,7 @@ error[E0507]: cannot move out of an `Rc`
 LL |     let _x = *Rc::new("hi".to_string());
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |              |
-   |              cannot move out of an `Rc`
+   |              move occurs because value has type `std::string::String`, which does not implement the `Copy` trait
    |              help: consider removing the `*`: `Rc::new("hi".to_string())`
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-static-item.rs b/src/test/ui/borrowck/borrowck-move-out-of-static-item.rs
index 8bb48a1d45f..d01fb261894 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-static-item.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-of-static-item.rs
@@ -12,5 +12,5 @@ fn test(f: Foo) {
 }
 
 fn main() {
-    test(BAR); //~ ERROR cannot move out of static item [E0507]
+    test(BAR); //~ ERROR cannot move out of static item `BAR` [E0507]
 }
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-static-item.stderr b/src/test/ui/borrowck/borrowck-move-out-of-static-item.stderr
index 5b38c1e3e12..edf8c954f81 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-static-item.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-static-item.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of static item
+error[E0507]: cannot move out of static item `BAR`
   --> $DIR/borrowck-move-out-of-static-item.rs:15:10
    |
 LL |     test(BAR);
-   |          ^^^ cannot move out of static item
+   |          ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.stderr b/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.stderr
index 059aa3081fc..a2f66f3ec46 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.stderr
@@ -5,13 +5,10 @@ LL |     match (S {f:"foo".to_string()}) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
 LL |
 LL |         S {f:_s} => {}
-   |              -- data moved here
-   |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:9:14
-   |
-LL |         S {f:_s} => {}
-   |              ^^
+   |              --
+   |              |
+   |              data moved here
+   |              move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
   --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:14:20
@@ -20,12 +17,7 @@ LL |     let S {f:_s} = S {f:"foo".to_string()};
    |              --    ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
    |              |
    |              data moved here
-   |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:14:14
-   |
-LL |     let S {f:_s} = S {f:"foo".to_string()};
-   |              ^^
+   |              move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
   --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:18:19
@@ -34,13 +26,8 @@ LL | fn move_in_fn_arg(S {f:_s}: S) {
    |                   ^^^^^--^
    |                   |    |
    |                   |    data moved here
+   |                   |    move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
    |                   cannot move out of here
-   |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:18:24
-   |
-LL | fn move_in_fn_arg(S {f:_s}: S) {
-   |                        ^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.stderr b/src/test/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.stderr
index a11bda0a006..f9a539c1c9f 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.stderr
@@ -5,13 +5,10 @@ LL |     match S("foo".to_string()) {
    |           ^^^^^^^^^^^^^^^^^^^^ cannot move out of here
 LL |
 LL |         S(_s) => {}
-   |           -- data moved here
-   |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:9:11
-   |
-LL |         S(_s) => {}
-   |           ^^
+   |           --
+   |           |
+   |           data moved here
+   |           move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
   --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:14:17
@@ -20,12 +17,7 @@ LL |     let S(_s) = S("foo".to_string());
    |           --    ^^^^^^^^^^^^^^^^^^^^ cannot move out of here
    |           |
    |           data moved here
-   |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:14:11
-   |
-LL |     let S(_s) = S("foo".to_string());
-   |           ^^
+   |           move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
   --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:18:19
@@ -34,13 +26,8 @@ LL | fn move_in_fn_arg(S(_s): S) {
    |                   ^^--^
    |                   | |
    |                   | data moved here
+   |                   | move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
    |                   cannot move out of here
-   |
-note: move occurs because `_s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:18:21
-   |
-LL | fn move_in_fn_arg(S(_s): S) {
-   |                     ^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs b/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs
index b3060824f87..ddc210f9aa2 100644
--- a/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs
+++ b/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs
@@ -18,5 +18,5 @@ fn main() {
     let v = MyVec::<Box<_>> { data: vec![box 1, box 2, box 3] };
     let good = &v[0]; // Shouldn't fail here
     let bad = v[0];
-    //~^ ERROR cannot move out of borrowed content
+    //~^ ERROR cannot move out of index of `MyVec<std::boxed::Box<i32>>`
 }
diff --git a/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.stderr b/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.stderr
index dbd805f1d26..57f42ede21c 100644
--- a/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.stderr
+++ b/src/test/ui/borrowck/borrowck-overloaded-index-move-from-vec.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `MyVec<std::boxed::Box<i32>>`
   --> $DIR/borrowck-overloaded-index-move-from-vec.rs:20:15
    |
 LL |     let bad = v[0];
    |               ^^^^
    |               |
-   |               cannot move out of borrowed content
+   |               move occurs because value has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
    |               help: consider borrowing here: `&v[0]`
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-struct-update-with-dtor.stderr b/src/test/ui/borrowck/borrowck-struct-update-with-dtor.stderr
index ea16502ebe5..c92c65ba736 100644
--- a/src/test/ui/borrowck/borrowck-struct-update-with-dtor.stderr
+++ b/src/test/ui/borrowck/borrowck-struct-update-with-dtor.stderr
@@ -2,13 +2,19 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
   --> $DIR/borrowck-struct-update-with-dtor.rs:12:15
    |
 LL |     let _s2 = S{a: 2, ..s0};
-   |               ^^^^^^^^^^^^^ cannot move out of here
+   |               ^^^^^^^^^^^^^
+   |               |
+   |               cannot move out of here
+   |               move occurs because `s0.b` has type `B`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `T`, which implements the `Drop` trait
   --> $DIR/borrowck-struct-update-with-dtor.rs:17:15
    |
 LL |     let _s2 = T{a: 2, ..s0};
-   |               ^^^^^^^^^^^^^ cannot move out of here
+   |               ^^^^^^^^^^^^^
+   |               |
+   |               cannot move out of here
+   |               move occurs because `s0.mv` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
index 3e2935f6df1..6448149391d 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
@@ -46,6 +46,7 @@ fn c() {
     }
     let a = vec[0]; //~ ERROR cannot move out
     //~| NOTE cannot move out of here
+    //~| NOTE move occurs because
     //~| HELP consider borrowing here
 }
 
@@ -64,6 +65,7 @@ fn d() {
     }
     let a = vec[0]; //~ ERROR cannot move out
     //~| NOTE cannot move out of here
+    //~| NOTE move occurs because
     //~| HELP consider borrowing here
 }
 
@@ -83,6 +85,7 @@ fn e() {
     }
     let a = vec[0]; //~ ERROR cannot move out
     //~| NOTE cannot move out of here
+    //~| NOTE move occurs because
     //~| HELP consider borrowing here
 }
 
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index 78c26cac9c1..072501f23ff 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -29,13 +29,10 @@ LL |     match vec {
    |           ^^^ cannot move out of here
 ...
 LL |         &mut [_a,
-   |               -- data moved here
-   |
-note: move occurs because `_a` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-vec-pattern-nesting.rs:38:15
-   |
-LL |         &mut [_a,
-   |               ^^
+   |               --
+   |               |
+   |               data moved here
+   |               move occurs because `_a` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 help: consider removing the `&mut`
    |
 LL |         [_a,
@@ -53,22 +50,20 @@ LL |     let a = vec[0];
    |             ^^^^^^
    |             |
    |             cannot move out of here
+   |             move occurs because `vec[_]` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&vec[0]`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:55:11
+  --> $DIR/borrowck-vec-pattern-nesting.rs:56:11
    |
 LL |     match vec {
    |           ^^^ cannot move out of here
 ...
 LL |          _b] => {}
-   |          -- data moved here
-   |
-note: move occurs because `_b` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-  --> $DIR/borrowck-vec-pattern-nesting.rs:60:10
-   |
-LL |          _b] => {}
-   |          ^^
+   |          --
+   |          |
+   |          data moved here
+   |          move occurs because `_b` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 help: consider removing the `&mut`
    |
 LL |         [
@@ -77,16 +72,17 @@ LL |          _b] => {}
    |
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:65:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:66:13
    |
 LL |     let a = vec[0];
    |             ^^^^^^
    |             |
    |             cannot move out of here
+   |             move occurs because `vec[_]` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&vec[0]`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:73:11
+  --> $DIR/borrowck-vec-pattern-nesting.rs:75:11
    |
 LL |     match vec {
    |           ^^^ cannot move out of here
@@ -100,18 +96,19 @@ LL |         &mut [_a, _b, _c] => {}
    |         help: consider removing the `&mut`: `[_a, _b, _c]`
    |
 note: move occurs because these variables have types that don't implement the `Copy` trait
-  --> $DIR/borrowck-vec-pattern-nesting.rs:76:15
+  --> $DIR/borrowck-vec-pattern-nesting.rs:78:15
    |
 LL |         &mut [_a, _b, _c] => {}
    |               ^^  ^^  ^^
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:84:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:86:13
    |
 LL |     let a = vec[0];
    |             ^^^^^^
    |             |
    |             cannot move out of here
+   |             move occurs because `vec[_]` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&vec[0]`
 
 error: aborting due to 8 previous errors
diff --git a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs
index 48dd14c4976..e95a6b7c88b 100644
--- a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs
+++ b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.rs
@@ -14,7 +14,7 @@ static mut X: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsiz
 
 fn main() {
     unsafe {
-        let mut x = X; //~ ERROR cannot move out of static item [E0507]
+        let mut x = X; //~ ERROR cannot move out of static item `X` [E0507]
         let _y = x.get_mut();
     }
 }
diff --git a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr
index eb71ab0b7ec..249a05192b2 100644
--- a/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr
+++ b/src/test/ui/borrowck/issue-47215-ice-from-drop-elab.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of static item
+error[E0507]: cannot move out of static item `X`
   --> $DIR/issue-47215-ice-from-drop-elab.rs:17:21
    |
 LL |         let mut x = X;
    |                     ^
    |                     |
-   |                     cannot move out of static item
+   |                     move occurs because `X` has type `std::sync::atomic::AtomicUsize`, which does not implement the `Copy` trait
    |                     help: consider borrowing here: `&X`
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/issue-51415.stderr b/src/test/ui/borrowck/issue-51415.stderr
index b025374257f..96175b14960 100644
--- a/src/test/ui/borrowck/issue-51415.stderr
+++ b/src/test/ui/borrowck/issue-51415.stderr
@@ -1,17 +1,11 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/issue-51415.rs:6:42
    |
 LL |     let opt = a.iter().enumerate().find(|(_, &s)| {
    |                                          ^^^^^-^
-   |                                          |    |
-   |                                          |    data moved here
-   |                                          cannot move out of borrowed content
-   |
-note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/issue-51415.rs:6:47
-   |
-LL |     let opt = a.iter().enumerate().find(|(_, &s)| {
-   |                                               ^
+   |                                               |
+   |                                               data moved here
+   |                                               move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
index 51df40016d8..3e46ee6f078 100644
--- a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
+++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
@@ -11,7 +11,7 @@ impl Value {
 fn foo(val: Value) {
     let _reviewers_original: Vec<Value> = match val.as_array() {
         Some(array) => {
-            *array //~ ERROR cannot move out of borrowed content
+            *array //~ ERROR cannot move out of `*array`
         }
         None => vec![]
     };
diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
index 519f1d6fb27..6ba801b9714 100644
--- a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
+++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*array` which is behind a shared reference
   --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:14:13
    |
 LL |             *array
    |             ^^^^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because `*array` has type `std::vec::Vec<Value>`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `array`
 
 error: aborting due to previous error
diff --git a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.stderr b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.stderr
index 9dcefac1b70..6619fb42c28 100644
--- a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.stderr
+++ b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.stderr
@@ -1,14 +1,14 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/move-in-static-initializer-issue-38520.rs:12:23
    |
 LL | static Y: usize = get(*&X);
-   |                       ^^^ cannot move out of borrowed content
+   |                       ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/move-in-static-initializer-issue-38520.rs:13:22
    |
 LL | const Z: usize = get(*&X);
-   |                      ^^^ cannot move out of borrowed content
+   |                      ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs
index f45aa90b607..d54b09c5da9 100644
--- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs
+++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs
@@ -9,6 +9,6 @@ fn main() {
     let y = vec![format!("World")];
     call(|| {
         y.into_iter();
-        //~^ ERROR cannot move out of captured variable in an `Fn` closure
+        //~^ ERROR cannot move out of `y`, a captured variable in an `Fn` closure
     });
 }
diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
index d6125cfd721..73cea6fc361 100644
--- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
+++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
@@ -1,11 +1,11 @@
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:11:9
    |
 LL |     let y = vec![format!("World")];
    |         - captured outer variable
 LL |     call(|| {
 LL |         y.into_iter();
-   |         ^ cannot move out of captured variable in an `Fn` closure
+   |         ^ move occurs because `y` has type `std::vec::Vec<std::string::String>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/by-move-pattern-binding.stderr b/src/test/ui/by-move-pattern-binding.stderr
index 8b531474553..1db4e2a66db 100644
--- a/src/test/ui/by-move-pattern-binding.stderr
+++ b/src/test/ui/by-move-pattern-binding.stderr
@@ -1,20 +1,15 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/by-move-pattern-binding.rs:14:11
    |
 LL |     match &s.x {
-   |           ^^^^ cannot move out of borrowed content
+   |           ^^^^
 LL |         &E::Foo => {}
 LL |         &E::Bar(identifier) => f(identifier.clone())
    |         -------------------
    |         |       |
    |         |       data moved here
+   |         |       move occurs because `identifier` has type `std::string::String`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `E::Bar(identifier)`
-   |
-note: move occurs because `identifier` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/by-move-pattern-binding.rs:16:17
-   |
-LL |         &E::Bar(identifier) => f(identifier.clone())
-   |                 ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr
index f35703a306d..a13c217483d 100644
--- a/src/test/ui/check-static-values-constraints.stderr
+++ b/src/test/ui/check-static-values-constraints.stderr
@@ -85,13 +85,13 @@ error[E0019]: static contains unimplemented expression type
 LL |     box 3;
    |         ^
 
-error[E0507]: cannot move out of static item
+error[E0507]: cannot move out of static item `x`
   --> $DIR/check-static-values-constraints.rs:116:45
    |
 LL |     let y = { static x: Box<isize> = box 3; x };
    |                                             ^
    |                                             |
-   |                                             cannot move out of static item
+   |                                             move occurs because `x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
    |                                             help: consider borrowing here: `&x`
 
 error[E0010]: allocations are not allowed in statics
diff --git a/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.stderr b/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.stderr
index fff3a64ff29..8c64149a0ff 100644
--- a/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.stderr
+++ b/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.stderr
@@ -5,12 +5,7 @@ LL |     let X { x: y } = x;
    |                -     ^ cannot move out of here
    |                |
    |                data moved here
-   |
-note: move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/disallowed-deconstructing-destructing-struct-let.rs:12:16
-   |
-LL |     let X { x: y } = x;
-   |                ^
+   |                move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.stderr b/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.stderr
index 762f64b8b2a..afc5170e1b8 100644
--- a/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.stderr
+++ b/src/test/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.stderr
@@ -5,13 +5,10 @@ LL |     match x {
    |           ^ cannot move out of here
 LL |
 LL |         X { x: y } => println!("contents: {}", y)
-   |                - data moved here
-   |
-note: move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/disallowed-deconstructing-destructing-struct-match.rs:16:16
-   |
-LL |         X { x: y } => println!("contents: {}", y)
-   |                ^
+   |                -
+   |                |
+   |                data moved here
+   |                move occurs because `y` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/dst/dst-index.rs b/src/test/ui/dst/dst-index.rs
index fced3144eb8..2f2c5df4626 100644
--- a/src/test/ui/dst/dst-index.rs
+++ b/src/test/ui/dst/dst-index.rs
@@ -29,9 +29,9 @@ impl Index<usize> for T {
 
 fn main() {
     S[0];
-    //~^ ERROR cannot move out of borrowed content
+    //~^ ERROR cannot move out of index of `S`
     //~^^ ERROR E0161
     T[0];
-    //~^ ERROR cannot move out of borrowed content
+    //~^ ERROR cannot move out of index of `T`
     //~^^ ERROR E0161
 }
diff --git a/src/test/ui/dst/dst-index.stderr b/src/test/ui/dst/dst-index.stderr
index ec09a93a4aa..6cdb0e76e90 100644
--- a/src/test/ui/dst/dst-index.stderr
+++ b/src/test/ui/dst/dst-index.stderr
@@ -10,17 +10,17 @@ error[E0161]: cannot move a value of type dyn std::fmt::Debug: the size of dyn s
 LL |     T[0];
    |     ^^^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `S`
   --> $DIR/dst-index.rs:31:5
    |
 LL |     S[0];
-   |     ^^^^ cannot move out of borrowed content
+   |     ^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `T`
   --> $DIR/dst-index.rs:34:5
    |
 LL |     T[0];
-   |     ^^^^ cannot move out of borrowed content
+   |     ^^^^ move occurs because value has type `dyn std::fmt::Debug`, which does not implement the `Copy` trait
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/dst/dst-rvalue.rs b/src/test/ui/dst/dst-rvalue.rs
index 5115bee836b..aa028396be4 100644
--- a/src/test/ui/dst/dst-rvalue.rs
+++ b/src/test/ui/dst/dst-rvalue.rs
@@ -5,7 +5,7 @@
 pub fn main() {
     let _x: Box<str> = box *"hello world";
     //~^ ERROR E0161
-    //~^^ ERROR cannot move out of borrowed content
+    //~^^ ERROR cannot move out of a shared reference
 
     let array: &[isize] = &[1, 2, 3];
     let _x: Box<[isize]> = box *array;
diff --git a/src/test/ui/dst/dst-rvalue.stderr b/src/test/ui/dst/dst-rvalue.stderr
index 7ef8e4dc72e..6a51c517558 100644
--- a/src/test/ui/dst/dst-rvalue.stderr
+++ b/src/test/ui/dst/dst-rvalue.stderr
@@ -10,17 +10,20 @@ error[E0161]: cannot move a value of type [isize]: the size of [isize] cannot be
 LL |     let _x: Box<[isize]> = box *array;
    |                                ^^^^^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/dst-rvalue.rs:6:28
    |
 LL |     let _x: Box<str> = box *"hello world";
-   |                            ^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                            ^^^^^^^^^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
 
 error[E0508]: cannot move out of type `[isize]`, a non-copy slice
   --> $DIR/dst-rvalue.rs:11:32
    |
 LL |     let _x: Box<[isize]> = box *array;
-   |                                ^^^^^^ cannot move out of here
+   |                                ^^^^^^
+   |                                |
+   |                                cannot move out of here
+   |                                move occurs because `*array` has type `[isize]`, which does not implement the `Copy` trait
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/error-codes/E0507.stderr b/src/test/ui/error-codes/E0507.stderr
index 1a596af1572..170b8831911 100644
--- a/src/test/ui/error-codes/E0507.stderr
+++ b/src/test/ui/error-codes/E0507.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of dereference of `std::cell::Ref<'_, TheDarkKnight>`
   --> $DIR/E0507.rs:12:5
    |
 LL |     x.borrow().nothing_is_true();
-   |     ^^^^^^^^^^ cannot move out of borrowed content
+   |     ^^^^^^^^^^ move occurs because value has type `TheDarkKnight`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0508-fail.stderr b/src/test/ui/error-codes/E0508-fail.stderr
index 63590bec32e..b69d7743b6c 100644
--- a/src/test/ui/error-codes/E0508-fail.stderr
+++ b/src/test/ui/error-codes/E0508-fail.stderr
@@ -5,6 +5,7 @@ LL |     let _value = array[0];
    |                  ^^^^^^^^
    |                  |
    |                  cannot move out of here
+   |                  move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait
    |                  help: consider borrowing here: `&array[0]`
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0508.stderr b/src/test/ui/error-codes/E0508.stderr
index 983062e450e..5e7b56dcd37 100644
--- a/src/test/ui/error-codes/E0508.stderr
+++ b/src/test/ui/error-codes/E0508.stderr
@@ -5,6 +5,7 @@ LL |     let _value = array[0];
    |                  ^^^^^^^^
    |                  |
    |                  cannot move out of here
+   |                  move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait
    |                  help: consider borrowing here: `&array[0]`
 
 error: aborting due to previous error
diff --git a/src/test/ui/error-codes/E0509.stderr b/src/test/ui/error-codes/E0509.stderr
index e5c0cf6e24e..cbfbc3ccf6a 100644
--- a/src/test/ui/error-codes/E0509.stderr
+++ b/src/test/ui/error-codes/E0509.stderr
@@ -5,6 +5,7 @@ LL |     let fancy_field = drop_struct.fancy;
    |                       ^^^^^^^^^^^^^^^^^
    |                       |
    |                       cannot move out of here
+   |                       move occurs because `drop_struct.fancy` has type `FancyNum`, which does not implement the `Copy` trait
    |                       help: consider borrowing here: `&drop_struct.fancy`
 
 error: aborting due to previous error
diff --git a/src/test/ui/functional-struct-update/functional-struct-update-noncopyable.stderr b/src/test/ui/functional-struct-update/functional-struct-update-noncopyable.stderr
index e7b45753421..635f83bbf48 100644
--- a/src/test/ui/functional-struct-update/functional-struct-update-noncopyable.stderr
+++ b/src/test/ui/functional-struct-update/functional-struct-update-noncopyable.stderr
@@ -2,7 +2,10 @@ error[E0509]: cannot move out of type `A`, which implements the `Drop` trait
   --> $DIR/functional-struct-update-noncopyable.rs:12:14
    |
 LL |     let _b = A { y: Arc::new(3), ..a };
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |
+   |              cannot move out of here
+   |              move occurs because `a.x` has type `std::sync::Arc<isize>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-17718-static-move.stderr b/src/test/ui/issues/issue-17718-static-move.stderr
index c3e6267d30f..984534bfb8b 100644
--- a/src/test/ui/issues/issue-17718-static-move.stderr
+++ b/src/test/ui/issues/issue-17718-static-move.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of static item
+error[E0507]: cannot move out of static item `FOO`
   --> $DIR/issue-17718-static-move.rs:6:14
    |
 LL |     let _a = FOO;
    |              ^^^
    |              |
-   |              cannot move out of static item
+   |              move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait
    |              help: consider borrowing here: `&FOO`
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-20801.rs b/src/test/ui/issues/issue-20801.rs
index 6f8ce66d8f2..35d6f8c0fae 100644
--- a/src/test/ui/issues/issue-20801.rs
+++ b/src/test/ui/issues/issue-20801.rs
@@ -24,14 +24,14 @@ fn const_ptr() -> *const T {
 
 pub fn main() {
     let a = unsafe { *mut_ref() };
-    //~^ ERROR cannot move out of borrowed content
+    //~^ ERROR cannot move out of a mutable reference
 
     let b = unsafe { *imm_ref() };
-    //~^ ERROR cannot move out of borrowed content
+    //~^ ERROR cannot move out of a shared reference
 
     let c = unsafe { *mut_ptr() };
-    //~^ ERROR cannot move out of dereference of raw pointer
+    //~^ ERROR cannot move out of a raw pointer
 
     let d = unsafe { *const_ptr() };
-    //~^ ERROR cannot move out of dereference of raw pointer
+    //~^ ERROR cannot move out of a raw pointer
 }
diff --git a/src/test/ui/issues/issue-20801.stderr b/src/test/ui/issues/issue-20801.stderr
index adcbe55aa32..1bbd874a448 100644
--- a/src/test/ui/issues/issue-20801.stderr
+++ b/src/test/ui/issues/issue-20801.stderr
@@ -1,37 +1,37 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/issue-20801.rs:26:22
    |
 LL |     let a = unsafe { *mut_ref() };
    |                      ^^^^^^^^^^
    |                      |
-   |                      cannot move out of borrowed content
+   |                      move occurs because value has type `T`, which does not implement the `Copy` trait
    |                      help: consider removing the `*`: `mut_ref()`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/issue-20801.rs:29:22
    |
 LL |     let b = unsafe { *imm_ref() };
    |                      ^^^^^^^^^^
    |                      |
-   |                      cannot move out of borrowed content
+   |                      move occurs because value has type `T`, which does not implement the `Copy` trait
    |                      help: consider removing the `*`: `imm_ref()`
 
-error[E0507]: cannot move out of dereference of raw pointer
+error[E0507]: cannot move out of a raw pointer
   --> $DIR/issue-20801.rs:32:22
    |
 LL |     let c = unsafe { *mut_ptr() };
    |                      ^^^^^^^^^^
    |                      |
-   |                      cannot move out of dereference of raw pointer
+   |                      move occurs because value has type `T`, which does not implement the `Copy` trait
    |                      help: consider removing the `*`: `mut_ptr()`
 
-error[E0507]: cannot move out of dereference of raw pointer
+error[E0507]: cannot move out of a raw pointer
   --> $DIR/issue-20801.rs:35:22
    |
 LL |     let d = unsafe { *const_ptr() };
    |                      ^^^^^^^^^^^^
    |                      |
-   |                      cannot move out of dereference of raw pointer
+   |                      move occurs because value has type `T`, which does not implement the `Copy` trait
    |                      help: consider removing the `*`: `const_ptr()`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/issues/issue-2590.rs b/src/test/ui/issues/issue-2590.rs
index 28d023db4f5..a9a0e5ca4ec 100644
--- a/src/test/ui/issues/issue-2590.rs
+++ b/src/test/ui/issues/issue-2590.rs
@@ -8,7 +8,7 @@ trait Parse {
 
 impl Parse for Parser {
     fn parse(&self) -> Vec<isize> {
-        self.tokens //~ ERROR cannot move out of borrowed content
+        self.tokens //~ ERROR cannot move out
     }
 }
 
diff --git a/src/test/ui/issues/issue-2590.stderr b/src/test/ui/issues/issue-2590.stderr
index e19e83dc747..3517d92403f 100644
--- a/src/test/ui/issues/issue-2590.stderr
+++ b/src/test/ui/issues/issue-2590.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `self.tokens` which is behind a shared reference
   --> $DIR/issue-2590.rs:11:9
    |
 LL |         self.tokens
-   |         ^^^^^^^^^^^ cannot move out of borrowed content
+   |         ^^^^^^^^^^^ move occurs because `self.tokens` has type `std::vec::Vec<isize>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs b/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs
index 1312aff30fe..e570b04a2be 100644
--- a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs
+++ b/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.rs
@@ -12,7 +12,7 @@ fn main() {
         None => {},
         ref mut foo
             if { (|| { let bar = foo; bar.take() })(); false } => {},
-        //~^ ERROR cannot move out of borrowed content [E0507]
+        //~^ ERROR cannot move out of `foo` in pattern guard [E0507]
         Some(s) => std::process::exit(*s),
     }
 }
diff --git a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr b/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr
index b5973ba8bd5..c5a9dd98a15 100644
--- a/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr
+++ b/src/test/ui/issues/issue-27282-move-ref-mut-into-guard.stderr
@@ -1,8 +1,14 @@
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/issue-27282-move-ref-mut-into-guard.rs:14:18
+error[E0507]: cannot move out of `foo` in pattern guard
+  --> $DIR/issue-27282-move-ref-mut-into-guard.rs:14:19
    |
 LL |             if { (|| { let bar = foo; bar.take() })(); false } => {},
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                   ^^             ---
+   |                   |              |
+   |                   |              move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait
+   |                   |              move occurs due to use in closure
+   |                   move out of `foo` occurs here
+   |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.rs b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.rs
index 786c37e5969..254956ae306 100644
--- a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.rs
+++ b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.rs
@@ -6,5 +6,5 @@ struct Foo {
 fn main() {
     let mut f = Foo { v: Vec::new() };
     f.v.push("hello".to_string());
-    let e = f.v[0]; //~ ERROR cannot move out of borrowed content
+    let e = f.v[0]; //~ ERROR cannot move out of index
 }
diff --git a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr
index fbfbc0cb977..8a9d9aab81a 100644
--- a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr
+++ b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<std::string::String>`
   --> $DIR/issue-40402-1.rs:9:13
    |
 LL |     let e = f.v[0];
    |             ^^^^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because value has type `std::string::String`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&f.v[0]`
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.rs b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.rs
index 480a4df48a3..1fb6e31e964 100644
--- a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.rs
+++ b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.rs
@@ -2,5 +2,5 @@
 // are nested within a pattern
 fn main() {
     let x = vec![(String::new(), String::new())];
-    let (a, b) = x[0]; //~ ERROR cannot move out of borrowed content
+    let (a, b) = x[0]; //~ ERROR cannot move out of index
 }
diff --git a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr
index 0c4a85b5901..e547ec7e475 100644
--- a/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr
+++ b/src/test/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr
@@ -1,11 +1,9 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<(std::string::String, std::string::String)>`
   --> $DIR/issue-40402-2.rs:5:18
    |
 LL |     let (a, b) = x[0];
-   |          -  -    ^^^^
-   |          |  |    |
-   |          |  |    cannot move out of borrowed content
-   |          |  |    help: consider borrowing here: `&x[0]`
+   |          -  -    ^^^^ help: consider borrowing here: `&x[0]`
+   |          |  |
    |          |  ...and here
    |          data moved here
    |
diff --git a/src/test/ui/issues/issue-4335.stderr b/src/test/ui/issues/issue-4335.stderr
index f1b6e475949..ca1c0b68d2a 100644
--- a/src/test/ui/issues/issue-4335.stderr
+++ b/src/test/ui/issues/issue-4335.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMut` closure
   --> $DIR/issue-4335.rs:6:20
    |
 LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
    |             - captured outer variable
 LL |     id(Box::new(|| *v))
-   |                    ^^ cannot move out of captured variable in an `FnMut` closure
+   |                    ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
 
 error[E0373]: closure may outlive the current function, but it borrows `v`, which is owned by the current function
   --> $DIR/issue-4335.rs:6:17
diff --git a/src/test/ui/moves/move-out-of-array-1.stderr b/src/test/ui/moves/move-out-of-array-1.stderr
index fb191b89bda..0af083e5b52 100644
--- a/src/test/ui/moves/move-out-of-array-1.stderr
+++ b/src/test/ui/moves/move-out-of-array-1.stderr
@@ -2,7 +2,10 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
   --> $DIR/move-out-of-array-1.rs:17:5
    |
 LL |     a[i]
-   |     ^^^^ cannot move out of here
+   |     ^^^^
+   |     |
+   |     cannot move out of here
+   |     move occurs because `a[_]` has type `D`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/moves/move-out-of-slice-1.stderr b/src/test/ui/moves/move-out-of-slice-1.stderr
index b4b1fe97ca9..ce5ddb3e183 100644
--- a/src/test/ui/moves/move-out-of-slice-1.stderr
+++ b/src/test/ui/moves/move-out-of-slice-1.stderr
@@ -4,13 +4,10 @@ error[E0508]: cannot move out of type `[A]`, a non-copy slice
 LL |     match a {
    |           ^ cannot move out of here
 LL |         box [a] => {},
-   |              - data moved here
-   |
-note: move occurs because `a` has type `A`, which does not implement the `Copy` trait
-  --> $DIR/move-out-of-slice-1.rs:8:14
-   |
-LL |         box [a] => {},
-   |              ^
+   |              -
+   |              |
+   |              data moved here
+   |              move occurs because `a` has type `A`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/moves/moves-based-on-type-block-bad.rs b/src/test/ui/moves/moves-based-on-type-block-bad.rs
index 516325ce1d7..085e249c0fb 100644
--- a/src/test/ui/moves/moves-based-on-type-block-bad.rs
+++ b/src/test/ui/moves/moves-based-on-type-block-bad.rs
@@ -20,7 +20,6 @@ fn main() {
     loop {
         f(&s, |hellothere| {
             match hellothere.x { //~ ERROR cannot move out
-                                 //~| cannot move out of borrowed content
                 box E::Foo(_) => {}
                 box E::Bar(x) => println!("{}", x.to_string()),
                 box E::Baz => {}
diff --git a/src/test/ui/moves/moves-based-on-type-block-bad.stderr b/src/test/ui/moves/moves-based-on-type-block-bad.stderr
index e28b22035f5..12b87c54b9c 100644
--- a/src/test/ui/moves/moves-based-on-type-block-bad.stderr
+++ b/src/test/ui/moves/moves-based-on-type-block-bad.stderr
@@ -1,20 +1,14 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `hellothere.x.0` which is behind a shared reference
   --> $DIR/moves-based-on-type-block-bad.rs:22:19
    |
 LL |             match hellothere.x {
-   |                   ^^^^^^^^^^^^
-   |                   |
-   |                   cannot move out of borrowed content
-   |                   help: consider borrowing here: `&hellothere.x`
-...
+   |                   ^^^^^^^^^^^^ help: consider borrowing here: `&hellothere.x`
+LL |                 box E::Foo(_) => {}
 LL |                 box E::Bar(x) => println!("{}", x.to_string()),
-   |                            - data moved here
-   |
-note: move occurs because `x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-  --> $DIR/moves-based-on-type-block-bad.rs:25:28
-   |
-LL |                 box E::Bar(x) => println!("{}", x.to_string()),
-   |                            ^
+   |                            -
+   |                            |
+   |                            data moved here
+   |                            move occurs because `x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
index 0568a2e94a7..fafd377c12b 100644
--- a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
+++ b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
   --> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:11:28
    |
 LL |     let i = box 3;
    |         - captured outer variable
 LL |     let _f = to_fn(|| test(i));
-   |                            ^ cannot move out of captured variable in an `Fn` closure
+   |                            ^ move occurs because `i` has type `std::boxed::Box<usize>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/cannot-move-block-spans.stderr b/src/test/ui/nll/cannot-move-block-spans.stderr
index c8dd07dabe1..4a9635b060d 100644
--- a/src/test/ui/nll/cannot-move-block-spans.stderr
+++ b/src/test/ui/nll/cannot-move-block-spans.stderr
@@ -1,28 +1,28 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*r` which is behind a shared reference
   --> $DIR/cannot-move-block-spans.rs:5:15
    |
 LL |     let x = { *r };
    |               ^^
    |               |
-   |               cannot move out of borrowed content
+   |               move occurs because `*r` has type `std::string::String`, which does not implement the `Copy` trait
    |               help: consider removing the `*`: `r`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*r` which is behind a shared reference
   --> $DIR/cannot-move-block-spans.rs:6:22
    |
 LL |     let y = unsafe { *r };
    |                      ^^
    |                      |
-   |                      cannot move out of borrowed content
+   |                      move occurs because `*r` has type `std::string::String`, which does not implement the `Copy` trait
    |                      help: consider removing the `*`: `r`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*r` which is behind a shared reference
   --> $DIR/cannot-move-block-spans.rs:7:26
    |
 LL |     let z = loop { break *r; };
    |                          ^^
    |                          |
-   |                          cannot move out of borrowed content
+   |                          move occurs because `*r` has type `std::string::String`, which does not implement the `Copy` trait
    |                          help: consider removing the `*`: `r`
 
 error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
@@ -32,6 +32,7 @@ LL |     let x = { arr[0] };
    |               ^^^^^^
    |               |
    |               cannot move out of here
+   |               move occurs because `arr[_]` has type `std::string::String`, which does not implement the `Copy` trait
    |               help: consider borrowing here: `&arr[0]`
 
 error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
@@ -41,6 +42,7 @@ LL |     let y = unsafe { arr[0] };
    |                      ^^^^^^
    |                      |
    |                      cannot move out of here
+   |                      move occurs because `arr[_]` has type `std::string::String`, which does not implement the `Copy` trait
    |                      help: consider borrowing here: `&arr[0]`
 
 error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
@@ -50,33 +52,34 @@ LL |     let z = loop { break arr[0]; };
    |                          ^^^^^^
    |                          |
    |                          cannot move out of here
+   |                          move occurs because `arr[_]` has type `std::string::String`, which does not implement the `Copy` trait
    |                          help: consider borrowing here: `&arr[0]`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*r` which is behind a shared reference
   --> $DIR/cannot-move-block-spans.rs:17:38
    |
 LL |     let x = { let mut u = 0; u += 1; *r };
    |                                      ^^
    |                                      |
-   |                                      cannot move out of borrowed content
+   |                                      move occurs because `*r` has type `std::string::String`, which does not implement the `Copy` trait
    |                                      help: consider removing the `*`: `r`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*r` which is behind a shared reference
   --> $DIR/cannot-move-block-spans.rs:18:45
    |
 LL |     let y = unsafe { let mut u = 0; u += 1; *r };
    |                                             ^^
    |                                             |
-   |                                             cannot move out of borrowed content
+   |                                             move occurs because `*r` has type `std::string::String`, which does not implement the `Copy` trait
    |                                             help: consider removing the `*`: `r`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*r` which is behind a shared reference
   --> $DIR/cannot-move-block-spans.rs:19:49
    |
 LL |     let z = loop { let mut u = 0; u += 1; break *r; u += 2; };
    |                                                 ^^
    |                                                 |
-   |                                                 cannot move out of borrowed content
+   |                                                 move occurs because `*r` has type `std::string::String`, which does not implement the `Copy` trait
    |                                                 help: consider removing the `*`: `r`
 
 error: aborting due to 9 previous errors
diff --git a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr
index 34259d06d38..ce48457abe7 100644
--- a/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr
+++ b/src/test/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.stderr
@@ -35,6 +35,7 @@ LL |     let p = s.url; p
    |             ^^^^^
    |             |
    |             cannot move out of here
+   |             move occurs because `s.url` has type `&mut std::string::String`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&s.url`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/nll/issue-52086.stderr b/src/test/ui/nll/issue-52086.stderr
index da453fb1f92..e9aa7939f77 100644
--- a/src/test/ui/nll/issue-52086.stderr
+++ b/src/test/ui/nll/issue-52086.stderr
@@ -2,13 +2,13 @@ error[E0507]: cannot move out of an `Rc`
   --> $DIR/issue-52086.rs:8:10
    |
 LL |     drop(x.field);
-   |          ^^^^^^^ cannot move out of an `Rc`
+   |          ^^^^^^^ move occurs because value has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
 
 error[E0507]: cannot move out of an `Arc`
   --> $DIR/issue-52086.rs:12:10
    |
 LL |     drop(y.field);
-   |          ^^^^^^^ cannot move out of an `Arc`
+   |          ^^^^^^^ move occurs because value has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs b/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs
index 24a4267f653..cd1f457a130 100644
--- a/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs
+++ b/src/test/ui/nll/issue-52663-span-decl-captured-variable.rs
@@ -6,6 +6,6 @@ fn main() {
    {
        let x = (vec![22], vec![44]);
        expect_fn(|| drop(x.0));
-       //~^ ERROR cannot move out of captured variable in an `Fn` closure [E0507]
+       //~^ ERROR cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure [E0507]
    }
 }
diff --git a/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr b/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
index 8958bdf4c2a..57b9dc1f0be 100644
--- a/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
+++ b/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/issue-52663-span-decl-captured-variable.rs:8:26
    |
 LL |        let x = (vec![22], vec![44]);
    |            - captured outer variable
 LL |        expect_fn(|| drop(x.0));
-   |                          ^^^ cannot move out of captured variable in an `Fn` closure
+   |                          ^^^ move occurs because `x.0` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/match-guards-always-borrow.rs b/src/test/ui/nll/match-guards-always-borrow.rs
index 5900dc3ade0..d423730bdbc 100644
--- a/src/test/ui/nll/match-guards-always-borrow.rs
+++ b/src/test/ui/nll/match-guards-always-borrow.rs
@@ -8,7 +8,7 @@ fn should_reject_destructive_mutate_in_guard() {
         None => {},
         ref mut foo if {
             (|| { let bar = foo; bar.take() })();
-            //~^ ERROR cannot move out of borrowed content [E0507]
+            //~^ ERROR cannot move out of `foo` in pattern guard [E0507]
             false } => { },
         Some(s) => std::process::exit(*s),
     }
diff --git a/src/test/ui/nll/match-guards-always-borrow.stderr b/src/test/ui/nll/match-guards-always-borrow.stderr
index 2492397c65d..5b49db45a52 100644
--- a/src/test/ui/nll/match-guards-always-borrow.stderr
+++ b/src/test/ui/nll/match-guards-always-borrow.stderr
@@ -1,8 +1,14 @@
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/match-guards-always-borrow.rs:10:13
+error[E0507]: cannot move out of `foo` in pattern guard
+  --> $DIR/match-guards-always-borrow.rs:10:14
    |
 LL |             (|| { let bar = foo; bar.take() })();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |              ^^             ---
+   |              |              |
+   |              |              move occurs because `foo` has type `&mut std::option::Option<&i32>`, which does not implement the `Copy` trait
+   |              |              move occurs due to use in closure
+   |              move out of `foo` occurs here
+   |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/move-errors.stderr b/src/test/ui/nll/move-errors.stderr
index a4af11e3d40..086f7bcdc4f 100644
--- a/src/test/ui/nll/move-errors.stderr
+++ b/src/test/ui/nll/move-errors.stderr
@@ -1,10 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*a` which is behind a shared reference
   --> $DIR/move-errors.rs:6:13
    |
 LL |     let b = *a;
    |             ^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because `*a` has type `A`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `a`
 
 error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
@@ -14,15 +14,16 @@ LL |     let b = a[0];
    |             ^^^^
    |             |
    |             cannot move out of here
+   |             move occurs because `a[_]` has type `A`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&a[0]`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `**r` which is behind a shared reference
   --> $DIR/move-errors.rs:19:13
    |
 LL |     let s = **r;
    |             ^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because `**r` has type `A`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `*r`
 
 error[E0507]: cannot move out of an `Rc`
@@ -31,7 +32,7 @@ error[E0507]: cannot move out of an `Rc`
 LL |     let s = *r;
    |             ^^
    |             |
-   |             cannot move out of an `Rc`
+   |             move occurs because value has type `A`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `r`
 
 error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
@@ -41,23 +42,17 @@ LL |     let a = [A("".to_string())][0];
    |             ^^^^^^^^^^^^^^^^^^^^^^
    |             |
    |             cannot move out of here
+   |             move occurs because value has type `A`, which does not implement the `Copy` trait
    |             help: consider borrowing here: `&[A("".to_string())][0]`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `a.0` which is behind a shared reference
   --> $DIR/move-errors.rs:38:16
    |
 LL |     let A(s) = *a;
-   |           -    ^^
-   |           |    |
-   |           |    cannot move out of borrowed content
-   |           |    help: consider removing the `*`: `a`
+   |           -    ^^ help: consider removing the `*`: `a`
+   |           |
    |           data moved here
-   |
-note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/move-errors.rs:38:11
-   |
-LL |     let A(s) = *a;
-   |           ^
+   |           move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
   --> $DIR/move-errors.rs:44:19
@@ -66,18 +61,13 @@ LL |     let C(D(s)) = c;
    |             -     ^ cannot move out of here
    |             |
    |             data moved here
-   |
-note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/move-errors.rs:44:13
-   |
-LL |     let C(D(s)) = c;
-   |             ^
+   |             move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*a` which is behind a shared reference
   --> $DIR/move-errors.rs:51:9
    |
 LL |     b = *a;
-   |         ^^ cannot move out of borrowed content
+   |         ^^ move occurs because `*a` has type `A`, which does not implement the `Copy` trait
 
 error[E0508]: cannot move out of type `[B; 1]`, a non-copy array
   --> $DIR/move-errors.rs:74:11
@@ -108,13 +98,10 @@ LL |     match x {
    |           ^ cannot move out of here
 ...
 LL |         B::U(D(s)) => (),
-   |                - data moved here
-   |
-note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/move-errors.rs:86:16
-   |
-LL |         B::U(D(s)) => (),
-   |                ^
+   |                -
+   |                |
+   |                data moved here
+   |                move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
   --> $DIR/move-errors.rs:92:11
@@ -123,28 +110,22 @@ LL |     match x {
    |           ^ cannot move out of here
 ...
 LL |         (D(s), &t) => (),
-   |            - data moved here
-   |
-note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/move-errors.rs:95:12
-   |
-LL |         (D(s), &t) => (),
-   |            ^
+   |            -
+   |            |
+   |            data moved here
+   |            move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*x.1` which is behind a shared reference
   --> $DIR/move-errors.rs:92:11
    |
 LL |     match x {
-   |           ^ cannot move out of borrowed content
+   |           ^
 ...
 LL |         (D(s), &t) => (),
-   |                 - data moved here
-   |
-note: move occurs because `t` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/move-errors.rs:95:17
-   |
-LL |         (D(s), &t) => (),
-   |                 ^
+   |                 -
+   |                 |
+   |                 data moved here
+   |                 move occurs because `t` has type `std::string::String`, which does not implement the `Copy` trait
 
 error[E0509]: cannot move out of type `F`, which implements the `Drop` trait
   --> $DIR/move-errors.rs:102:11
@@ -163,23 +144,17 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         F(s, mut t) => (),
    |           ^  ^^^^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `x.0` which is behind a shared reference
   --> $DIR/move-errors.rs:110:11
    |
 LL |     match *x {
-   |           ^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `x`
+   |           ^^ help: consider removing the `*`: `x`
 LL |
 LL |         Ok(s) | Err(s) => (),
-   |            - data moved here
-   |
-note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
-  --> $DIR/move-errors.rs:112:12
-   |
-LL |         Ok(s) | Err(s) => (),
-   |            ^
+   |            -
+   |            |
+   |            data moved here
+   |            move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to 14 previous errors
 
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
index 17fb7c4acdf..f6252f4ed79 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
@@ -7,11 +7,11 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
 LL |     ss.r
    |     ^^^^ lifetime `'static` required
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `ss.r` which is behind a mutable reference
   --> $DIR/object-lifetime-default-from-box-error.rs:18:5
    |
 LL |     ss.r
-   |     ^^^^ cannot move out of borrowed content
+   |     ^^^^ move occurs because `ss.r` has type `std::boxed::Box<dyn SomeTrait>`, which does not implement the `Copy` trait
 
 error[E0621]: explicit lifetime required in the type of `ss`
   --> $DIR/object-lifetime-default-from-box-error.rs:31:5
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs
index 0fec6b273d3..bf387d01b6b 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs
@@ -6,7 +6,7 @@ enum VecWrapper { A(Vec<i32>) }
 fn foo(x: VecWrapper) -> usize {
     match x {
         VecWrapper::A(v) if { drop(v); false } => 1,
-        //~^ ERROR cannot move out of borrowed content
+        //~^ ERROR cannot move out of `v` in pattern guard
         VecWrapper::A(v) => v.len()
     }
 }
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr
index 502006e1b3f..f6e4e5bd49b 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr
@@ -1,8 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `v` in pattern guard
   --> $DIR/rfc-reject-double-move-across-arms.rs:8:36
    |
 LL |         VecWrapper::A(v) if { drop(v); false } => 1,
-   |                                    ^ cannot move out of borrowed content
+   |                                    ^ move occurs because `v` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
+   |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs
index 396bfc1c931..ba999e9b3a4 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs
@@ -7,7 +7,7 @@ fn foo(n: i32) {
     let x = A { a: Box::new(n) };
     let _y = match x {
         A { a: v } if { drop(v); true } => v,
-        //~^ ERROR cannot move out of borrowed content
+        //~^ ERROR cannot move out of `v` in pattern guard
         _ => Box::new(0),
     };
 }
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr
index dd8f42f7497..ec133b028e8 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr
@@ -1,8 +1,10 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `v` in pattern guard
   --> $DIR/rfc-reject-double-move-in-first-arm.rs:9:30
    |
 LL |         A { a: v } if { drop(v); true } => v,
-   |                              ^ cannot move out of borrowed content
+   |                              ^ move occurs because `v` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
+   |
+   = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfc-2005-default-binding-mode/for.rs
index 919ae62a182..3bf053eb874 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/for.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/for.rs
@@ -5,6 +5,6 @@ pub fn main() {
     // The below desugars to &(ref n, mut m).
     for (n, mut m) in &tups {
         //~^ ERROR cannot bind by-move and by-ref in the same pattern
-        //~| ERROR cannot move out of borrowed content
+        //~| ERROR cannot move out of a shared reference
     }
 }
diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.stderr b/src/test/ui/rfc-2005-default-binding-mode/for.stderr
index d9a59e63453..8a1ded1d5b9 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr
@@ -6,19 +6,14 @@ LL |     for (n, mut m) in &tups {
    |          |
    |          both by-ref and by-move used
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/for.rs:6:23
    |
 LL |     for (n, mut m) in &tups {
-   |             -----     ^^^^^ cannot move out of borrowed content
+   |             -----     ^^^^^
    |             |
    |             data moved here
-   |
-note: move occurs because `m` has type `Foo`, which does not implement the `Copy` trait
-  --> $DIR/for.rs:6:13
-   |
-LL |     for (n, mut m) in &tups {
-   |             ^^^^^
+   |             move occurs because `m` has type `Foo`, which does not implement the `Copy` trait
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
index 6099263ccd0..938fdaf11f0 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs
@@ -55,7 +55,7 @@ fn test7() {
     f(Box::new(|a| {
         //~^ ERROR cannot move out of `f` because it is borrowed
         foo(f);
-        //~^ ERROR cannot move out of captured variable in an `FnMut` closure
+        //~^ ERROR cannot move out of `f`, a captured variable in an `FnMut` closure
     }), 3);
 }
 
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 72f979e8d3c..72f875bbd14 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -26,14 +26,14 @@ LL | fn test4(f: &Test) {
 LL |     f.f.call_mut(())
    |     ^^^ `f` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
    |
 LL |     let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
    |         ----- captured outer variable
 ...
 LL |         foo(f);
-   |             ^ cannot move out of captured variable in an `FnMut` closure
+   |             ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6 s:std::string::String]`, which does not implement the `Copy` trait
 
 error[E0505]: cannot move out of `f` because it is borrowed
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
diff --git a/src/test/ui/static/static-items-cant-move.stderr b/src/test/ui/static/static-items-cant-move.stderr
index fc1ed9b8d61..235e9ee9b91 100644
--- a/src/test/ui/static/static-items-cant-move.stderr
+++ b/src/test/ui/static/static-items-cant-move.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of static item
+error[E0507]: cannot move out of static item `BAR`
   --> $DIR/static-items-cant-move.rs:18:10
    |
 LL |     test(BAR);
-   |          ^^^ cannot move out of static item
+   |          ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/std-uncopyable-atomics.rs b/src/test/ui/std-uncopyable-atomics.rs
index 2c79a9c440e..d85864ecac2 100644
--- a/src/test/ui/std-uncopyable-atomics.rs
+++ b/src/test/ui/std-uncopyable-atomics.rs
@@ -6,11 +6,11 @@ use std::ptr;
 
 fn main() {
     let x = AtomicBool::new(false);
-    let x = *&x; //~ ERROR: cannot move out of borrowed content
+    let x = *&x; //~ ERROR: cannot move out of a shared reference
     let x = AtomicIsize::new(0);
-    let x = *&x; //~ ERROR: cannot move out of borrowed content
+    let x = *&x; //~ ERROR: cannot move out of a shared reference
     let x = AtomicUsize::new(0);
-    let x = *&x; //~ ERROR: cannot move out of borrowed content
+    let x = *&x; //~ ERROR: cannot move out of a shared reference
     let x: AtomicPtr<usize> = AtomicPtr::new(ptr::null_mut());
-    let x = *&x; //~ ERROR: cannot move out of borrowed content
+    let x = *&x; //~ ERROR: cannot move out of a shared reference
 }
diff --git a/src/test/ui/std-uncopyable-atomics.stderr b/src/test/ui/std-uncopyable-atomics.stderr
index 8241f6f1fdb..189a27db382 100644
--- a/src/test/ui/std-uncopyable-atomics.stderr
+++ b/src/test/ui/std-uncopyable-atomics.stderr
@@ -1,37 +1,37 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/std-uncopyable-atomics.rs:9:13
    |
 LL |     let x = *&x;
    |             ^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because value has type `std::sync::atomic::AtomicBool`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `&x`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/std-uncopyable-atomics.rs:11:13
    |
 LL |     let x = *&x;
    |             ^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because value has type `std::sync::atomic::AtomicIsize`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `&x`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/std-uncopyable-atomics.rs:13:13
    |
 LL |     let x = *&x;
    |             ^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because value has type `std::sync::atomic::AtomicUsize`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `&x`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/std-uncopyable-atomics.rs:15:13
    |
 LL |     let x = *&x;
    |             ^^^
    |             |
-   |             cannot move out of borrowed content
+   |             move occurs because value has type `std::sync::atomic::AtomicPtr<usize>`, which does not implement the `Copy` trait
    |             help: consider removing the `*`: `&x`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr
index f8e043fbfdf..c0b7a5a5b62 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr
+++ b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:39:27
    |
 LL |     let &(X(_t), X(_u)) = &(x.clone(), x.clone());
-   |         ---------------   ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |         ---------------   ^^^^^^^^^^^^^^^^^^^^^^^
    |         |   |      |
    |         |   |      ...and here
    |         |   data moved here
@@ -14,11 +14,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     let &(X(_t), X(_u)) = &(x.clone(), x.clone());
    |             ^^     ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:43:50
    |
 LL |     if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
-   |            -----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |            -----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^
    |            |             |                |
    |            |             |                ...and here
    |            |             data moved here
@@ -30,11 +30,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
    |                          ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:47:53
    |
 LL |     while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
-   |               -----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |               -----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^
    |               |             |                |
    |               |             |                ...and here
    |               |             data moved here
@@ -46,11 +46,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
    |                             ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:51:11
    |
 LL |     match &(e.clone(), e.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &(Either::One(_t), Either::Two(_u)) => (),
    |                       --               -- ...and here
@@ -77,11 +77,11 @@ help: consider removing the `&`
 LL |         (Either::Two(_t), Either::One(_u)) => (),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:61:11
    |
 LL |     match &(e.clone(), e.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &(Either::One(_t), Either::Two(_u))
    |         -----------------------------------
@@ -96,11 +96,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &(Either::One(_t), Either::Two(_u))
    |                       ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:70:11
    |
 LL |     match &(e.clone(), e.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &(Either::One(_t), Either::Two(_u)) => (),
    |         -----------------------------------
@@ -115,11 +115,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &(Either::One(_t), Either::Two(_u)) => (),
    |                       ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:78:11
    |
 LL |     match &(e.clone(), e.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &(Either::One(_t), Either::Two(_u)) => (),
    |         -----------------------------------
@@ -134,11 +134,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &(Either::One(_t), Either::Two(_u)) => (),
    |                       ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:91:31
    |
 LL |     let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
-   |         -------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |         -------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         |       |      |
    |         |       |      ...and here
    |         |       data moved here
@@ -150,11 +150,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
    |                 ^^     ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:95:54
    |
 LL |     if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
-   |            ---------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |            ---------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |            |                 |                |
    |            |                 |                ...and here
    |            |                 data moved here
@@ -166,11 +166,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
    |                              ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:99:57
    |
 LL |     while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
-   |               ---------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |               ---------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |               |                 |                |
    |               |                 |                ...and here
    |               |                 data moved here
@@ -182,11 +182,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
    |                                 ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:103:11
    |
 LL |     match &mut (em.clone(), em.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |                           --               -- ...and here
@@ -213,11 +213,11 @@ help: consider removing the `&mut`
 LL |         (Either::Two(_t), Either::One(_u)) => (),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:113:11
    |
 LL |     match &mut (em.clone(), em.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &mut (Either::One(_t), Either::Two(_u))
    |         ---------------------------------------
@@ -232,11 +232,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &mut (Either::One(_t), Either::Two(_u))
    |                           ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:122:11
    |
 LL |     match &mut (em.clone(), em.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |         ---------------------------------------
@@ -251,11 +251,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |                           ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:130:11
    |
 LL |     match &mut (em.clone(), em.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |         ---------------------------------------
@@ -270,11 +270,11 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |                           ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:138:11
    |
 LL |     match &mut (em.clone(), em.clone()) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |         ---------------------------------------
@@ -289,7 +289,7 @@ note: move occurs because these variables have types that don't implement the `C
 LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
    |                           ^^               ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/duplicate-suggestions.rs:86:11
    |
 LL |     fn f5(&(X(_t), X(_u)): &(X, X)) { }
@@ -297,7 +297,6 @@ LL |     fn f5(&(X(_t), X(_u)): &(X, X)) { }
    |           |   |      |
    |           |   |      ...and here
    |           |   data moved here
-   |           cannot move out of borrowed content
    |           help: consider removing the `&`: `(X(_t), X(_u))`
    |
 note: move occurs because these variables have types that don't implement the `Copy` trait
@@ -306,7 +305,7 @@ note: move occurs because these variables have types that don't implement the `C
 LL |     fn f5(&(X(_t), X(_u)): &(X, X)) { }
    |               ^^     ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/duplicate-suggestions.rs:146:11
    |
 LL |     fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { }
@@ -314,7 +313,6 @@ LL |     fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { }
    |           |       |      |
    |           |       |      ...and here
    |           |       data moved here
-   |           cannot move out of borrowed content
    |           help: consider removing the `&mut`: `(X(_t), X(_u))`
    |
 note: move occurs because these variables have types that don't implement the `Copy` trait
diff --git a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
index 74f3a63be57..c50cbcde855 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
+++ b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
@@ -1,419 +1,281 @@
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:28:21
    |
 LL |     let x = X(Y);
    |         - captured outer variable
 ...
 LL |         let X(_t) = x;
-   |               --    ^
-   |               |     |
-   |               |     cannot move out of captured variable in an `Fn` closure
-   |               |     help: consider borrowing here: `&x`
+   |               --    ^ help: consider borrowing here: `&x`
+   |               |
    |               data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:28:15
-   |
-LL |         let X(_t) = x;
-   |               ^^
+   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:32:34
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         if let Either::One(_t) = e { }
-   |                            --    ^
-   |                            |     |
-   |                            |     cannot move out of captured variable in an `Fn` closure
-   |                            |     help: consider borrowing here: `&e`
+   |                            --    ^ help: consider borrowing here: `&e`
+   |                            |
    |                            data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:32:28
-   |
-LL |         if let Either::One(_t) = e { }
-   |                            ^^
+   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:36:37
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         while let Either::One(_t) = e { }
-   |                               --    ^
-   |                               |     |
-   |                               |     cannot move out of captured variable in an `Fn` closure
-   |                               |     help: consider borrowing here: `&e`
+   |                               --    ^ help: consider borrowing here: `&e`
+   |                               |
    |                               data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:36:31
-   |
-LL |         while let Either::One(_t) = e { }
-   |                               ^^
+   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:40:15
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         match e {
-   |               ^
-   |               |
-   |               cannot move out of captured variable in an `Fn` closure
-   |               help: consider borrowing here: `&e`
+   |               ^ help: consider borrowing here: `&e`
 ...
 LL |             Either::One(_t)
-   |                         -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:44:25
-   |
-LL |             Either::One(_t)
-   |                         ^^
+   |                         --
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:47:15
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         match e {
-   |               ^
-   |               |
-   |               cannot move out of captured variable in an `Fn` closure
-   |               help: consider borrowing here: `&e`
+   |               ^ help: consider borrowing here: `&e`
 ...
 LL |             Either::One(_t) => (),
-   |                         -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:51:25
-   |
-LL |             Either::One(_t) => (),
-   |                         ^^
+   |                         --
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:56:25
    |
 LL |     let x = X(Y);
    |         - captured outer variable
 ...
 LL |         let X(mut _t) = x;
-   |               ------    ^
-   |               |         |
-   |               |         cannot move out of captured variable in an `Fn` closure
-   |               |         help: consider borrowing here: `&x`
+   |               ------    ^ help: consider borrowing here: `&x`
+   |               |
    |               data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:56:15
-   |
-LL |         let X(mut _t) = x;
-   |               ^^^^^^
+   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:60:38
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         if let Either::One(mut _t) = em { }
-   |                            ------    ^^
-   |                            |         |
-   |                            |         cannot move out of captured variable in an `Fn` closure
-   |                            |         help: consider borrowing here: `&em`
+   |                            ------    ^^ help: consider borrowing here: `&em`
+   |                            |
    |                            data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:60:28
-   |
-LL |         if let Either::One(mut _t) = em { }
-   |                            ^^^^^^
+   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:64:41
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         while let Either::One(mut _t) = em { }
-   |                               ------    ^^
-   |                               |         |
-   |                               |         cannot move out of captured variable in an `Fn` closure
-   |                               |         help: consider borrowing here: `&em`
+   |                               ------    ^^ help: consider borrowing here: `&em`
+   |                               |
    |                               data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:64:31
-   |
-LL |         while let Either::One(mut _t) = em { }
-   |                               ^^^^^^
+   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:68:15
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         match em {
-   |               ^^
-   |               |
-   |               cannot move out of captured variable in an `Fn` closure
-   |               help: consider borrowing here: `&em`
+   |               ^^ help: consider borrowing here: `&em`
 ...
 LL |             Either::One(mut _t)
-   |                         ------ data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:72:25
-   |
-LL |             Either::One(mut _t)
-   |                         ^^^^^^
+   |                         ------
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:75:15
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         match em {
-   |               ^^
-   |               |
-   |               cannot move out of captured variable in an `Fn` closure
-   |               help: consider borrowing here: `&em`
+   |               ^^ help: consider borrowing here: `&em`
 ...
 LL |             Either::One(mut _t) => (),
-   |                         ------ data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:79:25
-   |
-LL |             Either::One(mut _t) => (),
-   |                         ^^^^^^
+   |                         ------
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:95:21
    |
 LL |     let x = X(Y);
    |         - captured outer variable
 ...
 LL |         let X(_t) = x;
-   |               --    ^
-   |               |     |
-   |               |     cannot move out of captured variable in an `FnMut` closure
-   |               |     help: consider borrowing here: `&x`
+   |               --    ^ help: consider borrowing here: `&x`
+   |               |
    |               data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:95:15
-   |
-LL |         let X(_t) = x;
-   |               ^^
+   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:99:34
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         if let Either::One(_t) = e { }
-   |                            --    ^
-   |                            |     |
-   |                            |     cannot move out of captured variable in an `FnMut` closure
-   |                            |     help: consider borrowing here: `&e`
+   |                            --    ^ help: consider borrowing here: `&e`
+   |                            |
    |                            data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:99:28
-   |
-LL |         if let Either::One(_t) = e { }
-   |                            ^^
+   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:103:37
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         while let Either::One(_t) = e { }
-   |                               --    ^
-   |                               |     |
-   |                               |     cannot move out of captured variable in an `FnMut` closure
-   |                               |     help: consider borrowing here: `&e`
+   |                               --    ^ help: consider borrowing here: `&e`
+   |                               |
    |                               data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:103:31
-   |
-LL |         while let Either::One(_t) = e { }
-   |                               ^^
+   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:107:15
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         match e {
-   |               ^
-   |               |
-   |               cannot move out of captured variable in an `FnMut` closure
-   |               help: consider borrowing here: `&e`
+   |               ^ help: consider borrowing here: `&e`
 ...
 LL |             Either::One(_t)
-   |                         -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:111:25
-   |
-LL |             Either::One(_t)
-   |                         ^^
+   |                         --
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:114:15
    |
 LL |     let e = Either::One(X(Y));
    |         - captured outer variable
 ...
 LL |         match e {
-   |               ^
-   |               |
-   |               cannot move out of captured variable in an `FnMut` closure
-   |               help: consider borrowing here: `&e`
+   |               ^ help: consider borrowing here: `&e`
 ...
 LL |             Either::One(_t) => (),
-   |                         -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:118:25
-   |
-LL |             Either::One(_t) => (),
-   |                         ^^
+   |                         --
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:123:25
    |
 LL |     let x = X(Y);
    |         - captured outer variable
 ...
 LL |         let X(mut _t) = x;
-   |               ------    ^
-   |               |         |
-   |               |         cannot move out of captured variable in an `FnMut` closure
-   |               |         help: consider borrowing here: `&x`
+   |               ------    ^ help: consider borrowing here: `&x`
+   |               |
    |               data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:123:15
-   |
-LL |         let X(mut _t) = x;
-   |               ^^^^^^
+   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:127:38
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         if let Either::One(mut _t) = em { }
-   |                            ------    ^^
-   |                            |         |
-   |                            |         cannot move out of captured variable in an `FnMut` closure
-   |                            |         help: consider borrowing here: `&em`
+   |                            ------    ^^ help: consider borrowing here: `&em`
+   |                            |
    |                            data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:127:28
-   |
-LL |         if let Either::One(mut _t) = em { }
-   |                            ^^^^^^
+   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:131:41
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         while let Either::One(mut _t) = em { }
-   |                               ------    ^^
-   |                               |         |
-   |                               |         cannot move out of captured variable in an `FnMut` closure
-   |                               |         help: consider borrowing here: `&em`
+   |                               ------    ^^ help: consider borrowing here: `&em`
+   |                               |
    |                               data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:131:31
-   |
-LL |         while let Either::One(mut _t) = em { }
-   |                               ^^^^^^
+   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:135:15
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         match em {
-   |               ^^
-   |               |
-   |               cannot move out of captured variable in an `FnMut` closure
-   |               help: consider borrowing here: `&em`
+   |               ^^ help: consider borrowing here: `&em`
 ...
 LL |             Either::One(mut _t)
-   |                         ------ data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:139:25
-   |
-LL |             Either::One(mut _t)
-   |                         ^^^^^^
+   |                         ------
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:142:15
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         match em {
-   |               ^^
-   |               |
-   |               cannot move out of captured variable in an `FnMut` closure
-   |               help: consider borrowing here: `&em`
+   |               ^^ help: consider borrowing here: `&em`
 ...
 LL |             Either::One(mut _t) => (),
-   |                         ------ data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:146:25
-   |
-LL |             Either::One(mut _t) => (),
-   |                         ^^^^^^
+   |                         ------
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:150:15
    |
 LL |     let mut em = Either::One(X(Y));
    |         ------ captured outer variable
 ...
 LL |         match em {
-   |               ^^
-   |               |
-   |               cannot move out of captured variable in an `FnMut` closure
-   |               help: consider borrowing here: `&em`
+   |               ^^ help: consider borrowing here: `&em`
 ...
 LL |             Either::One(mut _t) => (),
-   |                         ------ data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/move-into-closure.rs:154:25
-   |
-LL |             Either::One(mut _t) => (),
-   |                         ^^^^^^
+   |                         ------
+   |                         |
+   |                         data moved here
+   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
 error: aborting due to 21 previous errors
 
diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr
index 7f2ba4da714..bde3afa3840 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/simple.stderr
+++ b/src/test/ui/suggestions/dont-suggest-ref/simple.stderr
@@ -1,524 +1,335 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `s.0` which is behind a shared reference
   --> $DIR/simple.rs:38:17
    |
 LL |     let X(_t) = *s;
-   |           --    ^^
-   |           |     |
-   |           |     cannot move out of borrowed content
-   |           |     help: consider removing the `*`: `s`
+   |           --    ^^ help: consider removing the `*`: `s`
+   |           |
    |           data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:38:11
-   |
-LL |     let X(_t) = *s;
-   |           ^^
+   |           move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:42:30
    |
 LL |     if let Either::One(_t) = *r { }
-   |                        --    ^^
-   |                        |     |
-   |                        |     cannot move out of borrowed content
-   |                        |     help: consider removing the `*`: `r`
+   |                        --    ^^ help: consider removing the `*`: `r`
+   |                        |
    |                        data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:42:24
-   |
-LL |     if let Either::One(_t) = *r { }
-   |                        ^^
+   |                        move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:46:33
    |
 LL |     while let Either::One(_t) = *r { }
-   |                           --    ^^
-   |                           |     |
-   |                           |     cannot move out of borrowed content
-   |                           |     help: consider removing the `*`: `r`
+   |                           --    ^^ help: consider removing the `*`: `r`
+   |                           |
    |                           data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:46:27
-   |
-LL |     while let Either::One(_t) = *r { }
-   |                           ^^
+   |                           move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:50:11
    |
 LL |     match *r {
-   |           ^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `r`
+   |           ^^ help: consider removing the `*`: `r`
 ...
 LL |         Either::One(_t)
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:54:21
-   |
-LL |         Either::One(_t)
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:57:11
    |
 LL |     match *r {
-   |           ^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `r`
+   |           ^^ help: consider removing the `*`: `r`
 ...
 LL |         Either::One(_t) => (),
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:61:21
-   |
-LL |         Either::One(_t) => (),
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `sm.0` which is behind a mutable reference
   --> $DIR/simple.rs:66:17
    |
 LL |     let X(_t) = *sm;
-   |           --    ^^^
-   |           |     |
-   |           |     cannot move out of borrowed content
-   |           |     help: consider removing the `*`: `sm`
+   |           --    ^^^ help: consider removing the `*`: `sm`
+   |           |
    |           data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:66:11
-   |
-LL |     let X(_t) = *sm;
-   |           ^^
+   |           move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:70:30
    |
 LL |     if let Either::One(_t) = *rm { }
-   |                        --    ^^^
-   |                        |     |
-   |                        |     cannot move out of borrowed content
-   |                        |     help: consider removing the `*`: `rm`
+   |                        --    ^^^ help: consider removing the `*`: `rm`
+   |                        |
    |                        data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:70:24
-   |
-LL |     if let Either::One(_t) = *rm { }
-   |                        ^^
+   |                        move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:74:33
    |
 LL |     while let Either::One(_t) = *rm { }
-   |                           --    ^^^
-   |                           |     |
-   |                           |     cannot move out of borrowed content
-   |                           |     help: consider removing the `*`: `rm`
+   |                           --    ^^^ help: consider removing the `*`: `rm`
+   |                           |
    |                           data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:74:27
-   |
-LL |     while let Either::One(_t) = *rm { }
-   |                           ^^
+   |                           move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:78:11
    |
 LL |     match *rm {
-   |           ^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `rm`
+   |           ^^^ help: consider removing the `*`: `rm`
 ...
 LL |         Either::One(_t)
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:82:21
-   |
-LL |         Either::One(_t)
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:85:11
    |
 LL |     match *rm {
-   |           ^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `rm`
+   |           ^^^ help: consider removing the `*`: `rm`
 ...
 LL |         Either::One(_t) => (),
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:89:21
-   |
-LL |         Either::One(_t) => (),
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:93:11
    |
 LL |     match *rm {
-   |           ^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider removing the `*`: `rm`
+   |           ^^^ help: consider removing the `*`: `rm`
 ...
 LL |         Either::One(_t) => (),
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:97:21
-   |
-LL |         Either::One(_t) => (),
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<X>`
   --> $DIR/simple.rs:102:17
    |
 LL |     let X(_t) = vs[0];
-   |           --    ^^^^^
-   |           |     |
-   |           |     cannot move out of borrowed content
-   |           |     help: consider borrowing here: `&vs[0]`
+   |           --    ^^^^^ help: consider borrowing here: `&vs[0]`
+   |           |
    |           data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:102:11
-   |
-LL |     let X(_t) = vs[0];
-   |           ^^
+   |           move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:106:30
    |
 LL |     if let Either::One(_t) = vr[0] { }
-   |                        --    ^^^^^
-   |                        |     |
-   |                        |     cannot move out of borrowed content
-   |                        |     help: consider borrowing here: `&vr[0]`
+   |                        --    ^^^^^ help: consider borrowing here: `&vr[0]`
+   |                        |
    |                        data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:106:24
-   |
-LL |     if let Either::One(_t) = vr[0] { }
-   |                        ^^
+   |                        move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:110:33
    |
 LL |     while let Either::One(_t) = vr[0] { }
-   |                           --    ^^^^^
-   |                           |     |
-   |                           |     cannot move out of borrowed content
-   |                           |     help: consider borrowing here: `&vr[0]`
+   |                           --    ^^^^^ help: consider borrowing here: `&vr[0]`
+   |                           |
    |                           data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:110:27
-   |
-LL |     while let Either::One(_t) = vr[0] { }
-   |                           ^^
+   |                           move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:114:11
    |
 LL |     match vr[0] {
-   |           ^^^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider borrowing here: `&vr[0]`
+   |           ^^^^^ help: consider borrowing here: `&vr[0]`
 ...
 LL |         Either::One(_t)
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:118:21
-   |
-LL |         Either::One(_t)
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:121:11
    |
 LL |     match vr[0] {
-   |           ^^^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider borrowing here: `&vr[0]`
+   |           ^^^^^ help: consider borrowing here: `&vr[0]`
 ...
 LL |         Either::One(_t) => (),
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:125:21
-   |
-LL |         Either::One(_t) => (),
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<X>`
   --> $DIR/simple.rs:130:17
    |
 LL |     let X(_t) = vsm[0];
-   |           --    ^^^^^^
-   |           |     |
-   |           |     cannot move out of borrowed content
-   |           |     help: consider borrowing here: `&vsm[0]`
+   |           --    ^^^^^^ help: consider borrowing here: `&vsm[0]`
+   |           |
    |           data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:130:11
-   |
-LL |     let X(_t) = vsm[0];
-   |           ^^
+   |           move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:134:30
    |
 LL |     if let Either::One(_t) = vrm[0] { }
-   |                        --    ^^^^^^
-   |                        |     |
-   |                        |     cannot move out of borrowed content
-   |                        |     help: consider borrowing here: `&vrm[0]`
+   |                        --    ^^^^^^ help: consider borrowing here: `&vrm[0]`
+   |                        |
    |                        data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:134:24
-   |
-LL |     if let Either::One(_t) = vrm[0] { }
-   |                        ^^
+   |                        move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:138:33
    |
 LL |     while let Either::One(_t) = vrm[0] { }
-   |                           --    ^^^^^^
-   |                           |     |
-   |                           |     cannot move out of borrowed content
-   |                           |     help: consider borrowing here: `&vrm[0]`
+   |                           --    ^^^^^^ help: consider borrowing here: `&vrm[0]`
+   |                           |
    |                           data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:138:27
-   |
-LL |     while let Either::One(_t) = vrm[0] { }
-   |                           ^^
+   |                           move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:142:11
    |
 LL |     match vrm[0] {
-   |           ^^^^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider borrowing here: `&vrm[0]`
+   |           ^^^^^^ help: consider borrowing here: `&vrm[0]`
 ...
 LL |         Either::One(_t)
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:146:21
-   |
-LL |         Either::One(_t)
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:149:11
    |
 LL |     match vrm[0] {
-   |           ^^^^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider borrowing here: `&vrm[0]`
+   |           ^^^^^^ help: consider borrowing here: `&vrm[0]`
 ...
 LL |         Either::One(_t) => (),
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:153:21
-   |
-LL |         Either::One(_t) => (),
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of index of `std::vec::Vec<Either>`
   --> $DIR/simple.rs:157:11
    |
 LL |     match vrm[0] {
-   |           ^^^^^^
-   |           |
-   |           cannot move out of borrowed content
-   |           help: consider borrowing here: `&vrm[0]`
+   |           ^^^^^^ help: consider borrowing here: `&vrm[0]`
 ...
 LL |         Either::One(_t) => (),
-   |                     -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:161:21
-   |
-LL |         Either::One(_t) => (),
-   |                     ^^
+   |                     --
+   |                     |
+   |                     data moved here
+   |                     move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `s.0` which is behind a shared reference
   --> $DIR/simple.rs:168:18
    |
 LL |     let &X(_t) = s;
-   |         ------   ^ cannot move out of borrowed content
+   |         ------   ^
    |         |  |
    |         |  data moved here
+   |         |  move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `X(_t)`
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:168:12
-   |
-LL |     let &X(_t) = s;
-   |            ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:172:31
    |
 LL |     if let &Either::One(_t) = r { }
-   |            ----------------   ^ cannot move out of borrowed content
+   |            ----------------   ^
    |            |            |
    |            |            data moved here
+   |            |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |            help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:172:25
-   |
-LL |     if let &Either::One(_t) = r { }
-   |                         ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:176:34
    |
 LL |     while let &Either::One(_t) = r { }
-   |               ----------------   ^ cannot move out of borrowed content
+   |               ----------------   ^
    |               |            |
    |               |            data moved here
+   |               |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |               help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:176:28
-   |
-LL |     while let &Either::One(_t) = r { }
-   |                            ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:180:11
    |
 LL |     match r {
-   |           ^ cannot move out of borrowed content
+   |           ^
 LL |
 LL |         &Either::One(_t)
    |         ----------------
    |         |            |
    |         |            data moved here
+   |         |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:182:22
-   |
-LL |         &Either::One(_t)
-   |                      ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:188:11
    |
 LL |     match r {
-   |           ^ cannot move out of borrowed content
+   |           ^
 LL |
 LL |         &Either::One(_t) => (),
    |         ----------------
    |         |            |
    |         |            data moved here
+   |         |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:190:22
-   |
-LL |         &Either::One(_t) => (),
-   |                      ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `r.0` which is behind a shared reference
   --> $DIR/simple.rs:195:11
    |
 LL |     match r {
-   |           ^ cannot move out of borrowed content
+   |           ^
 LL |
 LL |         &Either::One(_t) => (),
    |         ----------------
    |         |            |
    |         |            data moved here
+   |         |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:197:22
-   |
-LL |         &Either::One(_t) => (),
-   |                      ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `sm.0` which is behind a mutable reference
   --> $DIR/simple.rs:207:22
    |
 LL |     let &mut X(_t) = sm;
-   |         ----------   ^^ cannot move out of borrowed content
+   |         ----------   ^^
    |         |      |
    |         |      data moved here
+   |         |      move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `X(_t)`
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:207:16
-   |
-LL |     let &mut X(_t) = sm;
-   |                ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:211:35
    |
 LL |     if let &mut Either::One(_t) = rm { }
-   |            --------------------   ^^ cannot move out of borrowed content
+   |            --------------------   ^^
    |            |                |
    |            |                data moved here
+   |            |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |            help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:211:29
-   |
-LL |     if let &mut Either::One(_t) = rm { }
-   |                             ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:215:38
    |
 LL |     while let &mut Either::One(_t) = rm { }
-   |               --------------------   ^^ cannot move out of borrowed content
+   |               --------------------   ^^
    |               |                |
    |               |                data moved here
+   |               |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |               help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:215:32
-   |
-LL |     while let &mut Either::One(_t) = rm { }
-   |                                ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:219:11
    |
 LL |     match rm {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |                          -- data moved here
@@ -543,164 +354,116 @@ help: consider removing the `&mut`
 LL |         Either::Two(_t) => (),
    |         ^^^^^^^^^^^^^^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:228:11
    |
 LL |     match rm {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:230:26
-   |
-LL |         &mut Either::One(_t) => (),
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:235:11
    |
 LL |     match rm {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:237:26
-   |
-LL |         &mut Either::One(_t) => (),
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `rm.0` which is behind a mutable reference
   --> $DIR/simple.rs:242:11
    |
 LL |     match rm {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:244:26
-   |
-LL |         &mut Either::One(_t) => (),
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:258:21
    |
 LL |     let (&X(_t),) = (&x.clone(),);
-   |             --      ^^^^^^^^^^^^^ cannot move out of borrowed content
+   |             --      ^^^^^^^^^^^^^
    |             |
    |             data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:258:13
-   |
-LL |     let (&X(_t),) = (&x.clone(),);
-   |             ^^
+   |             move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:260:34
    |
 LL |     if let (&Either::One(_t),) = (&e.clone(),) { }
-   |                          --      ^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                          --      ^^^^^^^^^^^^^
    |                          |
    |                          data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:260:26
-   |
-LL |     if let (&Either::One(_t),) = (&e.clone(),) { }
-   |                          ^^
+   |                          move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:262:37
    |
 LL |     while let (&Either::One(_t),) = (&e.clone(),) { }
-   |                             --      ^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                             --      ^^^^^^^^^^^^^
    |                             |
    |                             data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:262:29
-   |
-LL |     while let (&Either::One(_t),) = (&e.clone(),) { }
-   |                             ^^
+   |                             move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:264:11
    |
 LL |     match (&e.clone(),) {
-   |           ^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^
 LL |
 LL |         (&Either::One(_t),)
-   |                       -- data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:266:23
-   |
-LL |         (&Either::One(_t),)
-   |                       ^^
+   |                       --
+   |                       |
+   |                       data moved here
+   |                       move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:272:25
    |
 LL |     let (&mut X(_t),) = (&mut xm.clone(),);
-   |                 --      ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                 --      ^^^^^^^^^^^^^^^^^^
    |                 |
    |                 data moved here
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:272:17
-   |
-LL |     let (&mut X(_t),) = (&mut xm.clone(),);
-   |                 ^^
+   |                 move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:274:38
    |
 LL |     if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
-   |                              --      ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                              --      ^^^^^^^^^^^^^^^^^^
    |                              |
    |                              data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:274:30
-   |
-LL |     if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
-   |                              ^^
+   |                              move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:276:41
    |
 LL |     while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
-   |                                 --      ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |                                 --      ^^^^^^^^^^^^^^^^^^
    |                                 |
    |                                 data moved here
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:276:33
-   |
-LL |     while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
-   |                                 ^^
+   |                                 move occurs because `_t` has type `X`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:278:11
    |
 LL |     match (&mut em.clone(),) {
-   |           ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^^^^^^^^^^^^
 LL |
 LL |         (&mut Either::One(_t),) => (),
    |                           -- data moved here
@@ -715,283 +478,194 @@ LL |         (&mut Either::One(_t),) => (),
 LL |         (&mut Either::Two(_t),) => (),
    |                           ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:288:18
    |
 LL |     let &X(_t) = &x;
-   |         ------   ^^ cannot move out of borrowed content
+   |         ------   ^^
    |         |  |
    |         |  data moved here
+   |         |  move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `X(_t)`
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:288:12
-   |
-LL |     let &X(_t) = &x;
-   |            ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:292:31
    |
 LL |     if let &Either::One(_t) = &e { }
-   |            ----------------   ^^ cannot move out of borrowed content
+   |            ----------------   ^^
    |            |            |
    |            |            data moved here
+   |            |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |            help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:292:25
-   |
-LL |     if let &Either::One(_t) = &e { }
-   |                         ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:296:34
    |
 LL |     while let &Either::One(_t) = &e { }
-   |               ----------------   ^^ cannot move out of borrowed content
+   |               ----------------   ^^
    |               |            |
    |               |            data moved here
+   |               |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |               help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:296:28
-   |
-LL |     while let &Either::One(_t) = &e { }
-   |                            ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:300:11
    |
 LL |     match &e {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &Either::One(_t)
    |         ----------------
    |         |            |
    |         |            data moved here
+   |         |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:302:22
-   |
-LL |         &Either::One(_t)
-   |                      ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:308:11
    |
 LL |     match &e {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &Either::One(_t) => (),
    |         ----------------
    |         |            |
    |         |            data moved here
+   |         |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:310:22
-   |
-LL |         &Either::One(_t) => (),
-   |                      ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:315:11
    |
 LL |     match &e {
-   |           ^^ cannot move out of borrowed content
+   |           ^^
 LL |
 LL |         &Either::One(_t) => (),
    |         ----------------
    |         |            |
    |         |            data moved here
+   |         |            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:317:22
-   |
-LL |         &Either::One(_t) => (),
-   |                      ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:323:22
    |
 LL |     let &mut X(_t) = &mut xm;
-   |         ----------   ^^^^^^^ cannot move out of borrowed content
+   |         ----------   ^^^^^^^
    |         |      |
    |         |      data moved here
+   |         |      move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `X(_t)`
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:323:16
-   |
-LL |     let &mut X(_t) = &mut xm;
-   |                ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:327:35
    |
 LL |     if let &mut Either::One(_t) = &mut em { }
-   |            --------------------   ^^^^^^^ cannot move out of borrowed content
+   |            --------------------   ^^^^^^^
    |            |                |
    |            |                data moved here
+   |            |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |            help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:327:29
-   |
-LL |     if let &mut Either::One(_t) = &mut em { }
-   |                             ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:331:38
    |
 LL |     while let &mut Either::One(_t) = &mut em { }
-   |               --------------------   ^^^^^^^ cannot move out of borrowed content
+   |               --------------------   ^^^^^^^
    |               |                |
    |               |                data moved here
+   |               |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |               help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:331:32
-   |
-LL |     while let &mut Either::One(_t) = &mut em { }
-   |                                ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:335:11
    |
 LL |     match &mut em {
-   |           ^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^
 LL |
 LL |         &mut Either::One(_t)
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:337:26
-   |
-LL |         &mut Either::One(_t)
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:343:11
    |
 LL |     match &mut em {
-   |           ^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:345:26
-   |
-LL |         &mut Either::One(_t) => (),
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:350:11
    |
 LL |     match &mut em {
-   |           ^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:352:26
-   |
-LL |         &mut Either::One(_t) => (),
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:357:11
    |
 LL |     match &mut em {
-   |           ^^^^^^^ cannot move out of borrowed content
+   |           ^^^^^^^
 LL |
 LL |         &mut Either::One(_t) => (),
    |         --------------------
    |         |                |
    |         |                data moved here
+   |         |                move occurs because `_t` has type `X`, which does not implement the `Copy` trait
    |         help: consider removing the `&mut`: `Either::One(_t)`
-   |
-note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:359:26
-   |
-LL |         &mut Either::One(_t) => (),
-   |                          ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:202:11
    |
 LL |     fn f1(&X(_t): &X) { }
    |           ^^^--^
    |           |  |
    |           |  data moved here
-   |           cannot move out of borrowed content
+   |           |  move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |           help: consider removing the `&`: `X(_t)`
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:202:14
-   |
-LL |     fn f1(&X(_t): &X) { }
-   |              ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:249:11
    |
 LL |     fn f2(&mut X(_t): &mut X) { }
    |           ^^^^^^^--^
    |           |      |
    |           |      data moved here
-   |           cannot move out of borrowed content
+   |           |      move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
    |           help: consider removing the `&mut`: `X(_t)`
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:249:18
-   |
-LL |     fn f2(&mut X(_t): &mut X) { }
-   |                  ^^
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a shared reference
   --> $DIR/simple.rs:269:11
    |
 LL |     fn f3((&X(_t),): (&X,)) { }
    |           ^^^^--^^^
-   |           |   |
-   |           |   data moved here
-   |           cannot move out of borrowed content
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:269:15
-   |
-LL |     fn f3((&X(_t),): (&X,)) { }
-   |               ^^
+   |               |
+   |               data moved here
+   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of a mutable reference
   --> $DIR/simple.rs:283:11
    |
 LL |     fn f4((&mut X(_t),): (&mut X,)) { }
    |           ^^^^^^^^--^^^
-   |           |       |
-   |           |       data moved here
-   |           cannot move out of borrowed content
-   |
-note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/simple.rs:283:19
-   |
-LL |     fn f4((&mut X(_t),): (&mut X,)) { }
-   |                   ^^
+   |                   |
+   |                   data moved here
+   |                   move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
 
 error: aborting due to 60 previous errors
 
diff --git a/src/test/ui/suggestions/option-content-move.fixed b/src/test/ui/suggestions/option-content-move.fixed
index f163cd104ff..ba16bcc8a33 100644
--- a/src/test/ui/suggestions/option-content-move.fixed
+++ b/src/test/ui/suggestions/option-content-move.fixed
@@ -9,7 +9,7 @@ impl LipogramCorpora {
         for selection in &self.selections {
             if selection.1.is_some() {
                 if selection.1.as_ref().unwrap().contains(selection.0) {
-                //~^ ERROR cannot move out of borrowed content
+                //~^ ERROR cannot move out of `selection.1`
                     return Err(selection.0);
                 }
             }
@@ -27,7 +27,7 @@ impl LipogramCorpora2 {
         for selection in &self.selections {
             if selection.1.is_ok() {
                 if selection.1.as_ref().unwrap().contains(selection.0) {
-                //~^ ERROR cannot move out of borrowed content
+                //~^ ERROR cannot move out of `selection.1`
                     return Err(selection.0);
                 }
             }
diff --git a/src/test/ui/suggestions/option-content-move.rs b/src/test/ui/suggestions/option-content-move.rs
index 350486a802d..ef38f114eca 100644
--- a/src/test/ui/suggestions/option-content-move.rs
+++ b/src/test/ui/suggestions/option-content-move.rs
@@ -9,7 +9,7 @@ impl LipogramCorpora {
         for selection in &self.selections {
             if selection.1.is_some() {
                 if selection.1.unwrap().contains(selection.0) {
-                //~^ ERROR cannot move out of borrowed content
+                //~^ ERROR cannot move out of `selection.1`
                     return Err(selection.0);
                 }
             }
@@ -27,7 +27,7 @@ impl LipogramCorpora2 {
         for selection in &self.selections {
             if selection.1.is_ok() {
                 if selection.1.unwrap().contains(selection.0) {
-                //~^ ERROR cannot move out of borrowed content
+                //~^ ERROR cannot move out of `selection.1`
                     return Err(selection.0);
                 }
             }
diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr
index 0a325ac54ea..c842e7b2930 100644
--- a/src/test/ui/suggestions/option-content-move.stderr
+++ b/src/test/ui/suggestions/option-content-move.stderr
@@ -1,19 +1,19 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `selection.1` which is behind a shared reference
   --> $DIR/option-content-move.rs:11:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
    |                    ^^^^^^^^^^^
    |                    |
-   |                    cannot move out of borrowed content
+   |                    move occurs because `selection.1` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait
    |                    help: consider borrowing the `Option`'s content: `selection.1.as_ref()`
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `selection.1` which is behind a shared reference
   --> $DIR/option-content-move.rs:29:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
    |                    ^^^^^^^^^^^
    |                    |
-   |                    cannot move out of borrowed content
+   |                    move occurs because `selection.1` has type `std::result::Result<std::string::String, std::string::String>`, which does not implement the `Copy` trait
    |                    help: consider borrowing the `Result`'s content: `selection.1.as_ref()`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr
index 68d8129843e..e96a2419686 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak-copy.stderr
@@ -1,8 +1,8 @@
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*t` which is behind a shared reference
   --> $DIR/trivial-bounds-leak-copy.rs:9:5
    |
 LL |     *t
-   |     ^^ cannot move out of borrowed content
+   |     ^^ move occurs because `*t` has type `std::string::String`, which does not implement the `Copy` trait
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
index 934d057ea09..58062872aa3 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
@@ -1,34 +1,34 @@
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closure-illegal-move.rs:15:31
    |
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn(|| drop(x));
-   |                               ^ cannot move out of captured variable in an `Fn` closure
+   |                               ^ move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:19:35
    |
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn_mut(|| drop(x));
-   |                                   ^ cannot move out of captured variable in an `FnMut` closure
+   |                                   ^ move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `Fn` closure
+error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closure-illegal-move.rs:28:36
    |
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn(move || drop(x));
-   |                                    ^ cannot move out of captured variable in an `Fn` closure
+   |                                    ^ move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of captured variable in an `FnMut` closure
+error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:32:40
    |
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn_mut(move || drop(x));
-   |                                        ^ cannot move out of captured variable in an `FnMut` closure
+   |                                        ^ move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/unop-move-semantics.rs b/src/test/ui/unop-move-semantics.rs
index 80f737e6c4e..8168da8242f 100644
--- a/src/test/ui/unop-move-semantics.rs
+++ b/src/test/ui/unop-move-semantics.rs
@@ -21,9 +21,9 @@ fn illegal_dereference<T: Not<Output=T>>(mut x: T, y: T) {
     let m = &mut x;
     let n = &y;
 
-    !*m;  //~ ERROR: cannot move out of borrowed content
+    !*m;  //~ ERROR: cannot move out of `*m`
 
-    !*n;  //~ ERROR: cannot move out of borrowed content
+    !*n;  //~ ERROR: cannot move out of `*n`
     use_imm(n); use_mut(m);
 }
 fn main() {}
diff --git a/src/test/ui/unop-move-semantics.stderr b/src/test/ui/unop-move-semantics.stderr
index 5122d16bd93..6aa3d0b0989 100644
--- a/src/test/ui/unop-move-semantics.stderr
+++ b/src/test/ui/unop-move-semantics.stderr
@@ -34,17 +34,17 @@ LL |     !y;
 LL |     use_mut(n); use_imm(m);
    |             - borrow later used here
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*m` which is behind a mutable reference
   --> $DIR/unop-move-semantics.rs:24:6
    |
 LL |     !*m;
-   |      ^^ cannot move out of borrowed content
+   |      ^^ move occurs because `*m` has type `T`, which does not implement the `Copy` trait
 
-error[E0507]: cannot move out of borrowed content
+error[E0507]: cannot move out of `*n` which is behind a shared reference
   --> $DIR/unop-move-semantics.rs:26:6
    |
 LL |     !*n;
-   |      ^^ cannot move out of borrowed content
+   |      ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/unsized-locals/unsized-exprs2.stderr b/src/test/ui/unsized-locals/unsized-exprs2.stderr
index a94414ef560..650285cb674 100644
--- a/src/test/ui/unsized-locals/unsized-exprs2.stderr
+++ b/src/test/ui/unsized-locals/unsized-exprs2.stderr
@@ -2,7 +2,10 @@ error[E0508]: cannot move out of type `[u8]`, a non-copy slice
   --> $DIR/unsized-exprs2.rs:22:19
    |
 LL |     udrop::<[u8]>(foo()[..]);
-   |                   ^^^^^^^^^ cannot move out of here
+   |                   ^^^^^^^^^
+   |                   |
+   |                   cannot move out of here
+   |                   move occurs because value has type `[u8]`, which does not implement the `Copy` trait
 
 error: aborting due to previous error