about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-07 23:36:21 +0000
committerbors <bors@rust-lang.org>2022-07-07 23:36:21 +0000
commit9b21131278cc38ab8d79444de340015faadd061c (patch)
treed1ab6e8690db439b7e41afc90a576d6a07dfaa04
parent1517f5de01c445b5124b30f02257b02b4c5ef3b2 (diff)
parent2a2df9dda98524c3027e4b77b95403a144086a9b (diff)
downloadrust-9b21131278cc38ab8d79444de340015faadd061c.tar.gz
rust-9b21131278cc38ab8d79444de340015faadd061c.zip
Auto merge of #98360 - estebank:uninit-binding, r=oli-obk
 On partial uninit error point at where we need init

When a binding is declared without a value, borrowck verifies that all
codepaths have *one* assignment to them to initialize them fully. If
there are any cases where a condition can be met that leaves the binding
uninitialized or we attempt to initialize a field of an uninitialized
binding, we emit E0381.

We now look at all the statements that initialize the binding, and use
them to explore branching code paths that *don't* and point at them. If
we find *no* potential places where an assignment to the binding might
be missing, we display the spans of all the existing initializers to
provide some context.

Fix https://github.com/rust-lang/rust/issues/97956.
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs26
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs295
-rw-r--r--compiler/rustc_borrowck/src/lib.rs10
-rw-r--r--src/test/ui/asm/aarch64/type-check-2-2.rs4
-rw-r--r--src/test/ui/asm/aarch64/type-check-2-2.stderr12
-rw-r--r--src/test/ui/asm/x86_64/type-check-5.rs4
-rw-r--r--src/test/ui/asm/x86_64/type-check-5.stderr12
-rw-r--r--src/test/ui/async-await/no-non-guaranteed-initialization.rs3
-rw-r--r--src/test/ui/async-await/no-non-guaranteed-initialization.stderr11
-rw-r--r--src/test/ui/async-await/partial-initialization-across-await.rs9
-rw-r--r--src/test/ui/async-await/partial-initialization-across-await.stderr28
-rw-r--r--src/test/ui/borrowck/assign_mutable_fields.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-and-init.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-and-init.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-block-unint.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-block-unint.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-break-uninit-2.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-break-uninit-2.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-break-uninit.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-break-uninit.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-field-sensitivity.rs6
-rw-r--r--src/test/ui/borrowck/borrowck-field-sensitivity.stderr24
-rw-r--r--src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs7
-rw-r--r--src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr13
-rw-r--r--src/test/ui/borrowck/borrowck-if-no-else.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-if-no-else.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-if-with-else.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-if-with-else.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-fn-expr.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-fru.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-fru.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-init-op-equal.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-init-op-equal.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-init-plus-equal.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-init-plus-equal.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-or-init.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-or-init.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-partial-reinit-4.rs3
-rw-r--r--src/test/ui/borrowck/borrowck-partial-reinit-4.stderr8
-rw-r--r--src/test/ui/borrowck/borrowck-return.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-return.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-storage-dead.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-after-item.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-after-item.stderr7
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-field-access.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-in-assignop.rs20
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr60
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-ref-chain.rs14
-rw-r--r--src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr50
-rw-r--r--src/test/ui/borrowck/borrowck-uninit.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-uninit.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-union-uninitialized.rs4
-rw-r--r--src/test/ui/borrowck/borrowck-union-uninitialized.stderr18
-rw-r--r--src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr12
-rw-r--r--src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-while-break.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-while-break.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-while-cond.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-while-cond.stderr6
-rw-r--r--src/test/ui/borrowck/borrowck-while.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-while.stderr8
-rw-r--r--src/test/ui/borrowck/disallow-possibly-uninitialized.rs8
-rw-r--r--src/test/ui/borrowck/disallow-possibly-uninitialized.stderr32
-rw-r--r--src/test/ui/borrowck/issue-24267-flow-exit.rs4
-rw-r--r--src/test/ui/borrowck/issue-24267-flow-exit.stderr14
-rw-r--r--src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs6
-rw-r--r--src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr24
-rw-r--r--src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs6
-rw-r--r--src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr24
-rw-r--r--src/test/ui/borrowck/issue-62107-match-arm-scopes.rs2
-rw-r--r--src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr6
-rw-r--r--src/test/ui/borrowck/reassignment_immutable_fields.stderr16
-rw-r--r--src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr8
-rw-r--r--src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr8
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs17
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr53
-rw-r--r--src/test/ui/const-generics/const-generic-default-wont-borrowck.rs3
-rw-r--r--src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr6
-rw-r--r--src/test/ui/consts/issue-78655.rs2
-rw-r--r--src/test/ui/consts/issue-78655.stderr6
-rw-r--r--src/test/ui/drop/repeat-drop-2.rs2
-rw-r--r--src/test/ui/drop/repeat-drop-2.stderr6
-rw-r--r--src/test/ui/generator/partial-initialization-across-yield.rs9
-rw-r--r--src/test/ui/generator/partial-initialization-across-yield.stderr28
-rw-r--r--src/test/ui/loops/loop-proper-liveness.rs2
-rw-r--r--src/test/ui/loops/loop-proper-liveness.stderr7
-rw-r--r--src/test/ui/mir/drop-elaboration-after-borrowck-error.rs2
-rw-r--r--src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr7
-rw-r--r--src/test/ui/moves/issue-72649-uninit-in-loop.rs12
-rw-r--r--src/test/ui/moves/issue-72649-uninit-in-loop.stderr13
-rw-r--r--src/test/ui/moves/move-into-dead-array-1.rs2
-rw-r--r--src/test/ui/moves/move-into-dead-array-1.stderr6
-rw-r--r--src/test/ui/moves/move-of-addr-of-mut.rs2
-rw-r--r--src/test/ui/moves/move-of-addr-of-mut.stderr6
-rw-r--r--src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs12
-rw-r--r--src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr42
-rw-r--r--src/test/ui/nll/issue-21232-partial-init-and-use.rs36
-rw-r--r--src/test/ui/nll/issue-21232-partial-init-and-use.stderr140
-rw-r--r--src/test/ui/nll/match-cfg-fake-edges.rs2
-rw-r--r--src/test/ui/nll/match-cfg-fake-edges.stderr10
-rw-r--r--src/test/ui/nll/match-on-borrowed.stderr6
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs6
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr24
-rw-r--r--src/test/ui/try-block/try-block-opt-init.rs2
-rw-r--r--src/test/ui/try-block/try-block-opt-init.stderr10
-rw-r--r--src/test/ui/uninhabited/privately-uninhabited-mir-call.rs2
-rw-r--r--src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr7
111 files changed, 1060 insertions, 445 deletions
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index a5d9a2bc597..08ea00d71ef 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -33,22 +33,6 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         err
     }
 
-    pub(crate) fn cannot_act_on_uninitialized_variable(
-        &self,
-        span: Span,
-        verb: &str,
-        desc: &str,
-    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
-        struct_span_err!(
-            self,
-            span,
-            E0381,
-            "{} of possibly-uninitialized variable: `{}`",
-            verb,
-            desc,
-        )
-    }
-
     pub(crate) fn cannot_mutably_borrow_multiply(
         &self,
         new_loan_span: Span,
@@ -175,8 +159,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             new_loan_span,
             E0501,
-            "cannot borrow {}{} as {} because previous closure \
-             requires unique access",
+            "cannot borrow {}{} as {} because previous closure requires unique access",
             desc_new,
             opt_via,
             kind_new,
@@ -453,9 +436,8 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             closure_span,
             E0373,
-            "{} may outlive the current function, \
-             but it borrows {}, \
-             which is owned by the current function",
+            "{} may outlive the current function, but it borrows {}, which is owned by the current \
+             function",
             closure_kind,
             borrowed_path,
         );
@@ -479,7 +461,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     #[rustc_lint_diagnostics]
-    fn struct_span_err_with_code<S: Into<MultiSpan>>(
+    pub(crate) fn struct_span_err_with_code<S: Into<MultiSpan>>(
         &self,
         sp: S,
         msg: impl Into<DiagnosticMessage>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index d2a54a646ec..b9cfc3732dc 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2,9 +2,12 @@ use either::Either;
 use rustc_const_eval::util::CallKind;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{
+    struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::ObligationCause;
@@ -18,6 +21,7 @@ use rustc_middle::ty::{
     self, subst::Subst, suggest_constraining_type_params, EarlyBinder, PredicateKind, Ty,
 };
 use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
+use rustc_span::hygiene::DesugaringKind;
 use rustc_span::symbol::sym;
 use rustc_span::{BytePos, Span};
 use rustc_trait_selection::infer::InferCtxtExt;
@@ -94,32 +98,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 return;
             }
 
-            let item_msg =
-                match self.describe_place_with_options(used_place, IncludingDowncast(true)) {
-                    Some(name) => format!("`{}`", name),
-                    None => "value".to_owned(),
-                };
-            let mut err = self.cannot_act_on_uninitialized_variable(
+            let err = self.report_use_of_uninitialized(
+                mpi,
+                used_place,
+                moved_place,
+                desired_action,
                 span,
-                desired_action.as_noun(),
-                &self
-                    .describe_place_with_options(moved_place, IncludingDowncast(true))
-                    .unwrap_or_else(|| "_".to_owned()),
+                use_spans,
             );
-            err.span_label(span, format!("use of possibly-uninitialized {}", item_msg));
-
-            use_spans.var_span_label_path_only(
-                &mut err,
-                format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
-            );
-
             self.buffer_error(err);
         } else {
             if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) {
                 if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) {
                     debug!(
-                        "report_use_of_moved_or_uninitialized place: error suppressed \
-                         mois={:?}",
+                        "report_use_of_moved_or_uninitialized place: error suppressed mois={:?}",
                         move_out_indices
                     );
                     return;
@@ -326,6 +318,130 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         }
     }
 
+    fn report_use_of_uninitialized(
+        &self,
+        mpi: MovePathIndex,
+        used_place: PlaceRef<'tcx>,
+        moved_place: PlaceRef<'tcx>,
+        desired_action: InitializationRequiringAction,
+        span: Span,
+        use_spans: UseSpans<'tcx>,
+    ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
+        // We need all statements in the body where the binding was assigned to to later find all
+        // the branching code paths where the binding *wasn't* assigned to.
+        let inits = &self.move_data.init_path_map[mpi];
+        let move_path = &self.move_data.move_paths[mpi];
+        let decl_span = self.body.local_decls[move_path.place.local].source_info.span;
+        let mut spans = vec![];
+        for init_idx in inits {
+            let init = &self.move_data.inits[*init_idx];
+            let span = init.span(&self.body);
+            if !span.is_dummy() {
+                spans.push(span);
+            }
+        }
+
+        let (name, desc) =
+            match self.describe_place_with_options(moved_place, IncludingDowncast(true)) {
+                Some(name) => (format!("`{name}`"), format!("`{name}` ")),
+                None => ("the variable".to_string(), String::new()),
+            };
+        let path = match self.describe_place_with_options(used_place, IncludingDowncast(true)) {
+            Some(name) => format!("`{name}`"),
+            None => "value".to_string(),
+        };
+
+        // We use the statements were the binding was initialized, and inspect the HIR to look
+        // for the branching codepaths that aren't covered, to point at them.
+        let hir_id = self.mir_hir_id();
+        let map = self.infcx.tcx.hir();
+        let body_id = map.body_owned_by(hir_id);
+        let body = map.body(body_id);
+
+        let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] };
+        visitor.visit_body(&body);
+
+        let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
+        | InitializationRequiringAction::Assignment = desired_action
+        {
+            // The same error is emitted for bindings that are *sometimes* initialized and the ones
+            // that are *partially* initialized by assigning to a field of an uninitialized
+            // binding. We differentiate between them for more accurate wording here.
+            "isn't fully initialized"
+        } else if spans
+            .iter()
+            .filter(|i| {
+                // We filter these to avoid misleading wording in cases like the following,
+                // where `x` has an `init`, but it is in the same place we're looking at:
+                // ```
+                // let x;
+                // x += 1;
+                // ```
+                !i.contains(span)
+                    // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
+                        && !visitor
+                            .errors
+                            .iter()
+                            .map(|(sp, _)| *sp)
+                            .any(|sp| span < sp && !sp.contains(span))
+            })
+            .count()
+            == 0
+        {
+            "isn't initialized"
+        } else {
+            "is possibly-uninitialized"
+        };
+
+        let used = desired_action.as_general_verb_in_past_tense();
+        let mut err =
+            struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}");
+        use_spans.var_span_label_path_only(
+            &mut err,
+            format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
+        );
+
+        if let InitializationRequiringAction::PartialAssignment
+        | InitializationRequiringAction::Assignment = desired_action
+        {
+            err.help(
+                "partial initialization isn't supported, fully initialize the binding with a \
+                 default value and mutate it, or use `std::mem::MaybeUninit`",
+            );
+        }
+        err.span_label(span, format!("{path} {used} here but it {isnt_initialized}"));
+
+        let mut shown = false;
+        for (sp, label) in visitor.errors {
+            if sp < span && !sp.overlaps(span) {
+                // When we have a case like `match-cfg-fake-edges.rs`, we don't want to mention
+                // match arms coming after the primary span because they aren't relevant:
+                // ```
+                // let x;
+                // match y {
+                //     _ if { x = 2; true } => {}
+                //     _ if {
+                //         x; //~ ERROR
+                //         false
+                //     } => {}
+                //     _ => {} // We don't want to point to this.
+                // };
+                // ```
+                err.span_label(sp, &label);
+                shown = true;
+            }
+        }
+        if !shown {
+            for sp in &spans {
+                if *sp < span && !sp.overlaps(span) {
+                    err.span_label(*sp, "binding initialized here in some conditions");
+                }
+            }
+        }
+        err.span_label(decl_span, "binding declared here but left uninitialized");
+        err
+    }
+
     fn suggest_borrow_fn_like(
         &self,
         err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
@@ -2448,3 +2564,142 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
         }
     }
 }
