From 656db98bd99caf7e5c5e81ad11ed8922e28c46fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 15 Jan 2023 03:06:44 +0000
Subject: [PATCH 01/16] Tweak E0597

CC #99430
---
 .../rustc_borrowck/src/borrowck_errors.rs     |   6 +-
 .../src/diagnostics/conflict_errors.rs        |   2 +-
 .../src/diagnostics/explain_borrow.rs         |  28 +++++
 .../src/diagnostics/move_errors.rs            |   2 +-
 .../src/traits/error_reporting/mod.rs         |   2 +-
 tests/ui/asm/type-check-4.stderr              |   6 +-
 .../associated-types-outlives.stderr          |   3 +
 ...sue-74072-lifetime-name-annotations.stderr |  16 +--
 .../issue-75785-confusing-named-region.stderr |   4 +-
 .../multiple-lifetimes/ret-ref.stderr         |  12 +-
 tests/ui/augmented-assignments.rs             |   2 +-
 tests/ui/augmented-assignments.stderr         |   2 +
 tests/ui/binop/binop-move-semantics.stderr    |   5 +
 .../borrowck-anon-fields-variant.stderr       |   4 +-
 tests/ui/borrowck/borrowck-assign-comp.stderr |  12 +-
 ...ck-assign-to-andmut-in-borrowed-loc.stderr |   6 +-
 .../borrowck-closures-mut-and-imm.stderr      |  16 +--
 .../borrowck/borrowck-describe-lvalue.stderr  |  42 +++----
 ...m-ref-to-mut-rec-field-issue-3162-c.stderr |   4 +-
 tests/ui/borrowck/borrowck-issue-14498.stderr |  32 +++---
 .../borrowck/borrowck-lend-flow-match.stderr  |   4 +-
 .../borrowck-loan-blocks-move-cc.stderr       |   4 +
 .../borrowck/borrowck-loan-blocks-move.stderr |   2 +
 ...wck-loan-of-static-data-issue-27616.stderr |   4 +-
 .../borrowck-loan-rcvr-overloaded-op.stderr   |   2 +-
 .../borrowck-match-already-borrowed.stderr    |   8 +-
 .../borrowck/borrowck-move-by-capture.stderr  |   2 +-
 ...-move-from-subpath-of-borrowed-path.stderr |   2 +
 .../borrowck-move-subcomponent.stderr         |   2 +
 .../borrowck-multiple-captures.stderr         |   6 +
 ...erloaded-index-and-overloaded-deref.stderr |   4 +-
 ...borrowck-overloaded-index-autoderef.stderr |  16 +--
 ...orrowck-overloaded-index-move-index.stderr |   4 +
 .../borrowck-pat-reassign-binding.stderr      |   4 +-
 .../borrowck-union-borrow-nested.stderr       |   2 +-
 .../ui/borrowck/borrowck-union-borrow.stderr  |  20 ++--
 .../borrowck/borrowck-use-mut-borrow.stderr   |  18 +--
 .../borrowck-vec-pattern-move-tail.stderr     |   4 +-
 .../borrowck/borrowck-vec-pattern-nesting.rs  |   8 +-
 .../borrowck-vec-pattern-nesting.stderr       |   8 +-
 tests/ui/borrowck/issue-25793.stderr          |   2 +-
 tests/ui/borrowck/issue-52713-bug.stderr      |   4 +-
 ...issue-58776-borrowck-scans-children.stderr |   4 +-
 tests/ui/borrowck/issue-81365-1.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-10.stderr       |   4 +-
 tests/ui/borrowck/issue-81365-11.stderr       |   4 +-
 tests/ui/borrowck/issue-81365-2.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-3.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-4.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-5.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-6.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-7.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-8.stderr        |   4 +-
 tests/ui/borrowck/issue-81365-9.stderr        |   4 +-
 ...ccess-during-reservation.nll_target.stderr |   4 +-
 .../two-phase-surprise-no-conflict.stderr     |   2 +-
 tests/ui/btreemap/btreemap_dropck.stderr      |   2 +
 tests/ui/c-variadic/variadic-ffi-4.stderr     |   4 +-
 .../diagnostics/arrays.stderr                 |  14 +--
 .../diagnostics/box.stderr                    |   8 +-
 .../diagnostics/union.rs                      |   4 +-
 .../diagnostics/union.stderr                  |   4 +-
 .../coerce-overloaded-autoderef-fail.stderr   |   4 +-
 tests/ui/consts/promote_const_let.stderr      |   1 +
 .../dropck-eyepatch-extern-crate.stderr       |   6 +
 .../ui/dropck/dropck-eyepatch-reorder.stderr  |   6 +
 tests/ui/dropck/dropck-eyepatch.stderr        |   6 +
 tests/ui/dropck/dropck-union.stderr           |   2 +
 .../dropck/dropck_trait_cycle_checked.stderr  |  12 +-
 tests/ui/dst/dst-bad-coerce3.stderr           |  10 +-
 tests/ui/error-codes/E0503.stderr             |   2 +-
 tests/ui/error-codes/E0504.stderr             |   2 +
 tests/ui/error-codes/E0505.stderr             |   3 +
 tests/ui/error-codes/E0506.stderr             |   4 +-
 tests/ui/error-codes/E0597.stderr             |   2 +
 ...ied-bounds-unnorm-associated-type-4.stderr |   2 +
 ...plied-bounds-unnorm-associated-type.stderr |   2 +
 .../issue-74684-1.stderr                      |   1 +
 .../hrtb-identity-fn-borrows.stderr           |   4 +-
 .../feature-self-return-type.stderr           |   3 +
 .../assoc-ty-wf-used-to-get-assoc-ty.stderr   |   2 +
 .../const-expr-lifetime-err.stderr            |   1 +
 tests/ui/issues/issue-40288.stderr            |   4 +-
 tests/ui/issues/issue-45697-1.stderr          |   6 +-
 tests/ui/issues/issue-45697.stderr            |   6 +-
 tests/ui/issues/issue-46471-1.stderr          |   7 +-
 ...600-expected-return-static-indirect.stderr |   2 +
 .../mut-pattern-internal-mutability.stderr    |   4 +-
 tests/ui/nll/borrowed-local-error.stderr      |   1 +
 .../ui/nll/borrowed-match-issue-45045.stderr  |   2 +-
 tests/ui/nll/capture-ref-in-struct.stderr     |   3 +
 tests/ui/nll/closure-access-spans.stderr      |   4 +-
 tests/ui/nll/closure-borrow-spans.stderr      |  14 +--
 .../escape-argument.stderr                    |   3 +
 ...er-to-static-comparing-against-free.stderr |   2 +
 tests/ui/nll/closure-use-spans.stderr         |  12 +-
 ...ignore-lifetime-bounds-in-copy-proj.stderr |   2 +
 ...-not-ignore-lifetime-bounds-in-copy.stderr |   2 +
 tests/ui/nll/dont-print-desugared.stderr      |   1 +
 tests/ui/nll/drop-no-may-dangle.stderr        |   8 +-
 tests/ui/nll/guarantor-issue-46974.stderr     |   4 +-
 ...issue-27282-move-ref-mut-into-guard.stderr |   4 +-
 .../nll/issue-27282-mutation-in-guard.stderr  |   4 +-
 tests/ui/nll/issue-27868.stderr               |   4 +-
 tests/ui/nll/issue-46036.stderr               |   2 +
 tests/ui/nll/issue-48803.stderr               |   4 +-
 tests/ui/nll/issue-52534-2.stderr             |   2 +
 tests/ui/nll/issue-52663-trait-object.stderr  |   2 +
 ...sue-54382-use-span-of-tail-of-block.stderr |   3 +
 tests/ui/nll/issue-54556-stephaneyfx.stderr   |   2 +
 ...ssue-54556-temps-in-tail-diagnostic.stderr |   3 +
 .../issue-54556-used-vs-unused-tails.stderr   | 103 ++++++++++--------
 tests/ui/nll/issue-54556-wrap-it-up.stderr    |   4 +-
 tests/ui/nll/issue-55511.stderr               |   2 +
 tests/ui/nll/issue-57989.stderr               |   4 +-
 tests/ui/nll/issue-68550.stderr               |   4 +-
 tests/ui/nll/issue-69114-static-mut-ty.stderr |   6 +
 tests/ui/nll/issue-69114-static-ty.stderr     |   2 +
 tests/ui/nll/loan_ends_mid_block_pair.stderr  |   4 +-
 .../nll/local-outlives-static-via-hrtb.stderr |   5 +
 tests/ui/nll/match-cfg-fake-edges2.stderr     |   2 +-
 .../ui/nll/match-guards-always-borrow.stderr  |   4 +-
 .../nll/match-guards-partially-borrow.stderr  |   8 +-
 tests/ui/nll/match-on-borrowed.stderr         |   6 +-
 ...ialized-drop-implicit-fragment-drop.stderr |   4 +-
 ...aybe-initialized-drop-with-fragment.stderr |   4 +-
 ...d-drop-with-uninitialized-fragments.stderr |   4 +-
 tests/ui/nll/maybe-initialized-drop.stderr    |   4 +-
 .../nll/polonius/polonius-smoke-test.stderr   |   2 +-
 tests/ui/nll/promoted-bounds.stderr           |   1 +
 ...erence-carried-through-struct-field.stderr |   2 +-
 .../nll/relate_tys/var-appears-twice.stderr   |   3 +
 .../user-annotations/adt-brace-enums.stderr   |   3 +
 .../user-annotations/adt-brace-structs.stderr |   3 +
 .../user-annotations/adt-nullary-enums.stderr |   6 +-
 .../user-annotations/adt-tuple-enums.stderr   |   3 +
 .../adt-tuple-struct-calls.stderr             |   7 +-
 .../user-annotations/adt-tuple-struct.stderr  |   3 +
 .../cast_static_lifetime.stderr               |   2 +
 .../constant-in-expr-inherent-2.stderr        |  11 ++
 tests/ui/nll/user-annotations/fns.stderr      |   3 +
 .../nll/user-annotations/method-call.stderr   |   4 +
 .../nll/user-annotations/method-ufcs-1.stderr |   5 +
 .../nll/user-annotations/method-ufcs-2.stderr |   8 +-
 .../nll/user-annotations/method-ufcs-3.stderr |   4 +
 .../method-ufcs-inherent-1.stderr             |   1 +
 .../method-ufcs-inherent-2.stderr             |   2 +
 .../method-ufcs-inherent-3.stderr             |   1 +
 .../method-ufcs-inherent-4.stderr             |   2 +
 .../nll/user-annotations/normalization.stderr |   4 +
 ...attern_substs_on_brace_enum_variant.stderr |   4 +
 .../pattern_substs_on_brace_struct.stderr     |   4 +
 ...attern_substs_on_tuple_enum_variant.stderr |   4 +
 .../pattern_substs_on_tuple_struct.stderr     |   4 +
 tests/ui/nll/user-annotations/patterns.stderr |  24 ++++
 .../promoted-annotation.stderr                |   1 +
 .../type_ascription_static_lifetime.stderr    |   2 +
 .../borrowck-move-ref-pattern.stderr          |   2 +
 ...suggest-adding-bound-to-opaque-type.stderr |   2 +
 tests/ui/regions/regions-addr-of-arg.stderr   |   2 +
 ...egions-free-region-ordering-caller1.stderr |   2 +
 .../regions-infer-proc-static-upvar.stderr    |   2 +
 tests/ui/regions/regions-nested-fns.stderr    |   2 +
 .../regions-pattern-typing-issue-19552.stderr |   2 +
 .../regions-pattern-typing-issue-19997.stderr |   4 +-
 .../borrowck-non-exhaustive.stderr            |   2 +-
 .../lifetime-update.stderr                    |   3 +
 tests/ui/self/issue-61882-2.stderr            |   2 +
 ...borrowck-call-is-borrow-issue-12224.stderr |   3 +
 tests/ui/span/dropck_arr_cycle_checked.stderr |   9 ++
 .../span/dropck_direct_cycle_with_drop.stderr |   5 +
 tests/ui/span/dropck_misc_variants.stderr     |   6 +
 tests/ui/span/dropck_vec_cycle_checked.stderr |   9 ++
 ...5-dropck-child-has-items-via-parent.stderr |   3 +
 .../issue-24805-dropck-trait-has-items.stderr |   9 ++
 .../span/issue-24895-copy-clone-dropck.stderr |   3 +
 tests/ui/span/issue-25199.stderr              |   2 +
 tests/ui/span/issue-26656.stderr              |   3 +
 tests/ui/span/issue-29106.stderr              |   6 +
 tests/ui/span/issue-36537.stderr              |   2 +
 tests/ui/span/issue-40157.stderr              |   8 +-
 .../issue28498-reject-lifetime-param.stderr   |   3 +
 .../issue28498-reject-passed-to-fn.stderr     |   3 +
 .../span/issue28498-reject-trait-bound.stderr |   3 +
 tests/ui/span/mut-ptr-cant-outlive-ref.stderr |   2 +
 tests/ui/span/range-2.stderr                  |   8 +-
 .../regionck-unboxed-closure-lifetimes.stderr |   2 +
 ...regions-close-over-type-parameter-2.stderr |   2 +
 .../regions-escape-loop-via-variable.stderr   |   4 +-
 .../span/regions-escape-loop-via-vec.stderr   |  13 +--
 .../send-is-not-static-ensures-scoping.stderr |   1 +
 .../span/send-is-not-static-std-sync-2.stderr |   6 +-
 .../span/send-is-not-static-std-sync.stderr   |   6 +
 .../vec-must-not-hide-type-from-dropck.stderr |   6 +
 .../vec_refs_data_with_early_death.stderr     |   6 +
 .../span/wf-method-late-bound-regions.stderr  |   1 +
 tests/ui/static/static-lifetime-bound.stderr  |   2 +
 .../suggestions/borrow-for-loop-head.stderr   |   2 +
 .../suggestions/option-content-move2.stderr   |   2 +-
 .../check-trait-object-bounds-3.stderr        |   2 +
 .../ui/traits/coercion-generic-regions.stderr |   2 +
 tests/ui/traits/vtable/issue-97381.stderr     |   3 +
 .../try-block/try-block-bad-lifetime.stderr   |   9 +-
 .../try-block-maybe-bad-lifetime.stderr       |   8 +-
 .../unboxed-closures-borrow-conflict.stderr   |   2 +-
 ...oxed-closures-failed-recursive-fn-1.stderr |   8 +-
 tests/ui/unop-move-semantics.stderr           |   5 +
 tests/ui/variance/variance-issue-20533.stderr |   6 +
 208 files changed, 772 insertions(+), 349 deletions(-)

diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index a4943d112042d..2bbb9618dbf09 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -37,7 +37,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
             desc,
         );
 
-        err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_desc));
+        err.span_label(borrow_span, format!("{} is borrowed here", borrow_desc));
         err.span_label(span, format!("use of borrowed {}", borrow_desc));
         err
     }
@@ -250,8 +250,8 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
             desc,
         );
 
-        err.span_label(borrow_span, format!("borrow of {} occurs here", desc));
-        err.span_label(span, format!("assignment to borrowed {} occurs here", desc));
+        err.span_label(borrow_span, format!("{} is borrowed here", desc));
+        err.span_label(span, format!("{} is assigned to here but it was already borrowed", desc));
         err
     }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 968c1f49b95c0..0ab8aabd63bd0 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1742,7 +1742,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 &self.local_names,
                 &mut err,
                 "",
-                None,
+                Some(borrow_span),
                 None,
             );
         }
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 2095747097b76..e4f45c53aefe5 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -1,6 +1,8 @@
 //! Print diagnostics to explain why values are borrowed.
 
 use rustc_errors::{Applicability, Diagnostic};