+
+/// Detect whether one of the provided spans is a statement nested within the top-most visited expr
+struct ReferencedStatementsVisitor<'a>(&'a [Span], bool);
+
+impl<'a, 'v> Visitor<'v> for ReferencedStatementsVisitor<'a> {
+    fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
+        match s.kind {
+            hir::StmtKind::Semi(expr) if self.0.contains(&expr.span) => {
+                self.1 = true;
+            }
+            _ => {}
+        }
+    }
+}
+
+/// Given a set of spans representing statements initializing the relevant binding, visit all the
+/// function expressions looking for branching code paths that *do not* initialize the binding.
+struct ConditionVisitor<'b> {
+    spans: &'b [Span],
+    name: &'b str,
+    errors: Vec<(Span, String)>,
+}
+
+impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
+    fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
+        match ex.kind {
+            hir::ExprKind::If(cond, body, None) => {
+                // `if` expressions with no `else` that initialize the binding might be missing an
+                // `else` arm.
+                let mut v = ReferencedStatementsVisitor(self.spans, false);
+                v.visit_expr(body);
+                if v.1 {
+                    self.errors.push((
+                        cond.span,
+                        format!(
+                            "if this `if` condition is `false`, {} is not initialized",
+                            self.name,
+                        ),
+                    ));
+                    self.errors.push((
+                        ex.span.shrink_to_hi(),
+                        format!("an `else` arm might be missing here, initializing {}", self.name),
+                    ));
+                }
+            }
+            hir::ExprKind::If(cond, body, Some(other)) => {
+                // `if` expressions where the binding is only initialized in one of the two arms
+                // might be missing a binding initialization.
+                let mut a = ReferencedStatementsVisitor(self.spans, false);
+                a.visit_expr(body);
+                let mut b = ReferencedStatementsVisitor(self.spans, false);
+                b.visit_expr(other);
+                match (a.1, b.1) {
+                    (true, true) | (false, false) => {}
+                    (true, false) => {
+                        if other.span.is_desugaring(DesugaringKind::WhileLoop) {
+                            self.errors.push((
+                                cond.span,
+                                format!(
+                                    "if this condition isn't met and the `while` loop runs 0 \
+                                     times, {} is not initialized",
+                                    self.name
+                                ),
+                            ));
+                        } else {
+                            self.errors.push((
+                                body.span.shrink_to_hi().until(other.span),
+                                format!(
+                                    "if the `if` condition is `false` and this `else` arm is \
+                                     executed, {} is not initialized",
+                                    self.name
+                                ),
+                            ));
+                        }
+                    }
+                    (false, true) => {
+                        self.errors.push((
+                            cond.span,
+                            format!(
+                                "if this condition is `true`, {} is not initialized",
+                                self.name
+                            ),
+                        ));
+                    }
+                }
+            }
+            hir::ExprKind::Match(e, arms, loop_desugar) => {
+                // If the binding is initialized in one of the match arms, then the other match
+                // arms might be missing an initialization.
+                let results: Vec<bool> = arms
+                    .iter()
+                    .map(|arm| {
+                        let mut v = ReferencedStatementsVisitor(self.spans, false);
+                        v.visit_arm(arm);
+                        v.1
+                    })
+                    .collect();
+                if results.iter().any(|x| *x) && !results.iter().all(|x| *x) {
+                    for (arm, seen) in arms.iter().zip(results) {
+                        if !seen {
+                            if loop_desugar == hir::MatchSource::ForLoopDesugar {
+                                self.errors.push((
+                                    e.span,
+                                    format!(
+                                        "if the `for` loop runs 0 times, {} is not initialized ",
+                                        self.name
+                                    ),
+                                ));
+                            } else if let Some(guard) = &arm.guard {
+                                self.errors.push((
+                                    arm.pat.span.to(guard.body().span),
+                                    format!(
+                                        "if this pattern and condition are matched, {} is not \
+                                         initialized",
+                                        self.name
+                                    ),
+                                ));
+                            } else {
+                                self.errors.push((
+                                    arm.pat.span,
+                                    format!(
+                                        "if this pattern is matched, {} is not initialized",
+                                        self.name
+                                    ),
+                                ));
+                            }
+                        }
+                    }
+                }
+            }
+            // FIXME: should we also account for binops, particularly `&&` and `||`? `try` should
+            // also be accounted for. For now it is fine, as if we don't find *any* relevant
+            // branching code paths, we point at the places where the binding *is* initialized for
+            // *some* context.
+            _ => {}
+        }
+        walk_expr(self, ex);
+    }
+}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 338df3c70e3..2ed35062da1 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -907,6 +907,16 @@ impl InitializationRequiringAction {
             InitializationRequiringAction::PartialAssignment => "partially assigned",
         }
     }
+
+    fn as_general_verb_in_past_tense(self) -> &'static str {
+        match self {
+            InitializationRequiringAction::Borrow
+            | InitializationRequiringAction::MatchOn
+            | InitializationRequiringAction::Use => "used",
+            InitializationRequiringAction::Assignment => "assigned",
+            InitializationRequiringAction::PartialAssignment => "partially assigned",
+        }
+    }
 }
 
 impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
diff --git a/src/test/ui/asm/aarch64/type-check-2-2.rs b/src/test/ui/asm/aarch64/type-check-2-2.rs
index e4d29754556..aa12d4aa4b4 100644
--- a/src/test/ui/asm/aarch64/type-check-2-2.rs
+++ b/src/test/ui/asm/aarch64/type-check-2-2.rs
@@ -17,10 +17,10 @@ fn main() {
 
         let x: u64;
         asm!("{}", in(reg) x);
-        //~^ ERROR use of possibly-uninitialized variable: `x`
+        //~^ ERROR used binding `x` isn't initialized
         let mut y: u64;
         asm!("{}", inout(reg) y);
-        //~^ ERROR use of possibly-uninitialized variable: `y`
+        //~^ ERROR used binding `y` isn't initialized
         let _ = y;
 
         // Outputs require mutable places
diff --git a/src/test/ui/asm/aarch64/type-check-2-2.stderr b/src/test/ui/asm/aarch64/type-check-2-2.stderr
index 37bbe394994..b2a695529f9 100644
--- a/src/test/ui/asm/aarch64/type-check-2-2.stderr
+++ b/src/test/ui/asm/aarch64/type-check-2-2.stderr
@@ -1,14 +1,18 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/type-check-2-2.rs:19:28
    |
+LL |         let x: u64;
+   |             - binding declared here but left uninitialized
 LL |         asm!("{}", in(reg) x);
-   |                            ^ use of possibly-uninitialized `x`
+   |                            ^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `y`
+error[E0381]: used binding `y` isn't initialized
   --> $DIR/type-check-2-2.rs:22:9
    |
+LL |         let mut y: u64;
+   |             ----- binding declared here but left uninitialized
 LL |         asm!("{}", inout(reg) y);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized
 
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
   --> $DIR/type-check-2-2.rs:30:29
diff --git a/src/test/ui/asm/x86_64/type-check-5.rs b/src/test/ui/asm/x86_64/type-check-5.rs
index 474478f6a88..6190e0b52f4 100644
--- a/src/test/ui/asm/x86_64/type-check-5.rs
+++ b/src/test/ui/asm/x86_64/type-check-5.rs
@@ -13,10 +13,10 @@ fn main() {
 
         let x: u64;
         asm!("{}", in(reg) x);
-        //~^ ERROR use of possibly-uninitialized variable: `x`
+        //~^ ERROR E0381
         let mut y: u64;
         asm!("{}", inout(reg) y);
-        //~^ ERROR use of possibly-uninitialized variable: `y`
+        //~^ ERROR E0381
         let _ = y;
 
         // Outputs require mutable places
diff --git a/src/test/ui/asm/x86_64/type-check-5.stderr b/src/test/ui/asm/x86_64/type-check-5.stderr
index 181ecaf5855..e9c93fea561 100644
--- a/src/test/ui/asm/x86_64/type-check-5.stderr
+++ b/src/test/ui/asm/x86_64/type-check-5.stderr
@@ -1,14 +1,18 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/type-check-5.rs:15:28
    |
+LL |         let x: u64;
+   |             - binding declared here but left uninitialized
 LL |         asm!("{}", in(reg) x);
-   |                            ^ use of possibly-uninitialized `x`
+   |                            ^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `y`
+error[E0381]: used binding `y` isn't initialized
   --> $DIR/type-check-5.rs:18:9
    |
+LL |         let mut y: u64;
+   |             ----- binding declared here but left uninitialized
 LL |         asm!("{}", inout(reg) y);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized
 
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
   --> $DIR/type-check-5.rs:26:29
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
index 24070fe3308..c4d81bf83a3 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
@@ -6,8 +6,7 @@ async fn no_non_guaranteed_initialization(x: usize) -> usize {
     if x > 5 {
         y = echo(10).await;
     }
-    y
-    //~^ use of possibly-uninitialized variable: `y`
+    y //~ ERROR E0381
 }
 
 async fn echo(x: usize) -> usize { x + 1 }
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
index f5991f4bcca..12c15bf56ce 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
@@ -1,8 +1,15 @@
-error[E0381]: use of possibly-uninitialized variable: `y`
+error[E0381]: used binding `y` is possibly-uninitialized
   --> $DIR/no-non-guaranteed-initialization.rs:9:5
    |
+LL |     let y;
+   |         - binding declared here but left uninitialized
+LL |     if x > 5 {
+   |        ----- if this `if` condition is `false`, `y` is not initialized
+LL |         y = echo(10).await;
+LL |     }
+   |      - an `else` arm might be missing here, initializing `y`
 LL |     y
-   |     ^ use of possibly-uninitialized `y`
+   |     ^ `y` used here but it is possibly-uninitialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs
index 8a98a4b0f6b..7577aee3fb7 100644
--- a/src/test/ui/async-await/partial-initialization-across-await.rs
+++ b/src/test/ui/async-await/partial-initialization-across-await.rs
@@ -10,8 +10,7 @@ async fn noop() {}
 
 async fn test_tuple() {
     let mut t: (i32, i32);
-    t.0 = 42;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    t.0 = 42; //~ ERROR E0381
     noop().await;
     t.1 = 88;
     let _ = t;
@@ -19,8 +18,7 @@ async fn test_tuple() {
 
 async fn test_tuple_struct() {
     let mut t: T;
-    t.0 = 42;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    t.0 = 42; //~ ERROR E0381
     noop().await;
     t.1 = 88;
     let _ = t;
@@ -28,8 +26,7 @@ async fn test_tuple_struct() {
 
 async fn test_struct() {
     let mut t: S;
-    t.x = 42;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    t.x = 42; //~ ERROR E0381
     noop().await;
     t.y = 88;
     let _ = t;
diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr
index 9a510c22c4b..6a0eeffb946 100644
--- a/src/test/ui/async-await/partial-initialization-across-await.stderr
+++ b/src/test/ui/async-await/partial-initialization-across-await.stderr
@@ -1,20 +1,32 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/partial-initialization-across-await.rs:13:5
    |
+LL |     let mut t: (i32, i32);
+   |         ----- binding declared here but left uninitialized
 LL |     t.0 = 42;
-   |     ^^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-await.rs:22:5
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/partial-initialization-across-await.rs:21:5
    |
+LL |     let mut t: T;
+   |         ----- binding declared here but left uninitialized
 LL |     t.0 = 42;
-   |     ^^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-await.rs:31:5
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/partial-initialization-across-await.rs:29:5
    |
+LL |     let mut t: S;
+   |         ----- binding declared here but left uninitialized
 LL |     t.x = 42;
-   |     ^^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.stderr
index 40f1aae092d..1ed92865da5 100644
--- a/src/test/ui/borrowck/assign_mutable_fields.stderr
+++ b/src/test/ui/borrowck/assign_mutable_fields.stderr
@@ -1,14 +1,22 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/assign_mutable_fields.rs:9:5
    |
+LL |     let mut x: (u32, u32);
+   |         ----- binding declared here but left uninitialized
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/assign_mutable_fields.rs:17:5
    |
+LL |     let mut x: (u32, u32);
+   |         ----- binding declared here but left uninitialized
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-and-init.rs b/src/test/ui/borrowck/borrowck-and-init.rs
index f11d44e2217..eeb4f05d60c 100644
--- a/src/test/ui/borrowck/borrowck-and-init.rs
+++ b/src/test/ui/borrowck/borrowck-and-init.rs
@@ -2,5 +2,5 @@ fn main() {
     let i: isize;
 
     println!("{}", false && { i = 5; true });
-    println!("{}", i); //~ ERROR borrow of possibly-uninitialized variable: `i`
+    println!("{}", i); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-and-init.stderr b/src/test/ui/borrowck/borrowck-and-init.stderr
index d2c7473c036..7f3d27d6091 100644
--- a/src/test/ui/borrowck/borrowck-and-init.stderr
+++ b/src/test/ui/borrowck/borrowck-and-init.stderr
@@ -1,8 +1,13 @@
-error[E0381]: borrow of possibly-uninitialized variable: `i`
+error[E0381]: used binding `i` is possibly-uninitialized
   --> $DIR/borrowck-and-init.rs:5:20
    |
+LL |     let i: isize;
+   |         - binding declared here but left uninitialized
+LL |
+LL |     println!("{}", false && { i = 5; true });
+   |                               ----- binding initialized here in some conditions
 LL |     println!("{}", i);
-   |                    ^ use of possibly-uninitialized `i`
+   |                    ^ `i` used here but it is possibly-uninitialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/borrowck/borrowck-block-unint.rs b/src/test/ui/borrowck/borrowck-block-unint.rs
index 1e7306acaee..8d13b25a357 100644
--- a/src/test/ui/borrowck/borrowck-block-unint.rs
+++ b/src/test/ui/borrowck/borrowck-block-unint.rs
@@ -1,7 +1,7 @@
 fn force<F>(f: F) where F: FnOnce() { f(); }
 fn main() {
     let x: isize;
-    force(|| {  //~ ERROR borrow of possibly-uninitialized variable: `x`
+    force(|| {  //~ ERROR E0381
         println!("{}", x);
     });
 }
diff --git a/src/test/ui/borrowck/borrowck-block-unint.stderr b/src/test/ui/borrowck/borrowck-block-unint.stderr
index 578f89df46c..e720db1c696 100644
--- a/src/test/ui/borrowck/borrowck-block-unint.stderr
+++ b/src/test/ui/borrowck/borrowck-block-unint.stderr
@@ -1,8 +1,10 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-block-unint.rs:4:11
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     force(|| {
-   |           ^^ use of possibly-uninitialized `x`
+   |           ^^ `x` used here but it isn't initialized
 LL |         println!("{}", x);
    |                        - borrow occurs due to use in closure
 
diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.rs b/src/test/ui/borrowck/borrowck-break-uninit-2.rs
index 126d991a51c..3abca33a84a 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit-2.rs
+++ b/src/test/ui/borrowck/borrowck-break-uninit-2.rs
@@ -6,7 +6,7 @@ fn foo() -> isize {
         x = 0;
     }
 
-    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
+    println!("{}", x); //~ ERROR E0381
 
     return 17;
 }
diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
index b134f5cc2d8..23ea1a2de7f 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
+++ b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
@@ -1,8 +1,11 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-break-uninit-2.rs:9:20
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
+...
 LL |     println!("{}", x);
-   |                    ^ use of possibly-uninitialized `x`
+   |                    ^ `x` used here but it isn't initialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/borrowck/borrowck-break-uninit.rs b/src/test/ui/borrowck/borrowck-break-uninit.rs
index 8ccb21ae8ee..824f91dbc62 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit.rs
+++ b/src/test/ui/borrowck/borrowck-break-uninit.rs
@@ -6,7 +6,7 @@ fn foo() -> isize {
         x = 0;
     }
 
-    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
+    println!("{}", x); //~ ERROR E0381
 
     return 17;
 }
diff --git a/src/test/ui/borrowck/borrowck-break-uninit.stderr b/src/test/ui/borrowck/borrowck-break-uninit.stderr
index 652d7d3076f..2b9b0a190f6 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit.stderr
+++ b/src/test/ui/borrowck/borrowck-break-uninit.stderr
@@ -1,8 +1,11 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-break-uninit.rs:9:20
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
+...
 LL |     println!("{}", x);
-   |                    ^ use of possibly-uninitialized `x`
+   |                    ^ `x` used here but it isn't initialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.rs b/src/test/ui/borrowck/borrowck-field-sensitivity.rs
index 50edfb6ba2d..03edf445ee9 100644
--- a/src/test/ui/borrowck/borrowck-field-sensitivity.rs
+++ b/src/test/ui/borrowck/borrowck-field-sensitivity.rs
@@ -78,20 +78,20 @@ fn fu_move_after_fu_move() {
 
 fn copy_after_field_assign_after_uninit() {
     let mut x: A;
-    x.a = 1; //~ ERROR assign to part of possibly-uninitialized variable: `x`
+    x.a = 1; //~ ERROR E0381
     drop(x.a);
 }
 
 fn borrow_after_field_assign_after_uninit() {
     let mut x: A;
-    x.a = 1; //~ ERROR assign to part of possibly-uninitialized variable: `x`
+    x.a = 1; //~ ERROR E0381
     let p = &x.a;
     drop(*p);
 }
 
 fn move_after_field_assign_after_uninit() {
     let mut x: A;
-    x.b = Box::new(1); //~ ERROR assign to part of possibly-uninitialized variable: `x`
+    x.b = Box::new(1); //~ ERROR E0381
     drop(x.b);
 }
 
diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr
index bb4d2f06016..e009f5913ed 100644
--- a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr
+++ b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr
@@ -108,23 +108,35 @@ LL |     let _z = A { a: 4, .. x };
    |
    = note: move occurs because `x.b` has type `Box<isize>`, which does not implement the `Copy` trait
 
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/borrowck-field-sensitivity.rs:81:5
    |
+LL |     let mut x: A;
+   |         ----- binding declared here but left uninitialized
 LL |     x.a = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/borrowck-field-sensitivity.rs:87:5
    |
+LL |     let mut x: A;
+   |         ----- binding declared here but left uninitialized
 LL |     x.a = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/borrowck-field-sensitivity.rs:94:5
    |
+LL |     let mut x: A;
+   |         ----- binding declared here but left uninitialized
 LL |     x.b = Box::new(1);
-   |     ^^^ use of possibly-uninitialized `x`
+   |     ^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 14 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs
new file mode 100644
index 00000000000..f619c045b25
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs
@@ -0,0 +1,7 @@
+fn f() -> isize {
+    let mut x: isize;
+    for _ in 0..0 { x = 10; }
+    return x; //~ ERROR E0381
+}
+
+fn main() { f(); }
diff --git a/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr
new file mode 100644
index 00000000000..c08c93f3617
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr
@@ -0,0 +1,13 @@
+error[E0381]: used binding `x` is possibly-uninitialized
+  --> $DIR/borrowck-for-loop-uninitialized-binding.rs:4:12
+   |
+LL |     let mut x: isize;
+   |         ----- binding declared here but left uninitialized
+LL |     for _ in 0..0 { x = 10; }
+   |              ---- if the `for` loop runs 0 times, `x` is not initialized 
+LL |     return x;
+   |            ^ `x` used here but it is possibly-uninitialized
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/borrowck/borrowck-if-no-else.rs b/src/test/ui/borrowck/borrowck-if-no-else.rs
index f59bcad6f61..534d771be1d 100644
--- a/src/test/ui/borrowck/borrowck-if-no-else.rs
+++ b/src/test/ui/borrowck/borrowck-if-no-else.rs
@@ -2,5 +2,5 @@ fn foo(x: isize) { println!("{}", x); }
 
 fn main() {
     let x: isize; if 1 > 2 { x = 10; }
-    foo(x); //~ ERROR use of possibly-uninitialized variable: `x`
+    foo(x); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-if-no-else.stderr b/src/test/ui/borrowck/borrowck-if-no-else.stderr
index 3e9d3d4f6d5..9eafc2c2a86 100644
--- a/src/test/ui/borrowck/borrowck-if-no-else.stderr
+++ b/src/test/ui/borrowck/borrowck-if-no-else.stderr
@@ -1,8 +1,13 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` is possibly-uninitialized
   --> $DIR/borrowck-if-no-else.rs:5:9
    |
+LL |     let x: isize; if 1 > 2 { x = 10; }
+   |         -            -----            - an `else` arm might be missing here, initializing `x`
+   |         |            |
+   |         |            if this `if` condition is `false`, `x` is not initialized
+   |         binding declared here but left uninitialized
 LL |     foo(x);
-   |         ^ use of possibly-uninitialized `x`
+   |         ^ `x` used here but it is possibly-uninitialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-if-with-else.rs b/src/test/ui/borrowck/borrowck-if-with-else.rs
index c13318b16c2..69d450c5989 100644
--- a/src/test/ui/borrowck/borrowck-if-with-else.rs
+++ b/src/test/ui/borrowck/borrowck-if-with-else.rs
@@ -7,5 +7,5 @@ fn main() {
     } else {
         x = 10;
     }
-    foo(x); //~ ERROR use of possibly-uninitialized variable: `x`
+    foo(x); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-if-with-else.stderr b/src/test/ui/borrowck/borrowck-if-with-else.stderr
index 53b8a6bba2c..3f0fe291ca2 100644
--- a/src/test/ui/borrowck/borrowck-if-with-else.stderr
+++ b/src/test/ui/borrowck/borrowck-if-with-else.stderr
@@ -1,8 +1,13 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` is possibly-uninitialized
   --> $DIR/borrowck-if-with-else.rs:10:9
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
+LL |     if 1 > 2 {
+   |        ----- if this condition is `true`, `x` is not initialized
+...
 LL |     foo(x);
-   |         ^ use of possibly-uninitialized `x`
+   |         ^ `x` used here but it is possibly-uninitialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs
index 9905e420f94..e6476b9c1be 100644
--- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs
+++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs
@@ -1,7 +1,7 @@
 fn main() {
     let j = || -> isize {
         let i: isize;
-        i //~ ERROR use of possibly-uninitialized variable: `i`
+        i //~ ERROR E0381
     };
     j();
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
index 2d1d9bc8fa4..e8a2fbc91ea 100644
--- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `i`
+error[E0381]: used binding `i` isn't initialized
   --> $DIR/borrowck-init-in-called-fn-expr.rs:4:9
    |
+LL |         let i: isize;
+   |             - binding declared here but left uninitialized
 LL |         i
-   |         ^ use of possibly-uninitialized `i`
+   |         ^ `i` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs b/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs
index 7dd3396c8c2..7eb204a0d16 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs
+++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs
@@ -1,7 +1,7 @@
 fn main() {
     let f  = || -> isize {
         let i: isize;
-        i //~ ERROR use of possibly-uninitialized variable: `i`
+        i //~ ERROR E0381
     };
     println!("{}", f());
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
index fd8b90eda60..1e950d6a20d 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `i`
+error[E0381]: used binding `i` isn't initialized
   --> $DIR/borrowck-init-in-fn-expr.rs:4:9
    |
+LL |         let i: isize;
+   |             - binding declared here but left uninitialized
 LL |         i
-   |         ^ use of possibly-uninitialized `i`
+   |         ^ `i` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.rs b/src/test/ui/borrowck/borrowck-init-in-fru.rs
index d7ec2ed75c8..c07957ab139 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fru.rs
+++ b/src/test/ui/borrowck/borrowck-init-in-fru.rs
@@ -7,6 +7,6 @@ struct Point {
 fn main() {
     let mut origin: Point;
     origin = Point { x: 10, ..origin };
-    //~^ ERROR use of possibly-uninitialized variable: `origin` [E0381]
+    //~^ ERROR E0381
     origin.clone();
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.stderr b/src/test/ui/borrowck/borrowck-init-in-fru.stderr
index f01afe1466a..83a3e3e0e3a 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fru.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-fru.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `origin`
+error[E0381]: used binding `origin` isn't initialized
   --> $DIR/borrowck-init-in-fru.rs:9:14
    |
+LL |     let mut origin: Point;
+   |         ---------- binding declared here but left uninitialized
 LL |     origin = Point { x: 10, ..origin };
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `origin.y`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ `origin.y` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.rs b/src/test/ui/borrowck/borrowck-init-op-equal.rs
index 784eb8cf85b..3d08c1b81a7 100644
--- a/src/test/ui/borrowck/borrowck-init-op-equal.rs
+++ b/src/test/ui/borrowck/borrowck-init-op-equal.rs
@@ -1,6 +1,6 @@
 fn test() {
     let v: isize;
-    v += 1; //~ ERROR use of possibly-uninitialized variable: `v`
+    v += 1; //~ ERROR E0381
     v.clone();
 }
 
diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.stderr b/src/test/ui/borrowck/borrowck-init-op-equal.stderr
index 6c88778ae0e..74704b2abfe 100644
--- a/src/test/ui/borrowck/borrowck-init-op-equal.stderr
+++ b/src/test/ui/borrowck/borrowck-init-op-equal.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `v`
+error[E0381]: used binding `v` isn't initialized
   --> $DIR/borrowck-init-op-equal.rs:3:5
    |
+LL |     let v: isize;
+   |         - binding declared here but left uninitialized
 LL |     v += 1;
-   |     ^^^^^^ use of possibly-uninitialized `v`
+   |     ^^^^^^ `v` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.rs b/src/test/ui/borrowck/borrowck-init-plus-equal.rs
index d9d20a2a9c1..2a52a3f4e5e 100644
--- a/src/test/ui/borrowck/borrowck-init-plus-equal.rs
+++ b/src/test/ui/borrowck/borrowck-init-plus-equal.rs
@@ -1,6 +1,6 @@
 fn test() {
     let mut v: isize;
-    v = v + 1; //~ ERROR use of possibly-uninitialized variable: `v`
+    v = v + 1; //~ ERROR E0381
     v.clone();
 }
 
diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr
index fe09c8581df..7542576d636 100644
--- a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr
+++ b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `v`
+error[E0381]: used binding `v` isn't initialized
   --> $DIR/borrowck-init-plus-equal.rs:3:9
    |
+LL |     let mut v: isize;
+   |         ----- binding declared here but left uninitialized
 LL |     v = v + 1;
-   |         ^ use of possibly-uninitialized `v`
+   |         ^ `v` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-or-init.rs b/src/test/ui/borrowck/borrowck-or-init.rs
index 81b0b80bf11..079cf899e6d 100644
--- a/src/test/ui/borrowck/borrowck-or-init.rs
+++ b/src/test/ui/borrowck/borrowck-or-init.rs
@@ -2,5 +2,5 @@ fn main() {
     let i: isize;
 
     println!("{}", false || { i = 5; true });
-    println!("{}", i); //~ ERROR borrow of possibly-uninitialized variable: `i`
+    println!("{}", i); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-or-init.stderr b/src/test/ui/borrowck/borrowck-or-init.stderr
index 6c757759f71..0bc24f1b693 100644
--- a/src/test/ui/borrowck/borrowck-or-init.stderr
+++ b/src/test/ui/borrowck/borrowck-or-init.stderr
@@ -1,8 +1,13 @@
-error[E0381]: borrow of possibly-uninitialized variable: `i`
+error[E0381]: used binding `i` is possibly-uninitialized
   --> $DIR/borrowck-or-init.rs:5:20
    |
+LL |     let i: isize;
+   |         - binding declared here but left uninitialized
+LL |
+LL |     println!("{}", false || { i = 5; true });
+   |                               ----- binding initialized here in some conditions
 LL |     println!("{}", i);
-   |                    ^ use of possibly-uninitialized `i`
+   |                    ^ `i` used here but it is possibly-uninitialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.rs b/src/test/ui/borrowck/borrowck-partial-reinit-4.rs
index 5e5a8cdf423..a43a1936678 100644
--- a/src/test/ui/borrowck/borrowck-partial-reinit-4.rs
+++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.rs
@@ -14,8 +14,7 @@ impl Drop for Test2 {
 
 fn stuff() {
     let mut x : (Test2, Test2);
-    (x.0).0 = Some(Test);
-    //~^ ERROR assign of possibly-uninitialized variable: `x.0`
+    (x.0).0 = Some(Test); //~ ERROR E0381
 }
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr
index 218c4f2de5b..d12a482cb69 100644
--- a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr
+++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr
@@ -1,8 +1,12 @@
-error[E0381]: assign of possibly-uninitialized variable: `x.0`
+error[E0381]: assigned binding `x.0` isn't fully initialized
   --> $DIR/borrowck-partial-reinit-4.rs:17:5
    |
+LL |     let mut x : (Test2, Test2);
+   |         ----- binding declared here but left uninitialized
 LL |     (x.0).0 = Some(Test);
-   |     ^^^^^^^ use of possibly-uninitialized `x.0`
+   |     ^^^^^^^ `x.0` assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-return.rs b/src/test/ui/borrowck/borrowck-return.rs
index 8c623356f6c..a63ffcff732 100644
--- a/src/test/ui/borrowck/borrowck-return.rs
+++ b/src/test/ui/borrowck/borrowck-return.rs
@@ -1,6 +1,6 @@
 fn f() -> isize {
     let x: isize;
-    return x; //~ ERROR use of possibly-uninitialized variable: `x`
+    return x; //~ ERROR E0381
 }
 
 fn main() { f(); }
diff --git a/src/test/ui/borrowck/borrowck-return.stderr b/src/test/ui/borrowck/borrowck-return.stderr
index bc74e8e3438..1c916e22317 100644
--- a/src/test/ui/borrowck/borrowck-return.stderr
+++ b/src/test/ui/borrowck/borrowck-return.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-return.rs:3:12
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     return x;
-   |            ^ use of possibly-uninitialized `x`
+   |            ^ `x` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-storage-dead.stderr b/src/test/ui/borrowck/borrowck-storage-dead.stderr
index 8e4932142f0..2cea4392d6a 100644
--- a/src/test/ui/borrowck/borrowck-storage-dead.stderr
+++ b/src/test/ui/borrowck/borrowck-storage-dead.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-storage-dead.rs:16:17
    |
+LL |         let x: i32;
+   |             - binding declared here but left uninitialized
 LL |         let _ = x + 1;
-   |                 ^ use of possibly-uninitialized `x`
+   |                 ^ `x` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.rs b/src/test/ui/borrowck/borrowck-uninit-after-item.rs
index e9a389657c8..e97ce6aa407 100644
--- a/src/test/ui/borrowck/borrowck-uninit-after-item.rs
+++ b/src/test/ui/borrowck/borrowck-uninit-after-item.rs
@@ -1,5 +1,5 @@
 fn main() {
     let bar;
     fn baz(_x: isize) { }
-    baz(bar); //~ ERROR use of possibly-uninitialized variable: `bar`
+    baz(bar); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr
index f7f069b81be..588b1b0c972 100644
--- a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr
@@ -1,8 +1,11 @@
-error[E0381]: use of possibly-uninitialized variable: `bar`
+error[E0381]: used binding `bar` isn't initialized
   --> $DIR/borrowck-uninit-after-item.rs:4:9
    |
+LL |     let bar;
+   |         --- binding declared here but left uninitialized
+LL |     fn baz(_x: isize) { }
 LL |     baz(bar);
-   |         ^^^ use of possibly-uninitialized `bar`
+   |         ^^^ `bar` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr
index 7951a5b1b5d..6a38a798919 100644
--- a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `a`
+error[E0381]: used binding `a` isn't initialized
   --> $DIR/borrowck-uninit-field-access.rs:21:13
    |
+LL |     let mut a: Point;
+   |         ----- binding declared here but left uninitialized
 LL |     let _ = a.x + 1;
-   |             ^^^ use of possibly-uninitialized `a.x`
+   |             ^^^ `a.x` used here but it isn't initialized
 
 error[E0382]: use of moved value: `line1.origin`
   --> $DIR/borrowck-uninit-field-access.rs:25:13
diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs b/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs
index 20350d61d5b..92c3692bd2f 100644
--- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs
+++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs
@@ -3,32 +3,32 @@
 
 pub fn main() {
     let x: isize;
-    x += 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x += 1; //~ ERROR E0381
 
     let x: isize;
-    x -= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x -= 1; //~ ERROR E0381
 
     let x: isize;
-    x *= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x *= 1; //~ ERROR E0381
 
     let x: isize;
-    x /= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x /= 1; //~ ERROR E0381
 
     let x: isize;
-    x %= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x %= 1; //~ ERROR E0381
 
     let x: isize;
-    x ^= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x ^= 1; //~ ERROR E0381
 
     let x: isize;
-    x &= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x &= 1; //~ ERROR E0381
 
     let x: isize;
-    x |= 1; //~ ERROR use of possibly-uninitialized variable: `x`
+    x |= 1; //~ ERROR E0381
 
     let x: isize;
-    x <<= 1;    //~ ERROR use of possibly-uninitialized variable: `x`
+    x <<= 1; //~ ERROR E0381
 
     let x: isize;
-    x >>= 1;    //~ ERROR use of possibly-uninitialized variable: `x`
+    x >>= 1; //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
index f2036df3ce9..744cb14e662 100644
--- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
@@ -1,62 +1,82 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:6:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x += 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:9:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x -= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:12:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x *= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:15:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x /= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:18:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x %= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:21:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x ^= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:24:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x &= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:27:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x |= 1;
-   |     ^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:30:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x <<= 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-in-assignop.rs:33:5
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     x >>= 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` used here but it isn't initialized
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs b/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs
index 0ccea49f329..c36b9707d22 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs
@@ -5,29 +5,29 @@ struct S<X, Y> {
 
 fn main() {
     let x: &&Box<i32>;
-    let _y = &**x; //~ [E0381]
+    let _y = &**x; //~ ERROR [E0381]
 
     let x: &&S<i32, i32>;
-    let _y = &**x; //~ [E0381]
+    let _y = &**x; //~ ERROR [E0381]
 
     let x: &&i32;
-    let _y = &**x; //~ [E0381]
+    let _y = &**x; //~ ERROR [E0381]
 
 
     let mut a: S<i32, i32>;
-    a.x = 0;            //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381]
+    a.x = 0; //~ ERROR [E0381]
     let _b = &a.x;
 
     let mut a: S<&&i32, &&i32>;
-    a.x = &&0;          //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381]
+    a.x = &&0; //~ ERROR [E0381]
     let _b = &**a.x;
 
 
     let mut a: S<i32, i32>;
-    a.x = 0;            //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381]
+    a.x = 0; //~ ERROR [E0381]
     let _b = &a.y;
 
     let mut a: S<&&i32, &&i32>;
-    a.x = &&0;          //~ assign to part of possibly-uninitialized variable: `a` [E0381]
+    a.x = &&0; //~ ERROR [E0381]
     let _b = &**a.y;
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr
index d99a50df75b..c486cb6dd0c 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr
@@ -1,44 +1,66 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:8:14
    |
+LL |     let x: &&Box<i32>;
+   |         - binding declared here but left uninitialized
 LL |     let _y = &**x;
-   |              ^^^^ use of possibly-uninitialized `**x`
+   |              ^^^^ `**x` used here but it isn't initialized
 
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:11:14
    |
+LL |     let x: &&S<i32, i32>;
+   |         - binding declared here but left uninitialized
 LL |     let _y = &**x;
-   |              ^^^^ use of possibly-uninitialized `**x`
+   |              ^^^^ `**x` used here but it isn't initialized
 
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:14:14
    |
+LL |     let x: &&i32;
+   |         - binding declared here but left uninitialized
 LL |     let _y = &**x;
-   |              ^^^^ use of possibly-uninitialized `**x`
+   |              ^^^^ `**x` used here but it isn't initialized
 
-error[E0381]: assign to part of possibly-uninitialized variable: `a`
+error[E0381]: partially assigned binding `a` isn't fully initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:18:5
    |
+LL |     let mut a: S<i32, i32>;
+   |         ----- binding declared here but left uninitialized
 LL |     a.x = 0;
-   |     ^^^^^^^ use of possibly-uninitialized `a`
+   |     ^^^^^^^ `a` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `a`
+error[E0381]: partially assigned binding `a` isn't fully initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:22:5
    |
+LL |     let mut a: S<&&i32, &&i32>;
+   |         ----- binding declared here but left uninitialized
 LL |     a.x = &&0;
-   |     ^^^^^^^^^ use of possibly-uninitialized `a`
+   |     ^^^^^^^^^ `a` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `a`
+error[E0381]: partially assigned binding `a` isn't fully initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:27:5
    |
+LL |     let mut a: S<i32, i32>;
+   |         ----- binding declared here but left uninitialized
 LL |     a.x = 0;
-   |     ^^^^^^^ use of possibly-uninitialized `a`
+   |     ^^^^^^^ `a` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `a`
+error[E0381]: partially assigned binding `a` isn't fully initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:31:5
    |
+LL |     let mut a: S<&&i32, &&i32>;
+   |         ----- binding declared here but left uninitialized
 LL |     a.x = &&0;
-   |     ^^^^^^^^^ use of possibly-uninitialized `a`
+   |     ^^^^^^^^^ `a` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-uninit.rs b/src/test/ui/borrowck/borrowck-uninit.rs
index 017b955a395..5d0ebabb008 100644
--- a/src/test/ui/borrowck/borrowck-uninit.rs
+++ b/src/test/ui/borrowck/borrowck-uninit.rs
@@ -2,5 +2,5 @@ fn foo(x: isize) { println!("{}", x); }
 
 fn main() {
     let x: isize;
-    foo(x); //~ ERROR use of possibly-uninitialized variable: `x`
+    foo(x); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit.stderr b/src/test/ui/borrowck/borrowck-uninit.stderr
index effc209e816..d5566691a82 100644
--- a/src/test/ui/borrowck/borrowck-uninit.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit.rs:5:9
    |
+LL |     let x: isize;
+   |         - binding declared here but left uninitialized
 LL |     foo(x);
-   |         ^ use of possibly-uninitialized `x`
+   |         ^ `x` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.rs b/src/test/ui/borrowck/borrowck-union-uninitialized.rs
index 3cc71e7cece..bbe9f22aac3 100644
--- a/src/test/ui/borrowck/borrowck-union-uninitialized.rs
+++ b/src/test/ui/borrowck/borrowck-union-uninitialized.rs
@@ -10,8 +10,8 @@ fn main() {
     unsafe {
         let mut s: S;
         let mut u: U;
-        s.a = 0; //~ ERROR assign to part of possibly-uninitialized variable: `s`
-        u.a = 0; //~ ERROR assign to part of possibly-uninitialized variable: `u`
+        s.a = 0; //~ ERROR E0381
+        u.a = 0; //~ ERROR E0381
         let sa = s.a;
         let ua = u.a;
     }
diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr
index bd9ec5e579c..b7ff5f3955e 100644
--- a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr
+++ b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr
@@ -1,14 +1,24 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `s`
+error[E0381]: partially assigned binding `s` isn't fully initialized
   --> $DIR/borrowck-union-uninitialized.rs:13:9
    |
+LL |         let mut s: S;
+   |             ----- binding declared here but left uninitialized
+LL |         let mut u: U;
 LL |         s.a = 0;
-   |         ^^^^^^^ use of possibly-uninitialized `s`
+   |         ^^^^^^^ `s` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `u`
+error[E0381]: partially assigned binding `u` isn't fully initialized
   --> $DIR/borrowck-union-uninitialized.rs:14:9
    |
+LL |         let mut u: U;
+   |             ----- binding declared here but left uninitialized
+LL |         s.a = 0;
 LL |         u.a = 0;
-   |         ^^^^^^^ use of possibly-uninitialized `u`
+   |         ^^^^^^^ `u` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr
index d1b396aba82..459cf1398b7 100644
--- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr
+++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr
@@ -1,14 +1,18 @@
-error[E0381]: use of possibly-uninitialized variable: `w`
+error[E0381]: used binding `w` isn't initialized
   --> $DIR/borrowck-use-in-index-lvalue.rs:3:5
    |
+LL |     let w: &mut [isize];
+   |         - binding declared here but left uninitialized
 LL |     w[5] = 0;
-   |     ^^^^ use of possibly-uninitialized `*w`
+   |     ^^^^ `*w` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `w`
+error[E0381]: used binding `w` isn't initialized
   --> $DIR/borrowck-use-in-index-lvalue.rs:6:5
    |
+LL |     let mut w: &mut [isize];
+   |         ----- binding declared here but left uninitialized
 LL |     w[5] = 0;
-   |     ^^^^ use of possibly-uninitialized `*w`
+   |     ^^^^ `*w` used here but it isn't initialized
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr
index ca5227c98c8..942ed4fc6ca 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr
@@ -1,8 +1,10 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13
    |
+LL |     let x: &i32;
+   |         - binding declared here but left uninitialized
 LL |     let y = x as *const dyn Foo;
-   |             ^ use of possibly-uninitialized `*x`
+   |             ^ `*x` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr
index 24897a0f2dc..f3289e23981 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr
@@ -1,8 +1,10 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13
    |
+LL |     let x: &i32;
+   |         - binding declared here but left uninitialized
 LL |     let y = x as *const i32;
-   |             ^ use of possibly-uninitialized `*x`
+   |             ^ `*x` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-while-break.rs b/src/test/ui/borrowck/borrowck-while-break.rs
index 48e42214702..7100b713031 100644
--- a/src/test/ui/borrowck/borrowck-while-break.rs
+++ b/src/test/ui/borrowck/borrowck-while-break.rs
@@ -4,7 +4,7 @@ fn test(cond: bool) {
         v = 3;
         break;
     }
-    println!("{}", v); //~ ERROR borrow of possibly-uninitialized variable: `v`
+    println!("{}", v); //~ ERROR E0381
 }
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-while-break.stderr b/src/test/ui/borrowck/borrowck-while-break.stderr
index fc144a066bb..44674febf49 100644
--- a/src/test/ui/borrowck/borrowck-while-break.stderr
+++ b/src/test/ui/borrowck/borrowck-while-break.stderr
@@ -1,8 +1,13 @@
-error[E0381]: borrow of possibly-uninitialized variable: `v`
+error[E0381]: used binding `v` is possibly-uninitialized
   --> $DIR/borrowck-while-break.rs:7:20
    |
+LL |     let v;
+   |         - binding declared here but left uninitialized
+LL |     while cond {
+   |           ---- if this condition isn't met and the `while` loop runs 0 times, `v` is not initialized
+...
 LL |     println!("{}", v);
-   |                    ^ use of possibly-uninitialized `v`
+   |                    ^ `v` used here but it is possibly-uninitialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/borrowck/borrowck-while-cond.rs b/src/test/ui/borrowck/borrowck-while-cond.rs
index b3ec20711c1..62a9bdd2020 100644
--- a/src/test/ui/borrowck/borrowck-while-cond.rs
+++ b/src/test/ui/borrowck/borrowck-while-cond.rs
@@ -1,4 +1,4 @@
 fn main() {
     let x: bool;
-    while x { } //~ ERROR use of possibly-uninitialized variable: `x`
+    while x { } //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/borrowck-while-cond.stderr b/src/test/ui/borrowck/borrowck-while-cond.stderr
index 92937a9c573..e41c1c55e60 100644
--- a/src/test/ui/borrowck/borrowck-while-cond.stderr
+++ b/src/test/ui/borrowck/borrowck-while-cond.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-while-cond.rs:3:11
    |
+LL |     let x: bool;
+   |         - binding declared here but left uninitialized
 LL |     while x { }
-   |           ^ use of possibly-uninitialized `x`
+   |           ^ `x` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-while.rs b/src/test/ui/borrowck/borrowck-while.rs
index 6b3220c7d85..f49a778eb6b 100644
--- a/src/test/ui/borrowck/borrowck-while.rs
+++ b/src/test/ui/borrowck/borrowck-while.rs
@@ -1,7 +1,7 @@
 fn f() -> isize {
     let mut x: isize;
     while 1 == 1 { x = 10; }
-    return x; //~ ERROR use of possibly-uninitialized variable: `x`
+    return x; //~ ERROR E0381
 }
 
 fn main() { f(); }
diff --git a/src/test/ui/borrowck/borrowck-while.stderr b/src/test/ui/borrowck/borrowck-while.stderr
index a1f8f64725d..c45235990c3 100644
--- a/src/test/ui/borrowck/borrowck-while.stderr
+++ b/src/test/ui/borrowck/borrowck-while.stderr
@@ -1,8 +1,12 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` is possibly-uninitialized
   --> $DIR/borrowck-while.rs:4:12
    |
+LL |     let mut x: isize;
+   |         ----- binding declared here but left uninitialized
+LL |     while 1 == 1 { x = 10; }
+   |           ------ if this condition isn't met and the `while` loop runs 0 times, `x` is not initialized
 LL |     return x;
-   |            ^ use of possibly-uninitialized `x`
+   |            ^ `x` used here but it is possibly-uninitialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
index 7043cb3a164..17de40d5ba9 100644
--- a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
@@ -4,19 +4,19 @@
 fn main() {
     let mut t: (u64, u64);
     t.0 = 1;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    //~^ ERROR E0381
     t.1 = 1;
 
     let mut t: (u64, u64);
     t.1 = 1;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    //~^ ERROR E0381
     t.0 = 1;
 
     let mut t: (u64, u64);
     t.0 = 1;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    //~^ ERROR E0381
 
     let mut t: (u64,);
     t.0 = 1;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    //~^ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
index 8d5b39341c1..9a84c6fefae 100644
--- a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
@@ -1,26 +1,42 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/disallow-possibly-uninitialized.rs:6:5
    |
+LL |     let mut t: (u64, u64);
+   |         ----- binding declared here but left uninitialized
 LL |     t.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/disallow-possibly-uninitialized.rs:11:5
    |
+LL |     let mut t: (u64, u64);
+   |         ----- binding declared here but left uninitialized
 LL |     t.1 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/disallow-possibly-uninitialized.rs:16:5
    |
+LL |     let mut t: (u64, u64);
+   |         ----- binding declared here but left uninitialized
 LL |     t.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/disallow-possibly-uninitialized.rs:20:5
    |
+LL |     let mut t: (u64,);
+   |         ----- binding declared here but left uninitialized
 LL |     t.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.rs b/src/test/ui/borrowck/issue-24267-flow-exit.rs
index d6809ee4143..c419c5840d9 100644
--- a/src/test/ui/borrowck/issue-24267-flow-exit.rs
+++ b/src/test/ui/borrowck/issue-24267-flow-exit.rs
@@ -9,11 +9,11 @@ pub fn main() {
 pub fn foo1() {
     let x: i32;
     loop { x = break; }
-    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
+    println!("{}", x); //~ ERROR E0381
 }
 
 pub fn foo2() {
     let x: i32;
     for _ in 0..10 { x = continue; }
-    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
+    println!("{}", x); //~ ERROR E0381
 }
diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.stderr b/src/test/ui/borrowck/issue-24267-flow-exit.stderr
index e29cf7a1a75..d436e8ff909 100644
--- a/src/test/ui/borrowck/issue-24267-flow-exit.stderr
+++ b/src/test/ui/borrowck/issue-24267-flow-exit.stderr
@@ -1,16 +1,22 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/issue-24267-flow-exit.rs:12:20
    |
+LL |     let x: i32;
+   |         - binding declared here but left uninitialized
+LL |     loop { x = break; }
 LL |     println!("{}", x);
-   |                    ^ use of possibly-uninitialized `x`
+   |                    ^ `x` used here but it isn't initialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/issue-24267-flow-exit.rs:18:20
    |
+LL |     let x: i32;
+   |         - binding declared here but left uninitialized
+LL |     for _ in 0..10 { x = continue; }
 LL |     println!("{}", x);
-   |                    ^ use of possibly-uninitialized `x`
+   |                    ^ `x` used here but it isn't initialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs
index f031a144443..205ea10c90b 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs
@@ -10,7 +10,7 @@ fn main() {
     {
         let mut t: Tuple;
         t.0 = S(1);
-        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+        //~^ ERROR E0381
         t.1 = 2;
         println!("{:?} {:?}", t.0, t.1);
     }
@@ -18,7 +18,7 @@ fn main() {
     {
         let mut u: Tpair;
         u.0 = S(1);
-        //~^ ERROR assign to part of possibly-uninitialized variable: `u` [E0381]
+        //~^ ERROR E0381
         u.1 = 2;
         println!("{:?} {:?}", u.0, u.1);
     }
@@ -26,7 +26,7 @@ fn main() {
     {
         let mut v: Spair;
         v.x = S(1);
-        //~^ ERROR assign to part of possibly-uninitialized variable: `v` [E0381]
+        //~^ ERROR E0381
         v.y = 2;
         println!("{:?} {:?}", v.x, v.y);
     }
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr
index 22c6c3964ed..2a0eba396f1 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr
@@ -1,20 +1,32 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:12:9
    |
+LL |         let mut t: Tuple;
+   |             ----- binding declared here but left uninitialized
 LL |         t.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly-uninitialized `t`
+   |         ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `u`
+error[E0381]: partially assigned binding `u` isn't fully initialized
   --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:20:9
    |
+LL |         let mut u: Tpair;
+   |             ----- binding declared here but left uninitialized
 LL |         u.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly-uninitialized `u`
+   |         ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `v`
+error[E0381]: partially assigned binding `v` isn't fully initialized
   --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:28:9
    |
+LL |         let mut v: Spair;
+   |             ----- binding declared here but left uninitialized
 LL |         v.x = S(1);
-   |         ^^^^^^^^^^ use of possibly-uninitialized `v`
+   |         ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs
index 660d9e85ef5..50d0c40fdf6 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs
@@ -10,7 +10,7 @@ fn main() {
     {
         let t: Tuple;
         t.0 = S(1);
-        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+        //~^ ERROR E0381
         t.1 = 2;
         println!("{:?} {:?}", t.0, t.1);
     }
@@ -18,7 +18,7 @@ fn main() {
     {
         let u: Tpair;
         u.0 = S(1);
-        //~^ ERROR assign to part of possibly-uninitialized variable: `u` [E0381]
+        //~^ ERROR E0381
         u.1 = 2;
         println!("{:?} {:?}", u.0, u.1);
     }
@@ -26,7 +26,7 @@ fn main() {
     {
         let v: Spair;
         v.x = S(1);
-        //~^ ERROR assign to part of possibly-uninitialized variable: `v` [E0381]
+        //~^ ERROR E0381
         v.y = 2;
         println!("{:?} {:?}", v.x, v.y);
     }
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr
index 5f9c978c342..67a62583057 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr
@@ -1,20 +1,32 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/issue-54499-field-mutation-of-never-init.rs:12:9
    |
+LL |         let t: Tuple;
+   |             - binding declared here but left uninitialized
 LL |         t.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly-uninitialized `t`
+   |         ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `u`
+error[E0381]: partially assigned binding `u` isn't fully initialized
   --> $DIR/issue-54499-field-mutation-of-never-init.rs:20:9
    |
+LL |         let u: Tpair;
+   |             - binding declared here but left uninitialized
 LL |         u.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly-uninitialized `u`
+   |         ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `v`
+error[E0381]: partially assigned binding `v` isn't fully initialized
   --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9
    |
+LL |         let v: Spair;
+   |             - binding declared here but left uninitialized
 LL |         v.x = S(1);
-   |         ^^^^^^^^^^ use of possibly-uninitialized `v`
+   |         ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs
index f8efa8c891e..93ce34d2fe5 100644
--- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs
+++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs
@@ -1,7 +1,7 @@
 fn main() {
     let e: i32;
     match e {
-        //~^ ERROR use of possibly-uninitialized variable
+        //~^ ERROR E0381
         ref u if true => {}
         ref v if true => {
             let tx = 0;
diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr
index 0eca447b551..f5d2eecfa91 100644
--- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr
+++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `e`
+error[E0381]: used binding `e` isn't initialized
   --> $DIR/issue-62107-match-arm-scopes.rs:3:11
    |
+LL |     let e: i32;
+   |         - binding declared here but left uninitialized
 LL |     match e {
-   |           ^ use of possibly-uninitialized `e`
+   |           ^ `e` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields.stderr b/src/test/ui/borrowck/reassignment_immutable_fields.stderr
index f09db378a75..e6b25573e70 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields.stderr
@@ -1,14 +1,22 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/reassignment_immutable_fields.rs:7:5
    |
+LL |     let x: (u32, u32);
+   |         - binding declared here but left uninitialized
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/reassignment_immutable_fields.rs:15:5
    |
+LL |     let x: (u32, u32);
+   |         - binding declared here but left uninitialized
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
index 0eae2c71e4a..a3885b5f5ca 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
@@ -1,8 +1,12 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/reassignment_immutable_fields_overlapping.rs:12:5
    |
+LL |     let x: Foo;
+   |         - binding declared here but left uninitialized
 LL |     x.a = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable
   --> $DIR/reassignment_immutable_fields_overlapping.rs:13:5
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
index f55e1a27f47..49c81adad49 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
@@ -7,11 +7,15 @@ LL |     x = (22, 44);
 LL |     x.0 = 1;
    |     ^^^^^^^ cannot assign
 
-error[E0381]: assign to part of possibly-uninitialized variable: `x`
+error[E0381]: partially assigned binding `x` isn't fully initialized
   --> $DIR/reassignment_immutable_fields_twice.rs:12:5
    |
+LL |     let x: (u32, u32);
+   |         - binding declared here but left uninitialized
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^ `x` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
index 0f288ffa95a..69cf920de94 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
+++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
@@ -6,14 +6,14 @@
 fn test1() {
     let x: !;
     let c1 = || match x { };
-    //~^ ERROR: use of possibly-uninitialized variable: `x`
+    //~^ ERROR E0381
 }
 
 // Should fake read the discriminant and throw an error
 fn test2() {
     let x: !;
     let c2 = || match x { _ => () };
-    //~^ ERROR: borrow of possibly-uninitialized variable: `x`
+    //~^ ERROR E0381
 }
 
 // Testing single variant patterns
@@ -25,7 +25,7 @@ enum SingleVariant {
 fn test3() {
     let variant: !;
     let c = || {
-    //~^ ERROR: borrow of possibly-uninitialized variable: `variant`
+    //~^ ERROR E0381
         match variant {
             SingleVariant::Points(_) => {}
         }
@@ -36,8 +36,7 @@ fn test3() {
 // Should fake read the discriminant and throw an error
 fn test4() {
     let variant: !;
-    let c = || {
-    //~^ ERROR: borrow of possibly-uninitialized variable: `variant`
+    let c = || { //~ ERROR E0381
         match variant {
             SingleVariant::Points(a) => {
                 println!("{:?}", a);
@@ -52,11 +51,9 @@ fn test5() {
     let g: !;
 
     let a = || {
-        match g { };
-        //~^ ERROR: use of possibly-uninitialized variable: `g`
+        match g { }; //~ ERROR E0381
         let c = ||  {
-            match t { };
-            //~^ ERROR: use of possibly-uninitialized variable: `t`
+            match t { }; //~ ERROR E0381
         };
 
         c();
@@ -68,7 +65,7 @@ fn test5() {
 fn test6() {
     let x: u8;
     let c1 = || match x { };
-    //~^ ERROR: use of possibly-uninitialized variable: `x`
+    //~^ ERROR E0381
     //~| ERROR: non-exhaustive patterns: type `u8` is non-empty
 }
 
diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
index e55fb7ce4bb..fea5441ec67 100644
--- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: type `u8` is non-empty
-  --> $DIR/pattern-matching-should-fail.rs:70:23
+  --> $DIR/pattern-matching-should-fail.rs:67:23
    |
 LL |     let c1 = || match x { };
    |                       ^
@@ -12,55 +12,70 @@ LL +         _ => todo!(),
 LL ~     };
    |
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/pattern-matching-should-fail.rs:8:23
    |
+LL |     let x: !;
+   |         - binding declared here but left uninitialized
 LL |     let c1 = || match x { };
-   |                       ^ use of possibly-uninitialized `x`
+   |                       ^ `x` used here but it isn't initialized
 
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/pattern-matching-should-fail.rs:15:14
    |
+LL |     let x: !;
+   |         - binding declared here but left uninitialized
 LL |     let c2 = || match x { _ => () };
    |              ^^       - borrow occurs due to use in closure
    |              |
-   |              use of possibly-uninitialized `x`
+   |              `x` used here but it isn't initialized
 
-error[E0381]: borrow of possibly-uninitialized variable: `variant`
+error[E0381]: used binding `variant` isn't initialized
   --> $DIR/pattern-matching-should-fail.rs:27:13
    |
+LL |     let variant: !;
+   |         ------- binding declared here but left uninitialized
 LL |     let c = || {
-   |             ^^ use of possibly-uninitialized `variant`
+   |             ^^ `variant` used here but it isn't initialized
 LL |
 LL |         match variant {
    |               ------- borrow occurs due to use in closure
 
-error[E0381]: borrow of possibly-uninitialized variable: `variant`
+error[E0381]: used binding `variant` isn't initialized
   --> $DIR/pattern-matching-should-fail.rs:39:13
    |
+LL |     let variant: !;
+   |         ------- binding declared here but left uninitialized
 LL |     let c = || {
-   |             ^^ use of possibly-uninitialized `variant`
-LL |
+   |             ^^ `variant` used here but it isn't initialized
 LL |         match variant {
    |               ------- borrow occurs due to use in closure
 
-error[E0381]: use of possibly-uninitialized variable: `g`
-  --> $DIR/pattern-matching-should-fail.rs:55:15
+error[E0381]: used binding `g` isn't initialized
+  --> $DIR/pattern-matching-should-fail.rs:54:15
    |
+LL |     let g: !;
+   |         - binding declared here but left uninitialized
+...
 LL |         match g { };
-   |               ^ use of possibly-uninitialized `g`
+   |               ^ `g` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `t`
-  --> $DIR/pattern-matching-should-fail.rs:58:19
+error[E0381]: used binding `t` isn't initialized
+  --> $DIR/pattern-matching-should-fail.rs:56:19
    |
+LL |     let t: !;
+   |         - binding declared here but left uninitialized
+...
 LL |             match t { };
-   |                   ^ use of possibly-uninitialized `t`
+   |                   ^ `t` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `x`
-  --> $DIR/pattern-matching-should-fail.rs:70:23
+error[E0381]: used binding `x` isn't initialized
+  --> $DIR/pattern-matching-should-fail.rs:67:23
    |
+LL |     let x: u8;
+   |         - binding declared here but left uninitialized
 LL |     let c1 = || match x { };
-   |                       ^ use of possibly-uninitialized `x`
+   |                       ^ `x` used here but it isn't initialized
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs b/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs
index bb5a2f1766f..e64adacac9f 100644
--- a/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs
+++ b/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs
@@ -1,6 +1,5 @@
 struct X<const N: usize = {
-    let s: &'static str; s.len()
-    //~^ ERROR borrow of possibly-uninitialized variable
+    let s: &'static str; s.len() //~ ERROR E0381
 }>;
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr
index 6c25019b0ce..c62f1d1d230 100644
--- a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr
+++ b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr
@@ -1,8 +1,10 @@
-error[E0381]: borrow of possibly-uninitialized variable: `s`
+error[E0381]: used binding `s` isn't initialized
   --> $DIR/const-generic-default-wont-borrowck.rs:2:26
    |
 LL |     let s: &'static str; s.len()
-   |                          ^^^^^^^ use of possibly-uninitialized `*s`
+   |         -                ^^^^^^^ `*s` used here but it isn't initialized
+   |         |
+   |         binding declared here but left uninitialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/issue-78655.rs b/src/test/ui/consts/issue-78655.rs
index b85e6129925..82d2d7c21d8 100644
--- a/src/test/ui/consts/issue-78655.rs
+++ b/src/test/ui/consts/issue-78655.rs
@@ -1,6 +1,6 @@
 const FOO: *const u32 = {
     let x;
-    &x //~ ERROR borrow of possibly-uninitialized variable: `x`
+    &x //~ ERROR E0381
 };
 
 fn main() {
diff --git a/src/test/ui/consts/issue-78655.stderr b/src/test/ui/consts/issue-78655.stderr
index 734266a3453..f5b1123e7f3 100644
--- a/src/test/ui/consts/issue-78655.stderr
+++ b/src/test/ui/consts/issue-78655.stderr
@@ -1,8 +1,10 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/issue-78655.rs:3:5
    |
+LL |     let x;
+   |         - binding declared here but left uninitialized
 LL |     &x
-   |     ^^ use of possibly-uninitialized `x`
+   |     ^^ `x` used here but it isn't initialized
 
 error: could not evaluate constant pattern
   --> $DIR/issue-78655.rs:7:9
diff --git a/src/test/ui/drop/repeat-drop-2.rs b/src/test/ui/drop/repeat-drop-2.rs
index 2e7855328ec..59d5ef20205 100644
--- a/src/test/ui/drop/repeat-drop-2.rs
+++ b/src/test/ui/drop/repeat-drop-2.rs
@@ -9,7 +9,7 @@ const _: [String; 0] = [String::new(); 0];
 
 fn must_be_init() {
     let x: u8;
-    let _ = [x; 0]; //~ ERROR: use of possibly-uninitialized variable: `x`
+    let _ = [x; 0]; //~ ERROR E0381
 }
 
 fn main() {}
diff --git a/src/test/ui/drop/repeat-drop-2.stderr b/src/test/ui/drop/repeat-drop-2.stderr
index cdc58180c37..48fa2bfa975 100644
--- a/src/test/ui/drop/repeat-drop-2.stderr
+++ b/src/test/ui/drop/repeat-drop-2.stderr
@@ -17,11 +17,13 @@ LL | const _: [String; 0] = [String::new(); 0];
    |                        |constants cannot evaluate destructors
    |                        value is dropped here
 
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/repeat-drop-2.rs:12:14
    |
+LL |     let x: u8;
+   |         - binding declared here but left uninitialized
 LL |     let _ = [x; 0];
-   |              ^ use of possibly-uninitialized `x`
+   |              ^ `x` used here but it isn't initialized
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs
index 8b757214203..65d9e6d39ca 100644
--- a/src/test/ui/generator/partial-initialization-across-yield.rs
+++ b/src/test/ui/generator/partial-initialization-across-yield.rs
@@ -9,8 +9,7 @@ struct T(i32, i32);
 fn test_tuple() {
     let _ = || {
         let mut t: (i32, i32);
-        t.0 = 42;
-        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+        t.0 = 42; //~ ERROR E0381
         yield;
         t.1 = 88;
         let _ = t;
@@ -20,8 +19,7 @@ fn test_tuple() {
 fn test_tuple_struct() {
     let _ = || {
         let mut t: T;
-        t.0 = 42;
-        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+        t.0 = 42; //~ ERROR E0381
         yield;
         t.1 = 88;
         let _ = t;
@@ -31,8 +29,7 @@ fn test_tuple_struct() {
 fn test_struct() {
     let _ = || {
         let mut t: S;
-        t.x = 42;
-        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+        t.x = 42; //~ ERROR E0381
         yield;
         t.y = 88;
         let _ = t;
diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr
index 66b86488eae..3f9f1c046ba 100644
--- a/src/test/ui/generator/partial-initialization-across-yield.stderr
+++ b/src/test/ui/generator/partial-initialization-across-yield.stderr
@@ -1,20 +1,32 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
+error[E0381]: partially assigned binding `t` isn't fully initialized
   --> $DIR/partial-initialization-across-yield.rs:12:9
    |
+LL |         let mut t: (i32, i32);
+   |             ----- binding declared here but left uninitialized
 LL |         t.0 = 42;
-   |         ^^^^^^^^ use of possibly-uninitialized `t`
+   |         ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-yield.rs:23:9
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/partial-initialization-across-yield.rs:22:9
    |
+LL |         let mut t: T;
+   |             ----- binding declared here but left uninitialized
 LL |         t.0 = 42;
-   |         ^^^^^^^^ use of possibly-uninitialized `t`
+   |         ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-yield.rs:34:9
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/partial-initialization-across-yield.rs:32:9
    |
+LL |         let mut t: S;
+   |             ----- binding declared here but left uninitialized
 LL |         t.x = 42;
-   |         ^^^^^^^^ use of possibly-uninitialized `t`
+   |         ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/loops/loop-proper-liveness.rs b/src/test/ui/loops/loop-proper-liveness.rs
index b242ec4296d..6546e397785 100644
--- a/src/test/ui/loops/loop-proper-liveness.rs
+++ b/src/test/ui/loops/loop-proper-liveness.rs
@@ -6,7 +6,7 @@ fn test1() {
     'a: loop {
         x = loop { break 'a };
     }
-    println!("{:?}", x); //~ ERROR borrow of possibly-uninitialized variable
+    println!("{:?}", x); //~ ERROR E0381
 }
 
 // test2 and test3 should not fail.
diff --git a/src/test/ui/loops/loop-proper-liveness.stderr b/src/test/ui/loops/loop-proper-liveness.stderr
index 20d5c66a3f2..75041031736 100644
--- a/src/test/ui/loops/loop-proper-liveness.stderr
+++ b/src/test/ui/loops/loop-proper-liveness.stderr
@@ -1,8 +1,11 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/loop-proper-liveness.rs:9:22
    |
+LL |     let x: i32;
+   |         - binding declared here but left uninitialized
+...
 LL |     println!("{:?}", x);
-   |                      ^ use of possibly-uninitialized `x`
+   |                      ^ `x` used here but it isn't initialized
    |
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs b/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs
index c44dd51a5ec..fc7341a563b 100644
--- a/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs
+++ b/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs
@@ -6,7 +6,7 @@ static A: () = {
     //~^ ERROR destructors cannot be evaluated at compile-time
     a[0] = String::new();
     //~^ ERROR destructors cannot be evaluated at compile-time
-    //~| ERROR use of possibly-uninitialized variable
+    //~| ERROR binding `a` isn't initialized
 };
 
 struct B<T>([T; 1]);
diff --git a/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr b/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr
index 80d5fc7ec67..d8154f8d2cb 100644
--- a/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr
+++ b/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr
@@ -16,11 +16,14 @@ LL |     let a: [String; 1];
 LL | };
    | - value is dropped here
 
-error[E0381]: use of possibly-uninitialized variable: `a`
+error[E0381]: used binding `a` isn't initialized
   --> $DIR/drop-elaboration-after-borrowck-error.rs:7:5
    |
+LL |     let a: [String; 1];
+   |         - binding declared here but left uninitialized
+LL |
 LL |     a[0] = String::new();
-   |     ^^^^ use of possibly-uninitialized `a`
+   |     ^^^^ `a` used here but it isn't initialized
 
 error[E0493]: destructors cannot be evaluated at compile-time
   --> $DIR/drop-elaboration-after-borrowck-error.rs:18:9
diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.rs b/src/test/ui/moves/issue-72649-uninit-in-loop.rs
index e6bc4e22ec2..d76b69ecdc8 100644
--- a/src/test/ui/moves/issue-72649-uninit-in-loop.rs
+++ b/src/test/ui/moves/issue-72649-uninit-in-loop.rs
@@ -57,17 +57,17 @@ fn moved_loop_2() {
 
 fn uninit_1() {
     loop {
-        let value: NonCopy;
-        let _used = value; //~ ERROR use of possibly-uninitialized variable: `value`
-        //~^ NOTE use of possibly-uninitialized `value`
+        let value: NonCopy; //~ NOTE declared here
+        let _used = value; //~ ERROR binding `value` isn't initialized
+        //~^ NOTE `value` used here but it isn't initialized
     }
 }
 
 fn uninit_2() {
-    let mut value: NonCopy;
+    let mut value: NonCopy; //~ NOTE declared here
     loop {
-        let _used = value; //~ ERROR use of possibly-uninitialized variable: `value`
-        //~^ NOTE use of possibly-uninitialized `value`
+        let _used = value; //~ ERROR binding `value` isn't initialized
+        //~^ NOTE `value` used here but it isn't initialized
     }
 }
 
diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr
index 076d3dff140..c7373b5be9d 100644
--- a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr
+++ b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr
@@ -40,17 +40,22 @@ LL |     let mut value = NonCopy{};
 LL |         let _used2 = value;
    |                      ^^^^^ value moved here, in previous iteration of loop
 
-error[E0381]: use of possibly-uninitialized variable: `value`
+error[E0381]: used binding `value` isn't initialized
   --> $DIR/issue-72649-uninit-in-loop.rs:61:21
    |
+LL |         let value: NonCopy;
+   |             ----- binding declared here but left uninitialized
 LL |         let _used = value;
-   |                     ^^^^^ use of possibly-uninitialized `value`
+   |                     ^^^^^ `value` used here but it isn't initialized
 
-error[E0381]: use of possibly-uninitialized variable: `value`
+error[E0381]: used binding `value` isn't initialized
   --> $DIR/issue-72649-uninit-in-loop.rs:69:21
    |
+LL |     let mut value: NonCopy;
+   |         --------- binding declared here but left uninitialized
+LL |     loop {
 LL |         let _used = value;
-   |                     ^^^^^ use of possibly-uninitialized `value`
+   |                     ^^^^^ `value` used here but it isn't initialized
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/moves/move-into-dead-array-1.rs b/src/test/ui/moves/move-into-dead-array-1.rs
index 2d0ff585263..0b8d76def87 100644
--- a/src/test/ui/moves/move-into-dead-array-1.rs
+++ b/src/test/ui/moves/move-into-dead-array-1.rs
@@ -11,5 +11,5 @@ fn main() {
 
 fn foo(i: usize) {
     let mut a: [D; 4];
-    a[i] = d();        //~ ERROR use of possibly-uninitialized variable: `a`
+    a[i] = d(); //~ ERROR E0381
 }
diff --git a/src/test/ui/moves/move-into-dead-array-1.stderr b/src/test/ui/moves/move-into-dead-array-1.stderr
index 5f20ccfeddf..344a6bbf0c9 100644
--- a/src/test/ui/moves/move-into-dead-array-1.stderr
+++ b/src/test/ui/moves/move-into-dead-array-1.stderr
@@ -1,8 +1,10 @@
-error[E0381]: use of possibly-uninitialized variable: `a`
+error[E0381]: used binding `a` isn't initialized
   --> $DIR/move-into-dead-array-1.rs:14:5
    |
+LL |     let mut a: [D; 4];
+   |         ----- binding declared here but left uninitialized
 LL |     a[i] = d();
-   |     ^^^^ use of possibly-uninitialized `a`
+   |     ^^^^ `a` used here but it isn't initialized
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/moves/move-of-addr-of-mut.rs b/src/test/ui/moves/move-of-addr-of-mut.rs
index f2f64e43cd2..19fd7028692 100644
--- a/src/test/ui/moves/move-of-addr-of-mut.rs
+++ b/src/test/ui/moves/move-of-addr-of-mut.rs
@@ -5,7 +5,7 @@ struct S;
 
 fn main() {
     let mut x: S;
-    std::ptr::addr_of_mut!(x); //~ borrow of
+    std::ptr::addr_of_mut!(x); //~ ERROR E0381
 
     let y = x; // Should error here if `addr_of_mut` is ever allowed on uninitialized variables
     drop(y);
diff --git a/src/test/ui/moves/move-of-addr-of-mut.stderr b/src/test/ui/moves/move-of-addr-of-mut.stderr
index ce8fb028316..e75f2b1c089 100644
--- a/src/test/ui/moves/move-of-addr-of-mut.stderr
+++ b/src/test/ui/moves/move-of-addr-of-mut.stderr
@@ -1,8 +1,10 @@
-error[E0381]: borrow of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/move-of-addr-of-mut.rs:8:5
    |
+LL |     let mut x: S;
+   |         ----- binding declared here but left uninitialized
 LL |     std::ptr::addr_of_mut!(x);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `x`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ `x` used here but it isn't initialized
    |
    = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs
index ebea6d3d9d1..46a156d2af9 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs
+++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs
@@ -25,14 +25,12 @@ impl Drop for D {
 
 fn cannot_partially_init_adt_with_drop() {
     let d: D;
-    d.x = 10;
-    //~^ ERROR assign of possibly-uninitialized variable: `d` [E0381]
+    d.x = 10; //~ ERROR E0381
 }
 
 fn cannot_partially_init_mutable_adt_with_drop() {
     let mut d: D;
-    d.x = 10;
-    //~^ ERROR assign of possibly-uninitialized variable: `d` [E0381]
+    d.x = 10; //~ ERROR E0381
 }
 
 fn cannot_partially_reinit_adt_with_drop() {
@@ -44,14 +42,12 @@ fn cannot_partially_reinit_adt_with_drop() {
 
 fn cannot_partially_init_inner_adt_via_outer_with_drop() {
     let d: D;
-    d.s.y = 20;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `d` [E0381]
+    d.s.y = 20; //~ ERROR E0381
 }
 
 fn cannot_partially_init_inner_adt_via_mutable_outer_with_drop() {
     let mut d: D;
-    d.s.y = 20;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `d` [E0381]
+    d.s.y = 20; //~ ERROR E0381
 }
 
 fn cannot_partially_reinit_inner_adt_via_outer_with_drop() {
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr
index 1b66e034d37..63f230be7d4 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr
+++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr
@@ -1,17 +1,25 @@
-error[E0381]: assign of possibly-uninitialized variable: `d`
+error[E0381]: assigned binding `d` isn't fully initialized
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5
    |
+LL |     let d: D;
+   |         - binding declared here but left uninitialized
 LL |     d.x = 10;
-   |     ^^^^^^^^ use of possibly-uninitialized `d`
+   |     ^^^^^^^^ `d` assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign of possibly-uninitialized variable: `d`
-  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:34:5
+error[E0381]: assigned binding `d` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:33:5
    |
+LL |     let mut d: D;
+   |         ----- binding declared here but left uninitialized
 LL |     d.x = 10;
-   |     ^^^^^^^^ use of possibly-uninitialized `d`
+   |     ^^^^^^^^ `d` assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign of moved value: `d`
-  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:41:5
+  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:39:5
    |
 LL |     let mut d = D { x: 0, s: S{ y: 0, z: 0 } };
    |         ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait
@@ -20,20 +28,28 @@ LL |     drop(d);
 LL |     d.x = 10;
    |     ^^^^^^^^ value assigned here after move
 
-error[E0381]: assign to part of possibly-uninitialized variable: `d`
-  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:47:5
+error[E0381]: partially assigned binding `d` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5
    |
+LL |     let d: D;
+   |         - binding declared here but left uninitialized
 LL |     d.s.y = 20;
-   |     ^^^^^^^^^^ use of possibly-uninitialized `d.s`
+   |     ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `d`
-  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:53:5
+error[E0381]: partially assigned binding `d` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5
    |
+LL |     let mut d: D;
+   |         ----- binding declared here but left uninitialized
 LL |     d.s.y = 20;
-   |     ^^^^^^^^^^ use of possibly-uninitialized `d.s`
+   |     ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign to part of moved value: `d`
-  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:60:5
+  --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5
    |
 LL |     let mut d = D { x: 0, s: S{ y: 0, z: 0} };
    |         ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
index 1836f766cc7..4cd1e406f94 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.rs
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
@@ -94,15 +94,13 @@ macro_rules! use_part {
 
 fn test_0000_local_fully_init_and_use_struct() {
     let s: S<B>;
-    s.x = 10; s.y = Box::new(20);
-    //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381]
+    s.x = 10; s.y = Box::new(20); //~ ERROR E0381
     use_fully!(struct s);
 }
 
 fn test_0001_local_fully_init_and_use_tuple() {
     let t: T;
-    t.0 = 10; t.1 = Box::new(20);
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    t.0 = 10; t.1 = Box::new(20); //~ ERROR E0381
     use_fully!(tuple t);
 }
 
@@ -122,15 +120,13 @@ fn test_0011_local_fully_reinit_and_use_tuple() {
 
 fn test_0100_local_partial_init_and_use_struct() {
     let s: S<B>;
-    s.x = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381]
+    s.x = 10; //~ ERROR E0381
     use_part!(struct s);
 }
 
 fn test_0101_local_partial_init_and_use_tuple() {
     let t: T;
-    t.0 = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    t.0 = 10; //~ ERROR E0381
     use_part!(tuple t);
 }
 
@@ -150,15 +146,13 @@ fn test_0111_local_partial_reinit_and_use_tuple() {
 
 fn test_0200_local_void_init_and_use_struct() {
     let s: S<Void>;
-    s.x = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381]
+    s.x = 10; //~ ERROR E0381
     use_part!(struct s);
 }
 
 fn test_0201_local_void_init_and_use_tuple() {
     let t: Tvoid;
-    t.0 = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
+    t.0 = 10; //~ ERROR E0381
     use_part!(tuple t);
 }
 
@@ -173,15 +167,13 @@ fn test_0201_local_void_init_and_use_tuple() {
 
 fn test_1000_field_fully_init_and_use_struct() {
     let q: Q<S<B>>;
-    q.r.f.x = 10; q.r.f.y = Box::new(20);
-    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
+    q.r.f.x = 10; q.r.f.y = Box::new(20); //~ ERROR E0381
     use_fully!(struct q.r.f);
 }
 
 fn test_1001_field_fully_init_and_use_tuple() {
     let q: Q<T>;
-    q.r.f.0 = 10; q.r.f.1 = Box::new(20);
-    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
+    q.r.f.0 = 10; q.r.f.1 = Box::new(20); //~ ERROR E0381
     use_fully!(tuple q.r.f);
 }
 
@@ -201,15 +193,13 @@ fn test_1011_field_fully_reinit_and_use_tuple() {
 
 fn test_1100_field_partial_init_and_use_struct() {
     let q: Q<S<B>>;
-    q.r.f.x = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
+    q.r.f.x = 10; //~ ERROR E0381
     use_part!(struct q.r.f);
 }
 
 fn test_1101_field_partial_init_and_use_tuple() {
     let q: Q<T>;
-    q.r.f.0 = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
+    q.r.f.0 = 10; //~ ERROR E0381
     use_part!(tuple q.r.f);
 }
 
@@ -229,15 +219,13 @@ fn test_1111_field_partial_reinit_and_use_tuple() {
 
 fn test_1200_field_void_init_and_use_struct() {
     let mut q: Q<S<Void>>;
-    q.r.f.x = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
+    q.r.f.x = 10; //~ ERROR E0381
     use_part!(struct q.r.f);
 }
 
 fn test_1201_field_void_init_and_use_tuple() {
     let mut q: Q<Tvoid>;
-    q.r.f.0 = 10;
-    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
+    q.r.f.0 = 10; //~ ERROR E0381
     use_part!(tuple q.r.f);
 }
 
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
index 77fa484c21d..947c9e29b45 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
@@ -1,17 +1,25 @@
-error[E0381]: assign to part of possibly-uninitialized variable: `s`
+error[E0381]: partially assigned binding `s` isn't fully initialized
   --> $DIR/issue-21232-partial-init-and-use.rs:97:5
    |
+LL |     let s: S<B>;
+   |         - binding declared here but left uninitialized
 LL |     s.x = 10; s.y = Box::new(20);
-   |     ^^^^^^^^ use of possibly-uninitialized `s`
+   |     ^^^^^^^^ `s` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/issue-21232-partial-init-and-use.rs:104:5
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:103:5
    |
+LL |     let t: T;
+   |         - binding declared here but left uninitialized
 LL |     t.0 = 10; t.1 = Box::new(20);
-   |     ^^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign to part of moved value: `s`
-  --> $DIR/issue-21232-partial-init-and-use.rs:111:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:109:5
    |
 LL |     let mut s: S<B> = S::new(); drop(s);
    |         -----                        - value moved here
@@ -21,7 +29,7 @@ LL |     s.x = 10; s.y = Box::new(20);
    |     ^^^^^^^^ value partially assigned here after move
 
 error[E0382]: assign to part of moved value: `t`
-  --> $DIR/issue-21232-partial-init-and-use.rs:118:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:116:5
    |
 LL |     let mut t: T = (0, Box::new(0)); drop(t);
    |         -----                             - value moved here
@@ -30,20 +38,28 @@ LL |     let mut t: T = (0, Box::new(0)); drop(t);
 LL |     t.0 = 10; t.1 = Box::new(20);
    |     ^^^^^^^^ value partially assigned here after move
 
-error[E0381]: assign to part of possibly-uninitialized variable: `s`
-  --> $DIR/issue-21232-partial-init-and-use.rs:125:5
+error[E0381]: partially assigned binding `s` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:123:5
    |
+LL |     let s: S<B>;
+   |         - binding declared here but left uninitialized
 LL |     s.x = 10;
-   |     ^^^^^^^^ use of possibly-uninitialized `s`
+   |     ^^^^^^^^ `s` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/issue-21232-partial-init-and-use.rs:132:5
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:129:5
    |
+LL |     let t: T;
+   |         - binding declared here but left uninitialized
 LL |     t.0 = 10;
-   |     ^^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign to part of moved value: `s`
-  --> $DIR/issue-21232-partial-init-and-use.rs:139:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:135:5
    |
 LL |     let mut s: S<B> = S::new(); drop(s);
    |         -----                        - value moved here
@@ -53,7 +69,7 @@ LL |     s.x = 10;
    |     ^^^^^^^^ value partially assigned here after move
 
 error[E0382]: assign to part of moved value: `t`
-  --> $DIR/issue-21232-partial-init-and-use.rs:146:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:142:5
    |
 LL |     let mut t: T = (0, Box::new(0)); drop(t);
    |         -----                             - value moved here
@@ -62,32 +78,48 @@ LL |     let mut t: T = (0, Box::new(0)); drop(t);
 LL |     t.0 = 10;
    |     ^^^^^^^^ value partially assigned here after move
 
-error[E0381]: assign to part of possibly-uninitialized variable: `s`
-  --> $DIR/issue-21232-partial-init-and-use.rs:153:5
+error[E0381]: partially assigned binding `s` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:149:5
    |
+LL |     let s: S<Void>;
+   |         - binding declared here but left uninitialized
 LL |     s.x = 10;
-   |     ^^^^^^^^ use of possibly-uninitialized `s`
+   |     ^^^^^^^^ `s` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `t`
-  --> $DIR/issue-21232-partial-init-and-use.rs:160:5
+error[E0381]: partially assigned binding `t` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:155:5
    |
+LL |     let t: Tvoid;
+   |         - binding declared here but left uninitialized
 LL |     t.0 = 10;
-   |     ^^^^^^^^ use of possibly-uninitialized `t`
+   |     ^^^^^^^^ `t` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `q`
-  --> $DIR/issue-21232-partial-init-and-use.rs:176:5
+error[E0381]: partially assigned binding `q` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:170:5
    |
+LL |     let q: Q<S<B>>;
+   |         - binding declared here but left uninitialized
 LL |     q.r.f.x = 10; q.r.f.y = Box::new(20);
-   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `q`
-  --> $DIR/issue-21232-partial-init-and-use.rs:183:5
+error[E0381]: partially assigned binding `q` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:176:5
    |
+LL |     let q: Q<T>;
+   |         - binding declared here but left uninitialized
 LL |     q.r.f.0 = 10; q.r.f.1 = Box::new(20);
-   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign to part of moved value: `q.r`
-  --> $DIR/issue-21232-partial-init-and-use.rs:190:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:182:5
    |
 LL |     let mut q: Q<S<B>> = Q::new(S::new()); drop(q.r);
    |                                                 --- value moved here
@@ -97,7 +129,7 @@ LL |     q.r.f.x = 10; q.r.f.y = Box::new(20);
    = note: move occurs because `q.r` has type `R<S<Box<u32>>>`, which does not implement the `Copy` trait
 
 error[E0382]: assign to part of moved value: `q.r`
-  --> $DIR/issue-21232-partial-init-and-use.rs:197:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:189:5
    |
 LL |     let mut q: Q<T> = Q::new((0, Box::new(0))); drop(q.r);
    |                                                      --- value moved here
@@ -106,20 +138,28 @@ LL |     q.r.f.0 = 10; q.r.f.1 = Box::new(20);
    |
    = note: move occurs because `q.r` has type `R<(u32, Box<u32>)>`, which does not implement the `Copy` trait
 
-error[E0381]: assign to part of possibly-uninitialized variable: `q`
-  --> $DIR/issue-21232-partial-init-and-use.rs:204:5
+error[E0381]: partially assigned binding `q` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:196:5
    |
+LL |     let q: Q<S<B>>;
+   |         - binding declared here but left uninitialized
 LL |     q.r.f.x = 10;
-   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `q`
-  --> $DIR/issue-21232-partial-init-and-use.rs:211:5
+error[E0381]: partially assigned binding `q` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:202:5
    |
+LL |     let q: Q<T>;
+   |         - binding declared here but left uninitialized
 LL |     q.r.f.0 = 10;
-   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign to part of moved value: `q.r`
-  --> $DIR/issue-21232-partial-init-and-use.rs:218:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:208:5
    |
 LL |     let mut q: Q<S<B>> = Q::new(S::new()); drop(q.r);
    |                                                 --- value moved here
@@ -129,7 +169,7 @@ LL |     q.r.f.x = 10;
    = note: move occurs because `q.r` has type `R<S<Box<u32>>>`, which does not implement the `Copy` trait
 
 error[E0382]: assign to part of moved value: `q.r`
-  --> $DIR/issue-21232-partial-init-and-use.rs:225:5
+  --> $DIR/issue-21232-partial-init-and-use.rs:215:5
    |
 LL |     let mut q: Q<T> = Q::new((0, Box::new(0))); drop(q.r);
    |                                                      --- value moved here
@@ -138,20 +178,28 @@ LL |     q.r.f.0 = 10;
    |
    = note: move occurs because `q.r` has type `R<(u32, Box<u32>)>`, which does not implement the `Copy` trait
 
-error[E0381]: assign to part of possibly-uninitialized variable: `q`
-  --> $DIR/issue-21232-partial-init-and-use.rs:232:5
+error[E0381]: partially assigned binding `q` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:222:5
    |
+LL |     let mut q: Q<S<Void>>;
+   |         ----- binding declared here but left uninitialized
 LL |     q.r.f.x = 10;
-   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
-error[E0381]: assign to part of possibly-uninitialized variable: `q`
-  --> $DIR/issue-21232-partial-init-and-use.rs:239:5
+error[E0381]: partially assigned binding `q` isn't fully initialized
+  --> $DIR/issue-21232-partial-init-and-use.rs:228:5
    |
+LL |     let mut q: Q<Tvoid>;
+   |         ----- binding declared here but left uninitialized
 LL |     q.r.f.0 = 10;
-   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized
+   |
+   = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit`
 
 error[E0382]: assign to part of moved value: `c`
-  --> $DIR/issue-21232-partial-init-and-use.rs:257:13
+  --> $DIR/issue-21232-partial-init-and-use.rs:245:13
    |
 LL |     let mut c = (1, "".to_owned());
    |         ----- move occurs because `c` has type `(i32, String)`, which does not implement the `Copy` trait
@@ -162,7 +210,7 @@ LL |             c.0 = 2;
    |             ^^^^^^^ value partially assigned here after move
 
 error[E0382]: assign to part of moved value: `c`
-  --> $DIR/issue-21232-partial-init-and-use.rs:267:13
+  --> $DIR/issue-21232-partial-init-and-use.rs:255:13
    |
 LL |     let mut c = (1, (1, "".to_owned()));
    |         ----- move occurs because `c` has type `(i32, (i32, String))`, which does not implement the `Copy` trait
@@ -173,7 +221,7 @@ LL |             (c.1).0 = 2;
    |             ^^^^^^^^^^^ value partially assigned here after move
 
 error[E0382]: assign to part of moved value: `c.1`
-  --> $DIR/issue-21232-partial-init-and-use.rs:275:13
+  --> $DIR/issue-21232-partial-init-and-use.rs:263:13
    |
 LL |         c2 => {
    |         -- value moved here
diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs
index 2e6d675fb64..252f7f8ba07 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.rs
+++ b/src/test/ui/nll/match-cfg-fake-edges.rs
@@ -18,7 +18,7 @@ fn guard_may_be_skipped(y: i32) {
     match y {
         _ if { x = 2; true } => 1,
         _ if {
-            x; //~ ERROR use of possibly-uninitialized variable: `x`
+            x; //~ ERROR E0381
             false
         } => 2,
         _ => 3,
diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr
index 4b3817929fd..250aa482e5c 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.stderr
+++ b/src/test/ui/nll/match-cfg-fake-edges.stderr
@@ -1,8 +1,14 @@
-error[E0381]: use of possibly-uninitialized variable: `x`
+error[E0381]: used binding `x` isn't initialized
   --> $DIR/match-cfg-fake-edges.rs:21:13
    |
+LL |     let x;
+   |         - binding declared here but left uninitialized
+...
+LL |         _ if { x = 2; true } => 1,
+   |                ----- binding initialized here in some conditions
+LL |         _ if {
 LL |             x;
-   |             ^ use of possibly-uninitialized `x`
+   |             ^ `x` used here but it isn't initialized
 
 error[E0382]: use of moved value: `x`
   --> $DIR/match-cfg-fake-edges.rs:35:13
diff --git a/src/test/ui/nll/match-on-borrowed.stderr b/src/test/ui/nll/match-on-borrowed.stderr
index 2121b59b02d..664f36f695c 100644
--- a/src/test/ui/nll/match-on-borrowed.stderr
+++ b/src/test/ui/nll/match-on-borrowed.stderr
@@ -33,11 +33,13 @@ LL |     match t {
 LL |     x;
    |     - borrow later used here
 
-error[E0381]: use of possibly-uninitialized variable: `n`
+error[E0381]: used binding `n` isn't initialized
   --> $DIR/match-on-borrowed.rs:93:11
    |
+LL |     let n: Never;
+   |         - binding declared here but left uninitialized
 LL |     match n {}
-   |           ^ use of possibly-uninitialized `n`
+   |           ^ `n` used here but it isn't initialized
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs
index a7e108d72d1..e0dded15217 100644
--- a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs
@@ -1,19 +1,19 @@
 fn and_chain() {
     let z;
     if true && { z = 3; true} && z == 3 {}
-    //~^ ERROR use of possibly-uninitialized
+    //~^ ERROR E0381
 }
 
 fn and_chain_2() {
     let z;
     true && { z = 3; true} && z == 3;
-    //~^ ERROR use of possibly-uninitialized
+    //~^ ERROR E0381
 }
 
 fn or_chain() {
     let z;
     if false || { z = 3; false} || z == 3 {}
-    //~^ ERROR use of possibly-uninitialized
+    //~^ ERROR E0381
 }
 
 fn main() {
diff --git a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr
index 3c47040cc8c..30d5a6779fc 100644
--- a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr
@@ -1,20 +1,32 @@
-error[E0381]: use of possibly-uninitialized variable: `z`
+error[E0381]: used binding `z` is possibly-uninitialized
   --> $DIR/chains-without-let.rs:3:34
    |
+LL |     let z;
+   |         - binding declared here but left uninitialized
 LL |     if true && { z = 3; true} && z == 3 {}
-   |                                  ^ use of possibly-uninitialized `z`
+   |                  -----           ^ `z` used here but it is possibly-uninitialized
+   |                  |
+   |                  binding initialized here in some conditions
 
-error[E0381]: use of possibly-uninitialized variable: `z`
+error[E0381]: used binding `z` is possibly-uninitialized
   --> $DIR/chains-without-let.rs:9:31
    |
+LL |     let z;
+   |         - binding declared here but left uninitialized
 LL |     true && { z = 3; true} && z == 3;
-   |                               ^ use of possibly-uninitialized `z`
+   |               -----           ^ `z` used here but it is possibly-uninitialized
+   |               |
+   |               binding initialized here in some conditions
 
-error[E0381]: use of possibly-uninitialized variable: `z`
+error[E0381]: used binding `z` is possibly-uninitialized
   --> $DIR/chains-without-let.rs:15:36
    |
+LL |     let z;
+   |         - binding declared here but left uninitialized
 LL |     if false || { z = 3; false} || z == 3 {}
-   |                                    ^ use of possibly-uninitialized `z`
+   |                   -----            ^ `z` used here but it is possibly-uninitialized
+   |                   |
+   |                   binding initialized here in some conditions
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/try-block/try-block-opt-init.rs b/src/test/ui/try-block/try-block-opt-init.rs
index ef10b47fd13..f4f45abcc75 100644
--- a/src/test/ui/try-block/try-block-opt-init.rs
+++ b/src/test/ui/try-block/try-block-opt-init.rs
@@ -12,5 +12,5 @@ pub fn main() {
         Ok::<(), ()>(())?;
         use_val(cfg_res);
     };
-    assert_eq!(cfg_res, 5); //~ ERROR borrow of possibly-uninitialized variable: `cfg_res`
+    assert_eq!(cfg_res, 5); //~ ERROR E0381
 }
diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr
index bd145fd64e7..c397385017f 100644
--- a/src/test/ui/try-block/try-block-opt-init.stderr
+++ b/src/test/ui/try-block/try-block-opt-init.stderr
@@ -1,8 +1,14 @@
-error[E0381]: borrow of possibly-uninitialized variable: `cfg_res`
+error[E0381]: used binding `cfg_res` is possibly-uninitialized
   --> $DIR/try-block-opt-init.rs:15:5
    |
+LL |     let cfg_res;
+   |         ------- binding declared here but left uninitialized
+...
+LL |         cfg_res = 5;
+   |         ----------- binding initialized here in some conditions
+...
 LL |     assert_eq!(cfg_res, 5);
-   |     ^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `cfg_res`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` used here but it is possibly-uninitialized
    |
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs
index b37ec2696de..2764bb563d3 100644
--- a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs
+++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs
@@ -25,5 +25,5 @@ fn main() {
     widget::Widget::new();
     // Error. Widget type is not known to be uninhabited here,
     // so the following code is considered reachable.
-    *y = 2; //~ ERROR use of possibly-uninitialized variable
+    *y = 2; //~ ERROR E0381
 }
diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr
index fb195341168..95c209f47c9 100644
--- a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr
+++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr
@@ -1,8 +1,11 @@
-error[E0381]: use of possibly-uninitialized variable: `y`
+error[E0381]: used binding `y` isn't initialized
   --> $DIR/privately-uninhabited-mir-call.rs:28:5
    |
+LL |     let y: &mut u32;
+   |         - binding declared here but left uninitialized
+...
 LL |     *y = 2;
-   |     ^^^^^^ use of possibly-uninitialized `y`
+   |     ^^^^^^ `y` used here but it isn't initialized
 
 error: aborting due to previous error