+use rustc_hir as hir;
+use rustc_hir::intravisit::Visitor;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_middle::mir::{
@@ -11,6 +13,7 @@ use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::{self, RegionVid, TyCtxt};
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::{sym, DesugaringKind, Span};
+use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
 
 use crate::region_infer::{BlameConstraint, ExtraConstraintInfo};
 use crate::{
@@ -63,6 +66,31 @@ impl<'tcx> BorrowExplanation<'tcx> {
         borrow_span: Option<Span>,
         multiple_borrow_span: Option<(Span, Span)>,
     ) {
+        if let Some(span) = borrow_span {
+            let def_id = body.source.def_id();
+            if let Some(node) = tcx.hir().get_if_local(def_id)
+                && let Some(body_id) = node.body_id()
+            {
+                let body = tcx.hir().body(body_id);
+                let mut expr_finder = FindExprBySpan::new(span);
+                expr_finder.visit_expr(body.value);
+                if let Some(mut expr) = expr_finder.result {
+                    while let hir::ExprKind::AddrOf(_, _, inner) = &expr.kind {
+                        expr = inner;
+                    }
+                    if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
+                        && let [hir::PathSegment { ident, args: None, .. }] = p.segments
+                        && let hir::def::Res::Local(hir_id) = p.res
+                        && let Some(hir::Node::Pat(pat)) = tcx.hir().find(hir_id)
+                    {
+                        err.span_label(
+                            pat.span,
+                            &format!("binding `{ident}` declared here"),
+                        );
+                    }
+                }
+            }
+        }
         match *self {
             BorrowExplanation::UsedLater(later_use_kind, var_or_use_span, path_span) => {
                 let message = match later_use_kind {
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 6db3c858ae714..ea58ad5ae3e34 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -448,7 +448,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 };
                 self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), "");
 
-                use_spans.args_span_label(err, format!("move out of {place_desc} occurs here"));
+                use_spans.args_span_label(err, format!("{place_desc} is moved here"));
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index edd187b8dec3b..c3d097b5d7559 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2827,7 +2827,7 @@ pub struct FindExprBySpan<'hir> {
 }
 
 impl<'hir> FindExprBySpan<'hir> {
-    fn new(span: Span) -> Self {
+    pub fn new(span: Span) -> Self {
         Self { span, result: None, ty_result: None }
     }
 }
diff --git a/tests/ui/asm/type-check-4.stderr b/tests/ui/asm/type-check-4.stderr
index c97cd171b1e38..b5ecb3e1b56fb 100644
--- a/tests/ui/asm/type-check-4.stderr
+++ b/tests/ui/asm/type-check-4.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `a` because it is borrowed
   --> $DIR/type-check-4.rs:14:9
    |
 LL |         let p = &a;
-   |                 -- borrow of `a` occurs here
+   |                 -- `a` is borrowed here
 LL |         asm!("{}", out(reg) a);
-   |         ^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `a` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^ `a` is assigned to here but it was already borrowed
 LL |
 LL |         println!("{}", p);
    |                        - borrow later used here
@@ -13,7 +13,7 @@ error[E0503]: cannot use `a` because it was mutably borrowed
   --> $DIR/type-check-4.rs:22:28
    |
 LL |         let p = &mut a;
-   |                 ------ borrow of `a` occurs here
+   |                 ------ `a` is borrowed here
 LL |         asm!("{}", in(reg) a);
    |                            ^ use of borrowed `a`
 LL |
diff --git a/tests/ui/associated-types/associated-types-outlives.stderr b/tests/ui/associated-types/associated-types-outlives.stderr
index 840e33b4b8a8e..2fe3f2d4a0250 100644
--- a/tests/ui/associated-types/associated-types-outlives.stderr
+++ b/tests/ui/associated-types/associated-types-outlives.stderr
@@ -1,6 +1,9 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/associated-types-outlives.rs:22:14
    |
+LL |                     F: for<'a> FnOnce(<T as Foo<'a>>::Bar)>(x: T, f: F) {
+   |                                                             - binding `x` declared here
+...
 LL |         's: loop { y = denormalise(&x); break }
    |                                    -- borrow of `x` occurs here
 LL |         drop(x);
diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr
index b96cab9f0f51a..628ba1a481893 100644
--- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr
+++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr
@@ -4,9 +4,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
 LL | pub async fn async_fn(x: &mut i32) -> &i32 {
    |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
-   |             --- borrow of `*x` occurs here
+   |             --- `*x` is borrowed here
 LL |     *x += 1;
-   |     ^^^^^^^ assignment to borrowed `*x` occurs here
+   |     ^^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |     y
    |     - returning this value requires that `*x` is borrowed for `'1`
 
@@ -14,9 +14,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:16:9
    |
 LL |         let y = &*x;
-   |                 --- borrow of `*x` occurs here
+   |                 --- `*x` is borrowed here
 LL |         *x += 1;
-   |         ^^^^^^^ assignment to borrowed `*x` occurs here
+   |         ^^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |         y
    |         - returning this value requires that `*x` is borrowed for `'1`
 LL |     })()
@@ -28,9 +28,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
 LL |     (async move || -> &i32 {
    |                       - let's call the lifetime of this reference `'1`
 LL |         let y = &*x;
-   |                 --- borrow of `*x` occurs here
+   |                 --- `*x` is borrowed here
 LL |         *x += 1;
-   |         ^^^^^^^ assignment to borrowed `*x` occurs here
+   |         ^^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |         y
    |         - returning this value requires that `*x` is borrowed for `'1`
 
@@ -38,9 +38,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:32:9
    |
 LL |         let y = &*x;
-   |                 --- borrow of `*x` occurs here
+   |                 --- `*x` is borrowed here
 LL |         *x += 1;
-   |         ^^^^^^^ assignment to borrowed `*x` occurs here
+   |         ^^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |         y
    |         - returning this value requires that `*x` is borrowed for `'1`
 LL |     }
diff --git a/tests/ui/async-await/issue-75785-confusing-named-region.stderr b/tests/ui/async-await/issue-75785-confusing-named-region.stderr
index 3b731d9c60a6a..b69033a0eda0b 100644
--- a/tests/ui/async-await/issue-75785-confusing-named-region.stderr
+++ b/tests/ui/async-await/issue-75785-confusing-named-region.stderr
@@ -4,9 +4,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
 LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
    |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
-   |             --- borrow of `*x` occurs here
+   |             --- `*x` is borrowed here
 LL |     *x += 1;
-   |     ^^^^^^^ assignment to borrowed `*x` occurs here
+   |     ^^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |     (&32, y)
    |     -------- returning this value requires that `*x` is borrowed for `'1`
 
diff --git a/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr b/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr
index d86e84033b8cd..a599ac1d92f83 100644
--- a/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr
+++ b/tests/ui/async-await/multiple-lifetimes/ret-ref.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `a` because it is borrowed
   --> $DIR/ret-ref.rs:16:5
    |
 LL |     let future = multiple_named_lifetimes(&a, &b);
-   |                                           -- borrow of `a` occurs here
+   |                                           -- `a` is borrowed here
 LL |     a += 1;
-   |     ^^^^^^ assignment to borrowed `a` occurs here
+   |     ^^^^^^ `a` is assigned to here but it was already borrowed
 LL |     b += 1;
 LL |     let p = future.await;
    |             ------ borrow later used here
@@ -13,10 +13,10 @@ error[E0506]: cannot assign to `b` because it is borrowed
   --> $DIR/ret-ref.rs:17:5
    |
 LL |     let future = multiple_named_lifetimes(&a, &b);
-   |                                               -- borrow of `b` occurs here
+   |                                               -- `b` is borrowed here
 LL |     a += 1;
 LL |     b += 1;
-   |     ^^^^^^ assignment to borrowed `b` occurs here
+   |     ^^^^^^ `b` is assigned to here but it was already borrowed
 LL |     let p = future.await;
    |             ------ borrow later used here
 
@@ -24,10 +24,10 @@ error[E0506]: cannot assign to `a` because it is borrowed
   --> $DIR/ret-ref.rs:28:5
    |
 LL |     let future = multiple_named_lifetimes(&a, &b);
-   |                                           -- borrow of `a` occurs here
+   |                                           -- `a` is borrowed here
 LL |     let p = future.await;
 LL |     a += 1;
-   |     ^^^^^^ assignment to borrowed `a` occurs here
+   |     ^^^^^^ `a` is assigned to here but it was already borrowed
 LL |     b += 1;
 LL |     drop(p);
    |          - borrow later used here
diff --git a/tests/ui/augmented-assignments.rs b/tests/ui/augmented-assignments.rs
index 20c7fb3a98395..bd2435a78bf22 100644
--- a/tests/ui/augmented-assignments.rs
+++ b/tests/ui/augmented-assignments.rs
@@ -9,7 +9,7 @@ impl AddAssign for Int {
 }
 
 fn main() {
-    let mut x = Int(1);
+    let mut x = Int(1); //~ NOTE binding `x` declared here
     x
     //~^ NOTE borrow of `x` occurs here
     +=
diff --git a/tests/ui/augmented-assignments.stderr b/tests/ui/augmented-assignments.stderr
index 2910c910d5524..d1096aea2794e 100644
--- a/tests/ui/augmented-assignments.stderr
+++ b/tests/ui/augmented-assignments.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/augmented-assignments.rs:16:5
    |
+LL |     let mut x = Int(1);
+   |         ----- binding `x` declared here
 LL |     x
    |     - borrow of `x` occurs here
 ...
diff --git a/tests/ui/binop/binop-move-semantics.stderr b/tests/ui/binop/binop-move-semantics.stderr
index dae267da05d17..8645169b98ac9 100644
--- a/tests/ui/binop/binop-move-semantics.stderr
+++ b/tests/ui/binop/binop-move-semantics.stderr
@@ -41,6 +41,8 @@ LL | fn move_then_borrow<T: Add<Output=()> + Clone + Copy>(x: T) {
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/binop-move-semantics.rs:21:5
    |
+LL | fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {
+   |                                     - binding `x` declared here
 LL |     let m = &x;
    |             -- borrow of `x` occurs here
 ...
@@ -53,6 +55,9 @@ LL |     use_mut(n); use_imm(m);
 error[E0505]: cannot move out of `y` because it is borrowed
   --> $DIR/binop-move-semantics.rs:23:5
    |
+LL | fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {
+   |                                           ----- binding `y` declared here
+LL |     let m = &x;
 LL |     let n = &mut y;
    |             ------ borrow of `y` occurs here
 ...
diff --git a/tests/ui/borrowck/borrowck-anon-fields-variant.stderr b/tests/ui/borrowck/borrowck-anon-fields-variant.stderr
index 98f6f00a7d48b..c1d668f74efb9 100644
--- a/tests/ui/borrowck/borrowck-anon-fields-variant.stderr
+++ b/tests/ui/borrowck/borrowck-anon-fields-variant.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `y` because it was mutably borrowed
   --> $DIR/borrowck-anon-fields-variant.rs:16:19
    |
 LL |       Foo::Y(ref mut a, _) => a,
-   |              --------- borrow of `y.0` occurs here
+   |              --------- `y.0` is borrowed here
 ...
 LL |     let b = match y {
    |                   ^ use of borrowed `y.0`
@@ -14,7 +14,7 @@ error[E0503]: cannot use `y` because it was mutably borrowed
   --> $DIR/borrowck-anon-fields-variant.rs:34:19
    |
 LL |       Foo::Y(ref mut a, _) => a,
-   |              --------- borrow of `y.0` occurs here
+   |              --------- `y.0` is borrowed here
 ...
 LL |     let b = match y {
    |                   ^ use of borrowed `y.0`
diff --git a/tests/ui/borrowck/borrowck-assign-comp.stderr b/tests/ui/borrowck/borrowck-assign-comp.stderr
index 2b7cef7b3253b..d35f2331a76f4 100644
--- a/tests/ui/borrowck/borrowck-assign-comp.stderr
+++ b/tests/ui/borrowck/borrowck-assign-comp.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `p.x` because it is borrowed
   --> $DIR/borrowck-assign-comp.rs:10:5
    |
 LL |     let q = &p;
-   |             -- borrow of `p.x` occurs here
+   |             -- `p.x` is borrowed here
 ...
 LL |     p.x = 5;
-   |     ^^^^^^^ assignment to borrowed `p.x` occurs here
+   |     ^^^^^^^ `p.x` is assigned to here but it was already borrowed
 LL |     q.x;
    |     --- borrow later used here
 
@@ -13,9 +13,9 @@ error[E0506]: cannot assign to `p` because it is borrowed
   --> $DIR/borrowck-assign-comp.rs:20:5
    |
 LL |     let q = &p.y;
-   |             ---- borrow of `p` occurs here
+   |             ---- `p` is borrowed here
 LL |     p = Point {x: 5, y: 7};
-   |     ^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `p` occurs here
+   |     ^^^^^^^^^^^^^^^^^^^^^^ `p` is assigned to here but it was already borrowed
 LL |     p.x; // silence warning
 LL |     *q; // stretch loan
    |     -- borrow later used here
@@ -24,9 +24,9 @@ error[E0506]: cannot assign to `p.y` because it is borrowed
   --> $DIR/borrowck-assign-comp.rs:31:5
    |
 LL |     let q = &p.y;
-   |             ---- borrow of `p.y` occurs here
+   |             ---- `p.y` is borrowed here
 LL |     p.y = 5;
-   |     ^^^^^^^ assignment to borrowed `p.y` occurs here
+   |     ^^^^^^^ `p.y` is assigned to here but it was already borrowed
 LL |     *q;
    |     -- borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.stderr b/tests/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.stderr
index 0b21d113f74ee..8c0a8efcc1828 100644
--- a/tests/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.stderr
+++ b/tests/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `*y.pointer` because it was mutably borrowed
   --> $DIR/borrowck-assign-to-andmut-in-borrowed-loc.rs:18:9
    |
 LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `y` occurs here
+   |                                   ------ `y` is borrowed here
 LL |         *y.pointer += 1;
    |         ^^^^^^^^^^^^^^^ use of borrowed `y`
 ...
@@ -13,9 +13,9 @@ error[E0506]: cannot assign to `*y.pointer` because it is borrowed
   --> $DIR/borrowck-assign-to-andmut-in-borrowed-loc.rs:18:9
    |
 LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `*y.pointer` occurs here
+   |                                   ------ `*y.pointer` is borrowed here
 LL |         *y.pointer += 1;
-   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
+   |         ^^^^^^^^^^^^^^^ `*y.pointer` is assigned to here but it was already borrowed
 ...
 LL |         *z.pointer += 1;
    |         --------------- borrow later used here
diff --git a/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr b/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr
index fadcd11a592aa..8a7870e0c44af 100644
--- a/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr
+++ b/tests/ui/borrowck/borrowck-closures-mut-and-imm.stderr
@@ -49,9 +49,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
 LL |     let c2 = || x * 5;
    |              -- - borrow occurs due to use in closure
    |              |
-   |              borrow of `x` occurs here
+   |              `x` is borrowed here
 LL |     x = 5;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |
 LL |     drop(c2);
    |          -- borrow later used here
@@ -62,9 +62,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
 LL |     let c1 = || get(&x);
    |              --      - borrow occurs due to use in closure
    |              |
-   |              borrow of `x` occurs here
+   |              `x` is borrowed here
 LL |     x = 5;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |
 LL |     drop(c1);
    |          -- borrow later used here
@@ -75,9 +75,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
 LL |     let c1 = || get(&*x);
    |              --      -- borrow occurs due to use in closure
    |              |
-   |              borrow of `*x` occurs here
+   |              `*x` is borrowed here
 LL |     *x = 5;
-   |     ^^^^^^ assignment to borrowed `*x` occurs here
+   |     ^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |
 LL |     drop(c1);
    |          -- borrow later used here
@@ -88,9 +88,9 @@ error[E0506]: cannot assign to `*x.f` because it is borrowed
 LL |     let c1 = || get(&*x.f);
    |              --      ---- borrow occurs due to use in closure
    |              |
-   |              borrow of `*x.f` occurs here
+   |              `*x.f` is borrowed here
 LL |     *x.f = 5;
-   |     ^^^^^^^^ assignment to borrowed `*x.f` occurs here
+   |     ^^^^^^^^ `*x.f` is assigned to here but it was already borrowed
 LL |
 LL |     drop(c1);
    |          -- borrow later used here
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.stderr b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
index 2c1b9c10d4660..cb29c9fdac3c6 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -45,7 +45,7 @@ error[E0503]: cannot use `f.x` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:37:9
    |
 LL |         let x = f.x();
-   |                 ----- borrow of `f` occurs here
+   |                 ----- `f` is borrowed here
 LL |         f.x;
    |         ^^^ use of borrowed `f`
 LL |         drop(x);
@@ -55,7 +55,7 @@ error[E0503]: cannot use `g.0` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:44:9
    |
 LL |         let x = g.x();
-   |                 ----- borrow of `g` occurs here
+   |                 ----- `g` is borrowed here
 LL |         g.0;
    |         ^^^ use of borrowed `g`
 LL |         drop(x);
@@ -65,7 +65,7 @@ error[E0503]: cannot use `h.0` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:51:9
    |
 LL |         let x = &mut h.0;
-   |                 -------- borrow of `h.0` occurs here
+   |                 -------- `h.0` is borrowed here
 LL |         h.0;
    |         ^^^ use of borrowed `h.0`
 LL |         drop(x);
@@ -75,7 +75,7 @@ error[E0503]: cannot use `e.0` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:59:20
    |
 LL |         let x = e.x();
-   |                 ----- borrow of `e` occurs here
+   |                 ----- `e` is borrowed here
 LL |         match e {
 LL |             Baz::X(value) => value
    |                    ^^^^^ use of borrowed `e`
@@ -87,7 +87,7 @@ error[E0503]: cannot use `u.a` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:67:9
    |
 LL |         let x = &mut u.a;
-   |                 -------- borrow of `u.a` occurs here
+   |                 -------- `u.a` is borrowed here
 LL |         u.a;
    |         ^^^ use of borrowed `u.a`
 LL |         drop(x);
@@ -97,7 +97,7 @@ error[E0503]: cannot use `f.x` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:74:9
    |
 LL |         let x = f.x();
-   |                 ----- borrow of `*f` occurs here
+   |                 ----- `*f` is borrowed here
 LL |         f.x;
    |         ^^^ use of borrowed `*f`
 LL |         drop(x);
@@ -107,7 +107,7 @@ error[E0503]: cannot use `g.0` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:81:9
    |
 LL |         let x = g.x();
-   |                 ----- borrow of `*g` occurs here
+   |                 ----- `*g` is borrowed here
 LL |         g.0;
    |         ^^^ use of borrowed `*g`
 LL |         drop(x);
@@ -117,7 +117,7 @@ error[E0503]: cannot use `h.0` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:88:9
    |
 LL |         let x = &mut h.0;
-   |                 -------- borrow of `h.0` occurs here
+   |                 -------- `h.0` is borrowed here
 LL |         h.0;
    |         ^^^ use of borrowed `h.0`
 LL |         drop(x);
@@ -127,7 +127,7 @@ error[E0503]: cannot use `e.0` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:96:20
    |
 LL |         let x = e.x();
-   |                 ----- borrow of `*e` occurs here
+   |                 ----- `*e` is borrowed here
 LL |         match *e {
 LL |             Baz::X(value) => value
    |                    ^^^^^ use of borrowed `*e`
@@ -139,7 +139,7 @@ error[E0503]: cannot use `u.a` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:105:9
    |
 LL |         let x = &mut u.a;
-   |                 -------- borrow of `u.a` occurs here
+   |                 -------- `u.a` is borrowed here
 LL |         u.a;
    |         ^^^ use of borrowed `u.a`
 LL |         drop(x);
@@ -149,7 +149,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:113:15
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 LL |         match v {
 LL |             &[x, _, .., _, _] => println!("{}", x),
    |               ^ use of borrowed `v`
@@ -161,7 +161,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:118:18
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 ...
 LL |             &[_, x, .., _, _] => println!("{}", x),
    |                  ^ use of borrowed `v`
@@ -173,7 +173,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:123:25
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 ...
 LL |             &[_, _, .., x, _] => println!("{}", x),
    |                         ^ use of borrowed `v`
@@ -185,7 +185,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:128:28
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 ...
 LL |             &[_, _, .., _, x] => println!("{}", x),
    |                            ^ use of borrowed `v`
@@ -197,7 +197,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:139:15
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 LL |         match v {
 LL |             &[x @ ..] => println!("{:?}", x),
    |               ^ use of borrowed `v`
@@ -209,7 +209,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:144:18
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 ...
 LL |             &[_, x @ ..] => println!("{:?}", x),
    |                  ^ use of borrowed `v`
@@ -221,7 +221,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:149:15
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 ...
 LL |             &[x @ .., _] => println!("{:?}", x),
    |               ^ use of borrowed `v`
@@ -233,7 +233,7 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:154:18
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 ...
 LL |             &[_, x @ .., _] => println!("{:?}", x),
    |                  ^ use of borrowed `v`
@@ -245,7 +245,7 @@ error[E0503]: cannot use `e` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:166:15
    |
 LL |         let x = &mut e;
-   |                 ------ borrow of `e` occurs here
+   |                 ------ `e` is borrowed here
 LL |         match e {
    |               ^ use of borrowed `e`
 ...
@@ -304,7 +304,7 @@ error[E0503]: cannot use `*v` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:232:9
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 LL |         v[0].y;
    |         ^^^^ use of borrowed `v`
 ...
@@ -315,7 +315,7 @@ error[E0503]: cannot use `v[_].y` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:232:9
    |
 LL |         let x = &mut v;
-   |                 ------ borrow of `v` occurs here
+   |                 ------ `v` is borrowed here
 LL |         v[0].y;
    |         ^^^^^^ use of borrowed `v`
 ...
diff --git a/tests/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.stderr b/tests/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.stderr
index a66db05ccc5fc..1a20ec85fc00f 100644
--- a/tests/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.stderr
+++ b/tests/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `_a` because it is borrowed
   --> $DIR/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs:6:9
    |
 LL |     let b = &mut _a;
-   |             ------- borrow of `_a` occurs here
+   |             ------- `_a` is borrowed here
 ...
 LL |         _a = 4;
-   |         ^^^^^^ assignment to borrowed `_a` occurs here
+   |         ^^^^^^ `_a` is assigned to here but it was already borrowed
 ...
 LL |     drop(b);
    |          - borrow later used here
diff --git a/tests/ui/borrowck/borrowck-issue-14498.stderr b/tests/ui/borrowck/borrowck-issue-14498.stderr
index 42a55b7a854ba..374c5ee3ed27b 100644
--- a/tests/ui/borrowck/borrowck-issue-14498.stderr
+++ b/tests/ui/borrowck/borrowck-issue-14498.stderr
@@ -13,10 +13,10 @@ error[E0506]: cannot assign to `**y` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:25:5
    |
 LL |     let p = &y;
-   |             -- borrow of `**y` occurs here
+   |             -- `**y` is borrowed here
 LL |     let q = &***p;
 LL |     **y = 2;
-   |     ^^^^^^^ assignment to borrowed `**y` occurs here
+   |     ^^^^^^^ `**y` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -24,10 +24,10 @@ error[E0506]: cannot assign to `**y` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:35:5
    |
 LL |     let p = &y;
-   |             -- borrow of `**y` occurs here
+   |             -- `**y` is borrowed here
 LL |     let q = &***p;
 LL |     **y = 2;
-   |     ^^^^^^^ assignment to borrowed `**y` occurs here
+   |     ^^^^^^^ `**y` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -35,10 +35,10 @@ error[E0506]: cannot assign to `**y` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:45:5
    |
 LL |     let p = &y;
-   |             -- borrow of `**y` occurs here
+   |             -- `**y` is borrowed here
 LL |     let q = &***p;
 LL |     **y = 2;
-   |     ^^^^^^^ assignment to borrowed `**y` occurs here
+   |     ^^^^^^^ `**y` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -46,10 +46,10 @@ error[E0506]: cannot assign to `**y` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:55:5
    |
 LL |     let p = &y;
-   |             -- borrow of `**y` occurs here
+   |             -- `**y` is borrowed here
 LL |     let q = &***p;
 LL |     **y = 2;
-   |     ^^^^^^^ assignment to borrowed `**y` occurs here
+   |     ^^^^^^^ `**y` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -57,10 +57,10 @@ error[E0506]: cannot assign to `**y.a` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:65:5
    |
 LL |     let p = &y.a;
-   |             ---- borrow of `**y.a` occurs here
+   |             ---- `**y.a` is borrowed here
 LL |     let q = &***p;
 LL |     **y.a = 2;
-   |     ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
+   |     ^^^^^^^^^ `**y.a` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -68,10 +68,10 @@ error[E0506]: cannot assign to `**y.a` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:75:5
    |
 LL |     let p = &y.a;
-   |             ---- borrow of `**y.a` occurs here
+   |             ---- `**y.a` is borrowed here
 LL |     let q = &***p;
 LL |     **y.a = 2;
-   |     ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
+   |     ^^^^^^^^^ `**y.a` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -79,10 +79,10 @@ error[E0506]: cannot assign to `**y.a` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:85:5
    |
 LL |     let p = &y.a;
-   |             ---- borrow of `**y.a` occurs here
+   |             ---- `**y.a` is borrowed here
 LL |     let q = &***p;
 LL |     **y.a = 2;
-   |     ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
+   |     ^^^^^^^^^ `**y.a` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
@@ -90,10 +90,10 @@ error[E0506]: cannot assign to `**y.a` because it is borrowed
   --> $DIR/borrowck-issue-14498.rs:95:5
    |
 LL |     let p = &y.a;
-   |             ---- borrow of `**y.a` occurs here
+   |             ---- `**y.a` is borrowed here
 LL |     let q = &***p;
 LL |     **y.a = 2;
-   |     ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
+   |     ^^^^^^^^^ `**y.a` is assigned to here but it was already borrowed
 LL |     drop(p);
    |          - borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-lend-flow-match.stderr b/tests/ui/borrowck/borrowck-lend-flow-match.stderr
index 66f1cd9bd5664..6cdce7bee8897 100644
--- a/tests/ui/borrowck/borrowck-lend-flow-match.stderr
+++ b/tests/ui/borrowck/borrowck-lend-flow-match.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/borrowck-lend-flow-match.rs:12:13
    |
 LL |         Some(ref r) => {
-   |              ----- borrow of `x` occurs here
+   |              ----- `x` is borrowed here
 LL |             x = Some(1);
-   |             ^^^^^^^^^^^ assignment to borrowed `x` occurs here
+   |             ^^^^^^^^^^^ `x` is assigned to here but it was already borrowed
 LL |             drop(r);
    |                  - borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr b/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr
index 3548da35b6139..6eabfff9054c4 100644
--- a/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr
+++ b/tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `v` because it is borrowed
   --> $DIR/borrowck-loan-blocks-move-cc.rs:14:19
    |
+LL |     let v: Box<_> = Box::new(3);
+   |         - binding `v` declared here
 LL |     let w = &v;
    |             -- borrow of `v` occurs here
 LL |     thread::spawn(move|| {
@@ -15,6 +17,8 @@ LL |     w.use_ref();
 error[E0505]: cannot move out of `v` because it is borrowed
   --> $DIR/borrowck-loan-blocks-move-cc.rs:24:19
    |
+LL |     let v: Box<_> = Box::new(3);
+   |         - binding `v` declared here
 LL |     let w = &v;
    |             -- borrow of `v` occurs here
 LL |     thread::spawn(move|| {
diff --git a/tests/ui/borrowck/borrowck-loan-blocks-move.stderr b/tests/ui/borrowck/borrowck-loan-blocks-move.stderr
index b5c6b101f765c..38e06fa018786 100644
--- a/tests/ui/borrowck/borrowck-loan-blocks-move.stderr
+++ b/tests/ui/borrowck/borrowck-loan-blocks-move.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `v` because it is borrowed
   --> $DIR/borrowck-loan-blocks-move.rs:11:10
    |
+LL |     let v = Box::new(3);
+   |         - binding `v` declared here
 LL |     let w = &v;
    |             -- borrow of `v` occurs here
 LL |     take(v);
diff --git a/tests/ui/borrowck/borrowck-loan-of-static-data-issue-27616.stderr b/tests/ui/borrowck/borrowck-loan-of-static-data-issue-27616.stderr
index 6994c837dfcbe..311369a260d76 100644
--- a/tests/ui/borrowck/borrowck-loan-of-static-data-issue-27616.stderr
+++ b/tests/ui/borrowck/borrowck-loan-of-static-data-issue-27616.stderr
@@ -2,12 +2,12 @@ error[E0506]: cannot assign to `*s` because it is borrowed
   --> $DIR/borrowck-loan-of-static-data-issue-27616.rs:16:5
    |
 LL |     let alias: &'static mut String = s;
-   |                -------------------   - borrow of `*s` occurs here
+   |                -------------------   - `*s` is borrowed here
    |                |
    |                type annotation requires that `*s` is borrowed for `'static`
 ...
 LL |     *s = String::new();
-   |     ^^ assignment to borrowed `*s` occurs here
+   |     ^^ `*s` is assigned to here but it was already borrowed
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/borrowck-loan-rcvr-overloaded-op.stderr b/tests/ui/borrowck/borrowck-loan-rcvr-overloaded-op.stderr
index 24cc4933ef1b0..f1640d3b7776f 100644
--- a/tests/ui/borrowck/borrowck-loan-rcvr-overloaded-op.stderr
+++ b/tests/ui/borrowck/borrowck-loan-rcvr-overloaded-op.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `p` because it was mutably borrowed
   --> $DIR/borrowck-loan-rcvr-overloaded-op.rs:38:5
    |
 LL |     let q = &mut p;
-   |             ------ borrow of `p` occurs here
+   |             ------ `p` is borrowed here
 LL |
 LL |     p + 3;
    |     ^ use of borrowed `p`
diff --git a/tests/ui/borrowck/borrowck-match-already-borrowed.stderr b/tests/ui/borrowck/borrowck-match-already-borrowed.stderr
index 39047be9de670..e5c0ec960a4a7 100644
--- a/tests/ui/borrowck/borrowck-match-already-borrowed.stderr
+++ b/tests/ui/borrowck/borrowck-match-already-borrowed.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `foo` because it was mutably borrowed
   --> $DIR/borrowck-match-already-borrowed.rs:9:19
    |
 LL |     let p = &mut foo;
-   |             -------- borrow of `foo` occurs here
+   |             -------- `foo` is borrowed here
 LL |     let _ = match foo {
    |                   ^^^ use of borrowed `foo`
 ...
@@ -13,7 +13,7 @@ error[E0503]: cannot use `foo.0` because it was mutably borrowed
   --> $DIR/borrowck-match-already-borrowed.rs:12:16
    |
 LL |     let p = &mut foo;
-   |             -------- borrow of `foo` occurs here
+   |             -------- `foo` is borrowed here
 ...
 LL |         Foo::A(x) => x
    |                ^ use of borrowed `foo`
@@ -25,7 +25,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/borrowck-match-already-borrowed.rs:22:9
    |
 LL |     let r = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     let _ = match x {
 LL |         x => x + 1,
    |         ^ use of borrowed `x`
@@ -37,7 +37,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/borrowck-match-already-borrowed.rs:23:9
    |
 LL |     let r = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 ...
 LL |         y => y + 2,
    |         ^ use of borrowed `x`
diff --git a/tests/ui/borrowck/borrowck-move-by-capture.stderr b/tests/ui/borrowck/borrowck-move-by-capture.stderr
index 8ddc48b2a99cd..6eaa1fa316932 100644
--- a/tests/ui/borrowck/borrowck-move-by-capture.stderr
+++ b/tests/ui/borrowck/borrowck-move-by-capture.stderr
@@ -10,7 +10,7 @@ LL |         let _h = to_fn_once(move || -> isize { *bar });
    |                             |                  |
    |                             |                  variable moved due to use in closure
    |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
-   |                             move out of `bar` occurs here
+   |                             `bar` is moved here
 
 error: aborting due to previous error
 
diff --git a/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr b/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr
index f833abcc02acf..bd94f1a4299b8 100644
--- a/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr
+++ b/tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `*a` because it is borrowed
   --> $DIR/borrowck-move-from-subpath-of-borrowed-path.rs:12:13
    |
+LL |     let a: Box<Box<_>> = Box::new(Box::new(2));
+   |         - binding `a` declared here
 LL |     let b = &a;
    |             -- borrow of `a` occurs here
 LL |
diff --git a/tests/ui/borrowck/borrowck-move-subcomponent.stderr b/tests/ui/borrowck/borrowck-move-subcomponent.stderr
index 8c9083fcf1356..341146bd18fd9 100644
--- a/tests/ui/borrowck/borrowck-move-subcomponent.stderr
+++ b/tests/ui/borrowck/borrowck-move-subcomponent.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `a.x` because it is borrowed
   --> $DIR/borrowck-move-subcomponent.rs:15:14
    |
+LL |   let a : S = S { x : Box::new(1) };
+   |       - binding `a` declared here
 LL |   let pb = &a;
    |            -- borrow of `a` occurs here
 LL |   let S { x: ax } = a;
diff --git a/tests/ui/borrowck/borrowck-multiple-captures.stderr b/tests/ui/borrowck/borrowck-multiple-captures.stderr
index f94cbc30db421..70abe7b346e1a 100644
--- a/tests/ui/borrowck/borrowck-multiple-captures.stderr
+++ b/tests/ui/borrowck/borrowck-multiple-captures.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `x1` because it is borrowed
   --> $DIR/borrowck-multiple-captures.rs:12:19
    |
+LL |     let x1: Box<_> = Box::new(1);
+   |         -- binding `x1` declared here
 LL |     let p1 = &x1;
    |              --- borrow of `x1` occurs here
 ...
@@ -16,6 +18,8 @@ LL |     borrow(&*p1);
 error[E0505]: cannot move out of `x2` because it is borrowed
   --> $DIR/borrowck-multiple-captures.rs:12:19
    |
+LL |     let x2: Box<_> = Box::new(2);
+   |         -- binding `x2` declared here
 LL |     let p2 = &x2;
    |              --- borrow of `x2` occurs here
 LL |     thread::spawn(move|| {
@@ -77,6 +81,8 @@ LL |         drop(x);
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/borrowck-multiple-captures.rs:38:19
    |
+LL |     let x: Box<_> = Box::new(1);
+   |         - binding `x` declared here
 LL |     let p = &x;
    |             -- borrow of `x` occurs here
 LL |     thread::spawn(move|| {
diff --git a/tests/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.stderr b/tests/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.stderr
index 5d52e49191831..7f42becd21c2a 100644
--- a/tests/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.stderr
+++ b/tests/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `v` because it is borrowed
   --> $DIR/borrowck-overloaded-index-and-overloaded-deref.rs:31:5
    |
 LL |     let i = &v[0].f;
-   |              - borrow of `v` occurs here
+   |              - `v` is borrowed here
 LL |     v = MyVec { x: MyPtr { x: Foo { f: 23 } } };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `v` occurs here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `v` is assigned to here but it was already borrowed
 LL |
 LL |     read(*i);
    |          -- borrow later used here
diff --git a/tests/ui/borrowck/borrowck-overloaded-index-autoderef.stderr b/tests/ui/borrowck/borrowck-overloaded-index-autoderef.stderr
index 087f2ac799eeb..fb7af50bcb565 100644
--- a/tests/ui/borrowck/borrowck-overloaded-index-autoderef.stderr
+++ b/tests/ui/borrowck/borrowck-overloaded-index-autoderef.stderr
@@ -42,9 +42,9 @@ error[E0506]: cannot assign to `f.foo` because it is borrowed
   --> $DIR/borrowck-overloaded-index-autoderef.rs:71:5
    |
 LL |     let p = &f.foo[&s];
-   |              ----- borrow of `f.foo` occurs here
+   |              ----- `f.foo` is borrowed here
 LL |     f.foo = g;
-   |     ^^^^^^^^^ assignment to borrowed `f.foo` occurs here
+   |     ^^^^^^^^^ `f.foo` is assigned to here but it was already borrowed
 LL |     p.use_ref();
    |     ----------- borrow later used here
 
@@ -52,9 +52,9 @@ error[E0506]: cannot assign to `*f` because it is borrowed
   --> $DIR/borrowck-overloaded-index-autoderef.rs:77:5
    |
 LL |     let p = &f.foo[&s];
-   |              ----- borrow of `*f` occurs here
+   |              ----- `*f` is borrowed here
 LL |     *f = g;
-   |     ^^^^^^ assignment to borrowed `*f` occurs here
+   |     ^^^^^^ `*f` is assigned to here but it was already borrowed
 LL |     p.use_ref();
    |     ----------- borrow later used here
 
@@ -62,9 +62,9 @@ error[E0506]: cannot assign to `f.foo` because it is borrowed
   --> $DIR/borrowck-overloaded-index-autoderef.rs:83:5
    |
 LL |     let p = &mut f.foo[&s];
-   |                  ----- borrow of `f.foo` occurs here
+   |                  ----- `f.foo` is borrowed here
 LL |     f.foo = g;
-   |     ^^^^^^^^^ assignment to borrowed `f.foo` occurs here
+   |     ^^^^^^^^^ `f.foo` is assigned to here but it was already borrowed
 LL |     p.use_mut();
    |     ----------- borrow later used here
 
@@ -72,9 +72,9 @@ error[E0506]: cannot assign to `*f` because it is borrowed
   --> $DIR/borrowck-overloaded-index-autoderef.rs:89:5
    |
 LL |     let p = &mut f.foo[&s];
-   |                  ----- borrow of `*f` occurs here
+   |                  ----- `*f` is borrowed here
 LL |     *f = g;
-   |     ^^^^^^ assignment to borrowed `*f` occurs here
+   |     ^^^^^^ `*f` is assigned to here but it was already borrowed
 LL |     p.use_mut();
    |     ----------- borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-overloaded-index-move-index.stderr b/tests/ui/borrowck/borrowck-overloaded-index-move-index.stderr
index fb0e274c2919a..7f8cc74a7157a 100644
--- a/tests/ui/borrowck/borrowck-overloaded-index-move-index.stderr
+++ b/tests/ui/borrowck/borrowck-overloaded-index-move-index.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `s` because it is borrowed
   --> $DIR/borrowck-overloaded-index-move-index.rs:50:22
    |
+LL |     let mut s = "hello".to_string();
+   |         ----- binding `s` declared here
 LL |     let rs = &mut s;
    |              ------ borrow of `s` occurs here
 LL |
@@ -13,6 +15,8 @@ LL |     use_mut(rs);
 error[E0505]: cannot move out of `s` because it is borrowed
   --> $DIR/borrowck-overloaded-index-move-index.rs:53:7
    |
+LL |     let mut s = "hello".to_string();
+   |         ----- binding `s` declared here
 LL |     let rs = &mut s;
    |              ------ borrow of `s` occurs here
 ...
diff --git a/tests/ui/borrowck/borrowck-pat-reassign-binding.stderr b/tests/ui/borrowck/borrowck-pat-reassign-binding.stderr
index 9e65ccf5a1913..b86a8693881a9 100644
--- a/tests/ui/borrowck/borrowck-pat-reassign-binding.stderr
+++ b/tests/ui/borrowck/borrowck-pat-reassign-binding.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/borrowck-pat-reassign-binding.rs:10:11
    |
 LL |       Some(ref i) => {
-   |            ----- borrow of `x` occurs here
+   |            ----- `x` is borrowed here
 LL |           // But on this branch, `i` is an outstanding borrow
 LL |           x = Some(*i+1);
-   |           ^^^^^^^^^^^^^^ assignment to borrowed `x` occurs here
+   |           ^^^^^^^^^^^^^^ `x` is assigned to here but it was already borrowed
 LL |           drop(i);
    |                - borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-union-borrow-nested.stderr b/tests/ui/borrowck/borrowck-union-borrow-nested.stderr
index 4bd7d54cffeda..a87a14e7cabd8 100644
--- a/tests/ui/borrowck/borrowck-union-borrow-nested.stderr
+++ b/tests/ui/borrowck/borrowck-union-borrow-nested.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `u.c` because it was mutably borrowed
   --> $DIR/borrowck-union-borrow-nested.rs:24:21
    |
 LL |             let ra = &mut u.s.a;
-   |                      ---------- borrow of `u.s.a` occurs here
+   |                      ---------- `u.s.a` is borrowed here
 LL |             let b = u.c;
    |                     ^^^ use of borrowed `u.s.a`
 LL |             ra.use_mut();
diff --git a/tests/ui/borrowck/borrowck-union-borrow.stderr b/tests/ui/borrowck/borrowck-union-borrow.stderr
index 090c7b6b51a31..11a28f6744b70 100644
--- a/tests/ui/borrowck/borrowck-union-borrow.stderr
+++ b/tests/ui/borrowck/borrowck-union-borrow.stderr
@@ -12,9 +12,9 @@ error[E0506]: cannot assign to `u.a` because it is borrowed
   --> $DIR/borrowck-union-borrow.rs:28:13
    |
 LL |             let ra = &u.a;
-   |                      ---- borrow of `u.a` occurs here
+   |                      ---- `u.a` is borrowed here
 LL |             u.a = 1;
-   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
+   |             ^^^^^^^ `u.a` is assigned to here but it was already borrowed
 LL |             drop(ra);
    |                  -- borrow later used here
 
@@ -34,9 +34,9 @@ error[E0506]: cannot assign to `u.b` because it is borrowed
   --> $DIR/borrowck-union-borrow.rs:49:13
    |
 LL |             let ra = &u.a;
-   |                      ---- borrow of `u.b` occurs here
+   |                      ---- `u.b` is borrowed here
 LL |             u.b = 1;
-   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
+   |             ^^^^^^^ `u.b` is assigned to here but it was already borrowed
 LL |             drop(ra);
    |                  -- borrow later used here
 
@@ -54,7 +54,7 @@ error[E0503]: cannot use `u.a` because it was mutably borrowed
   --> $DIR/borrowck-union-borrow.rs:60:21
    |
 LL |             let ra = &mut u.a;
-   |                      -------- borrow of `u.a` occurs here
+   |                      -------- `u.a` is borrowed here
 LL |             let a = u.a;
    |                     ^^^ use of borrowed `u.a`
 LL |             drop(ra);
@@ -74,9 +74,9 @@ error[E0506]: cannot assign to `u.a` because it is borrowed
   --> $DIR/borrowck-union-borrow.rs:70:13
    |
 LL |             let rma = &mut u.a;
-   |                       -------- borrow of `u.a` occurs here
+   |                       -------- `u.a` is borrowed here
 LL |             u.a = 1;
-   |             ^^^^^^^ assignment to borrowed `u.a` occurs here
+   |             ^^^^^^^ `u.a` is assigned to here but it was already borrowed
 LL |             drop(rma);
    |                  --- borrow later used here
 
@@ -96,7 +96,7 @@ error[E0503]: cannot use `u.b` because it was mutably borrowed
   --> $DIR/borrowck-union-borrow.rs:81:21
    |
 LL |             let ra = &mut u.a;
-   |                      -------- borrow of `u.a` occurs here
+   |                      -------- `u.a` is borrowed here
 LL |             let b = u.b;
    |                     ^^^ use of borrowed `u.a`
 LL |
@@ -119,9 +119,9 @@ error[E0506]: cannot assign to `u.b` because it is borrowed
   --> $DIR/borrowck-union-borrow.rs:92:13
    |
 LL |             let rma = &mut u.a;
-   |                       -------- borrow of `u.b` occurs here
+   |                       -------- `u.b` is borrowed here
 LL |             u.b = 1;
-   |             ^^^^^^^ assignment to borrowed `u.b` occurs here
+   |             ^^^^^^^ `u.b` is assigned to here but it was already borrowed
 LL |             drop(rma);
    |                  --- borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow.stderr b/tests/ui/borrowck/borrowck-use-mut-borrow.stderr
index 91d69c51e8180..4d300ae3c527b 100644
--- a/tests/ui/borrowck/borrowck-use-mut-borrow.stderr
+++ b/tests/ui/borrowck/borrowck-use-mut-borrow.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:11:10
    |
 LL |     let p = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     drop(x);
    |          ^ use of borrowed `x`
 LL |     *p = 2;
@@ -12,7 +12,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:18:10
    |
 LL |     let p = &mut x.a;
-   |             -------- borrow of `x.a` occurs here
+   |             -------- `x.a` is borrowed here
 LL |     drop(x);
    |          ^ use of borrowed `x.a`
 LL |     *p = 3;
@@ -22,7 +22,7 @@ error[E0503]: cannot use `x.a` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:25:10
    |
 LL |     let p = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     drop(x.a);
    |          ^^^ use of borrowed `x`
 LL |     p.a = 3;
@@ -32,7 +32,7 @@ error[E0503]: cannot use `x.a` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:32:10
    |
 LL |     let p = &mut x.a;
-   |             -------- borrow of `x.a` occurs here
+   |             -------- `x.a` is borrowed here
 LL |     drop(x.a);
    |          ^^^ use of borrowed `x.a`
 LL |     *p = 3;
@@ -42,7 +42,7 @@ error[E0503]: cannot use `x.a` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:39:13
    |
 LL |     let p = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     let y = A { b: 3, .. x };
    |             ^^^^^^^^^^^^^^^^ use of borrowed `x`
 LL |     drop(y);
@@ -53,7 +53,7 @@ error[E0503]: cannot use `x.a` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:47:13
    |
 LL |     let p = &mut x.a;
-   |             -------- borrow of `x.a` occurs here
+   |             -------- `x.a` is borrowed here
 LL |     let y = A { b: 3, .. x };
    |             ^^^^^^^^^^^^^^^^ use of borrowed `x.a`
 LL |     drop(y);
@@ -64,7 +64,7 @@ error[E0503]: cannot use `*x` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:55:10
    |
 LL |     let p = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     drop(*x);
    |          ^^ use of borrowed `x`
 LL |     **p = 2;
@@ -74,7 +74,7 @@ error[E0503]: cannot use `*x.b` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:62:10
    |
 LL |     let p = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     drop(*x.b);
    |          ^^^^ use of borrowed `x`
 LL |     p.a = 3;
@@ -84,7 +84,7 @@ error[E0503]: cannot use `*x.b` because it was mutably borrowed
   --> $DIR/borrowck-use-mut-borrow.rs:69:10
    |
 LL |     let p = &mut x.b;
-   |             -------- borrow of `x.b` occurs here
+   |             -------- `x.b` is borrowed here
 LL |     drop(*x.b);
    |          ^^^^ use of borrowed `x.b`
 LL |     **p = 3;
diff --git a/tests/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/tests/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
index 0ac7df944d781..494d8c351a152 100644
--- a/tests/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
+++ b/tests/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed
   --> $DIR/borrowck-vec-pattern-move-tail.rs:8:5
    |
 LL |         [1, 2, ref tail @ ..] => tail,
-   |                -------- borrow of `a[_]` occurs here
+   |                -------- `a[_]` is borrowed here
 ...
 LL |     a[2] = 0;
-   |     ^^^^^^^^ assignment to borrowed `a[_]` occurs here
+   |     ^^^^^^^^ `a[_]` is assigned to here but it was already borrowed
 LL |     println!("t[0]: {}", t[0]);
    |                          ---- borrow later used here
 
diff --git a/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs b/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs
index 0e9284a2cadd2..1bda7a4971375 100644
--- a/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs
@@ -5,9 +5,9 @@ fn a() {
     let mut vec = [Box::new(1), Box::new(2), Box::new(3)];
     match vec {
         [box ref _a, _, _] => {
-        //~^ NOTE borrow of `vec[_]` occurs here
+        //~^ NOTE `vec[_]` is borrowed here
             vec[0] = Box::new(4); //~ ERROR cannot assign
-            //~^ NOTE assignment to borrowed `vec[_]` occurs here
+            //~^ NOTE `vec[_]` is assigned to here
             _a.use_ref();
             //~^ NOTE borrow later used here
         }
@@ -19,9 +19,9 @@ fn b() {
     let vec: &mut [Box<isize>] = &mut vec;
     match vec {
         &mut [ref _b @ ..] => {
-        //~^ borrow of `vec[_]` occurs here
+        //~^ `vec[_]` is borrowed here
             vec[0] = Box::new(4); //~ ERROR cannot assign
-            //~^ NOTE assignment to borrowed `vec[_]` occurs here
+            //~^ NOTE `vec[_]` is assigned to here
             _b.use_ref();
             //~^ NOTE borrow later used here
         }
diff --git a/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index 0dc5e64e4ff30..70b9e4f4433b3 100644
--- a/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed
   --> $DIR/borrowck-vec-pattern-nesting.rs:9:13
    |
 LL |         [box ref _a, _, _] => {
-   |              ------ borrow of `vec[_]` occurs here
+   |              ------ `vec[_]` is borrowed here
 LL |
 LL |             vec[0] = Box::new(4);
-   |             ^^^^^^ assignment to borrowed `vec[_]` occurs here
+   |             ^^^^^^ `vec[_]` is assigned to here but it was already borrowed
 LL |
 LL |             _a.use_ref();
    |             ------------ borrow later used here
@@ -14,10 +14,10 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed
   --> $DIR/borrowck-vec-pattern-nesting.rs:23:13
    |
 LL |         &mut [ref _b @ ..] => {
-   |               ------ borrow of `vec[_]` occurs here
+   |               ------ `vec[_]` is borrowed here
 LL |
 LL |             vec[0] = Box::new(4);
-   |             ^^^^^^ assignment to borrowed `vec[_]` occurs here
+   |             ^^^^^^ `vec[_]` is assigned to here but it was already borrowed
 LL |
 LL |             _b.use_ref();
    |             ------------ borrow later used here
diff --git a/tests/ui/borrowck/issue-25793.stderr b/tests/ui/borrowck/issue-25793.stderr
index da3412f112d7a..27dab53e48fd5 100644
--- a/tests/ui/borrowck/issue-25793.stderr
+++ b/tests/ui/borrowck/issue-25793.stderr
@@ -5,7 +5,7 @@ LL |         $this.width.unwrap()
    |         ^^^^^^^^^^^ use of borrowed `*self`
 ...
 LL |         let r = &mut *self;
-   |                 ---------- borrow of `*self` occurs here
+   |                 ---------- `*self` is borrowed here
 LL |         r.get_size(width!(self))
    |           -------- ------------ in this macro invocation
    |           |
diff --git a/tests/ui/borrowck/issue-52713-bug.stderr b/tests/ui/borrowck/issue-52713-bug.stderr
index 4abb6fb2c7186..3f7715645e60c 100644
--- a/tests/ui/borrowck/issue-52713-bug.stderr
+++ b/tests/ui/borrowck/issue-52713-bug.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/issue-52713-bug.rs:12:5
    |
 LL |     let y = &x;
-   |             -- borrow of `x` occurs here
+   |             -- `x` is borrowed here
 ...
 LL |     x += 1;
-   |     ^^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^^ `x` is assigned to here but it was already borrowed
 LL |     println!("{}", y);
    |                    - borrow later used here
 
diff --git a/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr b/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr
index 57803247ba8d0..0870b4237690e 100644
--- a/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr
+++ b/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr
@@ -4,10 +4,10 @@ error[E0506]: cannot assign to `greeting` because it is borrowed
 LL |     let res = (|| (|| &greeting)())();
    |                --      -------- borrow occurs due to use in closure
    |                |
-   |                borrow of `greeting` occurs here
+   |                `greeting` is borrowed here
 LL |
 LL |     greeting = "DEALLOCATED".to_string();
-   |     ^^^^^^^^ assignment to borrowed `greeting` occurs here
+   |     ^^^^^^^^ `greeting` is assigned to here but it was already borrowed
 ...
 LL |     println!("thread result: {:?}", res);
    |                                     --- borrow later used here
diff --git a/tests/ui/borrowck/issue-81365-1.stderr b/tests/ui/borrowck/issue-81365-1.stderr
index d79394834dcad..0d803b0427ace 100644
--- a/tests/ui/borrowck/issue-81365-1.stderr
+++ b/tests/ui/borrowck/issue-81365-1.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-1.rs:21:9
    |
 LL |         let first = &self.target_field;
-   |                      ---- borrow of `self.container_field` occurs here
+   |                      ---- `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-10.stderr b/tests/ui/borrowck/issue-81365-10.stderr
index 27123ef2be1ef..d0986e9f922e6 100644
--- a/tests/ui/borrowck/issue-81365-10.stderr
+++ b/tests/ui/borrowck/issue-81365-10.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-10.rs:21:9
    |
 LL |         let first = &self.deref().target_field;
-   |                      ------------ borrow of `self.container_field` occurs here
+   |                      ------------ `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
 
diff --git a/tests/ui/borrowck/issue-81365-11.stderr b/tests/ui/borrowck/issue-81365-11.stderr
index 0770c136632db..5f7e86f11dcd1 100644
--- a/tests/ui/borrowck/issue-81365-11.stderr
+++ b/tests/ui/borrowck/issue-81365-11.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-11.rs:27:9
    |
 LL |         let first = &mut self.target_field;
-   |                          ---- borrow of `self.container_field` occurs here
+   |                          ---- `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
 
diff --git a/tests/ui/borrowck/issue-81365-2.stderr b/tests/ui/borrowck/issue-81365-2.stderr
index 764eaaa7cc7b4..d9aeaf15f2002 100644
--- a/tests/ui/borrowck/issue-81365-2.stderr
+++ b/tests/ui/borrowck/issue-81365-2.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container.container_field` because it is bo
   --> $DIR/issue-81365-2.rs:25:9
    |
 LL |         let first = &self.container.target_field;
-   |                      -------------- borrow of `self.container.container_field` occurs here
+   |                      -------------- `self.container.container_field` is borrowed here
 LL |         self.container.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-3.stderr b/tests/ui/borrowck/issue-81365-3.stderr
index 9447174fd21ea..0c0d1994baff2 100644
--- a/tests/ui/borrowck/issue-81365-3.stderr
+++ b/tests/ui/borrowck/issue-81365-3.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container.container_field` because it is bo
   --> $DIR/issue-81365-3.rs:32:9
    |
 LL |         let first = &self.target_field;
-   |                      ---- borrow of `self.container.container_field` occurs here
+   |                      ---- `self.container.container_field` is borrowed here
 LL |         self.container.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-4.stderr b/tests/ui/borrowck/issue-81365-4.stderr
index 0ab3fa92706b0..98093daa94520 100644
--- a/tests/ui/borrowck/issue-81365-4.stderr
+++ b/tests/ui/borrowck/issue-81365-4.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.outer_field` because it is borrowed
   --> $DIR/issue-81365-4.rs:33:9
    |
 LL |         let first = &self.target_field;
-   |                      ---- borrow of `self.outer_field` occurs here
+   |                      ---- `self.outer_field` is borrowed here
 LL |         self.outer_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.outer_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ `self.outer_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-5.stderr b/tests/ui/borrowck/issue-81365-5.stderr
index 20ff229ffe7dd..c00e48288ba07 100644
--- a/tests/ui/borrowck/issue-81365-5.stderr
+++ b/tests/ui/borrowck/issue-81365-5.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-5.rs:28:9
    |
 LL |         let first = self.get();
-   |                     ---------- borrow of `self.container_field` occurs here
+   |                     ---------- `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-6.stderr b/tests/ui/borrowck/issue-81365-6.stderr
index 575aed73b4663..e61dc95ecc8fa 100644
--- a/tests/ui/borrowck/issue-81365-6.stderr
+++ b/tests/ui/borrowck/issue-81365-6.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-6.rs:18:9
    |
 LL |         let first = &self[0];
-   |                      ---- borrow of `self.container_field` occurs here
+   |                      ---- `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-7.stderr b/tests/ui/borrowck/issue-81365-7.stderr
index 52d2d9e75a951..0565127e3875b 100644
--- a/tests/ui/borrowck/issue-81365-7.stderr
+++ b/tests/ui/borrowck/issue-81365-7.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `c.container_field` because it is borrowed
   --> $DIR/issue-81365-7.rs:20:5
    |
 LL |     let first = &c.target_field;
-   |                  - borrow of `c.container_field` occurs here
+   |                  - `c.container_field` is borrowed here
 LL |     c.container_field = true;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `c.container_field` occurs here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ `c.container_field` is assigned to here but it was already borrowed
 LL |     first;
    |     ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-8.stderr b/tests/ui/borrowck/issue-81365-8.stderr
index fd83e10a295dc..0ca732ff2ae43 100644
--- a/tests/ui/borrowck/issue-81365-8.stderr
+++ b/tests/ui/borrowck/issue-81365-8.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-8.rs:21:9
    |
 LL |         let first = &(*self).target_field;
-   |                      ------- borrow of `self.container_field` occurs here
+   |                      ------- `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
    |
diff --git a/tests/ui/borrowck/issue-81365-9.stderr b/tests/ui/borrowck/issue-81365-9.stderr
index c7d48214fd4a8..4d305268a0b33 100644
--- a/tests/ui/borrowck/issue-81365-9.stderr
+++ b/tests/ui/borrowck/issue-81365-9.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `self.container_field` because it is borrowed
   --> $DIR/issue-81365-9.rs:21:9
    |
 LL |         let first = &Deref::deref(self).target_field;
-   |                                   ---- borrow of `self.container_field` occurs here
+   |                                   ---- `self.container_field` is borrowed here
 LL |         self.container_field = true;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `self.container_field` occurs here
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self.container_field` is assigned to here but it was already borrowed
 LL |         first;
    |         ----- borrow later used here
 
diff --git a/tests/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr b/tests/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr
index a57ceb8473945..1356c80493cdb 100644
--- a/tests/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr
+++ b/tests/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `i` because it was mutably borrowed
   --> $DIR/two-phase-allow-access-during-reservation.rs:26:19
    |
 LL |     /*1*/ let p = &mut i; // (reservation of `i` starts here)
-   |                   ------ borrow of `i` occurs here
+   |                   ------ `i` is borrowed here
 LL |
 LL |     /*2*/ let j = i;      // OK: `i` is only reserved here
    |                   ^ use of borrowed `i`
@@ -14,7 +14,7 @@ error[E0503]: cannot use `i` because it was mutably borrowed
   --> $DIR/two-phase-allow-access-during-reservation.rs:31:19
    |
 LL |     /*1*/ let p = &mut i; // (reservation of `i` starts here)
-   |                   ------ borrow of `i` occurs here
+   |                   ------ `i` is borrowed here
 ...
 LL |     /*4*/ let k = i;
    |                   ^ use of borrowed `i`
diff --git a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr
index 5a240d90011e4..e75094d4f1309 100644
--- a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr
+++ b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `self.cx` because it was mutably borrowed
   --> $DIR/two-phase-surprise-no-conflict.rs:21:23
    |
 LL |         let _mut_borrow = &mut *self;
-   |                           ---------- borrow of `*self` occurs here
+   |                           ---------- `*self` is borrowed here
 LL |         let _access = self.cx;
    |                       ^^^^^^^ use of borrowed `*self`
 LL |
diff --git a/tests/ui/btreemap/btreemap_dropck.stderr b/tests/ui/btreemap/btreemap_dropck.stderr
index e953e7ae82bb8..d405e465aaeea 100644
--- a/tests/ui/btreemap/btreemap_dropck.stderr
+++ b/tests/ui/btreemap/btreemap_dropck.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `s` because it is borrowed
   --> $DIR/btreemap_dropck.rs:15:10
    |
+LL |     let s = String::from("Hello World!");
+   |         - binding `s` declared here
 LL |     let _map = BTreeMap::from_iter([((), PrintOnDrop(&s))]);
    |                                                      -- borrow of `s` occurs here
 LL |     drop(s);
diff --git a/tests/ui/c-variadic/variadic-ffi-4.stderr b/tests/ui/c-variadic/variadic-ffi-4.stderr
index 6f8e53298ace2..c9d90d73dea31 100644
--- a/tests/ui/c-variadic/variadic-ffi-4.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-4.stderr
@@ -107,7 +107,9 @@ error[E0597]: `ap1` does not live long enough
   --> $DIR/variadic-ffi-4.rs:28:11
    |
 LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                                        - let's call the lifetime of this reference `'3`
+   |                                                        -                ------- binding `ap1` declared here
+   |                                                        |
+   |                                                        let's call the lifetime of this reference `'3`
 LL |     ap0 = &mut ap1;
    |     ------^^^^^^^^
    |     |     |
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
index 4f41060dc9842..9e5200ef34b54 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `arr` because it was mutably borrowed
   --> $DIR/arrays.rs:14:5
    |
 LL |     let mut c = || {
-   |                 -- borrow of `arr` occurs here
+   |                 -- `arr` is borrowed here
 LL |         arr[0] += 10;
    |         --- borrow occurs due to use of `arr` in closure
 ...
@@ -16,7 +16,7 @@ error[E0503]: cannot use `arr[_]` because it was mutably borrowed
   --> $DIR/arrays.rs:14:5
    |
 LL |     let mut c = || {
-   |                 -- borrow of `arr` occurs here
+   |                 -- `arr` is borrowed here
 LL |         arr[0] += 10;
    |         --- borrow occurs due to use of `arr` in closure
 ...
@@ -30,12 +30,12 @@ error[E0506]: cannot assign to `arr[_]` because it is borrowed
   --> $DIR/arrays.rs:29:5
    |
 LL |     let c = || {
-   |             -- borrow of `arr[_]` occurs here
+   |             -- `arr[_]` is borrowed here
 LL |         println!("{:#?}", &arr[3..4]);
    |                            --- borrow occurs due to use in closure
 ...
 LL |     arr[1] += 10;
-   |     ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here
+   |     ^^^^^^^^^^^^ `arr[_]` is assigned to here but it was already borrowed
 LL |
 LL |     c();
    |     - borrow later used here
@@ -44,12 +44,12 @@ error[E0506]: cannot assign to `arr[_]` because it is borrowed
   --> $DIR/arrays.rs:43:5
    |
 LL |     let c = || {
-   |             -- borrow of `arr[_]` occurs here
+   |             -- `arr[_]` is borrowed here
 LL |         println!("{}", arr[3]);
    |                        --- borrow occurs due to use in closure
 ...
 LL |     arr[1] += 10;
-   |     ^^^^^^^^^^^^ assignment to borrowed `arr[_]` occurs here
+   |     ^^^^^^^^^^^^ `arr[_]` is assigned to here but it was already borrowed
 LL |
 LL |     c();
    |     - borrow later used here
@@ -58,7 +58,7 @@ error[E0503]: cannot use `arr` because it was mutably borrowed
   --> $DIR/arrays.rs:57:20
    |
 LL |     let mut c = || {
-   |                 -- borrow of `arr` occurs here
+   |                 -- `arr` is borrowed here
 LL |         arr[1] += 10;
    |         --- borrow occurs due to use of `arr` in closure
 ...
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr
index f8b178752351a..2e3259e640596 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr
@@ -2,12 +2,12 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
   --> $DIR/box.rs:21:5
    |
 LL |     let mut c = || {
-   |                 -- borrow of `e.0.0.m.x` occurs here
+   |                 -- `e.0.0.m.x` is borrowed here
 LL |         e.0.0.m.x = format!("not-x");
    |         --------- borrow occurs due to use in closure
 ...
 LL |     e.0.0.m.x = format!("not-x");
-   |     ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
+   |     ^^^^^^^^^ `e.0.0.m.x` is assigned to here but it was already borrowed
 LL |
 LL |     c();
    |     - borrow later used here
@@ -32,12 +32,12 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
   --> $DIR/box.rs:55:5
    |
 LL |     let c = || {
-   |             -- borrow of `e.0.0.m.x` occurs here
+   |             -- `e.0.0.m.x` is borrowed here
 LL |         println!("{}", e.0.0.m.x);
    |                        --------- borrow occurs due to use in closure
 ...
 LL |     e.0.0.m.x = format!("not-x");
-   |     ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
+   |     ^^^^^^^^^ `e.0.0.m.x` is assigned to here but it was already borrowed
 LL |
 LL |     c();
    |     - borrow later used here
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/union.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/union.rs
index 46b54846e32eb..695337ea82cf9 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/union.rs
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/union.rs
@@ -11,7 +11,7 @@ union A {
 fn main() {
     let mut a = A { y: 1 };
     let mut c = || {
-    //~^ borrow of `a.y` occurs here
+    //~^ `a.y` is borrowed here
         let _ = unsafe { &a.y };
         let _ = &mut a;
         //~^ borrow occurs due to use in closure
@@ -19,7 +19,7 @@ fn main() {
     };
     a.y = 1;
     //~^ cannot assign to `a.y` because it is borrowed [E0506]
-    //~| assignment to borrowed `a.y` occurs here
+    //~| `a.y` is assigned to here
     c();
     //~^ borrow later used here
 }
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/union.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/union.stderr
index 7c34e2336c867..17834e6123628 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/union.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/union.stderr
@@ -2,13 +2,13 @@ error[E0506]: cannot assign to `a.y` because it is borrowed
   --> $DIR/union.rs:20:5
    |
 LL |     let mut c = || {
-   |                 -- borrow of `a.y` occurs here
+   |                 -- `a.y` is borrowed here
 ...
 LL |         let _ = &mut a;
    |                      - borrow occurs due to use in closure
 ...
 LL |     a.y = 1;
-   |     ^^^^^^^ assignment to borrowed `a.y` occurs here
+   |     ^^^^^^^ `a.y` is assigned to here but it was already borrowed
 ...
 LL |     c();
    |     - borrow later used here
diff --git a/tests/ui/coercion/coerce-overloaded-autoderef-fail.stderr b/tests/ui/coercion/coerce-overloaded-autoderef-fail.stderr
index d067c3b3a1805..d412b8b08b79a 100644
--- a/tests/ui/coercion/coerce-overloaded-autoderef-fail.stderr
+++ b/tests/ui/coercion/coerce-overloaded-autoderef-fail.stderr
@@ -13,10 +13,10 @@ error[E0506]: cannot assign to `**x` because it is borrowed
   --> $DIR/coerce-overloaded-autoderef-fail.rs:17:5
    |
 LL |     let y = borrow(x);
-   |                    - borrow of `**x` occurs here
+   |                    - `**x` is borrowed here
 LL |     let z = borrow(x);
 LL |     **x += 1;
-   |     ^^^^^^^^ assignment to borrowed `**x` occurs here
+   |     ^^^^^^^^ `**x` is assigned to here but it was already borrowed
 LL |
 LL |     drop((y, z));
    |           - borrow later used here
diff --git a/tests/ui/consts/promote_const_let.stderr b/tests/ui/consts/promote_const_let.stderr
index 975a235a6495b..6e0349a4773cd 100644
--- a/tests/ui/consts/promote_const_let.stderr
+++ b/tests/ui/consts/promote_const_let.stderr
@@ -4,6 +4,7 @@ error[E0597]: `y` does not live long enough
 LL |     let x: &'static u32 = {
    |            ------------ type annotation requires that `y` is borrowed for `'static`
 LL |         let y = 42;
+   |             - binding `y` declared here
 LL |         &y
    |         ^^ borrowed value does not live long enough
 LL |     };
diff --git a/tests/ui/dropck/dropck-eyepatch-extern-crate.stderr b/tests/ui/dropck/dropck-eyepatch-extern-crate.stderr
index 5d53405579d9d..23d57634e8fd2 100644
--- a/tests/ui/dropck/dropck-eyepatch-extern-crate.stderr
+++ b/tests/ui/dropck/dropck-eyepatch-extern-crate.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `c_shortest` does not live long enough
   --> $DIR/dropck-eyepatch-extern-crate.rs:46:23
    |
+LL |         let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>);
+   |                              ---------- binding `c_shortest` declared here
+...
 LL |         dt = Dt("dt", &c_shortest);
    |                       ^^^^^^^^^^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL |     }
 error[E0597]: `c_shortest` does not live long enough
   --> $DIR/dropck-eyepatch-extern-crate.rs:68:32
    |
+LL |         let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>);
+   |                              ---------- binding `c_shortest` declared here
+...
 LL |         pt = Pt("pt", &c_long, &c_shortest);
    |                                ^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/dropck/dropck-eyepatch-reorder.stderr b/tests/ui/dropck/dropck-eyepatch-reorder.stderr
index 5055cdd8b2bf9..a5d5136b5c578 100644
--- a/tests/ui/dropck/dropck-eyepatch-reorder.stderr
+++ b/tests/ui/dropck/dropck-eyepatch-reorder.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `c_shortest` does not live long enough
   --> $DIR/dropck-eyepatch-reorder.rs:64:23
    |
+LL |         let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>);
+   |                              ---------- binding `c_shortest` declared here
+...
 LL |         dt = Dt("dt", &c_shortest);
    |                       ^^^^^^^^^^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL |     }
 error[E0597]: `c_shortest` does not live long enough
   --> $DIR/dropck-eyepatch-reorder.rs:86:32
    |
+LL |         let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>);
+   |                              ---------- binding `c_shortest` declared here
+...
 LL |         pt = Pt("pt", &c_long, &c_shortest);
    |                                ^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/dropck/dropck-eyepatch.stderr b/tests/ui/dropck/dropck-eyepatch.stderr
index 21295e6c6019e..dc3f8c05e7396 100644
--- a/tests/ui/dropck/dropck-eyepatch.stderr
+++ b/tests/ui/dropck/dropck-eyepatch.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `c_shortest` does not live long enough
   --> $DIR/dropck-eyepatch.rs:88:23
    |
+LL |         let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>);
+   |                              ---------- binding `c_shortest` declared here
+...
 LL |         dt = Dt("dt", &c_shortest);
    |                       ^^^^^^^^^^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL |     }
 error[E0597]: `c_shortest` does not live long enough
   --> $DIR/dropck-eyepatch.rs:110:32
    |
+LL |         let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>);
+   |                              ---------- binding `c_shortest` declared here
+...
 LL |         pt = Pt("pt", &c_long, &c_shortest);
    |                                ^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/dropck/dropck-union.stderr b/tests/ui/dropck/dropck-union.stderr
index 854e29385a81b..7d48e9fdcee31 100644
--- a/tests/ui/dropck/dropck-union.stderr
+++ b/tests/ui/dropck/dropck-union.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `v` does not live long enough
   --> $DIR/dropck-union.rs:37:18
    |
+LL |     let v : Wrap<C> = Wrap::new(C(Cell::new(None)));
+   |         - binding `v` declared here
 LL |     v.0.set(Some(&v));
    |                  ^^ borrowed value does not live long enough
 LL | }
diff --git a/tests/ui/dropck/dropck_trait_cycle_checked.stderr b/tests/ui/dropck/dropck_trait_cycle_checked.stderr
index dc3fbed593b79..4d4f7b9df1179 100644
--- a/tests/ui/dropck/dropck_trait_cycle_checked.stderr
+++ b/tests/ui/dropck/dropck_trait_cycle_checked.stderr
@@ -2,7 +2,7 @@ error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:111:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                     -------- cast requires that `o2` is borrowed for `'static`
+   |              -- binding `o2` declared here                          -------- cast requires that `o2` is borrowed for `'static`
 LL |     o1.set0(&o2);
    |             ^^^ borrowed value does not live long enough
 ...
@@ -13,7 +13,7 @@ error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:112:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                     -------- cast requires that `o3` is borrowed for `'static`
+   |                  -- binding `o3` declared here                      -------- cast requires that `o3` is borrowed for `'static`
 LL |     o1.set0(&o2);
 LL |     o1.set1(&o3);
    |             ^^^ borrowed value does not live long enough
@@ -25,7 +25,7 @@ error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:113:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                               -------- cast requires that `o2` is borrowed for `'static`
+   |              -- binding `o2` declared here                                    -------- cast requires that `o2` is borrowed for `'static`
 ...
 LL |     o2.set0(&o2);
    |             ^^^ borrowed value does not live long enough
@@ -37,7 +37,7 @@ error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:114:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                               -------- cast requires that `o3` is borrowed for `'static`
+   |                  -- binding `o3` declared here                                -------- cast requires that `o3` is borrowed for `'static`
 ...
 LL |     o2.set1(&o3);
    |             ^^^ borrowed value does not live long enough
@@ -49,7 +49,7 @@ error[E0597]: `o1` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:115:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                                         -------- cast requires that `o1` is borrowed for `'static`
+   |          -- binding `o1` declared here                                                  -------- cast requires that `o1` is borrowed for `'static`
 ...
 LL |     o3.set0(&o1);
    |             ^^^ borrowed value does not live long enough
@@ -61,7 +61,7 @@ error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:116:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                                         -------- cast requires that `o2` is borrowed for `'static`
+   |              -- binding `o2` declared here                                              -------- cast requires that `o2` is borrowed for `'static`
 ...
 LL |     o3.set1(&o2);
    |             ^^^ borrowed value does not live long enough
diff --git a/tests/ui/dst/dst-bad-coerce3.stderr b/tests/ui/dst/dst-bad-coerce3.stderr
index 957e98bbeee96..1254250bcbd85 100644
--- a/tests/ui/dst/dst-bad-coerce3.stderr
+++ b/tests/ui/dst/dst-bad-coerce3.stderr
@@ -3,7 +3,9 @@ error[E0597]: `f1` does not live long enough
    |
 LL | fn baz<'a>() {
    |        -- lifetime `'a` defined here
-...
+LL |     // With a vec of ints.
+LL |     let f1 = Fat { ptr: [1, 2, 3] };
+   |         -- binding `f1` declared here
 LL |     let f2: &Fat<[isize; 3]> = &f1;
    |                                ^^^ borrowed value does not live long enough
 LL |     let f3: &'a Fat<[isize]> = f2;
@@ -18,6 +20,8 @@ error[E0597]: `f1` does not live long enough
 LL | fn baz<'a>() {
    |        -- lifetime `'a` defined here
 ...
+LL |     let f1 = Fat { ptr: Foo };
+   |         -- binding `f1` declared here
 LL |     let f2: &Fat<Foo> = &f1;
    |                         ^^^ borrowed value does not live long enough
 LL |     let f3: &'a Fat<dyn Bar> = f2;
@@ -32,6 +36,8 @@ error[E0597]: `f1` does not live long enough
 LL | fn baz<'a>() {
    |        -- lifetime `'a` defined here
 ...
+LL |     let f1 = ([1, 2, 3],);
+   |         -- binding `f1` declared here
 LL |     let f2: &([isize; 3],) = &f1;
    |                              ^^^ borrowed value does not live long enough
 LL |     let f3: &'a ([isize],) = f2;
@@ -46,6 +52,8 @@ error[E0597]: `f1` does not live long enough
 LL | fn baz<'a>() {
    |        -- lifetime `'a` defined here
 ...
+LL |     let f1 = (Foo,);
+   |         -- binding `f1` declared here
 LL |     let f2: &(Foo,) = &f1;
    |                       ^^^ borrowed value does not live long enough
 LL |     let f3: &'a (dyn Bar,) = f2;
diff --git a/tests/ui/error-codes/E0503.stderr b/tests/ui/error-codes/E0503.stderr
index fafe363eb47a6..2f02e3b1a6138 100644
--- a/tests/ui/error-codes/E0503.stderr
+++ b/tests/ui/error-codes/E0503.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `value` because it was mutably borrowed
   --> $DIR/E0503.rs:4:16
    |
 LL |     let _borrow = &mut value;
-   |                   ---------- borrow of `value` occurs here
+   |                   ---------- `value` is borrowed here
 LL |     let _sum = value + 1;
    |                ^^^^^ use of borrowed `value`
 LL |     _borrow.use_mut();
diff --git a/tests/ui/error-codes/E0504.stderr b/tests/ui/error-codes/E0504.stderr
index e677e89161542..20e16a5381061 100644
--- a/tests/ui/error-codes/E0504.stderr
+++ b/tests/ui/error-codes/E0504.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `fancy_num` because it is borrowed
   --> $DIR/E0504.rs:9:13
    |
+LL |     let fancy_num = FancyNum { num: 5 };
+   |         --------- binding `fancy_num` declared here
 LL |     let fancy_ref = &fancy_num;
    |                     ---------- borrow of `fancy_num` occurs here
 LL |
diff --git a/tests/ui/error-codes/E0505.stderr b/tests/ui/error-codes/E0505.stderr
index bd3f37f54e0a8..2ecb4a75c4382 100644
--- a/tests/ui/error-codes/E0505.stderr
+++ b/tests/ui/error-codes/E0505.stderr
@@ -1,6 +1,9 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/E0505.rs:9:13
    |
+LL |     let x = Value{};
+   |         - binding `x` declared here
+LL |     {
 LL |         let _ref_to_val: &Value = &x;
    |                                   -- borrow of `x` occurs here
 LL |         eat(x);
diff --git a/tests/ui/error-codes/E0506.stderr b/tests/ui/error-codes/E0506.stderr
index d70406b750afc..17ad7c611f824 100644
--- a/tests/ui/error-codes/E0506.stderr
+++ b/tests/ui/error-codes/E0506.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `fancy_num` because it is borrowed
   --> $DIR/E0506.rs:8:5
    |
 LL |     let fancy_ref = &fancy_num;
-   |                     ---------- borrow of `fancy_num` occurs here
+   |                     ---------- `fancy_num` is borrowed here
 LL |     fancy_num = FancyNum { num: 6 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fancy_num` is assigned to here but it was already borrowed
 LL |
 LL |     println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
    |                                                 ------------- borrow later used here
diff --git a/tests/ui/error-codes/E0597.stderr b/tests/ui/error-codes/E0597.stderr
index b4a1180ad546c..82e3481b65a59 100644
--- a/tests/ui/error-codes/E0597.stderr
+++ b/tests/ui/error-codes/E0597.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/E0597.rs:8:16
    |
+LL |     let y = 0;
+   |         - binding `y` declared here
 LL |     x.x = Some(&y);
    |                ^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr
index fcbaa91d19f82..4df639232a332 100644
--- a/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr
+++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-4.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/implied-bounds-unnorm-associated-type-4.rs:21:10
    |
+LL |     let x = String::from("Hello World!");
+   |         - binding `x` declared here
 LL |     let y = f(&x, ());
    |               -- borrow of `x` occurs here
 LL |     drop(x);
diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr
index e35f46e4439a9..d417f28839368 100644
--- a/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr
+++ b/tests/ui/fn/implied-bounds-unnorm-associated-type.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/implied-bounds-unnorm-associated-type.rs:20:10
    |
+LL |     let x = String::from("Hello World!");
+   |         - binding `x` declared here
 LL |     let y = f(&x, ());
    |               -- borrow of `x` occurs here
 LL |     drop(x);
diff --git a/tests/ui/generic-associated-types/issue-74684-1.stderr b/tests/ui/generic-associated-types/issue-74684-1.stderr
index cacc973077ce7..b93ee37987f27 100644
--- a/tests/ui/generic-associated-types/issue-74684-1.stderr
+++ b/tests/ui/generic-associated-types/issue-74684-1.stderr
@@ -4,6 +4,7 @@ error[E0597]: `a` does not live long enough
 LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(_ : Box<T>) -> &'static T::F<'a> {
    |        -- lifetime `'a` defined here
 LL |     let a = [0; 1];
+   |         - binding `a` declared here
 LL |     let _x = T::identity(&a);
    |              ------------^^-
    |              |           |
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
index 4886a3c8bad62..25af011e3fc41 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
+++ b/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/hrtb-identity-fn-borrows.rs:14:5
    |
 LL |     let y = f.call(&x);
-   |                    -- borrow of `x` occurs here
+   |                    -- `x` is borrowed here
 LL |     x = 5;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 ...
 LL |     drop(y);
    |          - borrow later used here
diff --git a/tests/ui/impl-trait/feature-self-return-type.stderr b/tests/ui/impl-trait/feature-self-return-type.stderr
index 601e53b769459..b9b8d00ce308b 100644
--- a/tests/ui/impl-trait/feature-self-return-type.stderr
+++ b/tests/ui/impl-trait/feature-self-return-type.stderr
@@ -4,6 +4,7 @@ error[E0597]: `bar` does not live long enough
 LL |         let x = {
    |             - borrow later stored here
 LL |             let bar = 22;
+   |                 --- binding `bar` declared here
 LL |             Foo::new(&bar).into()
    |                      ^^^^ borrowed value does not live long enough
 LL |
@@ -16,6 +17,7 @@ error[E0597]: `y` does not live long enough
 LL |         let x = {
    |             - borrow later stored here
 LL |             let y = ();
+   |                 - binding `y` declared here
 LL |             foo(&y)
    |                 ^^ borrowed value does not live long enough
 LL |
@@ -28,6 +30,7 @@ error[E0597]: `y` does not live long enough
 LL |         let x = {
    |             - borrow later stored here
 LL |             let y = ();
+   |                 - binding `y` declared here
 LL |             foo(&y)
    |                 ^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr b/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
index d0249e74f39e9..307899297bc01 100644
--- a/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
+++ b/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/assoc-ty-wf-used-to-get-assoc-ty.rs:24:31
    |
+LL |     let x: u8 = 3;
+   |         - binding `x` declared here
 LL |     let _: &'static u8 = test(&x, &&3);
    |                          -----^^------
    |                          |    |
diff --git a/tests/ui/inline-const/const-expr-lifetime-err.stderr b/tests/ui/inline-const/const-expr-lifetime-err.stderr
index a23f7c9a796c5..443fcf89c4e11 100644
--- a/tests/ui/inline-const/const-expr-lifetime-err.stderr
+++ b/tests/ui/inline-const/const-expr-lifetime-err.stderr
@@ -4,6 +4,7 @@ error[E0597]: `y` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let y = ();
+   |         - binding `y` declared here
 LL |     equate(InvariantRef::new(&y), const { InvariantRef::<'a>::NEW });
    |            ------------------^^-
    |            |                 |
diff --git a/tests/ui/issues/issue-40288.stderr b/tests/ui/issues/issue-40288.stderr
index fb4ecab362db1..db5d064379a76 100644
--- a/tests/ui/issues/issue-40288.stderr
+++ b/tests/ui/issues/issue-40288.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `*refr` because it is borrowed
   --> $DIR/issue-40288.rs:16:5
    |
 LL |     save_ref(&*refr, &mut out);
-   |              ------ borrow of `*refr` occurs here
+   |              ------ `*refr` is borrowed here
 ...
 LL |     *refr = 3;
-   |     ^^^^^^^^^ assignment to borrowed `*refr` occurs here
+   |     ^^^^^^^^^ `*refr` is assigned to here but it was already borrowed
 ...
 LL |     println!("{:?}", out[0]);
    |                      ------ borrow later used here
diff --git a/tests/ui/issues/issue-45697-1.stderr b/tests/ui/issues/issue-45697-1.stderr
index 30c69f19658c8..474313398e2bc 100644
--- a/tests/ui/issues/issue-45697-1.stderr
+++ b/tests/ui/issues/issue-45697-1.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `*y.pointer` because it was mutably borrowed
   --> $DIR/issue-45697-1.rs:20:9
    |
 LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `y` occurs here
+   |                                   ------ `y` is borrowed here
 LL |         *y.pointer += 1;
    |         ^^^^^^^^^^^^^^^ use of borrowed `y`
 ...
@@ -13,9 +13,9 @@ error[E0506]: cannot assign to `*y.pointer` because it is borrowed
   --> $DIR/issue-45697-1.rs:20:9
    |
 LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `*y.pointer` occurs here
+   |                                   ------ `*y.pointer` is borrowed here
 LL |         *y.pointer += 1;
-   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
+   |         ^^^^^^^^^^^^^^^ `*y.pointer` is assigned to here but it was already borrowed
 ...
 LL |         *z.pointer += 1;
    |         --------------- borrow later used here
diff --git a/tests/ui/issues/issue-45697.stderr b/tests/ui/issues/issue-45697.stderr
index 26749d36f0b7b..7986fd5c9df2e 100644
--- a/tests/ui/issues/issue-45697.stderr
+++ b/tests/ui/issues/issue-45697.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `*y.pointer` because it was mutably borrowed
   --> $DIR/issue-45697.rs:20:9
    |
 LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `y` occurs here
+   |                                   ------ `y` is borrowed here
 LL |         *y.pointer += 1;
    |         ^^^^^^^^^^^^^^^ use of borrowed `y`
 ...
@@ -13,9 +13,9 @@ error[E0506]: cannot assign to `*y.pointer` because it is borrowed
   --> $DIR/issue-45697.rs:20:9
    |
 LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `*y.pointer` occurs here
+   |                                   ------ `*y.pointer` is borrowed here
 LL |         *y.pointer += 1;
-   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
+   |         ^^^^^^^^^^^^^^^ `*y.pointer` is assigned to here but it was already borrowed
 ...
 LL |         *z.pointer += 1;
    |         --------------- borrow later used here
diff --git a/tests/ui/issues/issue-46471-1.stderr b/tests/ui/issues/issue-46471-1.stderr
index b09f31729a5fd..2ae6e709d5ad5 100644
--- a/tests/ui/issues/issue-46471-1.stderr
+++ b/tests/ui/issues/issue-46471-1.stderr
@@ -1,11 +1,10 @@
 error[E0597]: `z` does not live long enough
   --> $DIR/issue-46471-1.rs:4:9
    |
+LL |         let mut z = 0;
+   |             ----- binding `z` declared here
 LL |         &mut z
-   |         ^^^^^^
-   |         |
-   |         borrowed value does not live long enough
-   |         borrow later used here
+   |         ^^^^^^ borrowed value does not live long enough
 LL |     };
    |     - `z` dropped here while still borrowed
 
diff --git a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
index 99e1e7217b45c..3602de8dd9577 100644
--- a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
+++ b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `foo` does not live long enough
   --> $DIR/issue-90600-expected-return-static-indirect.rs:7:32
    |
+LL | fn inner(mut foo: &[u8]) {
+   |          ------- binding `foo` declared here
 LL |     let refcell = RefCell::new(&mut foo);
    |                                ^^^^^^^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/mut/mut-pattern-internal-mutability.stderr b/tests/ui/mut/mut-pattern-internal-mutability.stderr
index 6583546aa5c1f..5f2074edb1240 100644
--- a/tests/ui/mut/mut-pattern-internal-mutability.stderr
+++ b/tests/ui/mut/mut-pattern-internal-mutability.stderr
@@ -13,9 +13,9 @@ error[E0506]: cannot assign to `*foo` because it is borrowed
   --> $DIR/mut-pattern-internal-mutability.rs:13:5
    |
 LL |     let &mut ref x = foo;
-   |              ----- borrow of `*foo` occurs here
+   |              ----- `*foo` is borrowed here
 LL |     *foo += 1;
-   |     ^^^^^^^^^ assignment to borrowed `*foo` occurs here
+   |     ^^^^^^^^^ `*foo` is assigned to here but it was already borrowed
 LL |     drop(x);
    |          - borrow later used here
 
diff --git a/tests/ui/nll/borrowed-local-error.stderr b/tests/ui/nll/borrowed-local-error.stderr
index d629caa435319..1cca4077d825a 100644
--- a/tests/ui/nll/borrowed-local-error.stderr
+++ b/tests/ui/nll/borrowed-local-error.stderr
@@ -4,6 +4,7 @@ error[E0597]: `v` does not live long enough
 LL |     let x = gimme({
    |             ----- borrow later used by call
 LL |         let v = (22,);
+   |             - binding `v` declared here
 LL |         &v
    |         ^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/nll/borrowed-match-issue-45045.stderr b/tests/ui/nll/borrowed-match-issue-45045.stderr
index 9d4682667dddd..33e3eb797969e 100644
--- a/tests/ui/nll/borrowed-match-issue-45045.stderr
+++ b/tests/ui/nll/borrowed-match-issue-45045.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `e` because it was mutably borrowed
   --> $DIR/borrowed-match-issue-45045.rs:12:11
    |
 LL |     let f = &mut e;
-   |             ------ borrow of `e` occurs here
+   |             ------ `e` is borrowed here
 LL |     let g = f;
 LL |     match e {
    |           ^ use of borrowed `e`
diff --git a/tests/ui/nll/capture-ref-in-struct.stderr b/tests/ui/nll/capture-ref-in-struct.stderr
index cdfe7f6db82a9..84b7ecf2f7da8 100644
--- a/tests/ui/nll/capture-ref-in-struct.stderr
+++ b/tests/ui/nll/capture-ref-in-struct.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/capture-ref-in-struct.rs:18:16
    |
+LL |         let y = 22;
+   |             - binding `y` declared here
+...
 LL |             y: &y,
    |                ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/closure-access-spans.stderr b/tests/ui/nll/closure-access-spans.stderr
index 0a09353b8ec0a..035dd5a561096 100644
--- a/tests/ui/nll/closure-access-spans.stderr
+++ b/tests/ui/nll/closure-access-spans.stderr
@@ -38,7 +38,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/closure-access-spans.rs:23:13
    |
 LL |     let r = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     move || x;
    |             ^ use of borrowed `x`
 LL |     r.use_ref();
@@ -47,6 +47,8 @@ LL |     r.use_ref();
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/closure-access-spans.rs:29:5
    |
+LL | fn closure_move_capture_conflict(mut x: String) {
+   |                                  ----- binding `x` declared here
 LL |     let r = &x;
    |             -- borrow of `x` occurs here
 LL |     || x;
diff --git a/tests/ui/nll/closure-borrow-spans.stderr b/tests/ui/nll/closure-borrow-spans.stderr
index bada4e1b84b52..cf0df5834cc0d 100644
--- a/tests/ui/nll/closure-borrow-spans.stderr
+++ b/tests/ui/nll/closure-borrow-spans.stderr
@@ -40,9 +40,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
 LL |     let f = || x;
    |             -- - borrow occurs due to use in closure
    |             |
-   |             borrow of `x` occurs here
+   |             `x` is borrowed here
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     f.use_ref();
    |     ----------- borrow later used here
 
@@ -52,7 +52,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
 LL |     let f = || x = 0;
    |             -- - borrow occurs due to use of `x` in closure
    |             |
-   |             borrow of `x` occurs here
+   |             `x` is borrowed here
 LL |     let y = x;
    |             ^ use of borrowed `x`
 LL |     f.use_ref();
@@ -100,9 +100,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
 LL |     let f = || x = 0;
    |             -- - borrow occurs due to use in closure
    |             |
-   |             borrow of `x` occurs here
+   |             `x` is borrowed here
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     f.use_ref();
    |     ----------- borrow later used here
 
@@ -160,9 +160,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
 LL |     let f = || *x = 0;
    |             -- -- borrow occurs due to use in closure
    |             |
-   |             borrow of `*x` occurs here
+   |             `*x` is borrowed here
 LL |     *x = 1;
-   |     ^^^^^^ assignment to borrowed `*x` occurs here
+   |     ^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |     f.use_ref();
    |     ----------- borrow later used here
 
diff --git a/tests/ui/nll/closure-requirements/escape-argument.stderr b/tests/ui/nll/closure-requirements/escape-argument.stderr
index f67c312b94688..5a8462d4dc56e 100644
--- a/tests/ui/nll/closure-requirements/escape-argument.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument.stderr
@@ -21,6 +21,9 @@ LL | fn test() {
 error[E0597]: `y` does not live long enough
   --> $DIR/escape-argument.rs:27:25
    |
+LL |         let y = 22;
+   |             - binding `y` declared here
+LL |         let mut closure = expect_sig(|p, y| *p = y);
 LL |         closure(&mut p, &y);
    |                         ^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 7991abeb7a800..721cd45ded98e 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -53,6 +53,8 @@ LL | fn case2() {
 error[E0597]: `a` does not live long enough
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:30:26
    |
+LL |       let a = 0;
+   |           - binding `a` declared here
 LL |       let cell = Cell::new(&a);
    |                            ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/closure-use-spans.stderr b/tests/ui/nll/closure-use-spans.stderr
index ad928f1bbc984..0e27e5f5f7c16 100644
--- a/tests/ui/nll/closure-use-spans.stderr
+++ b/tests/ui/nll/closure-use-spans.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/closure-use-spans.rs:5:5
    |
 LL |     let y = &x;
-   |             -- borrow of `x` occurs here
+   |             -- `x` is borrowed here
 LL |     x = 0;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     || *y;
    |        -- borrow later captured here by closure
 
@@ -12,9 +12,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/closure-use-spans.rs:11:5
    |
 LL |     let y = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     x = 0;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     || *y = 1;
    |        -- borrow later captured here by closure
 
@@ -22,9 +22,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/closure-use-spans.rs:17:5
    |
 LL |     let y = &x;
-   |             -- borrow of `x` occurs here
+   |             -- `x` is borrowed here
 LL |     x = 0;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     move || *y;
    |             -- borrow later captured here by closure
 
diff --git a/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr b/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr
index 65be3b37e0e3b..862c925b468fd 100644
--- a/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr
+++ b/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `s` does not live long enough
   --> $DIR/do-not-ignore-lifetime-bounds-in-copy-proj.rs:9:18
    |
+LL |     let s = 2;
+   |         - binding `s` declared here
 LL |     let a = (Foo(&s),);
    |                  ^^ borrowed value does not live long enough
 LL |     drop(a.0);
diff --git a/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy.stderr b/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy.stderr
index b811ba4fd0cd2..ebaf6d1244d7d 100644
--- a/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy.stderr
+++ b/tests/ui/nll/do-not-ignore-lifetime-bounds-in-copy.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `s` does not live long enough
   --> $DIR/do-not-ignore-lifetime-bounds-in-copy.rs:8:17
    |
+LL |     let s = 2;
+   |         - binding `s` declared here
 LL |     let a = Foo(&s);
    |                 ^^ borrowed value does not live long enough
 LL |     drop(a);
diff --git a/tests/ui/nll/dont-print-desugared.stderr b/tests/ui/nll/dont-print-desugared.stderr
index fad6121cbca52..289b246e663e1 100644
--- a/tests/ui/nll/dont-print-desugared.stderr
+++ b/tests/ui/nll/dont-print-desugared.stderr
@@ -10,6 +10,7 @@ error[E0597]: `y` does not live long enough
 LL |     for ref mut d in v {
    |                      - a temporary with access to the borrow is created here ...
 LL |         let y = ();
+   |             - binding `y` declared here
 LL |         *d = D(&y);
    |                ^^ borrowed value does not live long enough
 LL |     }
diff --git a/tests/ui/nll/drop-no-may-dangle.stderr b/tests/ui/nll/drop-no-may-dangle.stderr
index cb28088095004..0ddb7adbb3822 100644
--- a/tests/ui/nll/drop-no-may-dangle.stderr
+++ b/tests/ui/nll/drop-no-may-dangle.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `v[_]` because it is borrowed
   --> $DIR/drop-no-may-dangle.rs:18:9
    |
 LL |     let p: WrapMayNotDangle<&usize> = WrapMayNotDangle { value: &v[0] };
-   |                                                                 ----- borrow of `v[_]` occurs here
+   |                                                                 ----- `v[_]` is borrowed here
 ...
 LL |         v[0] += 1;
-   |         ^^^^^^^^^ assignment to borrowed `v[_]` occurs here
+   |         ^^^^^^^^^ `v[_]` is assigned to here but it was already borrowed
 ...
 LL | }
    | - borrow might be used here, when `p` is dropped and runs the `Drop` code for type `WrapMayNotDangle`
@@ -14,10 +14,10 @@ error[E0506]: cannot assign to `v[_]` because it is borrowed
   --> $DIR/drop-no-may-dangle.rs:21:5
    |
 LL |     let p: WrapMayNotDangle<&usize> = WrapMayNotDangle { value: &v[0] };
-   |                                                                 ----- borrow of `v[_]` occurs here
+   |                                                                 ----- `v[_]` is borrowed here
 ...
 LL |     v[0] += 1;
-   |     ^^^^^^^^^ assignment to borrowed `v[_]` occurs here
+   |     ^^^^^^^^^ `v[_]` is assigned to here but it was already borrowed
 LL | }
    | - borrow might be used here, when `p` is dropped and runs the `Drop` code for type `WrapMayNotDangle`
 
diff --git a/tests/ui/nll/guarantor-issue-46974.stderr b/tests/ui/nll/guarantor-issue-46974.stderr
index 8854dd8d68c9d..7edc3dcc5cde3 100644
--- a/tests/ui/nll/guarantor-issue-46974.stderr
+++ b/tests/ui/nll/guarantor-issue-46974.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `*s` because it is borrowed
   --> $DIR/guarantor-issue-46974.rs:7:5
    |
 LL |     let t = &mut *s; // this borrow should last for the entire function
-   |             ------- borrow of `*s` occurs here
+   |             ------- `*s` is borrowed here
 LL |     let x = &t.0;
 LL |     *s = (2,);
-   |     ^^^^^^^^^ assignment to borrowed `*s` occurs here
+   |     ^^^^^^^^^ `*s` is assigned to here but it was already borrowed
 LL |     *x
    |     -- borrow later used here
 
diff --git a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr
index 45119018d4e60..4a512560c8751 100644
--- a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr
+++ b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr
@@ -4,7 +4,7 @@ error[E0507]: cannot move out of `foo` in pattern guard
 LL |             if { (|| { let bar = foo; bar.take() })(); false } => {},
    |                   ^^             --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
    |                   |
-   |                   move out of `foo` occurs here
+   |                   `foo` is moved here
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
@@ -14,7 +14,7 @@ error[E0507]: cannot move out of `foo` in pattern guard
 LL |             if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {},
    |                                  ^^             --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
    |                                  |
-   |                                  move out of `foo` occurs here
+   |                                  `foo` is moved here
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
diff --git a/tests/ui/nll/issue-27282-mutation-in-guard.stderr b/tests/ui/nll/issue-27282-mutation-in-guard.stderr
index 1ba696593afff..0b5d723172c76 100644
--- a/tests/ui/nll/issue-27282-mutation-in-guard.stderr
+++ b/tests/ui/nll/issue-27282-mutation-in-guard.stderr
@@ -4,7 +4,7 @@ error[E0507]: cannot move out of `foo` in pattern guard
 LL |                 (|| { let bar = foo; bar.take() })();
    |                  ^^             --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
    |                  |
-   |                  move out of `foo` occurs here
+   |                  `foo` is moved here
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
@@ -14,7 +14,7 @@ error[E0507]: cannot move out of `foo` in pattern guard
 LL |                 (|| { let bar = foo; bar.take() })();
    |                  ^^             --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
    |                  |
-   |                  move out of `foo` occurs here
+   |                  `foo` is moved here
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
diff --git a/tests/ui/nll/issue-27868.stderr b/tests/ui/nll/issue-27868.stderr
index e0b3b5494d0a5..204eda3d26796 100644
--- a/tests/ui/nll/issue-27868.stderr
+++ b/tests/ui/nll/issue-27868.stderr
@@ -4,10 +4,10 @@ error[E0506]: cannot assign to `vecvec` because it is borrowed
 LL |       vecvec[0] += {
    |       ------
    |       |
-   |  _____borrow of `vecvec` occurs here
+   |  _____`vecvec` is borrowed here
    | |
 LL | |         vecvec = vec![];
-   | |         ^^^^^^ assignment to borrowed `vecvec` occurs here
+   | |         ^^^^^^ `vecvec` is assigned to here but it was already borrowed
 LL | |
 LL | |         0
 LL | |     };
diff --git a/tests/ui/nll/issue-46036.stderr b/tests/ui/nll/issue-46036.stderr
index e6e95ee613647..f337e23455070 100644
--- a/tests/ui/nll/issue-46036.stderr
+++ b/tests/ui/nll/issue-46036.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/issue-46036.rs:8:24
    |
+LL |     let a = 3;
+   |         - binding `a` declared here
 LL |     let foo = Foo { x: &a };
    |                        ^^
    |                        |
diff --git a/tests/ui/nll/issue-48803.stderr b/tests/ui/nll/issue-48803.stderr
index 2f94039c0c3a9..e24606e0b53e8 100644
--- a/tests/ui/nll/issue-48803.stderr
+++ b/tests/ui/nll/issue-48803.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/issue-48803.rs:10:5
    |
 LL |     let y = &x;
-   |             -- borrow of `x` occurs here
+   |             -- `x` is borrowed here
 ...
 LL |     x = "modified";
-   |     ^^^^^^^^^^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^^^^^^^^^^ `x` is assigned to here but it was already borrowed
 LL |
 LL |     println!("{}", w); // prints "modified"
    |                    - borrow later used here
diff --git a/tests/ui/nll/issue-52534-2.stderr b/tests/ui/nll/issue-52534-2.stderr
index ac385e056b9f8..35d39bb6e908d 100644
--- a/tests/ui/nll/issue-52534-2.stderr
+++ b/tests/ui/nll/issue-52534-2.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/issue-52534-2.rs:6:13
    |
+LL |         let x = 32;
+   |             - binding `x` declared here
 LL |         y = &x
    |             ^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/nll/issue-52663-trait-object.stderr b/tests/ui/nll/issue-52663-trait-object.stderr
index 5cedea6e66520..338f64841321f 100644
--- a/tests/ui/nll/issue-52663-trait-object.stderr
+++ b/tests/ui/nll/issue-52663-trait-object.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `tmp0` does not live long enough
   --> $DIR/issue-52663-trait-object.rs:12:20
    |
+LL |         let tmp0 = 3;
+   |             ---- binding `tmp0` declared here
 LL |         let tmp1 = &tmp0;
    |                    ^^^^^ borrowed value does not live long enough
 LL |         Box::new(tmp1) as Box<dyn Foo + '_>
diff --git a/tests/ui/nll/issue-54382-use-span-of-tail-of-block.stderr b/tests/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
index d8f43cbc92a1e..4a32c777a86f1 100644
--- a/tests/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
+++ b/tests/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `_thing1` does not live long enough
   --> $DIR/issue-54382-use-span-of-tail-of-block.rs:7:29
    |
+LL |         let mut _thing1 = D(Box::new("thing1"));
+   |             ----------- binding `_thing1` declared here
+...
 LL |             D("other").next(&_thing1)
    |             ----------------^^^^^^^^-
    |             |               |
diff --git a/tests/ui/nll/issue-54556-stephaneyfx.stderr b/tests/ui/nll/issue-54556-stephaneyfx.stderr
index 036a7a0abfdcc..f9e82cb003fc2 100644
--- a/tests/ui/nll/issue-54556-stephaneyfx.stderr
+++ b/tests/ui/nll/issue-54556-stephaneyfx.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `stmt` does not live long enough
   --> $DIR/issue-54556-stephaneyfx.rs:27:21
    |
+LL |     let stmt = Statement;
+   |         ---- binding `stmt` declared here
 LL |     let rows = Rows(&stmt);
    |                     ^^^^^ borrowed value does not live long enough
 LL |     rows.map(|row| row).next()
diff --git a/tests/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr b/tests/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
index 92f5ffdf388ed..4eae9fdcde0d2 100644
--- a/tests/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
+++ b/tests/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `_thing1` does not live long enough
   --> $DIR/issue-54556-temps-in-tail-diagnostic.rs:5:11
    |
+LL |         let mut _thing1 = D(Box::new("thing1"));
+   |             ----------- binding `_thing1` declared here
+LL |         // D("other").next(&_thing1).end()
 LL |         D(&_thing1).end()
    |         --^^^^^^^^-
    |         | |
diff --git a/tests/ui/nll/issue-54556-used-vs-unused-tails.stderr b/tests/ui/nll/issue-54556-used-vs-unused-tails.stderr
index 25226e2967353..a2a7a8486545c 100644
--- a/tests/ui/nll/issue-54556-used-vs-unused-tails.stderr
+++ b/tests/ui/nll/issue-54556-used-vs-unused-tails.stderr
@@ -2,11 +2,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:10:55
    |
 LL |     {              let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // suggest `;`
-   |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |              |
-   |                                                     | |              `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |              |
+   |                        |                            | |              `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
@@ -17,11 +18,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:13:55
    |
 LL |     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }  } ; // suggest `;`
-   |                                                     --^^^^-       -    - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |           |
-   |                                                     | |           `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-       -    - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |           |
+   |                        |                            | |           `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
@@ -32,11 +34,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:16:55
    |
 LL |     {            { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; }   // suggest `;`
-   |                                                     --^^^^-       -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |           |
-   |                                                     | |           `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-       -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |           |
+   |                        |                            | |           `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
@@ -47,11 +50,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:19:55
    |
 LL |     let _ =      { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // suggest `;`
-   |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |              |
-   |                                                     | |              `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |              |
+   |                        |                            | |              `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
@@ -62,11 +66,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:22:55
    |
 LL |     let _u =     { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   } ; // suggest `;`
-   |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |              |
-   |                                                     | |              `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |              |
+   |                        |                            | |              `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
@@ -77,11 +82,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:25:55
    |
 LL |     let _x =     { let mut _t1 = D(Box::new("t1")); D(&_t1).end()    } ; // `let x = ...; x`
-   |                                                     --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |              |
-   |                                                     | |              `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-          - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |              |
+   |                        |                            | |              `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
    = note: the temporary is part of an expression at the end of a block;
            consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
@@ -94,11 +100,12 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:30:55
    |
 LL |     _y =         { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x`
-   |                                                     --^^^^-       - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | |           |
-   |                                                     | |           `_t1` dropped here while still borrowed
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-       - - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | |           |
+   |                        |                            | |           `_t1` dropped here while still borrowed
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
    = note: the temporary is part of an expression at the end of a block;
            consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
@@ -111,12 +118,13 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:37:55
    |
 LL | fn f_local_ref() { let mut _t1 = D(Box::new("t1")); D(&_t1).unit()   }  // suggest `;`
-   |                                                     --^^^^-          -
-   |                                                     | |              |
-   |                                                     | |              `_t1` dropped here while still borrowed
-   |                                                     | |              ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-          -
+   |                        |                            | |              |
+   |                        |                            | |              `_t1` dropped here while still borrowed
+   |                        |                            | |              ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
 help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
    |
@@ -127,12 +135,13 @@ error[E0597]: `_t1` does not live long enough
   --> $DIR/issue-54556-used-vs-unused-tails.rs:40:55
    |
 LL | fn f() -> String { let mut _t1 = D(Box::new("t1")); D(&_t1).end()   }   // `let x = ...; x`
-   |                                                     --^^^^-         -
-   |                                                     | |             |
-   |                                                     | |             `_t1` dropped here while still borrowed
-   |                                                     | |             ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
-   |                                                     | borrowed value does not live long enough
-   |                                                     a temporary with access to the borrow is created here ...
+   |                        -------                      --^^^^-         -
+   |                        |                            | |             |
+   |                        |                            | |             `_t1` dropped here while still borrowed
+   |                        |                            | |             ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+   |                        |                            | borrowed value does not live long enough
+   |                        |                            a temporary with access to the borrow is created here ...
+   |                        binding `_t1` declared here
    |
    = note: the temporary is part of an expression at the end of a block;
            consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
diff --git a/tests/ui/nll/issue-54556-wrap-it-up.stderr b/tests/ui/nll/issue-54556-wrap-it-up.stderr
index 9f27fac15a7f6..adc419ae51562 100644
--- a/tests/ui/nll/issue-54556-wrap-it-up.stderr
+++ b/tests/ui/nll/issue-54556-wrap-it-up.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/issue-54556-wrap-it-up.rs:27:5
    |
 LL |     let wrap = Wrap { p: &mut x };
-   |                          ------ borrow of `x` occurs here
+   |                          ------ `x` is borrowed here
 ...
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL | }
    | - borrow might be used here, when `foo` is dropped and runs the destructor for type `Foo<'_>`
 
diff --git a/tests/ui/nll/issue-55511.stderr b/tests/ui/nll/issue-55511.stderr
index bf3e58e8cdb19..ecb9ef0aef96e 100644
--- a/tests/ui/nll/issue-55511.stderr
+++ b/tests/ui/nll/issue-55511.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/issue-55511.rs:13:28
    |
+LL |     let a = 22;
+   |         - binding `a` declared here
 LL |     let b = Some(Cell::new(&a));
    |                            ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/issue-57989.stderr b/tests/ui/nll/issue-57989.stderr
index 31f40d8252ed6..d5effd6f346d1 100644
--- a/tests/ui/nll/issue-57989.stderr
+++ b/tests/ui/nll/issue-57989.stderr
@@ -13,9 +13,9 @@ error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-57989.rs:5:5
    |
 LL |     let g = &x;
-   |             -- borrow of `*x` occurs here
+   |             -- `*x` is borrowed here
 LL |     *x = 0;
-   |     ^^^^^^ assignment to borrowed `*x` occurs here
+   |     ^^^^^^ `*x` is assigned to here but it was already borrowed
 LL |
 LL |     g;
    |     - borrow later used here
diff --git a/tests/ui/nll/issue-68550.stderr b/tests/ui/nll/issue-68550.stderr
index e234ebb04e16a..851e3628748f2 100644
--- a/tests/ui/nll/issue-68550.stderr
+++ b/tests/ui/nll/issue-68550.stderr
@@ -2,7 +2,9 @@ error[E0597]: `x` does not live long enough
   --> $DIR/issue-68550.rs:12:20
    |
 LL | fn run<'a, A>(x: A)
-   |        -- lifetime `'a` defined here
+   |        --     - binding `x` declared here
+   |        |
+   |        lifetime `'a` defined here
 ...
 LL |     let _: &'a A = &x;
    |            -----   ^^ borrowed value does not live long enough
diff --git a/tests/ui/nll/issue-69114-static-mut-ty.stderr b/tests/ui/nll/issue-69114-static-mut-ty.stderr
index 5e55cb502caa9..1b41230d7ba39 100644
--- a/tests/ui/nll/issue-69114-static-mut-ty.stderr
+++ b/tests/ui/nll/issue-69114-static-mut-ty.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `n` does not live long enough
   --> $DIR/issue-69114-static-mut-ty.rs:19:15
    |
+LL |     let n = 42;
+   |         - binding `n` declared here
+LL |     unsafe {
 LL |         BAR = &n;
    |         ------^^
    |         |     |
@@ -13,6 +16,9 @@ LL | }
 error[E0597]: `n` does not live long enough
   --> $DIR/issue-69114-static-mut-ty.rs:27:22
    |
+LL |     let n = 42;
+   |         - binding `n` declared here
+LL |     unsafe {
 LL |         BAR_ELIDED = &n;
    |         -------------^^
    |         |            |
diff --git a/tests/ui/nll/issue-69114-static-ty.stderr b/tests/ui/nll/issue-69114-static-ty.stderr
index 0815e74b5537d..9215e850f7d8f 100644
--- a/tests/ui/nll/issue-69114-static-ty.stderr
+++ b/tests/ui/nll/issue-69114-static-ty.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `n` does not live long enough
   --> $DIR/issue-69114-static-ty.rs:7:9
    |
+LL |     let n = 42;
+   |         - binding `n` declared here
 LL |     FOO(&n);
    |     ----^^-
    |     |   |
diff --git a/tests/ui/nll/loan_ends_mid_block_pair.stderr b/tests/ui/nll/loan_ends_mid_block_pair.stderr
index eb8442b31d7c7..58e378ab02118 100644
--- a/tests/ui/nll/loan_ends_mid_block_pair.stderr
+++ b/tests/ui/nll/loan_ends_mid_block_pair.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `data.0` because it is borrowed
   --> $DIR/loan_ends_mid_block_pair.rs:12:5
    |
 LL |     let c = &mut data.0;
-   |             ----------- borrow of `data.0` occurs here
+   |             ----------- `data.0` is borrowed here
 LL |     capitalize(c);
 LL |     data.0 = 'e';
-   |     ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here
+   |     ^^^^^^^^^^^^ `data.0` is assigned to here but it was already borrowed
 ...
 LL |     capitalize(c);
    |                - borrow later used here
diff --git a/tests/ui/nll/local-outlives-static-via-hrtb.stderr b/tests/ui/nll/local-outlives-static-via-hrtb.stderr
index f5c10f3ddea0e..a6b3328b5a294 100644
--- a/tests/ui/nll/local-outlives-static-via-hrtb.stderr
+++ b/tests/ui/nll/local-outlives-static-via-hrtb.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `local` does not live long enough
   --> $DIR/local-outlives-static-via-hrtb.rs:24:28
    |
+LL |     let local = 0;
+   |         ----- binding `local` declared here
 LL |     assert_static_via_hrtb(&local);
    |     -----------------------^^^^^^-
    |     |                      |
@@ -19,6 +21,9 @@ LL | fn assert_static_via_hrtb<G>(_: G) where for<'a> G: Outlives<'a> {}
 error[E0597]: `local` does not live long enough
   --> $DIR/local-outlives-static-via-hrtb.rs:25:45
    |
+LL |     let local = 0;
+   |         ----- binding `local` declared here
+LL |     assert_static_via_hrtb(&local);
 LL |     assert_static_via_hrtb_with_assoc_type(&&local);
    |     ----------------------------------------^^^^^^-
    |     |                                       |
diff --git a/tests/ui/nll/match-cfg-fake-edges2.stderr b/tests/ui/nll/match-cfg-fake-edges2.stderr
index c6d15a936d819..36f2cd0b85d1c 100644
--- a/tests/ui/nll/match-cfg-fake-edges2.stderr
+++ b/tests/ui/nll/match-cfg-fake-edges2.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `y.1` because it was mutably borrowed
   --> $DIR/match-cfg-fake-edges2.rs:8:5
    |
 LL |     let r = &mut y.1;
-   |             -------- borrow of `y.1` occurs here
+   |             -------- `y.1` is borrowed here
 ...
 LL |     match y {
    |     ^^^^^^^ use of borrowed `y.1`
diff --git a/tests/ui/nll/match-guards-always-borrow.stderr b/tests/ui/nll/match-guards-always-borrow.stderr
index fa01d3a6fd1e0..afd853c403ee3 100644
--- a/tests/ui/nll/match-guards-always-borrow.stderr
+++ b/tests/ui/nll/match-guards-always-borrow.stderr
@@ -4,7 +4,7 @@ error[E0507]: cannot move out of `foo` in pattern guard
 LL |             (|| { let bar = foo; bar.take() })();
    |              ^^             --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
    |              |
-   |              move out of `foo` occurs here
+   |              `foo` is moved here
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
@@ -14,7 +14,7 @@ error[E0507]: cannot move out of `foo` in pattern guard
 LL |             (|| { let bar = foo; bar.take() })();
    |              ^^             --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
    |              |
-   |              move out of `foo` occurs here
+   |              `foo` is moved here
    |
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
diff --git a/tests/ui/nll/match-guards-partially-borrow.stderr b/tests/ui/nll/match-guards-partially-borrow.stderr
index 60b8dee71a863..7bdcbcb9c6ef6 100644
--- a/tests/ui/nll/match-guards-partially-borrow.stderr
+++ b/tests/ui/nll/match-guards-partially-borrow.stderr
@@ -74,9 +74,9 @@ error[E0506]: cannot assign to `t` because it is borrowed
   --> $DIR/match-guards-partially-borrow.rs:225:13
    |
 LL |         s if {
-   |         - borrow of `t` occurs here
+   |         - `t` is borrowed here
 LL |             t = !t;
-   |             ^^^^^^ assignment to borrowed `t` occurs here
+   |             ^^^^^^ `t` is assigned to here but it was already borrowed
 LL |             false
 LL |         } => (), // What value should `s` have in the arm?
    |         - borrow later used here
@@ -85,9 +85,9 @@ error[E0506]: cannot assign to `t` because it is borrowed
   --> $DIR/match-guards-partially-borrow.rs:235:13
    |
 LL |         s if let Some(()) = {
-   |         - borrow of `t` occurs here
+   |         - `t` is borrowed here
 LL |             t = !t;
-   |             ^^^^^^ assignment to borrowed `t` occurs here
+   |             ^^^^^^ `t` is assigned to here but it was already borrowed
 LL |             None
 LL |         } => (), // What value should `s` have in the arm?
    |         - borrow later used here
diff --git a/tests/ui/nll/match-on-borrowed.stderr b/tests/ui/nll/match-on-borrowed.stderr
index 32666529f3f95..9273484565a19 100644
--- a/tests/ui/nll/match-on-borrowed.stderr
+++ b/tests/ui/nll/match-on-borrowed.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `e` because it was mutably borrowed
   --> $DIR/match-on-borrowed.rs:47:11
    |
 LL |         E::V(ref mut x, _) => x,
-   |              --------- borrow of `e.0` occurs here
+   |              --------- `e.0` is borrowed here
 ...
 LL |     match e { // Don't know that E uses a tag for its discriminant
    |           ^ use of borrowed `e.0`
@@ -14,7 +14,7 @@ error[E0503]: cannot use `*f` because it was mutably borrowed
   --> $DIR/match-on-borrowed.rs:61:11
    |
 LL |         E::V(ref mut x, _) => x,
-   |              --------- borrow of `f.0` occurs here
+   |              --------- `f.0` is borrowed here
 ...
 LL |     match f { // Don't know that E uses a tag for its discriminant
    |           ^ use of borrowed `f.0`
@@ -26,7 +26,7 @@ error[E0503]: cannot use `t` because it was mutably borrowed
   --> $DIR/match-on-borrowed.rs:81:5
    |
 LL |     let x = &mut t;
-   |             ------ borrow of `t` occurs here
+   |             ------ `t` is borrowed here
 LL |     match t {
    |     ^^^^^^^ use of borrowed `t`
 ...
diff --git a/tests/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr b/tests/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr
index 80e297807465d..55646b9dca986 100644
--- a/tests/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr
+++ b/tests/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/maybe-initialized-drop-implicit-fragment-drop.rs:17:5
    |
 LL |     let wrap = Wrap { p: &mut x };
-   |                          ------ borrow of `x` occurs here
+   |                          ------ `x` is borrowed here
 ...
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     // FIXME ^ Should not error in the future with implicit dtors, only manually implemented ones
 LL | }
    | - borrow might be used here, when `foo` is dropped and runs the destructor for type `Foo<'_>`
diff --git a/tests/ui/nll/maybe-initialized-drop-with-fragment.stderr b/tests/ui/nll/maybe-initialized-drop-with-fragment.stderr
index 14074472eaf88..c89f94a7894f0 100644
--- a/tests/ui/nll/maybe-initialized-drop-with-fragment.stderr
+++ b/tests/ui/nll/maybe-initialized-drop-with-fragment.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/maybe-initialized-drop-with-fragment.rs:19:5
    |
 LL |     let wrap = Wrap { p: &mut x };
-   |                          ------ borrow of `x` occurs here
+   |                          ------ `x` is borrowed here
 ...
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL | }
    | - borrow might be used here, when `foo` is dropped and runs the destructor for type `Foo<'_>`
 
diff --git a/tests/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr b/tests/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr
index 91c0afc1dbaa1..90db13bc57849 100644
--- a/tests/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr
+++ b/tests/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/maybe-initialized-drop-with-uninitialized-fragments.rs:20:5
    |
 LL |     let wrap = Wrap { p: &mut x };
-   |                          ------ borrow of `x` occurs here
+   |                          ------ `x` is borrowed here
 ...
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL |     // FIXME ^ This currently errors and it should not.
 LL | }
    | - borrow might be used here, when `foo` is dropped and runs the destructor for type `Foo<'_>`
diff --git a/tests/ui/nll/maybe-initialized-drop.stderr b/tests/ui/nll/maybe-initialized-drop.stderr
index 9825ba4611b7d..15a53a09af8c2 100644
--- a/tests/ui/nll/maybe-initialized-drop.stderr
+++ b/tests/ui/nll/maybe-initialized-drop.stderr
@@ -2,9 +2,9 @@ error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/maybe-initialized-drop.rs:14:5
    |
 LL |     let wrap = Wrap { p: &mut x };
-   |                          ------ borrow of `x` occurs here
+   |                          ------ `x` is borrowed here
 LL |     x = 1;
-   |     ^^^^^ assignment to borrowed `x` occurs here
+   |     ^^^^^ `x` is assigned to here but it was already borrowed
 LL | }
    | - borrow might be used here, when `wrap` is dropped and runs the `Drop` code for type `Wrap`
 
diff --git a/tests/ui/nll/polonius/polonius-smoke-test.stderr b/tests/ui/nll/polonius/polonius-smoke-test.stderr
index fa1a6a9c95786..789d202f73a7b 100644
--- a/tests/ui/nll/polonius/polonius-smoke-test.stderr
+++ b/tests/ui/nll/polonius/polonius-smoke-test.stderr
@@ -8,7 +8,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/polonius-smoke-test.rs:12:13
    |
 LL |     let y = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     let z = x;
    |             ^ use of borrowed `x`
 LL |     let w = y;
diff --git a/tests/ui/nll/promoted-bounds.stderr b/tests/ui/nll/promoted-bounds.stderr
index df347f4e7f0fe..d111256b8454f 100644
--- a/tests/ui/nll/promoted-bounds.stderr
+++ b/tests/ui/nll/promoted-bounds.stderr
@@ -4,6 +4,7 @@ error[E0597]: `l` does not live long enough
 LL |     let ptr = {
    |         --- borrow later stored here
 LL |         let l = 3;
+   |             - binding `l` declared here
 LL |         let b = &l;
    |                 ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/reference-carried-through-struct-field.stderr b/tests/ui/nll/reference-carried-through-struct-field.stderr
index 56d878e43033b..5672b9cd7e9cc 100644
--- a/tests/ui/nll/reference-carried-through-struct-field.stderr
+++ b/tests/ui/nll/reference-carried-through-struct-field.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/reference-carried-through-struct-field.rs:6:5
    |
 LL |     let wrapper = Wrap { w: &mut x };
-   |                             ------ borrow of `x` occurs here
+   |                             ------ `x` is borrowed here
 LL |     x += 1;
    |     ^^^^^^ use of borrowed `x`
 LL |     *wrapper.w += 1;
diff --git a/tests/ui/nll/relate_tys/var-appears-twice.stderr b/tests/ui/nll/relate_tys/var-appears-twice.stderr
index d032ce6f2132c..ff6ea598ff46f 100644
--- a/tests/ui/nll/relate_tys/var-appears-twice.stderr
+++ b/tests/ui/nll/relate_tys/var-appears-twice.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `b` does not live long enough
   --> $DIR/var-appears-twice.rs:20:38
    |
+LL |     let b = 44;
+   |         - binding `b` declared here
+...
 LL |     let x: DoubleCell<_> = make_cell(&b);
    |            -------------             ^^ borrowed value does not live long enough
    |            |
diff --git a/tests/ui/nll/user-annotations/adt-brace-enums.stderr b/tests/ui/nll/user-annotations/adt-brace-enums.stderr
index 253e382511045..9e94fd5a7826e 100644
--- a/tests/ui/nll/user-annotations/adt-brace-enums.stderr
+++ b/tests/ui/nll/user-annotations/adt-brace-enums.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-brace-enums.rs:25:48
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeEnum::SomeVariant::<&'static u32> { t: &c };
    |                                                ^^
    |                                                |
@@ -15,6 +17,7 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeEnum::SomeVariant::<&'a u32> { t: &c };
    |                                           ^^
    |                                           |
diff --git a/tests/ui/nll/user-annotations/adt-brace-structs.stderr b/tests/ui/nll/user-annotations/adt-brace-structs.stderr
index 8b9d1705df6ad..cbb7f6a55a989 100644
--- a/tests/ui/nll/user-annotations/adt-brace-structs.stderr
+++ b/tests/ui/nll/user-annotations/adt-brace-structs.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-brace-structs.rs:23:37
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeStruct::<&'static u32> { t: &c };
    |                                     ^^
    |                                     |
@@ -15,6 +17,7 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeStruct::<&'a u32> { t: &c };
    |                                ^^
    |                                |
diff --git a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr
index 3326fa521fc9c..bca85a90d1908 100644
--- a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr
+++ b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-nullary-enums.rs:33:41
    |
+LL |       let c = 66;
+   |           - binding `c` declared here
 LL | /     combine(
 LL | |         SomeEnum::SomeVariant(Cell::new(&c)),
    | |                                         ^^ borrowed value does not live long enough
@@ -15,7 +17,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
-...
+LL |     let c = 66;
+   |         - binding `c` declared here
+LL |     combine(
 LL |         SomeEnum::SomeVariant(Cell::new(&c)),
    |                               ----------^^-
    |                               |         |
diff --git a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr
index 2fa7042631d21..d2d85ec2b9b0f 100644
--- a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr
+++ b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-tuple-enums.rs:28:43
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeEnum::SomeVariant::<&'static u32>(&c);
    |                                           ^^
    |                                           |
@@ -15,6 +17,7 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeEnum::SomeVariant::<&'a u32>(&c);
    |                                      ^^
    |                                      |
diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
index 9664fb9f54831..b7bc2a10b7040 100644
--- a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
+++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-tuple-struct-calls.rs:27:7
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
+LL |     let f = SomeStruct::<&'static u32>;
 LL |     f(&c);
    |     --^^-
    |     | |
@@ -14,7 +17,9 @@ error[E0597]: `c` does not live long enough
    |
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
-...
+LL |     let c = 66;
+   |         - binding `c` declared here
+LL |     let f = SomeStruct::<&'a u32>;
 LL |     f(&c);
    |     --^^-
    |     | |
diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr
index 76b5252258c7b..97d39da265fe3 100644
--- a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr
+++ b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/adt-tuple-struct.rs:23:32
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeStruct::<&'static u32>(&c);
    |                                ^^
    |                                |
@@ -15,6 +17,7 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     SomeStruct::<&'a u32>(&c);
    |                           ^^
    |                           |
diff --git a/tests/ui/nll/user-annotations/cast_static_lifetime.stderr b/tests/ui/nll/user-annotations/cast_static_lifetime.stderr
index 4599d04e7e230..3b9363c41f20f 100644
--- a/tests/ui/nll/user-annotations/cast_static_lifetime.stderr
+++ b/tests/ui/nll/user-annotations/cast_static_lifetime.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/cast_static_lifetime.rs:5:19
    |
+LL |     let x = 22_u32;
+   |         - binding `x` declared here
 LL |     let y: &u32 = (&x) as &'static u32;
    |                   ^^^^----------------
    |                   |
diff --git a/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr b/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr
index 12065a85aa4a0..f164255ef305f 100644
--- a/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr
+++ b/tests/ui/nll/user-annotations/constant-in-expr-inherent-2.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/constant-in-expr-inherent-2.rs:23:9
    |
+LL |     let x = ();
+   |         - binding `x` declared here
 LL |     FUN(&x);
    |     ----^^-
    |     |   |
@@ -13,6 +15,9 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/constant-in-expr-inherent-2.rs:24:23
    |
+LL |     let x = ();
+   |         - binding `x` declared here
+LL |     FUN(&x);
 LL |     A::ASSOCIATED_FUN(&x);
    |     ------------------^^-
    |     |                 |
@@ -25,6 +30,9 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/constant-in-expr-inherent-2.rs:25:28
    |
+LL |     let x = ();
+   |         - binding `x` declared here
+...
 LL |     B::ALSO_ASSOCIATED_FUN(&x);
    |     -----------------------^^-
    |     |                      |
@@ -37,6 +45,9 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/constant-in-expr-inherent-2.rs:26:31
    |
+LL |     let x = ();
+   |         - binding `x` declared here
+...
 LL |     <_>::TRAIT_ASSOCIATED_FUN(&x);
    |     --------------------------^^-
    |     |                         |
diff --git a/tests/ui/nll/user-annotations/fns.stderr b/tests/ui/nll/user-annotations/fns.stderr
index e0640da39e2b6..8b53e138d9bd0 100644
--- a/tests/ui/nll/user-annotations/fns.stderr
+++ b/tests/ui/nll/user-annotations/fns.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/fns.rs:23:29
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     some_fn::<&'static u32>(&c);
    |     ------------------------^^-
    |     |                       |
@@ -15,6 +17,7 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     some_fn::<&'a u32>(&c);
    |     -------------------^^-
    |     |                  |
diff --git a/tests/ui/nll/user-annotations/method-call.stderr b/tests/ui/nll/user-annotations/method-call.stderr
index 10447e45a6d42..3803cbf776b67 100644
--- a/tests/ui/nll/user-annotations/method-call.stderr
+++ b/tests/ui/nll/user-annotations/method-call.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/method-call.rs:36:34
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     a.method::<&'static u32>(b,  &c);
    |     -----------------------------^^-
    |     |                            |
@@ -15,6 +17,8 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 ...
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     a.method::<&'a u32>(b,  &c);
    |     ------------------------^^-
    |     |                       |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-1.stderr
index 962ddfd2bd151..c7c08c948abdb 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-1.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-1.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/method-ufcs-1.rs:30:7
    |
+LL |     let a = 22;
+   |         - binding `a` declared here
+...
 LL |     x(&a, b, c);
    |     --^^-------
    |     | |
@@ -14,6 +17,8 @@ error[E0597]: `a` does not live long enough
    |
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
+LL |     let a = 22;
+   |         - binding `a` declared here
 ...
 LL |     <&'a u32 as Bazoom<_>>::method(&a, b, c);
    |     -------------------------------^^-------
diff --git a/tests/ui/nll/user-annotations/method-ufcs-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-2.stderr
index 63d59905e1c38..b7861a3bd069f 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-2.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-2.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/method-ufcs-2.rs:30:7
    |
+LL |     let a = 22;
+   |         - binding `a` declared here
+...
 LL |     x(&a, b, c);
    |     --^^-------
    |     | |
@@ -14,7 +17,10 @@ error[E0597]: `b` does not live long enough
    |
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
-...
+LL |     let a = 22;
+LL |     let b = 44;
+   |         - binding `b` declared here
+LL |     let c = 66;
 LL |     <_ as Bazoom<&'a u32>>::method(a, &b, c);
    |     ----------------------------------^^----
    |     |                                 |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-3.stderr
index e7851833e93b2..8cb995a03ce2f 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-3.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-3.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/method-ufcs-3.rs:36:53
    |
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     <_ as Bazoom<_>>::method::<&'static u32>(&a, b, &c);
    |     ------------------------------------------------^^-
    |     |                                               |
@@ -15,6 +17,8 @@ error[E0597]: `c` does not live long enough
 LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
    |                                   -- lifetime `'a` defined here
 ...
+LL |     let c = 66;
+   |         - binding `c` declared here
 LL |     <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c);
    |     -------------------------------------------^^-
    |     |                                          |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr
index 94861babd6f32..fb26b8d09e179 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-1.stderr
@@ -4,6 +4,7 @@ error[E0597]: `v` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let v = 22;
+   |         - binding `v` declared here
 LL |     let x = A::<'a>::new(&v, 22);
    |             -------------^^-----
    |             |            |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr
index 06f20d9b23559..03b97447e1aa0 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-2.stderr
@@ -4,6 +4,7 @@ error[E0597]: `v` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let v = 22;
+   |         - binding `v` declared here
 LL |     let x = A::<'a>::new::<&'a u32>(&v, &v);
    |             ------------------------^^-----
    |             |                       |
@@ -19,6 +20,7 @@ error[E0597]: `v` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let v = 22;
+   |         - binding `v` declared here
 LL |     let x = A::<'a>::new::<&'a u32>(&v, &v);
    |             ----------------------------^^-
    |             |                           |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr
index 4ad61dc81c493..69dd1d1aaae28 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-3.stderr
@@ -4,6 +4,7 @@ error[E0597]: `v` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let v = 22;
+   |         - binding `v` declared here
 LL |     let x = <A<'a>>::new(&v, 22);
    |             -------------^^-----
    |             |            |
diff --git a/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr b/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr
index 0f83e99cdfb92..66d82bb49dc68 100644
--- a/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr
+++ b/tests/ui/nll/user-annotations/method-ufcs-inherent-4.stderr
@@ -4,6 +4,7 @@ error[E0597]: `v` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let v = 22;
+   |         - binding `v` declared here
 LL |     let x = <A<'a>>::new::<&'a u32>(&v, &v);
    |             ------------------------^^-----
    |             |                       |
@@ -19,6 +20,7 @@ error[E0597]: `v` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let v = 22;
+   |         - binding `v` declared here
 LL |     let x = <A<'a>>::new::<&'a u32>(&v, &v);
    |             ----------------------------^^-
    |             |                           |
diff --git a/tests/ui/nll/user-annotations/normalization.stderr b/tests/ui/nll/user-annotations/normalization.stderr
index 975cb4b66d91d..acc3a1800f4fd 100644
--- a/tests/ui/nll/user-annotations/normalization.stderr
+++ b/tests/ui/nll/user-annotations/normalization.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/normalization.rs:10:31
    |
+LL |     let a = 22;
+   |         - binding `a` declared here
 LL |     let _: <() as Foo>::Out = &a;
    |            ----------------   ^^ borrowed value does not live long enough
    |            |
@@ -12,6 +14,8 @@ LL | }
 error[E0597]: `a` does not live long enough
   --> $DIR/normalization.rs:13:40
    |
+LL |     let a = 22;
+   |         - binding `a` declared here
 LL |     let _: <&'static () as Foo>::Out = &a;
    |            -------------------------   ^^ borrowed value does not live long enough
    |            |
diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr
index a97e7a9fd46fc..3e7969e117934 100644
--- a/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr
+++ b/tests/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_brace_enum_variant.rs:7:33
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo::Bar { field: &y };
    |                                 ^^ borrowed value does not live long enough
 LL |
@@ -12,6 +14,8 @@ LL | }
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_brace_enum_variant.rs:14:33
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo::Bar { field: &y };
    |                                 ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr
index 408d7c2a5e2a5..89a1e9545e8af 100644
--- a/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr
+++ b/tests/ui/nll/user-annotations/pattern_substs_on_brace_struct.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_brace_struct.rs:5:28
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo { field: &y };
    |                            ^^ borrowed value does not live long enough
 LL |
@@ -12,6 +14,8 @@ LL | }
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_brace_struct.rs:12:28
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo { field: &y };
    |                            ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr
index 920c906f63a58..8efeecc77098a 100644
--- a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr
+++ b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_tuple_enum_variant.rs:7:24
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo::Bar(&y);
    |                        ^^ borrowed value does not live long enough
 LL |
@@ -12,6 +14,8 @@ LL | }
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_tuple_enum_variant.rs:14:24
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo::Bar(&y);
    |                        ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr
index 3f01638d84757..d7f1dac88a618 100644
--- a/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr
+++ b/tests/ui/nll/user-annotations/pattern_substs_on_tuple_struct.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_tuple_struct.rs:5:19
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo(&y);
    |                   ^^ borrowed value does not live long enough
 LL |
@@ -12,6 +14,8 @@ LL | }
 error[E0597]: `y` does not live long enough
   --> $DIR/pattern_substs_on_tuple_struct.rs:12:19
    |
+LL |     let y = 22;
+   |         - binding `y` declared here
 LL |     let foo = Foo(&y);
    |                   ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/nll/user-annotations/patterns.stderr b/tests/ui/nll/user-annotations/patterns.stderr
index de6f8f80fe252..8bb714f1d0cdc 100644
--- a/tests/ui/nll/user-annotations/patterns.stderr
+++ b/tests/ui/nll/user-annotations/patterns.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:6:9
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let y: &'static u32;
    |            ------------ type annotation requires that `x` is borrowed for `'static`
 LL |     y = &x;
@@ -11,6 +13,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:14:9
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let (y, z): (&'static u32, &'static u32);
    |                 ---------------------------- type annotation requires that `x` is borrowed for `'static`
 LL |     y = &x;
@@ -21,6 +25,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:20:13
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let y = &x;
    |             ^^ borrowed value does not live long enough
 LL |     let ref z: &'static u32 = y;
@@ -32,6 +38,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:39:9
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let Single { value: y }: Single<&'static u32>;
    |                              -------------------- type annotation requires that `x` is borrowed for `'static`
 LL |     y = &x;
@@ -42,6 +50,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:51:10
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let Single2 { value: mut _y }: Single2<StaticU32>;
    |                                    ------------------ type annotation requires that `x` is borrowed for `'static`
 LL |     _y = &x;
@@ -52,6 +62,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:56:27
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let y: &'static u32 = &x;
    |            ------------   ^^ borrowed value does not live long enough
    |            |
@@ -62,6 +74,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:61:27
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let _: &'static u32 = &x;
    |            ------------   ^^ borrowed value does not live long enough
    |            |
@@ -100,6 +114,8 @@ LL |     let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:75:40
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let (_, _): (&'static u32, u32) = (&x, 44);
    |                 -------------------    ^^ borrowed value does not live long enough
    |                 |
@@ -110,6 +126,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:80:40
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let (y, _): (&'static u32, u32) = (&x, 44);
    |                 -------------------    ^^ borrowed value does not live long enough
    |                 |
@@ -120,6 +138,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:85:69
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let Single { value: y }: Single<&'static u32> = Single { value: &x };
    |                              --------------------                   ^^ borrowed value does not live long enough
    |                              |
@@ -130,6 +150,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:90:69
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let Single { value: _ }: Single<&'static u32> = Single { value: &x };
    |                              --------------------                   ^^ borrowed value does not live long enough
    |                              |
@@ -140,6 +162,8 @@ LL | }
 error[E0597]: `x` does not live long enough
   --> $DIR/patterns.rs:98:17
    |
+LL |     let x = 22;
+   |         - binding `x` declared here
 LL |     let Double { value1: _, value2: _ }: Double<&'static u32> = Double {
    |                                          -------------------- type annotation requires that `x` is borrowed for `'static`
 LL |         value1: &x,
diff --git a/tests/ui/nll/user-annotations/promoted-annotation.stderr b/tests/ui/nll/user-annotations/promoted-annotation.stderr
index cb99a6a369d0b..132a00ba41581 100644
--- a/tests/ui/nll/user-annotations/promoted-annotation.stderr
+++ b/tests/ui/nll/user-annotations/promoted-annotation.stderr
@@ -4,6 +4,7 @@ error[E0597]: `x` does not live long enough
 LL | fn foo<'a>() {
    |        -- lifetime `'a` defined here
 LL |     let x = 0;
+   |         - binding `x` declared here
 LL |     let f = &drop::<&'a i32>;
    |             ---------------- assignment requires that `x` is borrowed for `'a`
 LL |     f(&x);
diff --git a/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr
index ccbf3c1d927c6..766877f8835c4 100644
--- a/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr
+++ b/tests/ui/nll/user-annotations/type_ascription_static_lifetime.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/type_ascription_static_lifetime.rs:6:33
    |
+LL |     let x = 22_u32;
+   |         - binding `x` declared here
 LL |     let y: &u32 = type_ascribe!(&x, &'static u32);
    |                   --------------^^---------------
    |                   |             |
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
index 1b93267b39771..c7c7c074f7cd0 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `arr[..]` because it is borrowed
   --> $DIR/borrowck-move-ref-pattern.rs:8:24
    |
+LL |     let mut arr = [U, U, U, U, U];
+   |         ------- binding `arr` declared here
 LL |     let hold_all = &arr;
    |                    ---- borrow of `arr` occurs here
 LL |     let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr;
diff --git a/tests/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr b/tests/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr
index 6ea238f302f3f..d76a83b025809 100644
--- a/tests/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr
+++ b/tests/ui/regions/do-not-suggest-adding-bound-to-opaque-type.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/do-not-suggest-adding-bound-to-opaque-type.rs:9:7
    |
+LL |     let x = ();
+   |         - binding `x` declared here
 LL |     S(&x)
    |     --^^-
    |     | |
diff --git a/tests/ui/regions/regions-addr-of-arg.stderr b/tests/ui/regions/regions-addr-of-arg.stderr
index e77289287e536..99060a9c7f59f 100644
--- a/tests/ui/regions/regions-addr-of-arg.stderr
+++ b/tests/ui/regions/regions-addr-of-arg.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/regions-addr-of-arg.rs:5:30
    |
+LL | fn foo(a: isize) {
+   |        - binding `a` declared here
 LL |     let _p: &'static isize = &a;
    |             --------------   ^^ borrowed value does not live long enough
    |             |
diff --git a/tests/ui/regions/regions-free-region-ordering-caller1.stderr b/tests/ui/regions/regions-free-region-ordering-caller1.stderr
index 8ef7e22536bf9..c83cfc1c987b6 100644
--- a/tests/ui/regions/regions-free-region-ordering-caller1.stderr
+++ b/tests/ui/regions/regions-free-region-ordering-caller1.stderr
@@ -18,6 +18,8 @@ error[E0597]: `y` does not live long enough
 LL | fn call1<'a>(x: &'a usize) {
    |          -- lifetime `'a` defined here
 ...
+LL |     let y: usize = 3;
+   |         - binding `y` declared here
 LL |     let z: &'a & usize = &(&y);
    |            -----------    ^^^^ borrowed value does not live long enough
    |            |
diff --git a/tests/ui/regions/regions-infer-proc-static-upvar.stderr b/tests/ui/regions/regions-infer-proc-static-upvar.stderr
index 803d0d7449108..c8a33bbc52236 100644
--- a/tests/ui/regions/regions-infer-proc-static-upvar.stderr
+++ b/tests/ui/regions/regions-infer-proc-static-upvar.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/regions-infer-proc-static-upvar.rs:10:13
    |
+LL |       let x = 3;
+   |           - binding `x` declared here
 LL |       let y = &x;
    |               ^^ borrowed value does not live long enough
 LL | /     foo(move|| {
diff --git a/tests/ui/regions/regions-nested-fns.stderr b/tests/ui/regions/regions-nested-fns.stderr
index bb2740310f6a1..ee43f9fa5724d 100644
--- a/tests/ui/regions/regions-nested-fns.stderr
+++ b/tests/ui/regions/regions-nested-fns.stderr
@@ -13,6 +13,8 @@ LL |         ay = z;
 error[E0597]: `y` does not live long enough
   --> $DIR/regions-nested-fns.rs:5:18
    |
+LL |     let y = 3;
+   |         - binding `y` declared here
 LL |     let mut ay = &y;
    |                  ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr
index f77d94a24b88f..18aec29ad0b74 100644
--- a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr
+++ b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `line` does not live long enough
   --> $DIR/regions-pattern-typing-issue-19552.rs:5:14
    |
+LL |     let line = String::new();
+   |         ---- binding `line` declared here
 LL |     match [&*line] {
    |              ^^^^ borrowed value does not live long enough
 LL |         [ word ] => { assert_static(word); }
diff --git a/tests/ui/regions/regions-pattern-typing-issue-19997.stderr b/tests/ui/regions/regions-pattern-typing-issue-19997.stderr
index ae60e3c0d5d67..0abe77a86977f 100644
--- a/tests/ui/regions/regions-pattern-typing-issue-19997.stderr
+++ b/tests/ui/regions/regions-pattern-typing-issue-19997.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `a1` because it is borrowed
   --> $DIR/regions-pattern-typing-issue-19997.rs:7:13
    |
 LL |     match (&a1,) {
-   |            --- borrow of `a1` occurs here
+   |            --- `a1` is borrowed here
 LL |         (&ref b0,) => {
 LL |             a1 = &f;
-   |             ^^^^^^^ assignment to borrowed `a1` occurs here
+   |             ^^^^^^^ `a1` is assigned to here but it was already borrowed
 LL |             drop(b0);
    |                  -- borrow later used here
 
diff --git a/tests/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr b/tests/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
index de730ce1030f2..ad84ebe3a504c 100644
--- a/tests/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
+++ b/tests/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/borrowck-non-exhaustive.rs:12:11
    |
 LL |     let y = &mut x;
-   |             ------ borrow of `x` occurs here
+   |             ------ `x` is borrowed here
 LL |     match x {
    |           ^ use of borrowed `x`
 ...
diff --git a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
index 5f93ad6e0279e..1c26eb8803d7f 100644
--- a/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
+++ b/tests/ui/rfcs/rfc-2528-type-changing-struct-update/lifetime-update.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `s` does not live long enough
   --> $DIR/lifetime-update.rs:20:17
    |
+LL |     let s = String::from("hello");
+   |         - binding `s` declared here
+...
 LL |         lt_str: &s,
    |                 ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/self/issue-61882-2.stderr b/tests/ui/self/issue-61882-2.stderr
index 0b8e134c9662e..6faa4477d8c5d 100644
--- a/tests/ui/self/issue-61882-2.stderr
+++ b/tests/ui/self/issue-61882-2.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/issue-61882-2.rs:6:14
    |
+LL |         let x = 0;
+   |             - binding `x` declared here
 LL |         Self(&x);
    |              ^^
    |              |
diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 48b42bc78253f..9711dad80785b 100644
--- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -47,6 +47,9 @@ LL |         foo(f);
 error[E0505]: cannot move out of `f` because it is borrowed
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
    |
+LL |     let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
+   |         ----- binding `f` declared here
+...
 LL |     f(Box::new(|a| {
    |     -          ^^^ move out of `f` occurs here
    |     |
diff --git a/tests/ui/span/dropck_arr_cycle_checked.stderr b/tests/ui/span/dropck_arr_cycle_checked.stderr
index 068c779ae5267..23ebc8d598c67 100644
--- a/tests/ui/span/dropck_arr_cycle_checked.stderr
+++ b/tests/ui/span/dropck_arr_cycle_checked.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `b2` does not live long enough
   --> $DIR/dropck_arr_cycle_checked.rs:93:24
    |
+LL |     let (b1, b2, b3);
+   |              -- binding `b2` declared here
+...
 LL |     b1.a[0].v.set(Some(&b2));
    |                        ^^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL | }
 error[E0597]: `b3` does not live long enough
   --> $DIR/dropck_arr_cycle_checked.rs:95:24
    |
+LL |     let (b1, b2, b3);
+   |                  -- binding `b3` declared here
+...
 LL |     b1.a[1].v.set(Some(&b3));
    |                        ^^^ borrowed value does not live long enough
 ...
@@ -29,6 +35,9 @@ LL | }
 error[E0597]: `b1` does not live long enough
   --> $DIR/dropck_arr_cycle_checked.rs:99:24
    |
+LL |     let (b1, b2, b3);
+   |          -- binding `b1` declared here
+...
 LL |     b3.a[0].v.set(Some(&b1));
    |                        ^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/dropck_direct_cycle_with_drop.stderr b/tests/ui/span/dropck_direct_cycle_with_drop.stderr
index 07ae138ac71ea..1e75e3b2fa121 100644
--- a/tests/ui/span/dropck_direct_cycle_with_drop.stderr
+++ b/tests/ui/span/dropck_direct_cycle_with_drop.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `d2` does not live long enough
   --> $DIR/dropck_direct_cycle_with_drop.rs:36:19
    |
+LL |     let (d1, d2) = (D::new(format!("d1")), D::new(format!("d2")));
+   |              -- binding `d2` declared here
 LL |     d1.p.set(Some(&d2));
    |                   ^^^ borrowed value does not live long enough
 ...
@@ -15,6 +17,9 @@ LL | }
 error[E0597]: `d1` does not live long enough
   --> $DIR/dropck_direct_cycle_with_drop.rs:38:19
    |
+LL |     let (d1, d2) = (D::new(format!("d1")), D::new(format!("d2")));
+   |          -- binding `d1` declared here
+...
 LL |     d2.p.set(Some(&d1));
    |                   ^^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/span/dropck_misc_variants.stderr b/tests/ui/span/dropck_misc_variants.stderr
index 76e90574cef44..24a2c9089f5b1 100644
--- a/tests/ui/span/dropck_misc_variants.stderr
+++ b/tests/ui/span/dropck_misc_variants.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `bomb` does not live long enough
   --> $DIR/dropck_misc_variants.rs:23:36
    |
+LL |     let (_w, bomb);
+   |              ---- binding `bomb` declared here
+LL |     bomb = vec![""];
 LL |     _w = Wrap::<&[&str]>(NoisyDrop(&bomb));
    |                                    ^^^^^ borrowed value does not live long enough
 LL | }
@@ -14,6 +17,9 @@ LL | }
 error[E0597]: `v` does not live long enough
   --> $DIR/dropck_misc_variants.rs:31:27
    |
+LL |     let (_w,v);
+   |             - binding `v` declared here
+...
 LL |         let u = NoisyDrop(&v);
    |                           ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/dropck_vec_cycle_checked.stderr b/tests/ui/span/dropck_vec_cycle_checked.stderr
index 7ff991c0c3737..5817439c0d855 100644
--- a/tests/ui/span/dropck_vec_cycle_checked.stderr
+++ b/tests/ui/span/dropck_vec_cycle_checked.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `c2` does not live long enough
   --> $DIR/dropck_vec_cycle_checked.rs:98:24
    |
+LL |     let (mut c1, mut c2, mut c3);
+   |                  ------ binding `c2` declared here
+...
 LL |     c1.v[0].v.set(Some(&c2));
    |                        ^^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL | }
 error[E0597]: `c3` does not live long enough
   --> $DIR/dropck_vec_cycle_checked.rs:100:24
    |
+LL |     let (mut c1, mut c2, mut c3);
+   |                          ------ binding `c3` declared here
+...
 LL |     c1.v[1].v.set(Some(&c3));
    |                        ^^^ borrowed value does not live long enough
 ...
@@ -29,6 +35,9 @@ LL | }
 error[E0597]: `c1` does not live long enough
   --> $DIR/dropck_vec_cycle_checked.rs:104:24
    |
+LL |     let (mut c1, mut c2, mut c3);
+   |          ------ binding `c1` declared here
+...
 LL |     c3.v[0].v.set(Some(&c1));
    |                        ^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr b/tests/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
index 809e60a8c8aac..c3b6d7580b4e0 100644
--- a/tests/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
+++ b/tests/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `d1` does not live long enough
   --> $DIR/issue-24805-dropck-child-has-items-via-parent.rs:28:18
    |
+LL |     let (_d, d1);
+   |              -- binding `d1` declared here
+...
 LL |     _d = D_Child(&d1);
    |                  ^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/issue-24805-dropck-trait-has-items.stderr b/tests/ui/span/issue-24805-dropck-trait-has-items.stderr
index 2e217066915d3..e52c57d9ab1f8 100644
--- a/tests/ui/span/issue-24805-dropck-trait-has-items.stderr
+++ b/tests/ui/span/issue-24805-dropck-trait-has-items.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `d1` does not live long enough
   --> $DIR/issue-24805-dropck-trait-has-items.rs:37:26
    |
+LL |     let (_d, d1);
+   |              -- binding `d1` declared here
+LL |     d1 = D_HasSelfMethod(1);
 LL |     _d = D_HasSelfMethod(&d1);
    |                          ^^^ borrowed value does not live long enough
 LL | }
@@ -14,6 +17,9 @@ LL | }
 error[E0597]: `d1` does not live long enough
   --> $DIR/issue-24805-dropck-trait-has-items.rs:43:33
    |
+LL |     let (_d, d1);
+   |              -- binding `d1` declared here
+LL |     d1 = D_HasMethodWithSelfArg(1);
 LL |     _d = D_HasMethodWithSelfArg(&d1);
    |                                 ^^^ borrowed value does not live long enough
 LL | }
@@ -27,6 +33,9 @@ LL | }
 error[E0597]: `d1` does not live long enough
   --> $DIR/issue-24805-dropck-trait-has-items.rs:49:20
    |
+LL |     let (_d, d1);
+   |              -- binding `d1` declared here
+LL |     d1 = D_HasType(1);
 LL |     _d = D_HasType(&d1);
    |                    ^^^ borrowed value does not live long enough
 LL | }
diff --git a/tests/ui/span/issue-24895-copy-clone-dropck.stderr b/tests/ui/span/issue-24895-copy-clone-dropck.stderr
index 18a3dc9e6defa..83db4d509d499 100644
--- a/tests/ui/span/issue-24895-copy-clone-dropck.stderr
+++ b/tests/ui/span/issue-24895-copy-clone-dropck.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `d1` does not live long enough
   --> $DIR/issue-24895-copy-clone-dropck.rs:27:14
    |
+LL |     let (d2, d1);
+   |              -- binding `d1` declared here
+LL |     d1 = D(34, "d1");
 LL |     d2 = D(S(&d1, "inner"), "d2");
    |              ^^^ borrowed value does not live long enough
 LL | }
diff --git a/tests/ui/span/issue-25199.stderr b/tests/ui/span/issue-25199.stderr
index d70a4afc1bf34..1e0276f0c3694 100644
--- a/tests/ui/span/issue-25199.stderr
+++ b/tests/ui/span/issue-25199.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `container` does not live long enough
   --> $DIR/issue-25199.rs:70:27
    |
+LL |     let container = Container::new();
+   |         --------- binding `container` declared here
 LL |     let test = Test{test: &container};
    |                           ^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/issue-26656.stderr b/tests/ui/span/issue-26656.stderr
index 1e939c484fb7b..fea6e001238b5 100644
--- a/tests/ui/span/issue-26656.stderr
+++ b/tests/ui/span/issue-26656.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `ticking` does not live long enough
   --> $DIR/issue-26656.rs:40:35
    |
+LL |     let (mut zook, ticking);
+   |                    ------- binding `ticking` declared here
+...
 LL |     zook.button = B::BigRedButton(&ticking);
    |                                   ^^^^^^^^ borrowed value does not live long enough
 LL | }
diff --git a/tests/ui/span/issue-29106.stderr b/tests/ui/span/issue-29106.stderr
index 71fbd60ee733b..28ee7acd90e8c 100644
--- a/tests/ui/span/issue-29106.stderr
+++ b/tests/ui/span/issue-29106.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/issue-29106.rs:16:26
    |
+LL |         let (y, x);
+   |                 - binding `x` declared here
+LL |         x = "alive".to_string();
 LL |         y = Arc::new(Foo(&x));
    |                          ^^ borrowed value does not live long enough
 LL |     }
@@ -14,6 +17,9 @@ LL |     }
 error[E0597]: `x` does not live long enough
   --> $DIR/issue-29106.rs:23:25
    |
+LL |         let (y, x);
+   |                 - binding `x` declared here
+LL |         x = "alive".to_string();
 LL |         y = Rc::new(Foo(&x));
    |                         ^^ borrowed value does not live long enough
 LL |     }
diff --git a/tests/ui/span/issue-36537.stderr b/tests/ui/span/issue-36537.stderr
index 79a0ebaeb8db6..6c330c1a09475 100644
--- a/tests/ui/span/issue-36537.stderr
+++ b/tests/ui/span/issue-36537.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/issue-36537.rs:5:13
    |
+LL |         let a = 42;
+   |             - binding `a` declared here
 LL |         p = &a;
    |             ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/issue-40157.stderr b/tests/ui/span/issue-40157.stderr
index 57f80214a4f83..e9b84de505989 100644
--- a/tests/ui/span/issue-40157.stderr
+++ b/tests/ui/span/issue-40157.stderr
@@ -2,11 +2,9 @@ error[E0597]: `foo` does not live long enough
   --> $DIR/issue-40157.rs:2:53
    |
 LL |     {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });}
-   |                             ------------------------^^^^^^^^^^--
-   |                             |                       |          |
-   |                             |                       |          `foo` dropped here while still borrowed
-   |                             |                       borrowed value does not live long enough
-   |                             borrow later used here
+   |                                                     ^^^^^^^^^^ - `foo` dropped here while still borrowed
+   |                                                     |
+   |                                                     borrowed value does not live long enough
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/issue28498-reject-lifetime-param.stderr b/tests/ui/span/issue28498-reject-lifetime-param.stderr
index 3119ddd03cc26..94c450c7b1ece 100644
--- a/tests/ui/span/issue28498-reject-lifetime-param.stderr
+++ b/tests/ui/span/issue28498-reject-lifetime-param.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `first_dropped` does not live long enough
   --> $DIR/issue28498-reject-lifetime-param.rs:32:19
    |
+LL |     let (foo1, first_dropped);
+   |                ------------- binding `first_dropped` declared here
+...
 LL |     foo1 = Foo(1, &first_dropped);
    |                   ^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/issue28498-reject-passed-to-fn.stderr b/tests/ui/span/issue28498-reject-passed-to-fn.stderr
index 60e8a648cd597..e133f75d57bb7 100644
--- a/tests/ui/span/issue28498-reject-passed-to-fn.stderr
+++ b/tests/ui/span/issue28498-reject-passed-to-fn.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `first_dropped` does not live long enough
   --> $DIR/issue28498-reject-passed-to-fn.rs:34:19
    |
+LL |     let (foo1, first_dropped);
+   |                ------------- binding `first_dropped` declared here
+...
 LL |     foo1 = Foo(1, &first_dropped, Box::new(callback));
    |                   ^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/issue28498-reject-trait-bound.stderr b/tests/ui/span/issue28498-reject-trait-bound.stderr
index 22e4a8205b617..9ab3cdd1343a1 100644
--- a/tests/ui/span/issue28498-reject-trait-bound.stderr
+++ b/tests/ui/span/issue28498-reject-trait-bound.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `first_dropped` does not live long enough
   --> $DIR/issue28498-reject-trait-bound.rs:34:19
    |
+LL |     let (foo1, first_dropped);
+   |                ------------- binding `first_dropped` declared here
+...
 LL |     foo1 = Foo(1, &first_dropped);
    |                   ^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/mut-ptr-cant-outlive-ref.stderr b/tests/ui/span/mut-ptr-cant-outlive-ref.stderr
index 4d976a7bbfa47..be56f9489c770 100644
--- a/tests/ui/span/mut-ptr-cant-outlive-ref.stderr
+++ b/tests/ui/span/mut-ptr-cant-outlive-ref.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `b` does not live long enough
   --> $DIR/mut-ptr-cant-outlive-ref.rs:8:15
    |
+LL |         let b = m.borrow();
+   |             - binding `b` declared here
 LL |         p = &*b;
    |               ^ borrowed value does not live long enough
 LL |     }
diff --git a/tests/ui/span/range-2.stderr b/tests/ui/span/range-2.stderr
index 8ca8156b0830c..d7084b00ba402 100644
--- a/tests/ui/span/range-2.stderr
+++ b/tests/ui/span/range-2.stderr
@@ -3,7 +3,9 @@ error[E0597]: `a` does not live long enough
    |
 LL |     let r = {
    |         - borrow later stored here
-...
+LL |         let a = 42;
+   |             - binding `a` declared here
+LL |         let b = 42;
 LL |         &a..&b
    |         ^^ borrowed value does not live long enough
 LL |     };
@@ -14,7 +16,9 @@ error[E0597]: `b` does not live long enough
    |
 LL |     let r = {
    |         - borrow later stored here
-...
+LL |         let a = 42;
+LL |         let b = 42;
+   |             - binding `b` declared here
 LL |         &a..&b
    |             ^^ borrowed value does not live long enough
 LL |     };
diff --git a/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr b/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr
index 0b985de609c26..fb3fad6ae9050 100644
--- a/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr
+++ b/tests/ui/span/regionck-unboxed-closure-lifetimes.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `c` does not live long enough
   --> $DIR/regionck-unboxed-closure-lifetimes.rs:8:21
    |
+LL |         let c = 1;
+   |             - binding `c` declared here
 LL |         let c_ref = &c;
    |                     ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/regions-close-over-type-parameter-2.stderr b/tests/ui/span/regions-close-over-type-parameter-2.stderr
index 2e584d9a884f1..fed40a4fdd2a5 100644
--- a/tests/ui/span/regions-close-over-type-parameter-2.stderr
+++ b/tests/ui/span/regions-close-over-type-parameter-2.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `tmp0` does not live long enough
   --> $DIR/regions-close-over-type-parameter-2.rs:23:20
    |
+LL |         let tmp0 = 3;
+   |             ---- binding `tmp0` declared here
 LL |         let tmp1 = &tmp0;
    |                    ^^^^^ borrowed value does not live long enough
 LL |         repeater3(tmp1)
diff --git a/tests/ui/span/regions-escape-loop-via-variable.stderr b/tests/ui/span/regions-escape-loop-via-variable.stderr
index 42df668529749..e5c7d8b26ab00 100644
--- a/tests/ui/span/regions-escape-loop-via-variable.stderr
+++ b/tests/ui/span/regions-escape-loop-via-variable.stderr
@@ -2,7 +2,9 @@ error[E0597]: `x` does not live long enough
   --> $DIR/regions-escape-loop-via-variable.rs:11:13
    |
 LL |         let x = 1 + *p;
-   |                     -- borrow later used here
+   |             -       -- borrow later used here
+   |             |
+   |             binding `x` declared here
 LL |         p = &x;
    |             ^^ borrowed value does not live long enough
 LL |     }
diff --git a/tests/ui/span/regions-escape-loop-via-vec.stderr b/tests/ui/span/regions-escape-loop-via-vec.stderr
index 2b649307739f5..532ac3606c544 100644
--- a/tests/ui/span/regions-escape-loop-via-vec.stderr
+++ b/tests/ui/span/regions-escape-loop-via-vec.stderr
@@ -2,7 +2,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/regions-escape-loop-via-vec.rs:5:11
    |
 LL |     let mut _y = vec![&mut x];
-   |                       ------ borrow of `x` occurs here
+   |                       ------ `x` is borrowed here
 LL |     while x < 10 {
    |           ^ use of borrowed `x`
 LL |         let mut z = x;
@@ -13,7 +13,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/regions-escape-loop-via-vec.rs:6:21
    |
 LL |     let mut _y = vec![&mut x];
-   |                       ------ borrow of `x` occurs here
+   |                       ------ `x` is borrowed here
 LL |     while x < 10 {
 LL |         let mut z = x;
    |                     ^ use of borrowed `x`
@@ -23,11 +23,10 @@ LL |         _y.push(&mut z);
 error[E0597]: `z` does not live long enough
   --> $DIR/regions-escape-loop-via-vec.rs:7:17
    |
+LL |         let mut z = x;
+   |             ----- binding `z` declared here
 LL |         _y.push(&mut z);
-   |         --------^^^^^^-
-   |         |       |
-   |         |       borrowed value does not live long enough
-   |         borrow later used here
+   |                 ^^^^^^ borrowed value does not live long enough
 ...
 LL |     }
    |     - `z` dropped here while still borrowed
@@ -36,7 +35,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/regions-escape-loop-via-vec.rs:9:9
    |
 LL |     let mut _y = vec![&mut x];
-   |                       ------ borrow of `x` occurs here
+   |                       ------ `x` is borrowed here
 ...
 LL |         _y.push(&mut z);
    |         --------------- borrow later used here
diff --git a/tests/ui/span/send-is-not-static-ensures-scoping.stderr b/tests/ui/span/send-is-not-static-ensures-scoping.stderr
index 65d10c1305b8c..bae0befcacaa7 100644
--- a/tests/ui/span/send-is-not-static-ensures-scoping.stderr
+++ b/tests/ui/span/send-is-not-static-ensures-scoping.stderr
@@ -4,6 +4,7 @@ error[E0597]: `x` does not live long enough
 LL |     let bad = {
    |         --- borrow later stored here
 LL |         let x = 1;
+   |             - binding `x` declared here
 LL |         let y = &x;
    |                 ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/send-is-not-static-std-sync-2.stderr b/tests/ui/span/send-is-not-static-std-sync-2.stderr
index bcd07e1164777..b0267fa6f43b0 100644
--- a/tests/ui/span/send-is-not-static-std-sync-2.stderr
+++ b/tests/ui/span/send-is-not-static-std-sync-2.stderr
@@ -4,6 +4,7 @@ error[E0597]: `x` does not live long enough
 LL |     let lock = {
    |         ---- borrow later stored here
 LL |         let x = 1;
+   |             - binding `x` declared here
 LL |         Mutex::new(&x)
    |                    ^^ borrowed value does not live long enough
 LL |     };
@@ -15,6 +16,7 @@ error[E0597]: `x` does not live long enough
 LL |     let lock = {
    |         ---- borrow later stored here
 LL |         let x = 1;
+   |             - binding `x` declared here
 LL |         RwLock::new(&x)
    |                     ^^ borrowed value does not live long enough
 LL |     };
@@ -25,7 +27,9 @@ error[E0597]: `x` does not live long enough
    |
 LL |     let (_tx, rx) = {
    |          --- borrow later used here
-...
+LL |         let x = 1;
+   |             - binding `x` declared here
+LL |         let (tx, rx) = mpsc::channel();
 LL |         let _ = tx.send(&x);
    |                         ^^ borrowed value does not live long enough
 LL |         (tx, rx)
diff --git a/tests/ui/span/send-is-not-static-std-sync.stderr b/tests/ui/span/send-is-not-static-std-sync.stderr
index 5d493a3e4ee55..28b1c5fe7152a 100644
--- a/tests/ui/span/send-is-not-static-std-sync.stderr
+++ b/tests/ui/span/send-is-not-static-std-sync.stderr
@@ -12,6 +12,8 @@ LL |         *lock.lock().unwrap() = &z;
 error[E0597]: `z` does not live long enough
   --> $DIR/send-is-not-static-std-sync.rs:16:33
    |
+LL |         let z = 2;
+   |             - binding `z` declared here
 LL |         *lock.lock().unwrap() = &z;
    |                                 ^^ borrowed value does not live long enough
 LL |     }
@@ -34,6 +36,8 @@ LL |         *lock.write().unwrap() = &z;
 error[E0597]: `z` does not live long enough
   --> $DIR/send-is-not-static-std-sync.rs:30:34
    |
+LL |         let z = 2;
+   |             - binding `z` declared here
 LL |         *lock.write().unwrap() = &z;
    |                                  ^^ borrowed value does not live long enough
 LL |     }
@@ -56,6 +60,8 @@ LL |         tx.send(&z).unwrap();
 error[E0597]: `z` does not live long enough
   --> $DIR/send-is-not-static-std-sync.rs:46:17
    |
+LL |         let z = 2;
+   |             - binding `z` declared here
 LL |         tx.send(&z).unwrap();
    |                 ^^ borrowed value does not live long enough
 LL |     }
diff --git a/tests/ui/span/vec-must-not-hide-type-from-dropck.stderr b/tests/ui/span/vec-must-not-hide-type-from-dropck.stderr
index f87c32d1ad0c6..f2fefca414ec4 100644
--- a/tests/ui/span/vec-must-not-hide-type-from-dropck.stderr
+++ b/tests/ui/span/vec-must-not-hide-type-from-dropck.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `c2` does not live long enough
   --> $DIR/vec-must-not-hide-type-from-dropck.rs:117:24
    |
+LL |     let (mut c1, mut c2);
+   |                  ------ binding `c2` declared here
+...
 LL |     c1.v[0].v.set(Some(&c2));
    |                        ^^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL | }
 error[E0597]: `c1` does not live long enough
   --> $DIR/vec-must-not-hide-type-from-dropck.rs:119:24
    |
+LL |     let (mut c1, mut c2);
+   |          ------ binding `c1` declared here
+...
 LL |     c2.v[0].v.set(Some(&c1));
    |                        ^^^ borrowed value does not live long enough
 LL |
diff --git a/tests/ui/span/vec_refs_data_with_early_death.stderr b/tests/ui/span/vec_refs_data_with_early_death.stderr
index 684e784531325..73f27144af423 100644
--- a/tests/ui/span/vec_refs_data_with_early_death.stderr
+++ b/tests/ui/span/vec_refs_data_with_early_death.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/vec_refs_data_with_early_death.rs:17:12
    |
+LL |     let x: i8 = 3;
+   |         - binding `x` declared here
+...
 LL |     v.push(&x);
    |            ^^ borrowed value does not live long enough
 ...
@@ -15,6 +18,9 @@ LL | }
 error[E0597]: `y` does not live long enough
   --> $DIR/vec_refs_data_with_early_death.rs:19:12
    |
+LL |     let y: i8 = 4;
+   |         - binding `y` declared here
+...
 LL |     v.push(&y);
    |            ^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/wf-method-late-bound-regions.stderr b/tests/ui/span/wf-method-late-bound-regions.stderr
index 6b0b008208f17..64c2d0f160665 100644
--- a/tests/ui/span/wf-method-late-bound-regions.stderr
+++ b/tests/ui/span/wf-method-late-bound-regions.stderr
@@ -4,6 +4,7 @@ error[E0597]: `pointer` does not live long enough
 LL |     let dangling = {
    |         -------- borrow later stored here
 LL |         let pointer = Box::new(42);
+   |             ------- binding `pointer` declared here
 LL |         f2.xmute(&pointer)
    |                  ^^^^^^^^ borrowed value does not live long enough
 LL |     };
diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr
index ef07a89315f40..e22411b13b776 100644
--- a/tests/ui/static/static-lifetime-bound.stderr
+++ b/tests/ui/static/static-lifetime-bound.stderr
@@ -9,6 +9,8 @@ LL | fn f<'a: 'static>(_: &'a i32) {}
 error[E0597]: `x` does not live long enough
   --> $DIR/static-lifetime-bound.rs:5:7
    |
+LL |     let x = 0;
+   |         - binding `x` declared here
 LL |     f(&x);
    |     --^^-
    |     | |
diff --git a/tests/ui/suggestions/borrow-for-loop-head.stderr b/tests/ui/suggestions/borrow-for-loop-head.stderr
index cbdb94877bdb7..0f179438a1263 100644
--- a/tests/ui/suggestions/borrow-for-loop-head.stderr
+++ b/tests/ui/suggestions/borrow-for-loop-head.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/borrow-for-loop-head.rs:4:18
    |
+LL |     let a = vec![1, 2, 3];
+   |         - binding `a` declared here
 LL |     for i in &a {
    |              -- borrow of `a` occurs here
 LL |         for j in a {
diff --git a/tests/ui/suggestions/option-content-move2.stderr b/tests/ui/suggestions/option-content-move2.stderr
index 1d3dff3be3476..94acda73c4efe 100644
--- a/tests/ui/suggestions/option-content-move2.stderr
+++ b/tests/ui/suggestions/option-content-move2.stderr
@@ -7,7 +7,7 @@ LL |     func(|| {
    |          -- captured by this `FnMut` closure
 LL |         // Shouldn't suggest `move ||.as_ref()` here
 LL |         move || {
-   |         ^^^^^^^ move out of `var` occurs here
+   |         ^^^^^^^ `var` is moved here
 LL |
 LL |             var = Some(NotCopyable);
    |             ---
diff --git a/tests/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr b/tests/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr
index ade552c4bab41..c7af71a421438 100644
--- a/tests/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr
+++ b/tests/ui/traits/associated_type_bound/check-trait-object-bounds-3.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `s` does not live long enough
   --> $DIR/check-trait-object-bounds-3.rs:15:34
    |
+LL |         let s = String::from("abcdef");
+   |             - binding `s` declared here
 LL |         z = f::<dyn X<Y = &str>>(&s);
    |             ---------------------^^-
    |             |                    |
diff --git a/tests/ui/traits/coercion-generic-regions.stderr b/tests/ui/traits/coercion-generic-regions.stderr
index 5cfb64901233e..ae70202ab7ccd 100644
--- a/tests/ui/traits/coercion-generic-regions.stderr
+++ b/tests/ui/traits/coercion-generic-regions.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `person` does not live long enough
   --> $DIR/coercion-generic-regions.rs:17:24
    |
+LL |     let person = "Fred".to_string();
+   |         ------ binding `person` declared here
 LL |     let person: &str = &person;
    |                        ^^^^^^^
    |                        |
diff --git a/tests/ui/traits/vtable/issue-97381.stderr b/tests/ui/traits/vtable/issue-97381.stderr
index c4f8294e26356..89360c44e78b4 100644
--- a/tests/ui/traits/vtable/issue-97381.stderr
+++ b/tests/ui/traits/vtable/issue-97381.stderr
@@ -1,6 +1,9 @@
 error[E0505]: cannot move out of `v` because it is borrowed
   --> $DIR/issue-97381.rs:26:14
    |
+LL |     let v = [1, 2, 3]
+   |         - binding `v` declared here
+...
 LL |     let el = &v[0];
    |               - borrow of `v` occurs here
 LL |
diff --git a/tests/ui/try-block/try-block-bad-lifetime.stderr b/tests/ui/try-block/try-block-bad-lifetime.stderr
index ea079e30d9c39..28941cb0a9e40 100644
--- a/tests/ui/try-block/try-block-bad-lifetime.stderr
+++ b/tests/ui/try-block/try-block-bad-lifetime.stderr
@@ -4,6 +4,7 @@ error[E0597]: `my_string` does not live long enough
 LL |         let result: Result<(), &str> = try {
    |             ------ borrow later stored here
 LL |             let my_string = String::from("");
+   |                 --------- binding `my_string` declared here
 LL |             let my_str: & str = & my_string;
    |                                 ^^^^^^^^^^^ borrowed value does not live long enough
 ...
@@ -14,10 +15,10 @@ error[E0506]: cannot assign to `i` because it is borrowed
   --> $DIR/try-block-bad-lifetime.rs:29:13
    |
 LL |         let k = &mut i;
-   |                 ------ borrow of `i` occurs here
+   |                 ------ `i` is borrowed here
 ...
 LL |             i = 10;
-   |             ^^^^^^ assignment to borrowed `i` occurs here
+   |             ^^^^^^ `i` is assigned to here but it was already borrowed
 LL |         };
 LL |         ::std::mem::drop(k);
    |                          - borrow later used here
@@ -38,10 +39,10 @@ error[E0506]: cannot assign to `i` because it is borrowed
   --> $DIR/try-block-bad-lifetime.rs:32:9
    |
 LL |         let k = &mut i;
-   |                 ------ borrow of `i` occurs here
+   |                 ------ `i` is borrowed here
 ...
 LL |         i = 40;
-   |         ^^^^^^ assignment to borrowed `i` occurs here
+   |         ^^^^^^ `i` is assigned to here but it was already borrowed
 LL |
 LL |         let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") };
    |                                         - borrow later used here
diff --git a/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr b/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr
index f738b03eed6b8..71c7e460c3992 100644
--- a/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr
+++ b/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr
@@ -2,10 +2,10 @@ error[E0506]: cannot assign to `i` because it is borrowed
   --> $DIR/try-block-maybe-bad-lifetime.rs:17:9
    |
 LL |             &i
-   |             -- borrow of `i` occurs here
+   |             -- `i` is borrowed here
 LL |         };
 LL |         i = 0;
-   |         ^^^^^ assignment to borrowed `i` occurs here
+   |         ^^^^^ `i` is assigned to here but it was already borrowed
 LL |         let _ = i;
 LL |         do_something_with(x);
    |                           - borrow later used here
@@ -32,10 +32,10 @@ error[E0506]: cannot assign to `i` because it is borrowed
   --> $DIR/try-block-maybe-bad-lifetime.rs:40:9
    |
 LL |             j = &i;
-   |                 -- borrow of `i` occurs here
+   |                 -- `i` is borrowed here
 LL |         };
 LL |         i = 0;
-   |         ^^^^^ assignment to borrowed `i` occurs here
+   |         ^^^^^ `i` is assigned to here but it was already borrowed
 LL |         let _ = i;
 LL |         do_something_with(j);
    |                           - borrow later used here
diff --git a/tests/ui/unboxed-closures/unboxed-closures-borrow-conflict.stderr b/tests/ui/unboxed-closures/unboxed-closures-borrow-conflict.stderr
index 21d6b4fde7e90..98fe97c5c1814 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-borrow-conflict.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-borrow-conflict.stderr
@@ -4,7 +4,7 @@ error[E0503]: cannot use `x` because it was mutably borrowed
 LL |     let f = || x += 1;
    |             -- - borrow occurs due to use of `x` in closure
    |             |
-   |             borrow of `x` occurs here
+   |             `x` is borrowed here
 LL |     let _y = x;
    |              ^ use of borrowed `x`
 LL |     f;
diff --git a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr
index cbdb4dd0fb5c8..23aa18d7156ac 100644
--- a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr
@@ -16,14 +16,14 @@ error[E0506]: cannot assign to `factorial` because it is borrowed
   --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:20:5
    |
 LL |     let f = |x: u32| -> u32 {
-   |             --------------- borrow of `factorial` occurs here
+   |             --------------- `factorial` is borrowed here
 LL |         let g = factorial.as_ref().unwrap();
    |                 --------- borrow occurs due to use in closure
 ...
 LL |     factorial = Some(Box::new(f));
    |     ^^^^^^^^^
    |     |
-   |     assignment to borrowed `factorial` occurs here
+   |     `factorial` is assigned to here but it was already borrowed
    |     borrow later used here
 
 error[E0597]: `factorial` does not live long enough
@@ -47,12 +47,12 @@ LL |     let mut factorial: Option<Box<dyn Fn(u32) -> u32 + 'static>> = None;
    |                        ----------------------------------------- type annotation requires that `factorial` is borrowed for `'static`
 LL |
 LL |     let f = |x: u32| -> u32 {
-   |             --------------- borrow of `factorial` occurs here
+   |             --------------- `factorial` is borrowed here
 LL |         let g = factorial.as_ref().unwrap();
    |                 --------- borrow occurs due to use in closure
 ...
 LL |     factorial = Some(Box::new(f));
-   |     ^^^^^^^^^ assignment to borrowed `factorial` occurs here
+   |     ^^^^^^^^^ `factorial` is assigned to here but it was already borrowed
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/unop-move-semantics.stderr b/tests/ui/unop-move-semantics.stderr
index 2a3ca14433f62..e47785c465ac6 100644
--- a/tests/ui/unop-move-semantics.stderr
+++ b/tests/ui/unop-move-semantics.stderr
@@ -23,6 +23,8 @@ LL | fn move_then_borrow<T: Not<Output=T> + Clone + Copy>(x: T) {
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/unop-move-semantics.rs:15:6
    |
+LL | fn move_borrowed<T: Not<Output=T>>(x: T, mut y: T) {
+   |                                    - binding `x` declared here
 LL |     let m = &x;
    |             -- borrow of `x` occurs here
 ...
@@ -35,6 +37,9 @@ LL |     use_mut(n); use_imm(m);
 error[E0505]: cannot move out of `y` because it is borrowed
   --> $DIR/unop-move-semantics.rs:17:6
    |
+LL | fn move_borrowed<T: Not<Output=T>>(x: T, mut y: T) {
+   |                                          ----- binding `y` declared here
+LL |     let m = &x;
 LL |     let n = &mut y;
    |             ------ borrow of `y` occurs here
 ...
diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr
index 008e2a002bbb0..258f67db5ce4b 100644
--- a/tests/ui/variance/variance-issue-20533.stderr
+++ b/tests/ui/variance/variance-issue-20533.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/variance-issue-20533.rs:28:14
    |
+LL |         let a = AffineU32(1);
+   |             - binding `a` declared here
 LL |         let x = foo(&a);
    |                     -- borrow of `a` occurs here
 LL |         drop(a);
@@ -11,6 +13,8 @@ LL |         drop(x);
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/variance-issue-20533.rs:34:14
    |
+LL |         let a = AffineU32(1);
+   |             - binding `a` declared here
 LL |         let x = bar(&a);
    |                     -- borrow of `a` occurs here
 LL |         drop(a);
@@ -21,6 +25,8 @@ LL |         drop(x);
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/variance-issue-20533.rs:40:14
    |
+LL |         let a = AffineU32(1);
+   |             - binding `a` declared here
 LL |         let x = baz(&a);
    |                     -- borrow of `a` occurs here
 LL |         drop(a);

From e4f61afa779e01af24c6f20394de8e3950b368c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 15 Jan 2023 19:57:32 +0000
Subject: [PATCH 02/16] Fix fulldeps-ui tests

---
 tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr | 2 ++
 tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr b/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr
index 4299688221a8b..47897dc003a43 100644
--- a/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr
+++ b/tests/ui-fulldeps/dropck-tarena-cycle-checked.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `arena` does not live long enough
   --> $DIR/dropck-tarena-cycle-checked.rs:116:7
    |
+LL |     let arena = TypedArena::default();
+   |         ----- binding `arena` declared here
 LL |     f(&arena);
    |       ^^^^^^ borrowed value does not live long enough
 LL | }
diff --git a/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr b/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr
index ccffee9cdbda9..493d74b0bdec9 100644
--- a/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr
+++ b/tests/ui-fulldeps/dropck-tarena-unsound-drop.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `arena` does not live long enough
   --> $DIR/dropck-tarena-unsound-drop.rs:41:7
    |
+LL |     let arena: TypedArena<C> = TypedArena::default();
+   |         ----- binding `arena` declared here
 LL |     f(&arena);
    |       ^^^^^^ borrowed value does not live long enough
 LL | }

From be2ec32b18f7ad858dc746b26eb3a91a62a2c360 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 17 Jan 2023 02:45:11 +0000
Subject: [PATCH 03/16] Account for `*` when looking for inner-most path in
 expression

---
 .../rustc_borrowck/src/diagnostics/explain_borrow.rs     | 4 +++-
 tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr  | 5 +++++
 tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr      | 2 ++
 tests/ui/borrowck/borrowck-unary-move.stderr             | 2 ++
 tests/ui/nll/polonius/polonius-smoke-test.stderr         | 6 +++++-
 tests/ui/span/dropck-object-cycle.stderr                 | 2 ++
 .../span/regions-infer-borrow-scope-within-loop.stderr   | 3 +++
 tests/ui/span/send-is-not-static-std-sync.stderr         | 9 +++++++++
 8 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index e4f45c53aefe5..d60facb91b455 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -75,7 +75,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
                 let mut expr_finder = FindExprBySpan::new(span);
                 expr_finder.visit_expr(body.value);
                 if let Some(mut expr) = expr_finder.result {
-                    while let hir::ExprKind::AddrOf(_, _, inner) = &expr.kind {
+                    while let hir::ExprKind::AddrOf(_, _, inner)
+                        | hir::ExprKind::Unary(hir::UnOp::Deref, inner) = &expr.kind
+                    {
                         expr = inner;
                     }
                     if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
diff --git a/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr b/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr
index 371bcf2b69cf8..e582ec605defe 100644
--- a/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr
+++ b/tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr
@@ -1,6 +1,9 @@
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/borrowck-bad-nested-calls-move.rs:25:9
    |
+LL |     let mut a: Box<_> = Box::new(1);
+   |         ----- binding `a` declared here
+...
 LL |     add(
    |     --- borrow later used by call
 LL |         &*a,
@@ -11,6 +14,8 @@ LL |         a);
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/borrowck-bad-nested-calls-move.rs:32:9
    |
+LL |     let mut a: Box<_> = Box::new(1);
+   |         ----- binding `a` declared here
 LL |     add(
    |     --- borrow later used by call
 LL |         &*a,
diff --git a/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr b/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr
index d5ff0c501c4bd..cdad20c52bfaf 100644
--- a/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr
+++ b/tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `t0` because it is borrowed
   --> $DIR/borrowck-move-mut-base-ptr.rs:10:14
    |
+LL | fn foo(t0: &mut isize) {
+   |        -- binding `t0` declared here
 LL |     let p: &isize = &*t0; // Freezes `*t0`
    |                     ---- borrow of `*t0` occurs here
 LL |     let t1 = t0;
diff --git a/tests/ui/borrowck/borrowck-unary-move.stderr b/tests/ui/borrowck/borrowck-unary-move.stderr
index aab225ed4a429..f3b962059f5b4 100644
--- a/tests/ui/borrowck/borrowck-unary-move.stderr
+++ b/tests/ui/borrowck/borrowck-unary-move.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/borrowck-unary-move.rs:3:10
    |
+LL | fn foo(x: Box<isize>) -> isize {
+   |        - binding `x` declared here
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     free(x);
diff --git a/tests/ui/nll/polonius/polonius-smoke-test.stderr b/tests/ui/nll/polonius/polonius-smoke-test.stderr
index 789d202f73a7b..534813b2d9f5a 100644
--- a/tests/ui/nll/polonius/polonius-smoke-test.stderr
+++ b/tests/ui/nll/polonius/polonius-smoke-test.stderr
@@ -18,7 +18,9 @@ error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/polonius-smoke-test.rs:18:13
    |
 LL | pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 {
-   |                            - let's call the lifetime of this reference `'1`
+   |                         -  - let's call the lifetime of this reference `'1`
+   |                         |
+   |                         binding `x` declared here
 LL |     let y = &mut *x;
    |             ------- borrow of `*x` occurs here
 LL |     let z = x;
@@ -29,6 +31,8 @@ LL |     y
 error[E0505]: cannot move out of `s` because it is borrowed
   --> $DIR/polonius-smoke-test.rs:42:5
    |
+LL |     let s = &mut 1;
+   |         - binding `s` declared here
 LL |     let r = &mut *s;
    |             ------- borrow of `*s` occurs here
 LL |     let tmp = foo(&r);
diff --git a/tests/ui/span/dropck-object-cycle.stderr b/tests/ui/span/dropck-object-cycle.stderr
index 229d17e1cf903..097fb6219f1fd 100644
--- a/tests/ui/span/dropck-object-cycle.stderr
+++ b/tests/ui/span/dropck-object-cycle.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `*m` does not live long enough
   --> $DIR/dropck-object-cycle.rs:27:31
    |
+LL |     let m : Box<dyn Trait+'static> = make_val();
+   |         - binding `m` declared here
 LL |     assert_eq!(object_invoke1(&*m), (4,5));
    |                               ^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/regions-infer-borrow-scope-within-loop.stderr b/tests/ui/span/regions-infer-borrow-scope-within-loop.stderr
index fd67c65c4e917..47931db84cabe 100644
--- a/tests/ui/span/regions-infer-borrow-scope-within-loop.stderr
+++ b/tests/ui/span/regions-infer-borrow-scope-within-loop.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `*x` does not live long enough
   --> $DIR/regions-infer-borrow-scope-within-loop.rs:13:20
    |
+LL |         let x = make_box();
+   |             - binding `x` declared here
+...
 LL |         y = borrow(&*x);
    |                    ^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/span/send-is-not-static-std-sync.stderr b/tests/ui/span/send-is-not-static-std-sync.stderr
index 28b1c5fe7152a..7dfe94bca603f 100644
--- a/tests/ui/span/send-is-not-static-std-sync.stderr
+++ b/tests/ui/span/send-is-not-static-std-sync.stderr
@@ -1,6 +1,9 @@
 error[E0505]: cannot move out of `y` because it is borrowed
   --> $DIR/send-is-not-static-std-sync.rs:13:10
    |
+LL |     let y = Box::new(1);
+   |         - binding `y` declared here
+LL |     let lock = Mutex::new(&x);
 LL |     *lock.lock().unwrap() = &*y;
    |                             --- borrow of `*y` occurs here
 LL |     drop(y);
@@ -25,6 +28,9 @@ LL |     lock.use_ref(); // (Mutex is #[may_dangle] so its dtor does not use `z`
 error[E0505]: cannot move out of `y` because it is borrowed
   --> $DIR/send-is-not-static-std-sync.rs:27:10
    |
+LL |     let y = Box::new(1);
+   |         - binding `y` declared here
+LL |     let lock = RwLock::new(&x);
 LL |     *lock.write().unwrap() = &*y;
    |                              --- borrow of `*y` occurs here
 LL |     drop(y);
@@ -49,6 +55,9 @@ LL |     lock.use_ref(); // (RwLock is #[may_dangle] so its dtor does not use `z
 error[E0505]: cannot move out of `y` because it is borrowed
   --> $DIR/send-is-not-static-std-sync.rs:43:10
    |
+LL |     let y = Box::new(1);
+   |         - binding `y` declared here
+...
 LL |     tx.send(&*y);
    |             --- borrow of `*y` occurs here
 LL |     drop(y);

From c6111e8d232964f11eb3540ed7228de6e13782df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 17 Jan 2023 02:47:50 +0000
Subject: [PATCH 04/16] Account for field access when looking for inner-most
 path in expression

---
 compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs     | 3 ++-
 tests/ui/borrowck/borrow-tuple-fields.stderr                  | 4 ++++
 tests/ui/borrowck/borrowck-field-sensitivity.stderr           | 4 ++++
 .../borrowck-local-borrow-with-panic-outlives-fn.stderr       | 2 ++
 4 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index d60facb91b455..b6a676ef63690 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -76,7 +76,8 @@ impl<'tcx> BorrowExplanation<'tcx> {
                 expr_finder.visit_expr(body.value);
                 if let Some(mut expr) = expr_finder.result {
                     while let hir::ExprKind::AddrOf(_, _, inner)
-                        | hir::ExprKind::Unary(hir::UnOp::Deref, inner) = &expr.kind
+                        | hir::ExprKind::Unary(hir::UnOp::Deref, inner)
+                        | hir::ExprKind::Field(inner, _) = &expr.kind
                     {
                         expr = inner;
                     }
diff --git a/tests/ui/borrowck/borrow-tuple-fields.stderr b/tests/ui/borrowck/borrow-tuple-fields.stderr
index befa751a6007b..d7d3efe492cef 100644
--- a/tests/ui/borrowck/borrow-tuple-fields.stderr
+++ b/tests/ui/borrowck/borrow-tuple-fields.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/borrow-tuple-fields.rs:12:13
    |
+LL |     let x: (Box<_>, _) = (Box::new(1), 2);
+   |         - binding `x` declared here
 LL |     let r = &x.0;
    |             ---- borrow of `x.0` occurs here
 LL |     let y = x;
@@ -32,6 +34,8 @@ LL |     a.use_ref();
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/borrow-tuple-fields.rs:28:13
    |
+LL |     let x = Foo(Box::new(1), 2);
+   |         - binding `x` declared here
 LL |     let r = &x.0;
    |             ---- borrow of `x.0` occurs here
 LL |     let y = x;
diff --git a/tests/ui/borrowck/borrowck-field-sensitivity.stderr b/tests/ui/borrowck/borrowck-field-sensitivity.stderr
index e009f5913edd0..11812847dd181 100644
--- a/tests/ui/borrowck/borrowck-field-sensitivity.stderr
+++ b/tests/ui/borrowck/borrowck-field-sensitivity.stderr
@@ -41,6 +41,8 @@ LL |     let p = &x.b;
 error[E0505]: cannot move out of `x.b` because it is borrowed
   --> $DIR/borrowck-field-sensitivity.rs:34:10
    |
+LL |     let x = A { a: 1, b: Box::new(2) };
+   |         - binding `x` declared here
 LL |     let p = &x.b;
    |             ---- borrow of `x.b` occurs here
 LL |     drop(x.b);
@@ -51,6 +53,8 @@ LL |     drop(**p);
 error[E0505]: cannot move out of `x.b` because it is borrowed
   --> $DIR/borrowck-field-sensitivity.rs:41:14
    |
+LL |     let x = A { a: 1, b: Box::new(2) };
+   |         - binding `x` declared here
 LL |     let p = &x.b;
    |             ---- borrow of `x.b` occurs here
 LL |     let _y = A { a: 3, .. x };
diff --git a/tests/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.stderr b/tests/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.stderr
index 6ea6951ad9665..0fdb1dabbc50c 100644
--- a/tests/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.stderr
+++ b/tests/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `z.1` does not live long enough
   --> $DIR/borrowck-local-borrow-with-panic-outlives-fn.rs:3:15
    |
+LL |     let mut z = (0, 0);
+   |         ----- binding `z` declared here
 LL |     *x = Some(&mut z.1);
    |     ----------^^^^^^^^-
    |     |         |

From 7b8251e1886924dde68ff9b6a1c02e9973d0bd0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 17 Jan 2023 02:52:43 +0000
Subject: [PATCH 05/16] Account for method call and indexing when looking for
 inner-most path in expression

---
 .../rustc_borrowck/src/diagnostics/explain_borrow.rs  |  4 +++-
 tests/ui/box/leak-alloc.stderr                        |  2 ++
 tests/ui/dropck/drop-with-active-borrows-1.stderr     |  2 ++
 tests/ui/generator/dropck.stderr                      |  3 +++
 .../ui/issues/issue-52126-assign-op-invariance.stderr |  2 ++
 .../ui/macros/format-args-temporaries-in-write.stderr |  4 ++++
 tests/ui/match/issue-74050-end-span.stderr            |  1 +
 tests/ui/moves/move-fn-self-receiver.stderr           |  2 ++
 tests/ui/nll/issue-54556-niconii.stderr               |  3 +++
 tests/ui/span/borrowck-let-suggestion-suffixes.rs     |  1 +
 tests/ui/span/borrowck-let-suggestion-suffixes.stderr | 11 +++++++----
 tests/ui/span/destructor-restrictions.stderr          |  2 ++
 ...issue-23338-locals-die-before-temps-of-body.stderr |  4 ++++
 tests/ui/span/issue-40157.stderr                      |  7 ++++---
 14 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index b6a676ef63690..19855075ced80 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -77,7 +77,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
                 if let Some(mut expr) = expr_finder.result {
                     while let hir::ExprKind::AddrOf(_, _, inner)
                         | hir::ExprKind::Unary(hir::UnOp::Deref, inner)
-                        | hir::ExprKind::Field(inner, _) = &expr.kind
+                        | hir::ExprKind::Field(inner, _)
+                        | hir::ExprKind::MethodCall(_, inner, _, _)
+                        | hir::ExprKind::Index(inner, _) = &expr.kind
                     {
                         expr = inner;
                     }
diff --git a/tests/ui/box/leak-alloc.stderr b/tests/ui/box/leak-alloc.stderr
index e8a6ad0995a0f..5140b58934a5c 100644
--- a/tests/ui/box/leak-alloc.stderr
+++ b/tests/ui/box/leak-alloc.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `alloc` because it is borrowed
   --> $DIR/leak-alloc.rs:26:10
    |
+LL |     let alloc = Alloc {};
+   |         ----- binding `alloc` declared here
 LL |     let boxed = Box::new_in(10, alloc.by_ref());
    |                                 -------------- borrow of `alloc` occurs here
 LL |     let theref = Box::leak(boxed);
diff --git a/tests/ui/dropck/drop-with-active-borrows-1.stderr b/tests/ui/dropck/drop-with-active-borrows-1.stderr
index 8d6a7f3721f0f..4585b22974cdb 100644
--- a/tests/ui/dropck/drop-with-active-borrows-1.stderr
+++ b/tests/ui/dropck/drop-with-active-borrows-1.stderr
@@ -1,6 +1,8 @@
 error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/drop-with-active-borrows-1.rs:4:10
    |
+LL |     let a = "".to_string();
+   |         - binding `a` declared here
 LL |     let b: Vec<&str> = a.lines().collect();
    |                        --------- borrow of `a` occurs here
 LL |     drop(a);
diff --git a/tests/ui/generator/dropck.stderr b/tests/ui/generator/dropck.stderr
index 7bb188352d7a2..b9a3a124acb61 100644
--- a/tests/ui/generator/dropck.stderr
+++ b/tests/ui/generator/dropck.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `*cell` does not live long enough
   --> $DIR/dropck.rs:10:40
    |
+LL |     let (mut gen, cell);
+   |                   ---- binding `cell` declared here
+LL |     cell = Box::new(RefCell::new(0));
 LL |     let ref_ = Box::leak(Box::new(Some(cell.borrow_mut())));
    |                                        ^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/issues/issue-52126-assign-op-invariance.stderr b/tests/ui/issues/issue-52126-assign-op-invariance.stderr
index d450675776268..2d3b48832c527 100644
--- a/tests/ui/issues/issue-52126-assign-op-invariance.stderr
+++ b/tests/ui/issues/issue-52126-assign-op-invariance.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `line` does not live long enough
   --> $DIR/issue-52126-assign-op-invariance.rs:34:28
    |
+LL |     for line in vec!["123456789".to_string(), "12345678".to_string()] {
+   |         ---- binding `line` declared here
 LL |         let v: Vec<&str> = line.split_whitespace().collect();
    |                            ^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/macros/format-args-temporaries-in-write.stderr b/tests/ui/macros/format-args-temporaries-in-write.stderr
index 287cd7d67044e..520b2ce50526f 100644
--- a/tests/ui/macros/format-args-temporaries-in-write.stderr
+++ b/tests/ui/macros/format-args-temporaries-in-write.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `mutex` does not live long enough
   --> $DIR/format-args-temporaries-in-write.rs:41:27
    |
+LL |         let mutex = Mutex;
+   |             ----- binding `mutex` declared here
 LL |         write!(Out, "{}", mutex.lock()) /* no semicolon */
    |                           ^^^^^^^^^^^^
    |                           |
@@ -16,6 +18,8 @@ LL |     };
 error[E0597]: `mutex` does not live long enough
   --> $DIR/format-args-temporaries-in-write.rs:47:29
    |
+LL |         let mutex = Mutex;
+   |             ----- binding `mutex` declared here
 LL |         writeln!(Out, "{}", mutex.lock()) /* no semicolon */
    |                             ^^^^^^^^^^^^
    |                             |
diff --git a/tests/ui/match/issue-74050-end-span.stderr b/tests/ui/match/issue-74050-end-span.stderr
index 59c091e44eb87..0b3425f2b1a1c 100644
--- a/tests/ui/match/issue-74050-end-span.stderr
+++ b/tests/ui/match/issue-74050-end-span.stderr
@@ -4,6 +4,7 @@ error[E0597]: `arg` does not live long enough
 LL |     let _arg = match args.next() {
    |         ---- borrow later stored here
 LL |         Some(arg) => {
+   |              --- binding `arg` declared here
 LL |             match arg.to_str() {
    |                   ^^^^^^^^^^^^ borrowed value does not live long enough
 ...
diff --git a/tests/ui/moves/move-fn-self-receiver.stderr b/tests/ui/moves/move-fn-self-receiver.stderr
index 7f69e5dcfb784..91d237b1d1a90 100644
--- a/tests/ui/moves/move-fn-self-receiver.stderr
+++ b/tests/ui/moves/move-fn-self-receiver.stderr
@@ -75,6 +75,8 @@ LL |     fn use_pin_box_self(self: Pin<Box<Self>>) {}
 error[E0505]: cannot move out of `mut_foo` because it is borrowed
   --> $DIR/move-fn-self-receiver.rs:50:5
    |
+LL |     let mut mut_foo = Foo;
+   |         ----------- binding `mut_foo` declared here
 LL |     let ret = mut_foo.use_mut_self();
    |               ---------------------- borrow of `mut_foo` occurs here
 LL |     mut_foo;
diff --git a/tests/ui/nll/issue-54556-niconii.stderr b/tests/ui/nll/issue-54556-niconii.stderr
index a8e1edc549742..d41d462f2bcb0 100644
--- a/tests/ui/nll/issue-54556-niconii.stderr
+++ b/tests/ui/nll/issue-54556-niconii.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `counter` does not live long enough
   --> $DIR/issue-54556-niconii.rs:22:20
    |
+LL |     let counter = Mutex;
+   |         ------- binding `counter` declared here
+LL |
 LL |     if let Ok(_) = counter.lock() { }
    |                    ^^^^^^^^^^^^^^
    |                    |
diff --git a/tests/ui/span/borrowck-let-suggestion-suffixes.rs b/tests/ui/span/borrowck-let-suggestion-suffixes.rs
index 18abfb5c3fbec..ad556f281df12 100644
--- a/tests/ui/span/borrowck-let-suggestion-suffixes.rs
+++ b/tests/ui/span/borrowck-let-suggestion-suffixes.rs
@@ -8,6 +8,7 @@ fn f() {
 
     {
         let young = ['y'];       // statement 3
+        //~^ NOTE binding `young` declared here
 
         v2.push(&young[0]);      // statement 4
         //~^ ERROR `young[_]` does not live long enough
diff --git a/tests/ui/span/borrowck-let-suggestion-suffixes.stderr b/tests/ui/span/borrowck-let-suggestion-suffixes.stderr
index 2dc29a78d204d..545b235a552d1 100644
--- a/tests/ui/span/borrowck-let-suggestion-suffixes.stderr
+++ b/tests/ui/span/borrowck-let-suggestion-suffixes.stderr
@@ -1,6 +1,9 @@
 error[E0597]: `young[_]` does not live long enough
-  --> $DIR/borrowck-let-suggestion-suffixes.rs:12:17
+  --> $DIR/borrowck-let-suggestion-suffixes.rs:13:17
    |
+LL |         let young = ['y'];       // statement 3
+   |             ----- binding `young` declared here
+...
 LL |         v2.push(&young[0]);      // statement 4
    |                 ^^^^^^^^^ borrowed value does not live long enough
 ...
@@ -11,7 +14,7 @@ LL |     (v1, v2, v3, /* v4 is above. */ v5).use_ref();
    |          -- borrow later used here
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/borrowck-let-suggestion-suffixes.rs:19:14
+  --> $DIR/borrowck-let-suggestion-suffixes.rs:20:14
    |
 LL |     v3.push(&id('x'));           // statement 6
    |              ^^^^^^^ - temporary value is freed at the end of this statement
@@ -28,7 +31,7 @@ LL ~     v3.push(&binding);           // statement 6
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/borrowck-let-suggestion-suffixes.rs:29:18
+  --> $DIR/borrowck-let-suggestion-suffixes.rs:30:18
    |
 LL |         v4.push(&id('y'));
    |                  ^^^^^^^ - temporary value is freed at the end of this statement
@@ -41,7 +44,7 @@ LL |         v4.use_ref();
    = note: consider using a `let` binding to create a longer lived value
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/borrowck-let-suggestion-suffixes.rs:40:14
+  --> $DIR/borrowck-let-suggestion-suffixes.rs:41:14
    |
 LL |     v5.push(&id('z'));
    |              ^^^^^^^ - temporary value is freed at the end of this statement
diff --git a/tests/ui/span/destructor-restrictions.stderr b/tests/ui/span/destructor-restrictions.stderr
index 53c9404620f35..281248626c826 100644
--- a/tests/ui/span/destructor-restrictions.stderr
+++ b/tests/ui/span/destructor-restrictions.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `*a` does not live long enough
   --> $DIR/destructor-restrictions.rs:8:10
    |
+LL |         let a = Box::new(RefCell::new(4));
+   |             - binding `a` declared here
 LL |         *a.borrow() + 1
    |          ^^^^^^^^^^
    |          |
diff --git a/tests/ui/span/issue-23338-locals-die-before-temps-of-body.stderr b/tests/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
index 3c2022748f094..e1a377203e296 100644
--- a/tests/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
+++ b/tests/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
@@ -1,6 +1,8 @@
 error[E0597]: `y` does not live long enough
   --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:10:5
    |
+LL |     let y = x;
+   |         - binding `y` declared here
 LL |     y.borrow().clone()
    |     ^^^^^^^^^^
    |     |
@@ -22,6 +24,8 @@ LL |     let x = y.borrow().clone(); x
 error[E0597]: `y` does not live long enough
   --> $DIR/issue-23338-locals-die-before-temps-of-body.rs:17:9
    |
+LL |         let y = x;
+   |             - binding `y` declared here
 LL |         y.borrow().clone()
    |         ^^^^^^^^^^
    |         |
diff --git a/tests/ui/span/issue-40157.stderr b/tests/ui/span/issue-40157.stderr
index e9b84de505989..a0afd33f7c7c4 100644
--- a/tests/ui/span/issue-40157.stderr
+++ b/tests/ui/span/issue-40157.stderr
@@ -2,9 +2,10 @@ error[E0597]: `foo` does not live long enough
   --> $DIR/issue-40157.rs:2:53
    |
 LL |     {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });}
-   |                                                     ^^^^^^^^^^ - `foo` dropped here while still borrowed
-   |                                                     |
-   |                                                     borrowed value does not live long enough
+   |                                   ---               ^^^^^^^^^^ - `foo` dropped here while still borrowed
+   |                                   |                 |
+   |                                   |                 borrowed value does not live long enough
+   |                                   binding `foo` declared here
 
 error: aborting due to previous error
 

From e1f630f23de2cbce1870e4a226fa0cb8312f106c Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Mon, 16 Jan 2023 18:50:45 +0100
Subject: [PATCH 06/16] Add `OnceCell<T>: !Sync` impl for diagnostics

---
 library/core/src/cell/once.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs
index 7757068a4f2b9..f74e563f1b9c0 100644
--- a/library/core/src/cell/once.rs
+++ b/library/core/src/cell/once.rs
@@ -298,3 +298,7 @@ impl<T> const From<T> for OnceCell<T> {
         OnceCell { inner: UnsafeCell::new(Some(value)) }
     }
 }
+
+// Just like for `Cell<T>` this isn't needed, but results in nicer error messages.
+#[unstable(feature = "once_cell", issue = "74465")]
+impl<T> !Sync for OnceCell<T> {}

From 6d0c91fda35f7a78ff688ea623d1d2ee9b16cad7 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Mon, 16 Jan 2023 18:51:31 +0100
Subject: [PATCH 07/16] Add `rustc_on_unimplemented` on `Sync` for cell types

Suggest using a lock instead.
---
 library/core/src/marker.rs                    | 56 ++++++++++++++++++
 .../issue-68112.drop_tracking.stderr          |  3 +
 .../issue-68112.no_drop_tracking.stderr       |  3 +
 tests/ui/generator/issue-68112.rs             |  2 +
 tests/ui/generator/issue-68112.stderr         | 12 ++--
 tests/ui/generator/not-send-sync.stderr       |  2 +
 .../print/generator-print-verbose-1.stderr    |  2 +
 .../print/generator-print-verbose-2.stderr    |  2 +
 tests/ui/issues/issue-7364.stderr             |  1 +
 tests/ui/stdlib-unit-tests/not-sync.stderr    |  2 +
 tests/ui/{ => sync}/mutexguard-sync.rs        |  0
 tests/ui/{ => sync}/mutexguard-sync.stderr    |  1 +
 tests/ui/sync/suggest-cell.rs                 | 31 ++++++++++
 tests/ui/sync/suggest-cell.stderr             | 59 +++++++++++++++++++
 tests/ui/sync/suggest-once-cell.rs            | 12 ++++
 tests/ui/sync/suggest-once-cell.stderr        | 17 ++++++
 tests/ui/sync/suggest-ref-cell.rs             | 12 ++++
 tests/ui/sync/suggest-ref-cell.stderr         | 17 ++++++
 18 files changed, 229 insertions(+), 5 deletions(-)
 rename tests/ui/{ => sync}/mutexguard-sync.rs (100%)
 rename tests/ui/{ => sync}/mutexguard-sync.stderr (83%)
 create mode 100644 tests/ui/sync/suggest-cell.rs
 create mode 100644 tests/ui/sync/suggest-cell.stderr
 create mode 100644 tests/ui/sync/suggest-once-cell.rs
 create mode 100644 tests/ui/sync/suggest-once-cell.stderr
 create mode 100644 tests/ui/sync/suggest-ref-cell.rs
 create mode 100644 tests/ui/sync/suggest-ref-cell.stderr

diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1326fc9ab096f..74055602ec2e6 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -469,6 +469,62 @@ pub macro Copy($item:item) {
 #[cfg_attr(not(test), rustc_diagnostic_item = "Sync")]
 #[lang = "sync"]
 #[rustc_on_unimplemented(
+    on(
+        _Self = "std::cell::OnceCell<T>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead"
+    ),
+    on(
+        _Self = "std::cell::Cell<u8>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<u16>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<u32>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<u64>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<usize>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<i8>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<i16>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<i32>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<i64>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<isize>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<bool>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead",
+    ),
+    on(
+        _Self = "std::cell::Cell<T>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`",
+    ),
+    on(
+        _Self = "std::cell::RefCell<T>",
+        note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
+    ),
     message = "`{Self}` cannot be shared between threads safely",
     label = "`{Self}` cannot be shared between threads safely"
 )]
diff --git a/tests/ui/async-await/issue-68112.drop_tracking.stderr b/tests/ui/async-await/issue-68112.drop_tracking.stderr
index f2802698fd5b6..bd648de30672d 100644
--- a/tests/ui/async-await/issue-68112.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-68112.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     require_send(send_fut);
    |                  ^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/issue-68112.rs:34:17
    |
@@ -23,6 +24,7 @@ LL |     require_send(send_fut);
    |                  ^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/issue-68112.rs:43:17
    |
@@ -43,6 +45,7 @@ LL |     require_send(send_fut);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this `async fn` body
   --> $DIR/issue-68112.rs:50:31
diff --git a/tests/ui/async-await/issue-68112.no_drop_tracking.stderr b/tests/ui/async-await/issue-68112.no_drop_tracking.stderr
index 38eb85b302fd5..35b7341f63a4d 100644
--- a/tests/ui/async-await/issue-68112.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-68112.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     require_send(send_fut);
    |                  ^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/issue-68112.rs:34:17
    |
@@ -23,6 +24,7 @@ LL |     require_send(send_fut);
    |                  ^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/issue-68112.rs:43:17
    |
@@ -43,6 +45,7 @@ LL |     require_send(send_fut);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this `async fn` body
   --> $DIR/issue-68112.rs:50:31
diff --git a/tests/ui/generator/issue-68112.rs b/tests/ui/generator/issue-68112.rs
index 21026f45cb823..9def544e3d25c 100644
--- a/tests/ui/generator/issue-68112.rs
+++ b/tests/ui/generator/issue-68112.rs
@@ -40,6 +40,7 @@ fn test1() {
     require_send(send_gen);
     //~^ ERROR generator cannot be sent between threads
     //~| NOTE not `Send`
+    //~| NOTE use `std::sync::RwLock` instead
 }
 
 pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
@@ -66,6 +67,7 @@ fn test2() {
     //~| NOTE required for
     //~| NOTE required by a bound introduced by this call
     //~| NOTE captures the following types
+    //~| NOTE use `std::sync::RwLock` instead
 }
 
 fn main() {}
diff --git a/tests/ui/generator/issue-68112.stderr b/tests/ui/generator/issue-68112.stderr
index eb99d42c92068..b42bc93d01f66 100644
--- a/tests/ui/generator/issue-68112.stderr
+++ b/tests/ui/generator/issue-68112.stderr
@@ -5,6 +5,7 @@ LL |     require_send(send_gen);
    |                  ^^^^^^^^ generator is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-68112.rs:36:9
    |
@@ -23,7 +24,7 @@ LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
 
 error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:63:18
+  --> $DIR/issue-68112.rs:64:18
    |
 LL |     require_send(send_gen);
    |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
@@ -31,25 +32,26 @@ LL |     require_send(send_gen);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:48:5
+  --> $DIR/issue-68112.rs:49:5
    |
 LL |     || {
    |     ^^
 note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:45:30
+  --> $DIR/issue-68112.rs:46:30
    |
 LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:53:34
+  --> $DIR/issue-68112.rs:54:34
    |
 LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`, `()`
 note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:59:20
+  --> $DIR/issue-68112.rs:60:20
    |
 LL |     let send_gen = || {
    |                    ^^
diff --git a/tests/ui/generator/not-send-sync.stderr b/tests/ui/generator/not-send-sync.stderr
index a821c57b923a0..1711df729b8c0 100644
--- a/tests/ui/generator/not-send-sync.stderr
+++ b/tests/ui/generator/not-send-sync.stderr
@@ -12,6 +12,7 @@ LL | |     });
    | |_____^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
    = note: required for `&Cell<i32>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/not-send-sync.rs:16:17
@@ -36,6 +37,7 @@ LL | |     });
    | |_____^ generator is not `Sync`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:9:17: 9:19]`, the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:12:9
    |
diff --git a/tests/ui/generator/print/generator-print-verbose-1.stderr b/tests/ui/generator/print/generator-print-verbose-1.stderr
index ebf35be581c60..45d018b8ebad5 100644
--- a/tests/ui/generator/print/generator-print-verbose-1.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-1.stderr
@@ -5,6 +5,7 @@ LL |     require_send(send_gen);
    |                  ^^^^^^^^ generator is not `Send`
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/generator-print-verbose-1.rs:35:9
    |
@@ -29,6 +30,7 @@ LL |     require_send(send_gen);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/generator-print-verbose-1.rs:42:5
diff --git a/tests/ui/generator/print/generator-print-verbose-2.stderr b/tests/ui/generator/print/generator-print-verbose-2.stderr
index 909e49c38b8d1..59112ce0a79e6 100644
--- a/tests/ui/generator/print/generator-print-verbose-2.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-2.stderr
@@ -12,6 +12,7 @@ LL | |     });
    | |_____^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
    = note: required for `&'_#4r Cell<i32>` to implement `Send`
 note: required because it's used within this generator
   --> $DIR/generator-print-verbose-2.rs:19:17
@@ -36,6 +37,7 @@ LL | |     });
    | |_____^ generator is not `Sync`
    |
    = help: within `[main::{closure#0} upvar_tys=() {Cell<i32>, ()}]`, the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:15:9
    |
diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr
index 5dc8c2b607e61..aee73380f15e7 100644
--- a/tests/ui/issues/issue-7364.stderr
+++ b/tests/ui/issues/issue-7364.stderr
@@ -5,6 +5,7 @@ LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
    |               ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<isize>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Unique<RefCell<isize>>` to implement `Sync`
    = note: required because it appears within the type `Box<RefCell<isize>>`
    = note: shared static variables must have a type that implements `Sync`
diff --git a/tests/ui/stdlib-unit-tests/not-sync.stderr b/tests/ui/stdlib-unit-tests/not-sync.stderr
index 1ee358ba8368e..4e34e10e37789 100644
--- a/tests/ui/stdlib-unit-tests/not-sync.stderr
+++ b/tests/ui/stdlib-unit-tests/not-sync.stderr
@@ -5,6 +5,7 @@ LL |     test::<Cell<i32>>();
    |            ^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
 note: required by a bound in `test`
   --> $DIR/not-sync.rs:5:12
    |
@@ -18,6 +19,7 @@ LL |     test::<RefCell<i32>>();
    |            ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: required by a bound in `test`
   --> $DIR/not-sync.rs:5:12
    |
diff --git a/tests/ui/mutexguard-sync.rs b/tests/ui/sync/mutexguard-sync.rs
similarity index 100%
rename from tests/ui/mutexguard-sync.rs
rename to tests/ui/sync/mutexguard-sync.rs
diff --git a/tests/ui/mutexguard-sync.stderr b/tests/ui/sync/mutexguard-sync.stderr
similarity index 83%
rename from tests/ui/mutexguard-sync.stderr
rename to tests/ui/sync/mutexguard-sync.stderr
index 3fbb2ddf183d3..4dc5571196c14 100644
--- a/tests/ui/mutexguard-sync.stderr
+++ b/tests/ui/sync/mutexguard-sync.stderr
@@ -7,6 +7,7 @@ LL |     test_sync(guard);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
    = note: required for `MutexGuard<'_, Cell<i32>>` to implement `Sync`
 note: required by a bound in `test_sync`
   --> $DIR/mutexguard-sync.rs:5:17
diff --git a/tests/ui/sync/suggest-cell.rs b/tests/ui/sync/suggest-cell.rs
new file mode 100644
index 0000000000000..3284eae7be181
--- /dev/null
+++ b/tests/ui/sync/suggest-cell.rs
@@ -0,0 +1,31 @@
+fn require_sync<T: Sync>() {}
+//~^ NOTE required by this bound in `require_sync`
+//~| NOTE required by this bound in `require_sync`
+//~| NOTE required by this bound in `require_sync`
+//~| NOTE required by this bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+
+fn main() {
+    require_sync::<std::cell::Cell<()>>();
+    //~^ ERROR `Cell<()>` cannot be shared between threads safely
+    //~| NOTE `Cell<()>` cannot be shared between threads safely
+    //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
+
+    require_sync::<std::cell::Cell<u8>>();
+    //~^ ERROR `Cell<u8>` cannot be shared between threads safely
+    //~| NOTE `Cell<u8>` cannot be shared between threads safely
+    //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead
+
+    require_sync::<std::cell::Cell<i32>>();
+    //~^ ERROR `Cell<i32>` cannot be shared between threads safely
+    //~| NOTE `Cell<i32>` cannot be shared between threads safely
+    //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
+
+    require_sync::<std::cell::Cell<bool>>();
+    //~^ ERROR `Cell<bool>` cannot be shared between threads safely
+    //~| NOTE `Cell<bool>` cannot be shared between threads safely
+    //~| NOTE if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead
+}
diff --git a/tests/ui/sync/suggest-cell.stderr b/tests/ui/sync/suggest-cell.stderr
new file mode 100644
index 0000000000000..c232c1ccd53dd
--- /dev/null
+++ b/tests/ui/sync/suggest-cell.stderr
@@ -0,0 +1,59 @@
+error[E0277]: `Cell<()>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:12:20
+   |
+LL |     require_sync::<std::cell::Cell<()>>();
+   |                    ^^^^^^^^^^^^^^^^^^^ `Cell<()>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<()>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
+note: required by a bound in `require_sync`
+  --> $DIR/suggest-cell.rs:1:20
+   |
+LL | fn require_sync<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error[E0277]: `Cell<u8>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:17:20
+   |
+LL |     require_sync::<std::cell::Cell<u8>>();
+   |                    ^^^^^^^^^^^^^^^^^^^ `Cell<u8>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<u8>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead
+note: required by a bound in `require_sync`
+  --> $DIR/suggest-cell.rs:1:20
+   |
+LL | fn require_sync<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error[E0277]: `Cell<i32>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:22:20
+   |
+LL |     require_sync::<std::cell::Cell<i32>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^ `Cell<i32>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<i32>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
+note: required by a bound in `require_sync`
+  --> $DIR/suggest-cell.rs:1:20
+   |
+LL | fn require_sync<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error[E0277]: `Cell<bool>` cannot be shared between threads safely
+  --> $DIR/suggest-cell.rs:27:20
+   |
+LL |     require_sync::<std::cell::Cell<bool>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^^ `Cell<bool>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `Cell<bool>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead
+note: required by a bound in `require_sync`
+  --> $DIR/suggest-cell.rs:1:20
+   |
+LL | fn require_sync<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/sync/suggest-once-cell.rs b/tests/ui/sync/suggest-once-cell.rs
new file mode 100644
index 0000000000000..82fca45b1a47f
--- /dev/null
+++ b/tests/ui/sync/suggest-once-cell.rs
@@ -0,0 +1,12 @@
+#![feature(once_cell)]
+
+fn require_sync<T: Sync>() {}
+//~^ NOTE required by this bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+
+fn main() {
+    require_sync::<std::cell::OnceCell<()>>();
+    //~^ ERROR `OnceCell<()>` cannot be shared between threads safely
+    //~| NOTE `OnceCell<()>` cannot be shared between threads safely
+    //~| NOTE use `std::sync::OnceLock` instead
+}
diff --git a/tests/ui/sync/suggest-once-cell.stderr b/tests/ui/sync/suggest-once-cell.stderr
new file mode 100644
index 0000000000000..fadf05374d8ca
--- /dev/null
+++ b/tests/ui/sync/suggest-once-cell.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `OnceCell<()>` cannot be shared between threads safely
+  --> $DIR/suggest-once-cell.rs:8:20
+   |
+LL |     require_sync::<std::cell::OnceCell<()>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^ `OnceCell<()>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `OnceCell<()>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead
+note: required by a bound in `require_sync`
+  --> $DIR/suggest-once-cell.rs:3:20
+   |
+LL | fn require_sync<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/sync/suggest-ref-cell.rs b/tests/ui/sync/suggest-ref-cell.rs
new file mode 100644
index 0000000000000..6b972ae09622e
--- /dev/null
+++ b/tests/ui/sync/suggest-ref-cell.rs
@@ -0,0 +1,12 @@
+#![feature(once_cell)]
+
+fn require_sync<T: Sync>() {}
+//~^ NOTE required by this bound in `require_sync`
+//~| NOTE required by a bound in `require_sync`
+
+fn main() {
+    require_sync::<std::cell::RefCell<()>>();
+    //~^ ERROR `RefCell<()>` cannot be shared between threads safely
+    //~| NOTE `RefCell<()>` cannot be shared between threads safely
+    //~| NOTE use `std::sync::RwLock` instead
+}
diff --git a/tests/ui/sync/suggest-ref-cell.stderr b/tests/ui/sync/suggest-ref-cell.stderr
new file mode 100644
index 0000000000000..9e8b8fcb42ed0
--- /dev/null
+++ b/tests/ui/sync/suggest-ref-cell.stderr
@@ -0,0 +1,17 @@
+error[E0277]: `RefCell<()>` cannot be shared between threads safely
+  --> $DIR/suggest-ref-cell.rs:8:20
+   |
+LL |     require_sync::<std::cell::RefCell<()>>();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<()>` cannot be shared between threads safely
+   |
+   = help: the trait `Sync` is not implemented for `RefCell<()>`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
+note: required by a bound in `require_sync`
+  --> $DIR/suggest-ref-cell.rs:3:20
+   |
+LL | fn require_sync<T: Sync>() {}
+   |                    ^^^^ required by this bound in `require_sync`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.

From 62a1e76d2beaa87d7f02a55e2d7faa03cdd5fd7f Mon Sep 17 00:00:00 2001
From: yanchen4791 <ychen2@futurewei.com>
Date: Mon, 5 Dec 2022 16:51:49 -0800
Subject: [PATCH 08/16] Add hint for missing lifetime bound on trait object
 when type alias is used

---
 .../src/diagnostics/region_errors.rs          | 59 +++++++++++++------
 compiler/rustc_hir/src/hir.rs                 |  7 +++
 compiler/rustc_middle/src/ty/context.rs       | 24 ++++++++
 ...und-on-trait-object-using-type-alias.fixed | 45 ++++++++++++++
 ...-bound-on-trait-object-using-type-alias.rs | 45 ++++++++++++++
 ...nd-on-trait-object-using-type-alias.stderr | 15 +++++
 6 files changed, 176 insertions(+), 19 deletions(-)
 create mode 100644 tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed
 create mode 100644 tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs
 create mode 100644 tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr

diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 187861ba127bd..87db08ef5b510 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -813,17 +813,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             if *outlived_f != ty::ReStatic {
                 return;
             }
+            let suitable_region = self.infcx.tcx.is_suitable_region(f);
+            let Some(suitable_region) = suitable_region else { return; };
 
-            let fn_returns = self
-                .infcx
-                .tcx
-                .is_suitable_region(f)
-                .map(|r| self.infcx.tcx.return_type_impl_or_dyn_traits(r.def_id))
-                .unwrap_or_default();
-
-            if fn_returns.is_empty() {
-                return;
-            }
+            let fn_returns = self.infcx.tcx.return_type_impl_or_dyn_traits(suitable_region.def_id);
 
             let param = if let Some(param) = find_param_with_region(self.infcx.tcx, f, outlived_f) {
                 param
@@ -839,15 +832,43 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             };
             let captures = format!("captures data from {arg}");
 
-            return nice_region_error::suggest_new_region_bound(
-                self.infcx.tcx,
-                diag,
-                fn_returns,
-                lifetime.to_string(),
-                Some(arg),
-                captures,
-                Some((param.param_ty_span, param.param_ty.to_string())),
-                self.infcx.tcx.is_suitable_region(f).map(|r| r.def_id),
+            if !fn_returns.is_empty() {
+                nice_region_error::suggest_new_region_bound(
+                    self.infcx.tcx,
+                    diag,
+                    fn_returns,
+                    lifetime.to_string(),
+                    Some(arg),
+                    captures,
+                    Some((param.param_ty_span, param.param_ty.to_string())),
+                    Some(suitable_region.def_id),
+                );
+                return;
+            }
+
+            let Some((alias_tys, alias_span)) = self
+                .infcx
+                .tcx
+                .return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; };
+
+            // in case the return type of the method is a type alias
+            let mut spans_suggs: Vec<_> = Vec::new();
+            for alias_ty in alias_tys {
+                if alias_ty.span.desugaring_kind().is_some() {
+                    // Skip `async` desugaring `impl Future`.
+                    ()
+                }
+                if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
+                    spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
+                }
+            }
+            spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
+            diag.multipart_suggestion_verbose(
+                &format!(
+                    "to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"
+                ),
+                spans_suggs,
+                Applicability::MaybeIncorrect,
             );
         }
     }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index d6566860f8170..b456bd08048db 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3524,6 +3524,13 @@ impl<'hir> Node<'hir> {
         }
     }
 
+    pub fn alias_ty(self) -> Option<&'hir Ty<'hir>> {
+        match self {
+            Node::Item(Item { kind: ItemKind::TyAlias(ty, ..), .. }) => Some(ty),
+            _ => None,
+        }
+    }
+
     pub fn body_id(&self) -> Option<BodyId> {
         match self {
             Node::TraitItem(TraitItem {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index ce04d8d21f4cd..0b16270ea9874 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -997,6 +997,30 @@ impl<'tcx> TyCtxt<'tcx> {
         v.0
     }
 
+    /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type and associated alias span when type alias is used
+    pub fn return_type_impl_or_dyn_traits_with_type_alias(
+        self,
+        scope_def_id: LocalDefId,
+    ) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span)> {
+        let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
+        let mut v = TraitObjectVisitor(vec![], self.hir());
+        // when the return type is a type alias
+        if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id)
+            && let hir::TyKind::Path(hir::QPath::Resolved(
+                None,
+                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
+            && let Some(local_id) = def_id.as_local()
+            && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
+            && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
+        {
+            v.visit_ty(alias_ty);
+            if !v.0.is_empty() {
+                return Some((v.0, alias_generics.span));
+            }
+        }
+        return None;
+    }
+
     pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
         // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
         match self.hir().get_by_def_id(scope_def_id) {
diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed
new file mode 100644
index 0000000000000..aa3bce2945b68
--- /dev/null
+++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.fixed
@@ -0,0 +1,45 @@
+// run-rustfix
+
+trait Greeter0 {
+    fn greet(&self);
+}
+
+trait Greeter1 {
+    fn greet(&self);
+}
+
+type BoxedGreeter<'a> = (Box<dyn Greeter0 + 'a>, Box<dyn Greeter1 + 'a>);
+//~^ HELP to declare that the trait object captures data from argument `self`, you can add a lifetime parameter `'a` in the type alias
+
+struct FixedGreeter<'a>(pub &'a str);
+
+impl Greeter0 for FixedGreeter<'_> {
+    fn greet(&self) {
+        println!("0 {}", self.0)
+    }
+}
+
+impl Greeter1 for FixedGreeter<'_> {
+    fn greet(&self) {
+        println!("1 {}", self.0)
+    }
+}
+
+struct Greetings(pub Vec<String>);
+
+impl Greetings {
+    pub fn get(&self, i: usize) -> BoxedGreeter {
+        (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i])))
+        //~^ ERROR lifetime may not live long enough
+    }
+}
+
+fn main() {
+    let mut g = Greetings {0 : vec!()};
+    g.0.push("a".to_string());
+    g.0.push("b".to_string());
+    g.get(0).0.greet();
+    g.get(0).1.greet();
+    g.get(1).0.greet();
+    g.get(1).1.greet();
+}
diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs
new file mode 100644
index 0000000000000..20c88ec69813a
--- /dev/null
+++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs
@@ -0,0 +1,45 @@
+// run-rustfix
+
+trait Greeter0 {
+    fn greet(&self);
+}
+
+trait Greeter1 {
+    fn greet(&self);
+}
+
+type BoxedGreeter = (Box<dyn Greeter0>, Box<dyn Greeter1>);
+//~^ HELP to declare that the trait object captures data from argument `self`, you can add a lifetime parameter `'a` in the type alias
+
+struct FixedGreeter<'a>(pub &'a str);
+
+impl Greeter0 for FixedGreeter<'_> {
+    fn greet(&self) {
+        println!("0 {}", self.0)
+    }
+}
+
+impl Greeter1 for FixedGreeter<'_> {
+    fn greet(&self) {
+        println!("1 {}", self.0)
+    }
+}
+
+struct Greetings(pub Vec<String>);
+
+impl Greetings {
+    pub fn get(&self, i: usize) -> BoxedGreeter {
+        (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i])))
+        //~^ ERROR lifetime may not live long enough
+    }
+}
+
+fn main() {
+    let mut g = Greetings {0 : vec!()};
+    g.0.push("a".to_string());
+    g.0.push("b".to_string());
+    g.get(0).0.greet();
+    g.get(0).1.greet();
+    g.get(1).0.greet();
+    g.get(1).1.greet();
+}
diff --git a/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr
new file mode 100644
index 0000000000000..808d8bb905885
--- /dev/null
+++ b/tests/ui/lifetimes/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/issue-103582-hint-for-missing-lifetime-bound-on-trait-object-using-type-alias.rs:32:9
+   |
+LL |     pub fn get(&self, i: usize) -> BoxedGreeter {
+   |                - let's call the lifetime of this reference `'1`
+LL |         (Box::new(FixedGreeter(&self.0[i])), Box::new(FixedGreeter(&self.0[i])))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `self`, you can add a lifetime parameter `'a` in the type alias
+   |
+LL | type BoxedGreeter<'a> = (Box<dyn Greeter0 + 'a>, Box<dyn Greeter1 + 'a>);
+   |                  ++++                     ++++                    ++++
+
+error: aborting due to previous error
+

From 7f5ce942809e15f65d91089e8baacc6affdf6c9c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com>
Date: Mon, 23 Jan 2023 00:00:00 +0000
Subject: [PATCH 09/16] Bring tests back into rustc source tarball

They were missing after recent move from src/test to tests.
---
 src/bootstrap/dist.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 2d86ff1d2baea..02e35d2436e2f 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -962,7 +962,7 @@ impl Step for PlainSourceTarball {
             "Cargo.toml",
             "Cargo.lock",
         ];
-        let src_dirs = ["src", "compiler", "library"];
+        let src_dirs = ["src", "compiler", "library", "tests"];
 
         copy_src_dirs(builder, &builder.src, &src_dirs, &[], &plain_dst_src);
 

From e65b36110f943118b7e50c4e39e26ad1f07d8552 Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Mon, 23 Jan 2023 17:10:54 -0700
Subject: [PATCH 10/16] rustdoc: rearrange HTML in primitive reference links

This patch avoids hard-to-click single character links by making
the generic part of the link:

Before: <a href="#">&</a>T

After: <a href="#">&T</a>
---
 src/librustdoc/html/format.rs                          | 10 ++--------
 tests/rustdoc/whitespace-after-where-clause.enum.html  |  2 +-
 tests/rustdoc/whitespace-after-where-clause.enum2.html |  2 +-
 .../rustdoc/whitespace-after-where-clause.struct.html  |  2 +-
 .../rustdoc/whitespace-after-where-clause.struct2.html |  2 +-
 5 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d3dc4065dfc72..33404a7683597 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1064,14 +1064,8 @@ fn fmt_type<'cx>(
                     fmt_type(ty, f, use_absolute, cx)?;
                     write!(f, ")")
                 }
-                clean::Generic(..) => {
-                    primitive_link(
-                        f,
-                        PrimitiveType::Reference,
-                        &format!("{}{}{}", amp, lt, m),
-                        cx,
-                    )?;
-                    fmt_type(ty, f, use_absolute, cx)
+                clean::Generic(name) => {
+                    primitive_link(f, PrimitiveType::Reference, &format!("{amp}{lt}{m}{name}"), cx)
                 }
                 _ => {
                     write!(f, "{}{}{}", amp, lt, m)?;
diff --git a/tests/rustdoc/whitespace-after-where-clause.enum.html b/tests/rustdoc/whitespace-after-where-clause.enum.html
index 20bde549a0378..eeb22878f3c63 100644
--- a/tests/rustdoc/whitespace-after-where-clause.enum.html
+++ b/tests/rustdoc/whitespace-after-where-clause.enum.html
@@ -1,4 +1,4 @@
 <div class="item-decl"><pre class="rust"><code>pub enum Cow&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
-    Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B),
+    Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>),
     Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
 }</code></pre></div>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.enum2.html b/tests/rustdoc/whitespace-after-where-clause.enum2.html
index d9fc0c22309db..c8037c2a8df5a 100644
--- a/tests/rustdoc/whitespace-after-where-clause.enum2.html
+++ b/tests/rustdoc/whitespace-after-where-clause.enum2.html
@@ -1,4 +1,4 @@
 <div class="item-decl"><pre class="rust"><code>pub enum Cow2&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + 'a&gt; {
-    Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B),
+    Borrowed(<a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>),
     Whatever(<a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>),
 }</code></pre></div>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc/whitespace-after-where-clause.struct.html
index f375265d7c183..5892270b2f930 100644
--- a/tests/rustdoc/whitespace-after-where-clause.struct.html
+++ b/tests/rustdoc/whitespace-after-where-clause.struct.html
@@ -1,4 +1,4 @@
 <div class="item-decl"><pre class="rust"><code>pub struct Struct&lt;'a, B&gt;<span class="where fmt-newline">where<br />&#160;&#160;&#160;&#160;B: <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + ?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + 'a,</span>{
-    pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B,
+    pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>,
     pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
 }</code></pre></div>
\ No newline at end of file
diff --git a/tests/rustdoc/whitespace-after-where-clause.struct2.html b/tests/rustdoc/whitespace-after-where-clause.struct2.html
index 1c59962eb1c58..d3952b0c56699 100644
--- a/tests/rustdoc/whitespace-after-where-clause.struct2.html
+++ b/tests/rustdoc/whitespace-after-where-clause.struct2.html
@@ -1,4 +1,4 @@
 <div class="item-decl"><pre class="rust"><code>pub struct Struct2&lt;'a, B:&#160;?<a class="trait" href="{{channel}}/core/marker/trait.Sized.html" title="trait core::marker::Sized">Sized</a> + <a class="trait" href="trait.ToOwned.html" title="trait foo::ToOwned">ToOwned</a>&lt;dyn <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>&gt; + 'a&gt; {
-    pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a </a>B,
+    pub a: <a class="primitive" href="{{channel}}/std/primitive.reference.html">&amp;'a B</a>,
     pub b: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a>,
 }</code></pre></div>
\ No newline at end of file

From e6e93e021e7be6c9ae400145a2aa235f16f9eb45 Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Tue, 24 Jan 2023 12:41:18 +0100
Subject: [PATCH 11/16] add test where we ignore hr implied bounds

---
 tests/ui/regions/higher-ranked-implied.rs     | 14 +++++++++++++
 tests/ui/regions/higher-ranked-implied.stderr | 21 +++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 tests/ui/regions/higher-ranked-implied.rs
 create mode 100644 tests/ui/regions/higher-ranked-implied.stderr

diff --git a/tests/ui/regions/higher-ranked-implied.rs b/tests/ui/regions/higher-ranked-implied.rs
new file mode 100644
index 0000000000000..103884c50313f
--- /dev/null
+++ b/tests/ui/regions/higher-ranked-implied.rs
@@ -0,0 +1,14 @@
+// FIXME: This test should pass as the first two fields add implied bounds that
+// `'a` is equal to `'b` while the last one should simply use that fact. With
+// the current implementation this errors. We have to be careful as implied bounds
+// are only sound if they're also correctly checked.
+
+struct Inv<T>(*mut T); // `T` is invariant.
+type A = for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>);
+type B = for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>);
+
+fn main() {
+    let x: A = |_, _, _| ();
+    let y: B = x; //~ ERROR mismatched types
+    let _: A = y; //~ ERROR mismatched types
+}
diff --git a/tests/ui/regions/higher-ranked-implied.stderr b/tests/ui/regions/higher-ranked-implied.stderr
new file mode 100644
index 0000000000000..9d80eacd7c320
--- /dev/null
+++ b/tests/ui/regions/higher-ranked-implied.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-implied.rs:12:16
+   |
+LL |     let y: B = x;
+   |                ^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
+              found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
+
+error[E0308]: mismatched types
+  --> $DIR/higher-ranked-implied.rs:13:16
+   |
+LL |     let _: A = y;
+   |                ^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
+              found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.

From ad7393668f7f54372b974baa37854601756bacc3 Mon Sep 17 00:00:00 2001
From: Jakob Degen <jakob.e.degen@gmail.com>
Date: Tue, 24 Jan 2023 04:13:52 -0800
Subject: [PATCH 12/16] Delete `SimplifyArmIdentity` and `SimplifyBranchSame`
 mir opts

---
 compiler/rustc_mir_transform/src/lib.rs       |   3 -
 .../rustc_mir_transform/src/simplify_try.rs   | 822 ------------------
 ..._regression.encode.SimplifyBranchSame.diff |  29 -
 tests/mir-opt/76803_regression.rs             |  19 -
 .../issue_73223.main.SimplifyArmIdentity.diff | 156 ----
 tests/mir-opt/issue_73223.rs                  |  12 -
 6 files changed, 1041 deletions(-)
 delete mode 100644 compiler/rustc_mir_transform/src/simplify_try.rs
 delete mode 100644 tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff
 delete mode 100644 tests/mir-opt/76803_regression.rs
 delete mode 100644 tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
 delete mode 100644 tests/mir-opt/issue_73223.rs

diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 20b7fdcfe6d4d..4a598862d10f8 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -90,7 +90,6 @@ mod shim;
 pub mod simplify;
 mod simplify_branches;
 mod simplify_comparison_integral;
-mod simplify_try;
 mod sroa;
 mod uninhabited_enum_branching;
 mod unreachable_prop;
@@ -567,8 +566,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             &o1(simplify_branches::SimplifyConstCondition::new("after-const-prop")),
             &early_otherwise_branch::EarlyOtherwiseBranch,
             &simplify_comparison_integral::SimplifyComparisonIntegral,
-            &simplify_try::SimplifyArmIdentity,
-            &simplify_try::SimplifyBranchSame,
             &dead_store_elimination::DeadStoreElimination,
             &dest_prop::DestinationPropagation,
             &o1(simplify_branches::SimplifyConstCondition::new("final")),
diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs
deleted file mode 100644
index e4f3ace9a93da..0000000000000
--- a/compiler/rustc_mir_transform/src/simplify_try.rs
+++ /dev/null
@@ -1,822 +0,0 @@
-//! The general point of the optimizations provided here is to simplify something like:
-//!
-//! ```rust
-//! # fn foo<T, E>(x: Result<T, E>) -> Result<T, E> {
-//! match x {
-//!     Ok(x) => Ok(x),
-//!     Err(x) => Err(x)
-//! }
-//! # }
-//! ```
-//!
-//! into just `x`.
-
-use crate::{simplify, MirPass};
-use itertools::Itertools as _;
-use rustc_index::{bit_set::BitSet, vec::IndexVec};
-use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
-use rustc_middle::mir::*;
-use rustc_middle::ty::{self, List, Ty, TyCtxt};
-use rustc_target::abi::VariantIdx;
-use std::iter::{once, Enumerate, Peekable};
-use std::slice::Iter;
-
-/// Simplifies arms of form `Variant(x) => Variant(x)` to just a move.
-///
-/// This is done by transforming basic blocks where the statements match:
-///
-/// ```ignore (MIR)
-/// _LOCAL_TMP = ((_LOCAL_1 as Variant ).FIELD: TY );
-/// _TMP_2 = _LOCAL_TMP;
-/// ((_LOCAL_0 as Variant).FIELD: TY) = move _TMP_2;
-/// discriminant(_LOCAL_0) = VAR_IDX;
-/// ```
-///
-/// into:
-///
-/// ```ignore (MIR)
-/// _LOCAL_0 = move _LOCAL_1
-/// ```
-pub struct SimplifyArmIdentity;
-
-#[derive(Debug)]
-struct ArmIdentityInfo<'tcx> {
-    /// Storage location for the variant's field
-    local_temp_0: Local,
-    /// Storage location holding the variant being read from
-    local_1: Local,
-    /// The variant field being read from
-    vf_s0: VarField<'tcx>,
-    /// Index of the statement which loads the variant being read
-    get_variant_field_stmt: usize,
-
-    /// Tracks each assignment to a temporary of the variant's field
-    field_tmp_assignments: Vec<(Local, Local)>,
-
-    /// Storage location holding the variant's field that was read from
-    local_tmp_s1: Local,
-    /// Storage location holding the enum that we are writing to
-    local_0: Local,
-    /// The variant field being written to
-    vf_s1: VarField<'tcx>,
-
-    /// Storage location that the discriminant is being written to
-    set_discr_local: Local,
-    /// The variant being written
-    set_discr_var_idx: VariantIdx,
-
-    /// Index of the statement that should be overwritten as a move
-    stmt_to_overwrite: usize,
-    /// SourceInfo for the new move
-    source_info: SourceInfo,
-
-    /// Indices of matching Storage{Live,Dead} statements encountered.
-    /// (StorageLive index,, StorageDead index, Local)
-    storage_stmts: Vec<(usize, usize, Local)>,
-
-    /// The statements that should be removed (turned into nops)
-    stmts_to_remove: Vec<usize>,
-
-    /// Indices of debug variables that need to be adjusted to point to
-    // `{local_0}.{dbg_projection}`.
-    dbg_info_to_adjust: Vec<usize>,
-
-    /// The projection used to rewrite debug info.
-    dbg_projection: &'tcx List<PlaceElem<'tcx>>,
-}
-
-fn get_arm_identity_info<'a, 'tcx>(
-    stmts: &'a [Statement<'tcx>],
-    locals_count: usize,
-    debug_info: &'a [VarDebugInfo<'tcx>],
-) -> Option<ArmIdentityInfo<'tcx>> {
-    // This can't possibly match unless there are at least 3 statements in the block
-    // so fail fast on tiny blocks.
-    if stmts.len() < 3 {
-        return None;
-    }
-
-    let mut tmp_assigns = Vec::new();
-    let mut nop_stmts = Vec::new();
-    let mut storage_stmts = Vec::new();
-    let mut storage_live_stmts = Vec::new();
-    let mut storage_dead_stmts = Vec::new();
-
-    type StmtIter<'a, 'tcx> = Peekable<Enumerate<Iter<'a, Statement<'tcx>>>>;
-
-    fn is_storage_stmt(stmt: &Statement<'_>) -> bool {
-        matches!(stmt.kind, StatementKind::StorageLive(_) | StatementKind::StorageDead(_))
-    }
-
-    /// Eats consecutive Statements which match `test`, performing the specified `action` for each.
-    /// The iterator `stmt_iter` is not advanced if none were matched.
-    fn try_eat<'a, 'tcx>(
-        stmt_iter: &mut StmtIter<'a, 'tcx>,
-        test: impl Fn(&'a Statement<'tcx>) -> bool,
-        mut action: impl FnMut(usize, &'a Statement<'tcx>),
-    ) {
-        while stmt_iter.peek().map_or(false, |(_, stmt)| test(stmt)) {
-            let (idx, stmt) = stmt_iter.next().unwrap();
-
-            action(idx, stmt);
-        }
-    }
-
-    /// Eats consecutive `StorageLive` and `StorageDead` Statements.
-    /// The iterator `stmt_iter` is not advanced if none were found.
-    fn try_eat_storage_stmts(
-        stmt_iter: &mut StmtIter<'_, '_>,
-        storage_live_stmts: &mut Vec<(usize, Local)>,
-        storage_dead_stmts: &mut Vec<(usize, Local)>,
-    ) {
-        try_eat(stmt_iter, is_storage_stmt, |idx, stmt| {
-            if let StatementKind::StorageLive(l) = stmt.kind {
-                storage_live_stmts.push((idx, l));
-            } else if let StatementKind::StorageDead(l) = stmt.kind {
-                storage_dead_stmts.push((idx, l));
-            }
-        })
-    }
-
-    fn is_tmp_storage_stmt(stmt: &Statement<'_>) -> bool {
-        use rustc_middle::mir::StatementKind::Assign;
-        if let Assign(box (place, Rvalue::Use(Operand::Copy(p) | Operand::Move(p)))) = &stmt.kind {
-            place.as_local().is_some() && p.as_local().is_some()
-        } else {
-            false
-        }
-    }
-
-    /// Eats consecutive `Assign` Statements.
-    // The iterator `stmt_iter` is not advanced if none were found.
-    fn try_eat_assign_tmp_stmts(
-        stmt_iter: &mut StmtIter<'_, '_>,
-        tmp_assigns: &mut Vec<(Local, Local)>,
-        nop_stmts: &mut Vec<usize>,
-    ) {
-        try_eat(stmt_iter, is_tmp_storage_stmt, |idx, stmt| {
-            use rustc_middle::mir::StatementKind::Assign;
-            if let Assign(box (place, Rvalue::Use(Operand::Copy(p) | Operand::Move(p)))) =
-                &stmt.kind
-            {
-                tmp_assigns.push((place.as_local().unwrap(), p.as_local().unwrap()));
-                nop_stmts.push(idx);
-            }
-        })
-    }
-
-    fn find_storage_live_dead_stmts_for_local(
-        local: Local,
-        stmts: &[Statement<'_>],
-    ) -> Option<(usize, usize)> {
-        trace!("looking for {:?}", local);
-        let mut storage_live_stmt = None;
-        let mut storage_dead_stmt = None;
-        for (idx, stmt) in stmts.iter().enumerate() {
-            if stmt.kind == StatementKind::StorageLive(local) {
-                storage_live_stmt = Some(idx);
-            } else if stmt.kind == StatementKind::StorageDead(local) {
-                storage_dead_stmt = Some(idx);
-            }
-        }
-
-        Some((storage_live_stmt?, storage_dead_stmt.unwrap_or(usize::MAX)))
-    }
-
-    // Try to match the expected MIR structure with the basic block we're processing.
-    // We want to see something that looks like:
-    // ```
-    // (StorageLive(_) | StorageDead(_));*
-    // _LOCAL_INTO = ((_LOCAL_FROM as Variant).FIELD: TY);
-    // (StorageLive(_) | StorageDead(_));*
-    // (tmp_n+1 = tmp_n);*
-    // (StorageLive(_) | StorageDead(_));*
-    // (tmp_n+1 = tmp_n);*
-    // ((LOCAL_FROM as Variant).FIELD: TY) = move tmp;
-    // discriminant(LOCAL_FROM) = VariantIdx;
-    // (StorageLive(_) | StorageDead(_));*
-    // ```
-    let mut stmt_iter = stmts.iter().enumerate().peekable();
-
-    try_eat_storage_stmts(&mut stmt_iter, &mut storage_live_stmts, &mut storage_dead_stmts);
-
-    let (get_variant_field_stmt, stmt) = stmt_iter.next()?;
-    let (local_tmp_s0, local_1, vf_s0, dbg_projection) = match_get_variant_field(stmt)?;
-
-    try_eat_storage_stmts(&mut stmt_iter, &mut storage_live_stmts, &mut storage_dead_stmts);
-
-    try_eat_assign_tmp_stmts(&mut stmt_iter, &mut tmp_assigns, &mut nop_stmts);
-
-    try_eat_storage_stmts(&mut stmt_iter, &mut storage_live_stmts, &mut storage_dead_stmts);
-
-    try_eat_assign_tmp_stmts(&mut stmt_iter, &mut tmp_assigns, &mut nop_stmts);
-
-    let (idx, stmt) = stmt_iter.next()?;
-    let (local_tmp_s1, local_0, vf_s1) = match_set_variant_field(stmt)?;
-    nop_stmts.push(idx);
-
-    let (idx, stmt) = stmt_iter.next()?;
-    let (set_discr_local, set_discr_var_idx) = match_set_discr(stmt)?;
-    let discr_stmt_source_info = stmt.source_info;
-    nop_stmts.push(idx);
-
-    try_eat_storage_stmts(&mut stmt_iter, &mut storage_live_stmts, &mut storage_dead_stmts);
-
-    for (live_idx, live_local) in storage_live_stmts {
-        if let Some(i) = storage_dead_stmts.iter().rposition(|(_, l)| *l == live_local) {
-            let (dead_idx, _) = storage_dead_stmts.swap_remove(i);
-            storage_stmts.push((live_idx, dead_idx, live_local));
-
-            if live_local == local_tmp_s0 {
-                nop_stmts.push(get_variant_field_stmt);
-            }
-        }
-    }
-    // We sort primitive usize here so we can use unstable sort
-    nop_stmts.sort_unstable();
-
-    // Use one of the statements we're going to discard between the point
-    // where the storage location for the variant field becomes live and
-    // is killed.
-    let (live_idx, dead_idx) = find_storage_live_dead_stmts_for_local(local_tmp_s0, stmts)?;
-    let stmt_to_overwrite =
-        nop_stmts.iter().find(|stmt_idx| live_idx < **stmt_idx && **stmt_idx < dead_idx);
-
-    let mut tmp_assigned_vars = BitSet::new_empty(locals_count);
-    for (l, r) in &tmp_assigns {
-        tmp_assigned_vars.insert(*l);
-        tmp_assigned_vars.insert(*r);
-    }
-
-    let dbg_info_to_adjust: Vec<_> = debug_info
-        .iter()
-        .enumerate()
-        .filter_map(|(i, var_info)| {
-            if let VarDebugInfoContents::Place(p) = var_info.value {
-                if tmp_assigned_vars.contains(p.local) {
-                    return Some(i);
-                }
-            }
-
-            None
-        })
-        .collect();
-
-    Some(ArmIdentityInfo {
-        local_temp_0: local_tmp_s0,
-        local_1,
-        vf_s0,
-        get_variant_field_stmt,
-        field_tmp_assignments: tmp_assigns,
-        local_tmp_s1,
-        local_0,
-        vf_s1,
-        set_discr_local,
-        set_discr_var_idx,
-        stmt_to_overwrite: *stmt_to_overwrite?,
-        source_info: discr_stmt_source_info,
-        storage_stmts,
-        stmts_to_remove: nop_stmts,
-        dbg_info_to_adjust,
-        dbg_projection,
-    })
-}
-
-fn optimization_applies<'tcx>(
-    opt_info: &ArmIdentityInfo<'tcx>,
-    local_decls: &IndexVec<Local, LocalDecl<'tcx>>,
-    local_uses: &IndexVec<Local, usize>,
-    var_debug_info: &[VarDebugInfo<'tcx>],
-) -> bool {
-    trace!("testing if optimization applies...");
-
-    // FIXME(wesleywiser): possibly relax this restriction?
-    if opt_info.local_0 == opt_info.local_1 {
-        trace!("NO: moving into ourselves");
-        return false;
-    } else if opt_info.vf_s0 != opt_info.vf_s1 {
-        trace!("NO: the field-and-variant information do not match");
-        return false;
-    } else if local_decls[opt_info.local_0].ty != local_decls[opt_info.local_1].ty {
-        // FIXME(Centril,oli-obk): possibly relax to same layout?
-        trace!("NO: source and target locals have different types");
-        return false;
-    } else if (opt_info.local_0, opt_info.vf_s0.var_idx)
-        != (opt_info.set_discr_local, opt_info.set_discr_var_idx)
-    {
-        trace!("NO: the discriminants do not match");
-        return false;
-    }
-
-    // Verify the assignment chain consists of the form b = a; c = b; d = c; etc...
-    if opt_info.field_tmp_assignments.is_empty() {
-        trace!("NO: no assignments found");
-        return false;
-    }
-    let mut last_assigned_to = opt_info.field_tmp_assignments[0].1;
-    let source_local = last_assigned_to;
-    for (l, r) in &opt_info.field_tmp_assignments {
-        if *r != last_assigned_to {
-            trace!("NO: found unexpected assignment {:?} = {:?}", l, r);
-            return false;
-        }
-
-        last_assigned_to = *l;
-    }
-
-    // Check that the first and last used locals are only used twice
-    // since they are of the form:
-    //
-    // ```
-    // _first = ((_x as Variant).n: ty);
-    // _n = _first;
-    // ...
-    // ((_y as Variant).n: ty) = _n;
-    // discriminant(_y) = z;
-    // ```
-    for (l, r) in &opt_info.field_tmp_assignments {
-        if local_uses[*l] != 2 {
-            warn!("NO: FAILED assignment chain local {:?} was used more than twice", l);
-            return false;
-        } else if local_uses[*r] != 2 {
-            warn!("NO: FAILED assignment chain local {:?} was used more than twice", r);
-            return false;
-        }
-    }
-
-    // Check that debug info only points to full Locals and not projections.
-    for dbg_idx in &opt_info.dbg_info_to_adjust {
-        let dbg_info = &var_debug_info[*dbg_idx];
-        if let VarDebugInfoContents::Place(p) = dbg_info.value {
-            if !p.projection.is_empty() {
-                trace!("NO: debug info for {:?} had a projection {:?}", dbg_info.name, p);
-                return false;
-            }
-        }
-    }
-
-    if source_local != opt_info.local_temp_0 {
-        trace!(
-            "NO: start of assignment chain does not match enum variant temp: {:?} != {:?}",
-            source_local,
-            opt_info.local_temp_0
-        );
-        return false;
-    } else if last_assigned_to != opt_info.local_tmp_s1 {
-        trace!(
-            "NO: end of assignment chain does not match written enum temp: {:?} != {:?}",
-            last_assigned_to,
-            opt_info.local_tmp_s1
-        );
-        return false;
-    }
-
-    trace!("SUCCESS: optimization applies!");
-    true
-}
-
-impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        // FIXME(77359): This optimization can result in unsoundness.
-        if !tcx.sess.opts.unstable_opts.unsound_mir_opts {
-            return;
-        }
-
-        let source = body.source;
-        trace!("running SimplifyArmIdentity on {:?}", source);
-
-        let local_uses = LocalUseCounter::get_local_uses(body);
-        for bb in body.basic_blocks.as_mut() {
-            if let Some(opt_info) =
-                get_arm_identity_info(&bb.statements, body.local_decls.len(), &body.var_debug_info)
-            {
-                trace!("got opt_info = {:#?}", opt_info);
-                if !optimization_applies(
-                    &opt_info,
-                    &body.local_decls,
-                    &local_uses,
-                    &body.var_debug_info,
-                ) {
-                    debug!("optimization skipped for {:?}", source);
-                    continue;
-                }
-
-                // Also remove unused Storage{Live,Dead} statements which correspond
-                // to temps used previously.
-                for (live_idx, dead_idx, local) in &opt_info.storage_stmts {
-                    // The temporary that we've read the variant field into is scoped to this block,
-                    // so we can remove the assignment.
-                    if *local == opt_info.local_temp_0 {
-                        bb.statements[opt_info.get_variant_field_stmt].make_nop();
-                    }
-
-                    for (left, right) in &opt_info.field_tmp_assignments {
-                        if local == left || local == right {
-                            bb.statements[*live_idx].make_nop();
-                            bb.statements[*dead_idx].make_nop();
-                        }
-                    }
-                }
-
-                // Right shape; transform
-                for stmt_idx in opt_info.stmts_to_remove {
-                    bb.statements[stmt_idx].make_nop();
-                }
-
-                let stmt = &mut bb.statements[opt_info.stmt_to_overwrite];
-                stmt.source_info = opt_info.source_info;
-                stmt.kind = StatementKind::Assign(Box::new((
-                    opt_info.local_0.into(),
-                    Rvalue::Use(Operand::Move(opt_info.local_1.into())),
-                )));
-
-                bb.statements.retain(|stmt| stmt.kind != StatementKind::Nop);
-
-                // Fix the debug info to point to the right local
-                for dbg_index in opt_info.dbg_info_to_adjust {
-                    let dbg_info = &mut body.var_debug_info[dbg_index];
-                    assert!(
-                        matches!(dbg_info.value, VarDebugInfoContents::Place(_)),
-                        "value was not a Place"
-                    );
-                    if let VarDebugInfoContents::Place(p) = &mut dbg_info.value {
-                        assert!(p.projection.is_empty());
-                        p.local = opt_info.local_0;
-                        p.projection = opt_info.dbg_projection;
-                    }
-                }
-
-                trace!("block is now {:?}", bb.statements);
-            }
-        }
-    }
-}
-
-struct LocalUseCounter {
-    local_uses: IndexVec<Local, usize>,
-}
-
-impl LocalUseCounter {
-    fn get_local_uses(body: &Body<'_>) -> IndexVec<Local, usize> {
-        let mut counter = LocalUseCounter { local_uses: IndexVec::from_elem(0, &body.local_decls) };
-        counter.visit_body(body);
-        counter.local_uses
-    }
-}
-
-impl Visitor<'_> for LocalUseCounter {
-    fn visit_local(&mut self, local: Local, context: PlaceContext, _location: Location) {
-        if context.is_storage_marker()
-            || context == PlaceContext::NonUse(NonUseContext::VarDebugInfo)
-        {
-            return;
-        }
-
-        self.local_uses[local] += 1;
-    }
-}
-
-/// Match on:
-/// ```ignore (MIR)
-/// _LOCAL_INTO = ((_LOCAL_FROM as Variant).FIELD: TY);
-/// ```
-fn match_get_variant_field<'tcx>(
-    stmt: &Statement<'tcx>,
-) -> Option<(Local, Local, VarField<'tcx>, &'tcx List<PlaceElem<'tcx>>)> {
-    match &stmt.kind {
-        StatementKind::Assign(box (
-            place_into,
-            Rvalue::Use(Operand::Copy(pf) | Operand::Move(pf)),
-        )) => {
-            let local_into = place_into.as_local()?;
-            let (local_from, vf) = match_variant_field_place(*pf)?;
-            Some((local_into, local_from, vf, pf.projection))
-        }
-        _ => None,
-    }
-}
-
-/// Match on:
-/// ```ignore (MIR)
-/// ((_LOCAL_FROM as Variant).FIELD: TY) = move _LOCAL_INTO;
-/// ```
-fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local, VarField<'tcx>)> {
-    match &stmt.kind {
-        StatementKind::Assign(box (place_from, Rvalue::Use(Operand::Move(place_into)))) => {
-            let local_into = place_into.as_local()?;
-            let (local_from, vf) = match_variant_field_place(*place_from)?;
-            Some((local_into, local_from, vf))
-        }
-        _ => None,
-    }
-}
-
-/// Match on:
-/// ```ignore (MIR)
-/// discriminant(_LOCAL_TO_SET) = VAR_IDX;
-/// ```
-fn match_set_discr(stmt: &Statement<'_>) -> Option<(Local, VariantIdx)> {
-    match &stmt.kind {
-        StatementKind::SetDiscriminant { place, variant_index } => {
-            Some((place.as_local()?, *variant_index))
-        }
-        _ => None,
-    }
-}
-
-#[derive(PartialEq, Debug)]
-struct VarField<'tcx> {
-    field: Field,
-    field_ty: Ty<'tcx>,
-    var_idx: VariantIdx,
-}
-
-/// Match on `((_LOCAL as Variant).FIELD: TY)`.
-fn match_variant_field_place(place: Place<'_>) -> Option<(Local, VarField<'_>)> {
-    match place.as_ref() {
-        PlaceRef {
-            local,
-            projection: &[ProjectionElem::Downcast(_, var_idx), ProjectionElem::Field(field, ty)],
-        } => Some((local, VarField { field, field_ty: ty, var_idx })),
-        _ => None,
-    }
-}
-
-/// Simplifies `SwitchInt(_) -> [targets]`,
-/// where all the `targets` have the same form,
-/// into `goto -> target_first`.
-pub struct SimplifyBranchSame;
-
-impl<'tcx> MirPass<'tcx> for SimplifyBranchSame {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        // This optimization is disabled by default for now due to
-        // soundness concerns; see issue #89485 and PR #89489.
-        if !tcx.sess.opts.unstable_opts.unsound_mir_opts {
-            return;
-        }
-
-        trace!("Running SimplifyBranchSame on {:?}", body.source);
-        let finder = SimplifyBranchSameOptimizationFinder { body, tcx };
-        let opts = finder.find();
-
-        let did_remove_blocks = opts.len() > 0;
-        for opt in opts.iter() {
-            trace!("SUCCESS: Applying optimization {:?}", opt);
-            // Replace `SwitchInt(..) -> [bb_first, ..];` with a `goto -> bb_first;`.
-            body.basic_blocks_mut()[opt.bb_to_opt_terminator].terminator_mut().kind =
-                TerminatorKind::Goto { target: opt.bb_to_goto };
-        }
-
-        if did_remove_blocks {
-            // We have dead blocks now, so remove those.
-            simplify::remove_dead_blocks(tcx, body);
-        }
-    }
-}
-
-#[derive(Debug)]
-struct SimplifyBranchSameOptimization {
-    /// All basic blocks are equal so go to this one
-    bb_to_goto: BasicBlock,
-    /// Basic block where the terminator can be simplified to a goto
-    bb_to_opt_terminator: BasicBlock,
-}
-
-struct SwitchTargetAndValue {
-    target: BasicBlock,
-    // None in case of the `otherwise` case
-    value: Option<u128>,
-}
-
-struct SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> SimplifyBranchSameOptimizationFinder<'_, 'tcx> {
-    fn find(&self) -> Vec<SimplifyBranchSameOptimization> {
-        self.body
-            .basic_blocks
-            .iter_enumerated()
-            .filter_map(|(bb_idx, bb)| {
-                let (discr_switched_on, targets_and_values) = match &bb.terminator().kind {
-                    TerminatorKind::SwitchInt { targets, discr, .. } => {
-                        let targets_and_values: Vec<_> = targets.iter()
-                            .map(|(val, target)| SwitchTargetAndValue { target, value: Some(val) })
-                            .chain(once(SwitchTargetAndValue { target: targets.otherwise(), value: None }))
-                            .collect();
-                        (discr, targets_and_values)
-                    },
-                    _ => return None,
-                };
-
-                // find the adt that has its discriminant read
-                // assuming this must be the last statement of the block
-                let adt_matched_on = match &bb.statements.last()?.kind {
-                    StatementKind::Assign(box (place, rhs))
-                        if Some(*place) == discr_switched_on.place() =>
-                    {
-                        match rhs {
-                            Rvalue::Discriminant(adt_place) if adt_place.ty(self.body, self.tcx).ty.is_enum() => adt_place,
-                            _ => {
-                                trace!("NO: expected a discriminant read of an enum instead of: {:?}", rhs);
-                                return None;
-                            }
-                        }
-                    }
-                    other => {
-                        trace!("NO: expected an assignment of a discriminant read to a place. Found: {:?}", other);
-                        return None
-                    },
-                };
-
-                let mut iter_bbs_reachable = targets_and_values
-                    .iter()
-                    .map(|target_and_value| (target_and_value, &self.body.basic_blocks[target_and_value.target]))
-                    .filter(|(_, bb)| {
-                        // Reaching `unreachable` is UB so assume it doesn't happen.
-                        bb.terminator().kind != TerminatorKind::Unreachable
-                    })
-                    .peekable();
-
-                let bb_first = iter_bbs_reachable.peek().map_or(&targets_and_values[0], |(idx, _)| *idx);
-                let mut all_successors_equivalent = StatementEquality::TrivialEqual;
-
-                // All successor basic blocks must be equal or contain statements that are pairwise considered equal.
-                for ((target_and_value_l,bb_l), (target_and_value_r,bb_r)) in iter_bbs_reachable.tuple_windows() {
-                    let trivial_checks = bb_l.is_cleanup == bb_r.is_cleanup
-                                            && bb_l.terminator().kind == bb_r.terminator().kind
-                                            && bb_l.statements.len() == bb_r.statements.len();
-                    let statement_check = || {
-                        bb_l.statements.iter().zip(&bb_r.statements).try_fold(StatementEquality::TrivialEqual, |acc,(l,r)| {
-                            let stmt_equality = self.statement_equality(*adt_matched_on, &l, target_and_value_l, &r, target_and_value_r);
-                            if matches!(stmt_equality, StatementEquality::NotEqual) {
-                                // short circuit
-                                None
-                            } else {
-                                Some(acc.combine(&stmt_equality))
-                            }
-                        })
-                        .unwrap_or(StatementEquality::NotEqual)
-                    };
-                    if !trivial_checks {
-                        all_successors_equivalent = StatementEquality::NotEqual;
-                        break;
-                    }
-                    all_successors_equivalent = all_successors_equivalent.combine(&statement_check());
-                };
-
-                match all_successors_equivalent{
-                    StatementEquality::TrivialEqual => {
-                        // statements are trivially equal, so just take first
-                        trace!("Statements are trivially equal");
-                        Some(SimplifyBranchSameOptimization {
-                            bb_to_goto: bb_first.target,
-                            bb_to_opt_terminator: bb_idx,
-                        })
-                    }
-                    StatementEquality::ConsideredEqual(bb_to_choose) => {
-                        trace!("Statements are considered equal");
-                        Some(SimplifyBranchSameOptimization {
-                            bb_to_goto: bb_to_choose,
-                            bb_to_opt_terminator: bb_idx,
-                        })
-                    }
-                    StatementEquality::NotEqual => {
-                        trace!("NO: not all successors of basic block {:?} were equivalent", bb_idx);
-                        None
-                    }
-                }
-            })
-            .collect()
-    }
-
-    /// Tests if two statements can be considered equal
-    ///
-    /// Statements can be trivially equal if the kinds match.
-    /// But they can also be considered equal in the following case A:
-    /// ```ignore (MIR)
-    /// discriminant(_0) = 0;   // bb1
-    /// _0 = move _1;           // bb2
-    /// ```
-    /// In this case the two statements are equal iff
-    /// - `_0` is an enum where the variant index 0 is fieldless, and
-    /// -  bb1 was targeted by a switch where the discriminant of `_1` was switched on
-    fn statement_equality(
-        &self,
-        adt_matched_on: Place<'tcx>,
-        x: &Statement<'tcx>,
-        x_target_and_value: &SwitchTargetAndValue,
-        y: &Statement<'tcx>,
-        y_target_and_value: &SwitchTargetAndValue,
-    ) -> StatementEquality {
-        let helper = |rhs: &Rvalue<'tcx>,
-                      place: &Place<'tcx>,
-                      variant_index: VariantIdx,
-                      switch_value: u128,
-                      side_to_choose| {
-            let place_type = place.ty(self.body, self.tcx).ty;
-            let adt = match *place_type.kind() {
-                ty::Adt(adt, _) if adt.is_enum() => adt,
-                _ => return StatementEquality::NotEqual,
-            };
-            // We need to make sure that the switch value that targets the bb with
-            // SetDiscriminant is the same as the variant discriminant.
-            let variant_discr = adt.discriminant_for_variant(self.tcx, variant_index).val;
-            if variant_discr != switch_value {
-                trace!(
-                    "NO: variant discriminant {} does not equal switch value {}",
-                    variant_discr,
-                    switch_value
-                );
-                return StatementEquality::NotEqual;
-            }
-            let variant_is_fieldless = adt.variant(variant_index).fields.is_empty();
-            if !variant_is_fieldless {
-                trace!("NO: variant {:?} was not fieldless", variant_index);
-                return StatementEquality::NotEqual;
-            }
-
-            match rhs {
-                Rvalue::Use(operand) if operand.place() == Some(adt_matched_on) => {
-                    StatementEquality::ConsideredEqual(side_to_choose)
-                }
-                _ => {
-                    trace!(
-                        "NO: RHS of assignment was {:?}, but expected it to match the adt being matched on in the switch, which is {:?}",
-                        rhs,
-                        adt_matched_on
-                    );
-                    StatementEquality::NotEqual
-                }
-            }
-        };
-        match (&x.kind, &y.kind) {
-            // trivial case
-            (x, y) if x == y => StatementEquality::TrivialEqual,
-
-            // check for case A
-            (
-                StatementKind::Assign(box (_, rhs)),
-                &StatementKind::SetDiscriminant { ref place, variant_index },
-            ) if y_target_and_value.value.is_some() => {
-                // choose basic block of x, as that has the assign
-                helper(
-                    rhs,
-                    place,
-                    variant_index,
-                    y_target_and_value.value.unwrap(),
-                    x_target_and_value.target,
-                )
-            }
-            (
-                &StatementKind::SetDiscriminant { ref place, variant_index },
-                &StatementKind::Assign(box (_, ref rhs)),
-            ) if x_target_and_value.value.is_some() => {
-                // choose basic block of y, as that has the assign
-                helper(
-                    rhs,
-                    place,
-                    variant_index,
-                    x_target_and_value.value.unwrap(),
-                    y_target_and_value.target,
-                )
-            }
-            _ => {
-                trace!("NO: statements `{:?}` and `{:?}` not considered equal", x, y);
-                StatementEquality::NotEqual
-            }
-        }
-    }
-}
-
-#[derive(Copy, Clone, Eq, PartialEq)]
-enum StatementEquality {
-    /// The two statements are trivially equal; same kind
-    TrivialEqual,
-    /// The two statements are considered equal, but may be of different kinds. The BasicBlock field is the basic block to jump to when performing the branch-same optimization.
-    /// For example, `_0 = _1` and `discriminant(_0) = discriminant(0)` are considered equal if 0 is a fieldless variant of an enum. But we don't want to jump to the basic block with the SetDiscriminant, as that is not legal if _1 is not the 0 variant index
-    ConsideredEqual(BasicBlock),
-    /// The two statements are not equal
-    NotEqual,
-}
-
-impl StatementEquality {
-    fn combine(&self, other: &StatementEquality) -> StatementEquality {
-        use StatementEquality::*;
-        match (self, other) {
-            (TrivialEqual, TrivialEqual) => TrivialEqual,
-            (TrivialEqual, ConsideredEqual(b)) | (ConsideredEqual(b), TrivialEqual) => {
-                ConsideredEqual(*b)
-            }
-            (ConsideredEqual(b1), ConsideredEqual(b2)) => {
-                if b1 == b2 {
-                    ConsideredEqual(*b1)
-                } else {
-                    NotEqual
-                }
-            }
-            (_, NotEqual) | (NotEqual, _) => NotEqual,
-        }
-    }
-}
diff --git a/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff b/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff
deleted file mode 100644
index 9780332d8bf18..0000000000000
--- a/tests/mir-opt/76803_regression.encode.SimplifyBranchSame.diff
+++ /dev/null
@@ -1,29 +0,0 @@
-- // MIR for `encode` before SimplifyBranchSame
-+ // MIR for `encode` after SimplifyBranchSame
-  
-  fn encode(_1: Type) -> Type {
-      debug v => _1;                       // in scope 0 at $DIR/76803_regression.rs:+0:15: +0:16
-      let mut _0: Type;                    // return place in scope 0 at $DIR/76803_regression.rs:+0:27: +0:31
-      let mut _2: isize;                   // in scope 0 at $DIR/76803_regression.rs:+2:9: +2:16
-  
-      bb0: {
-          _2 = discriminant(_1);           // scope 0 at $DIR/76803_regression.rs:+1:11: +1:12
-          switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/76803_regression.rs:+1:5: +1:12
-      }
-  
-      bb1: {
-          _0 = move _1;                    // scope 0 at $DIR/76803_regression.rs:+3:14: +3:15
-          goto -> bb3;                     // scope 0 at $DIR/76803_regression.rs:+3:14: +3:15
-      }
-  
-      bb2: {
-          Deinit(_0);                      // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27
-          discriminant(_0) = 1;            // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27
-          goto -> bb3;                     // scope 0 at $DIR/76803_regression.rs:+2:20: +2:27
-      }
-  
-      bb3: {
-          return;                          // scope 0 at $DIR/76803_regression.rs:+5:2: +5:2
-      }
-  }
-  
diff --git a/tests/mir-opt/76803_regression.rs b/tests/mir-opt/76803_regression.rs
deleted file mode 100644
index 05dc3c9784109..0000000000000
--- a/tests/mir-opt/76803_regression.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// compile-flags: -Z mir-opt-level=1
-// EMIT_MIR 76803_regression.encode.SimplifyBranchSame.diff
-
-#[derive(Debug, Eq, PartialEq)]
-pub enum Type {
-    A,
-    B,
-}
-
-pub fn encode(v: Type) -> Type {
-    match v {
-        Type::A => Type::B,
-        _ => v,
-    }
-}
-
-fn main() {
-    assert_eq!(Type::B, encode(Type::A));
-}
diff --git a/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
deleted file mode 100644
index bf3bcfdb59442..0000000000000
--- a/tests/mir-opt/issue_73223.main.SimplifyArmIdentity.diff
+++ /dev/null
@@ -1,156 +0,0 @@
-- // MIR for `main` before SimplifyArmIdentity
-+ // MIR for `main` after SimplifyArmIdentity
-  
-  fn main() -> () {
-      let mut _0: ();                      // return place in scope 0 at $DIR/issue_73223.rs:+0:11: +0:11
-      let _1: i32;                         // in scope 0 at $DIR/issue_73223.rs:+1:9: +1:14
-      let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-      let mut _3: isize;                   // in scope 0 at $DIR/issue_73223.rs:+2:9: +2:16
-      let _4: i32;                         // in scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
-      let mut _6: i32;                     // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27
-      let mut _7: &i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _8: &i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _11: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _12: bool;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _13: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _14: i32;                    // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _16: !;                          // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _17: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _18: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _19: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _20: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let _21: &i32;                       // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _22: std::option::Option<std::fmt::Arguments<'_>>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _24: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      let mut _25: &i32;                   // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      scope 1 {
-          debug split => _1;               // in scope 1 at $DIR/issue_73223.rs:+1:9: +1:14
-          let _5: std::option::Option<i32>; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14
-          scope 3 {
-              debug _prev => _5;           // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14
-              let _9: &i32;                // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              let _10: &i32;               // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              let mut _23: &i32;           // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-              scope 4 {
-                  debug left_val => _9;    // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  debug right_val => _10;  // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  let _15: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  scope 5 {
-                      debug kind => _15;   // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                  }
-              }
-          }
-      }
-      scope 2 {
-          debug v => _4;                   // in scope 2 at $DIR/issue_73223.rs:+2:14: +2:15
-      }
-  
-      bb0: {
-          StorageLive(_1);                 // scope 0 at $DIR/issue_73223.rs:+1:9: +1:14
-          StorageLive(_2);                 // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-          Deinit(_2);                      // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-          ((_2 as Some).0: i32) = const 1_i32; // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-          discriminant(_2) = 1;            // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-          _3 = const 1_isize;              // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-          goto -> bb3;                     // scope 0 at $DIR/issue_73223.rs:+1:17: +1:30
-      }
-  
-      bb1: {
-          StorageDead(_2);                 // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7
-          StorageDead(_1);                 // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2
-          return;                          // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2
-      }
-  
-      bb2: {
-          unreachable;                     // scope 0 at $DIR/issue_73223.rs:+1:23: +1:30
-      }
-  
-      bb3: {
-          StorageLive(_4);                 // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
-          _4 = ((_2 as Some).0: i32);      // scope 0 at $DIR/issue_73223.rs:+2:14: +2:15
-          _1 = _4;                         // scope 2 at $DIR/issue_73223.rs:+2:20: +2:21
-          StorageDead(_4);                 // scope 0 at $DIR/issue_73223.rs:+2:20: +2:21
-          StorageDead(_2);                 // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7
-          StorageLive(_5);                 // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14
-          StorageLive(_6);                 // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27
-          _6 = _1;                         // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27
-          Deinit(_5);                      // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
-          ((_5 as Some).0: i32) = move _6; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
-          discriminant(_5) = 1;            // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28
-          StorageDead(_6);                 // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28
-          StorageLive(_24);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_25);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_7);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _7 = &_1;                        // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _23 = const _;                   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) }
-          _8 = _23;                        // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_24);                     // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_25);                     // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _24 = move _7;                   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _25 = move _8;                   // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_8);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_7);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _9 = _24;                        // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _10 = _25;                       // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_11);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_12);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_13);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _13 = (*_9);                     // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_14);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _14 = const 1_i32;               // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _12 = Eq(move _13, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_14);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_13);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _11 = Not(move _12);             // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_12);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          switchInt(move _11) -> [0: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-      }
-  
-      bb4: {
-          StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_15);                     // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          discriminant(_15) = 0;           // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_16);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_17);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _17 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
-          StorageLive(_18);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_19);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _19 = _9;                        // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _18 = _19;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_20);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_21);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _21 = _10;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _20 = _21;                       // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageLive(_22);                // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          Deinit(_22);                     // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          discriminant(_22) = 0;           // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          _16 = core::panicking::assert_failed::<i32, i32>(const core::panicking::AssertKind::Eq, move _18, move _20, move _22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: for<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a i32, &'b i32, Option<Arguments<'c>>) -> ! {core::panicking::assert_failed::<i32, i32>}, val: Value(<ZST>) }
-                                           // mir::Constant
-                                           // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
-                                           // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) }
-      }
-  
-      bb5: {
-          StorageDead(_11);                // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_10);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_9);                 // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_24);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_25);                // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
-          StorageDead(_5);                 // scope 1 at $DIR/issue_73223.rs:+8:1: +8:2
-          StorageDead(_1);                 // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2
-          return;                          // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2
-      }
-  }
-  
diff --git a/tests/mir-opt/issue_73223.rs b/tests/mir-opt/issue_73223.rs
deleted file mode 100644
index be114cab719c0..0000000000000
--- a/tests/mir-opt/issue_73223.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-fn main() {
-    let split = match Some(1) {
-        Some(v) => v,
-        None => return,
-    };
-
-    let _prev = Some(split);
-    assert_eq!(split, 1);
-}
-
-
-// EMIT_MIR issue_73223.main.SimplifyArmIdentity.diff

From 11a94f242d48739a557b6e09cbd8d3cde2fcdedf Mon Sep 17 00:00:00 2001
From: KaDiWa <kalle.wachsmuth@gmail.com>
Date: Tue, 24 Jan 2023 16:46:45 +0100
Subject: [PATCH 13/16] rustdoc: prevent scroll bar on source viewer

---
 src/librustdoc/html/static/css/rustdoc.css | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 424bbb0ec42be..bf83ff2044e69 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -533,7 +533,7 @@ ul.block, .block li {
 .rustdoc .example-wrap > pre {
 	margin: 0;
 	flex-grow: 1;
-	overflow-x: auto;
+	overflow: auto hidden;
 }
 
 .rustdoc .example-wrap > pre.example-line-numbers,

From 430dab0b424abdf68d9071232a654874771570bc Mon Sep 17 00:00:00 2001
From: Boxy <supbscripter@gmail.com>
Date: Tue, 24 Jan 2023 23:24:25 +0000
Subject: [PATCH 14/16] implement builtin candidate

---
 .../src/solve/assembly.rs                     |  7 ++
 .../src/solve/project_goals.rs                | 92 +++++++++++++++++++
 .../src/solve/trait_goals.rs                  |  7 ++
 tests/ui/traits/new-solver/pointee.rs         | 23 +++++
 4 files changed, 129 insertions(+)
 create mode 100644 tests/ui/traits/new-solver/pointee.rs

diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs
index cdb72d49834f0..0b642fcba2812 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly.rs
@@ -133,6 +133,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx>;
+
+    fn consider_builtin_pointee_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx>;
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -259,6 +264,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             G::consider_builtin_fn_trait_candidates(self, goal, kind)
         } else if lang_items.tuple_trait() == Some(trait_def_id) {
             G::consider_builtin_tuple_candidate(self, goal)
+        } else if lang_items.pointee_trait() == Some(trait_def_id) {
+            G::consider_builtin_pointee_candidate(self, goal)
         } else {
             Err(NoSolution)
         };
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 32e15f03998b3..914a1d6a66a67 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -7,6 +7,7 @@ use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
+use rustc_hir::LangItem;
 use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::specialization_graph::LeafDef;
@@ -391,6 +392,97 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
     ) -> QueryResult<'tcx> {
         bug!("`Tuple` does not have an associated type: {:?}", goal);
     }
+
+    fn consider_builtin_pointee_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx> {
+        let tcx = ecx.tcx();
+        ecx.infcx.probe(|_| {
+            let metadata_ty = match goal.predicate.self_ty().kind() {
+                ty::Bool
+                | ty::Char
+                | ty::Int(..)
+                | ty::Uint(..)
+                | ty::Float(..)
+                | ty::Array(..)
+                | ty::RawPtr(..)
+                | ty::Ref(..)
+                | ty::FnDef(..)
+                | ty::FnPtr(..)
+                | ty::Closure(..)
+                | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
+                | ty::Generator(..)
+                | ty::GeneratorWitness(..)
+                | ty::Never
+                | ty::Foreign(..) => tcx.types.unit,
+
+                ty::Error(e) => tcx.ty_error_with_guaranteed(*e),
+
+                ty::Str | ty::Slice(_) => tcx.types.usize,
+
+                ty::Dynamic(_, _, _) => {
+                    let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
+                    tcx.bound_type_of(dyn_metadata)
+                        .subst(tcx, &[ty::GenericArg::from(goal.predicate.self_ty())])
+                }
+
+                ty::Infer(ty::TyVar(..)) | ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
+                    // FIXME(erica_solver, ptr_metadata): It would also be possible to return a `Ok(Ambig)` with no constraints.
+                    let sized_predicate = ty::Binder::dummy(tcx.at(DUMMY_SP).mk_trait_ref(
+                        LangItem::Sized,
+                        [ty::GenericArg::from(goal.predicate.self_ty())],
+                    ))
+                    .without_const();
+
+                    let mut nested_goals = ecx.infcx.eq(
+                        goal.param_env,
+                        goal.predicate.term.ty().unwrap(),
+                        tcx.types.unit,
+                    )?;
+                    nested_goals.push(goal.with(tcx, sized_predicate));
+
+                    return ecx.evaluate_all_and_make_canonical_response(nested_goals);
+                }
+
+                ty::Adt(def, substs) if def.is_struct() => {
+                    match def.non_enum_variant().fields.last() {
+                        None => tcx.types.unit,
+                        Some(field_def) => {
+                            let self_ty = field_def.ty(tcx, substs);
+                            let new_goal = goal.with(
+                                tcx,
+                                ty::Binder::dummy(goal.predicate.with_self_ty(tcx, self_ty)),
+                            );
+                            return ecx.evaluate_all_and_make_canonical_response(vec![new_goal]);
+                        }
+                    }
+                }
+                ty::Adt(_, _) => tcx.types.unit,
+
+                ty::Tuple(elements) => match elements.last() {
+                    None => tcx.types.unit,
+                    Some(&self_ty) => {
+                        let new_goal = goal.with(
+                            tcx,
+                            ty::Binder::dummy(goal.predicate.with_self_ty(tcx, self_ty)),
+                        );
+                        return ecx.evaluate_all_and_make_canonical_response(vec![new_goal]);
+                    }
+                },
+
+                ty::Infer(ty::FreshTy(..) | ty::FreshIntTy(..) | ty::FreshFloatTy(..))
+                | ty::Bound(..) => bug!(
+                    "unexpected self ty `{:?}` when normalizing `<T as Pointee>::Metadata`",
+                    goal.predicate.self_ty()
+                ),
+            };
+
+            let nested_goals =
+                ecx.infcx.eq(goal.param_env, goal.predicate.term.ty().unwrap(), metadata_ty)?;
+            ecx.evaluate_all_and_make_canonical_response(nested_goals)
+        })
+    }
 }
 
 /// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 4b6d673c999c9..67bd249566546 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -185,6 +185,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             Err(NoSolution)
         }
     }
+
+    fn consider_builtin_pointee_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        _goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx> {
+        ecx.make_canonical_response(Certainty::Yes)
+    }
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
diff --git a/tests/ui/traits/new-solver/pointee.rs b/tests/ui/traits/new-solver/pointee.rs
new file mode 100644
index 0000000000000..fa6ee2e2daf64
--- /dev/null
+++ b/tests/ui/traits/new-solver/pointee.rs
@@ -0,0 +1,23 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+#![feature(ptr_metadata)]
+
+use std::ptr::{DynMetadata, Pointee};
+
+trait Trait<U> {}
+struct MyDst<T: ?Sized>(T);
+
+fn works<T>() {
+    let _: <T as Pointee>::Metadata = ();
+    let _: <[T] as Pointee>::Metadata = 1_usize;
+    let _: <str as Pointee>::Metadata = 1_usize;
+    let _: <dyn Trait<T> as Pointee>::Metadata = give::<DynMetadata<dyn Trait<T>>>();
+    let _: <MyDst<T> as Pointee>::Metadata = ();
+    let _: <((((([u8],),),),),) as Pointee>::Metadata = 1_usize;
+}
+
+fn give<U>() -> U {
+    loop {}
+}
+
+fn main() {}

From 2f924b0e3cdebc341c88056af8fa0bacaed5acde Mon Sep 17 00:00:00 2001
From: Boxy <supbscripter@gmail.com>
Date: Tue, 24 Jan 2023 23:29:02 +0000
Subject: [PATCH 15/16] sorry erica

---
 compiler/rustc_trait_selection/src/solve/project_goals.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 914a1d6a66a67..d33dfba6247d8 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -428,7 +428,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 }
 
                 ty::Infer(ty::TyVar(..)) | ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
-                    // FIXME(erica_solver, ptr_metadata): It would also be possible to return a `Ok(Ambig)` with no constraints.
+                    // FIXME(ptr_metadata): It would also be possible to return a `Ok(Ambig)` with no constraints.
                     let sized_predicate = ty::Binder::dummy(tcx.at(DUMMY_SP).mk_trait_ref(
                         LangItem::Sized,
                         [ty::GenericArg::from(goal.predicate.self_ty())],

From a418e39b75a8b3628cfea0b233de2f8985331f6d Mon Sep 17 00:00:00 2001
From: Boxy <supbscripter@gmail.com>
Date: Tue, 24 Jan 2023 23:32:47 +0000
Subject: [PATCH 16/16] no without_constness

---
 compiler/rustc_trait_selection/src/solve/project_goals.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index d33dfba6247d8..e5072d8e2d152 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -432,8 +432,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                     let sized_predicate = ty::Binder::dummy(tcx.at(DUMMY_SP).mk_trait_ref(
                         LangItem::Sized,
                         [ty::GenericArg::from(goal.predicate.self_ty())],
-                    ))
-                    .without_const();
+                    ));
 
                     let mut nested_goals = ecx.infcx.eq(
                         goal.param_env,