diff --git a/Cargo.lock b/Cargo.lock
index ce3c43ea424c8..6f112b5986ff1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3101,7 +3101,6 @@ name = "racer"
 version = "2.2.2"
 dependencies = [
  "bitflags",
- "clap 2.34.0",
  "derive_more",
  "env_logger 0.7.1",
  "humantime 2.0.1",
@@ -3325,7 +3324,7 @@ dependencies = [
  "difference",
  "env_logger 0.9.0",
  "futures 0.3.19",
- "heck 0.3.1",
+ "heck 0.4.0",
  "home",
  "itertools",
  "jsonrpc-core",
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index a1233d62cb02e..b6cf5275394fb 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -31,22 +31,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,
@@ -173,8 +157,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,
@@ -451,9 +434,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,
         );
@@ -476,7 +458,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",)
     }
 
-    fn struct_span_err_with_code<S: Into<MultiSpan>>(
+    pub(crate) fn struct_span_err_with_code<S: Into<MultiSpan>>(
         &self,
         sp: S,
         msg: &str,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 73c0bf16a1f99..2820ac7401b28 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 8ef2974c37232..3e31dc199a084 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -905,6 +905,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/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 200253d575599..c56909ba18b14 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -226,7 +226,7 @@ pub trait PrettyPrinter<'tcx>:
         value.as_ref().skip_binder().print(self)
     }
 
-    fn wrap_binder<T, F: Fn(&T, Self) -> Result<Self, fmt::Error>>(
+    fn wrap_binder<T, F: FnOnce(&T, Self) -> Result<Self, fmt::Error>>(
         self,
         value: &ty::Binder<'tcx, T>,
         f: F,
@@ -773,18 +773,18 @@ pub trait PrettyPrinter<'tcx>:
         def_id: DefId,
         substs: &'tcx ty::List<ty::GenericArg<'tcx>>,
     ) -> Result<Self::Type, Self::Error> {
-        define_scoped_cx!(self);
+        let tcx = self.tcx();
 
         // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
         // by looking up the projections associated with the def_id.
-        let bounds = self.tcx().bound_explicit_item_bounds(def_id);
+        let bounds = tcx.bound_explicit_item_bounds(def_id);
 
         let mut traits = FxIndexMap::default();
         let mut fn_traits = FxIndexMap::default();
         let mut is_sized = false;
 
         for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
-            let predicate = predicate.subst(self.tcx(), substs);
+            let predicate = predicate.subst(tcx, substs);
             let bound_predicate = predicate.kind();
 
             match bound_predicate.skip_binder() {
@@ -792,7 +792,7 @@ pub trait PrettyPrinter<'tcx>:
                     let trait_ref = bound_predicate.rebind(pred.trait_ref);
 
                     // Don't print + Sized, but rather + ?Sized if absent.
-                    if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
+                    if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
                         is_sized = true;
                         continue;
                     }
@@ -801,7 +801,7 @@ pub trait PrettyPrinter<'tcx>:
                 }
                 ty::PredicateKind::Projection(pred) => {
                     let proj_ref = bound_predicate.rebind(pred);
-                    let trait_ref = proj_ref.required_poly_trait_ref(self.tcx());
+                    let trait_ref = proj_ref.required_poly_trait_ref(tcx);
 
                     // Projection type entry -- the def-id for naming, and the ty.
                     let proj_ty = (proj_ref.projection_def_id(), proj_ref.term());
@@ -817,148 +817,155 @@ pub trait PrettyPrinter<'tcx>:
             }
         }
 
+        write!(self, "impl ")?;
+
         let mut first = true;
         // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
         let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized;
 
-        p!("impl");
-
         for (fn_once_trait_ref, entry) in fn_traits {
-            // Get the (single) generic ty (the args) of this FnOnce trait ref.
-            let generics = self.tcx().generics_of(fn_once_trait_ref.def_id());
-            let args =
-                generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs);
-
-            match (entry.return_ty, args[0].expect_ty()) {
-                // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
-                // a return type.
-                (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
-                    let name = if entry.fn_trait_ref.is_some() {
-                        "Fn"
-                    } else if entry.fn_mut_trait_ref.is_some() {
-                        "FnMut"
-                    } else {
-                        "FnOnce"
-                    };
+            write!(self, "{}", if first { "" } else { " + " })?;
+            write!(self, "{}", if paren_needed { "(" } else { "" })?;
 
-                    p!(
-                        write("{}", if first { " " } else { " + " }),
-                        write("{}{}(", if paren_needed { "(" } else { "" }, name)
-                    );
+            self = self.wrap_binder(&fn_once_trait_ref, |trait_ref, mut cx| {
+                define_scoped_cx!(cx);
+                // Get the (single) generic ty (the args) of this FnOnce trait ref.
+                let generics = tcx.generics_of(trait_ref.def_id);
+                let args = generics.own_substs_no_defaults(tcx, trait_ref.substs);
+
+                match (entry.return_ty, args[0].expect_ty()) {
+                    // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
+                    // a return type.
+                    (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
+                        let name = if entry.fn_trait_ref.is_some() {
+                            "Fn"
+                        } else if entry.fn_mut_trait_ref.is_some() {
+                            "FnMut"
+                        } else {
+                            "FnOnce"
+                        };
 
-                    for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() {
-                        if idx > 0 {
-                            p!(", ");
+                        p!(write("{}(", name));
+
+                        for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() {
+                            if idx > 0 {
+                                p!(", ");
+                            }
+                            p!(print(ty));
                         }
-                        p!(print(ty));
-                    }
 
-                    p!(")");
-                    if let Term::Ty(ty) = return_ty.skip_binder() {
-                        if !ty.is_unit() {
-                            p!(" -> ", print(return_ty));
+                        p!(")");
+                        if let Term::Ty(ty) = return_ty.skip_binder() {
+                            if !ty.is_unit() {
+                                p!(" -> ", print(return_ty));
+                            }
                         }
-                    }
-                    p!(write("{}", if paren_needed { ")" } else { "" }));
+                        p!(write("{}", if paren_needed { ")" } else { "" }));
 
-                    first = false;
-                }
-                // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
-                // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
-                _ => {
-                    if entry.has_fn_once {
-                        traits.entry(fn_once_trait_ref).or_default().extend(
-                            // Group the return ty with its def id, if we had one.
-                            entry
-                                .return_ty
-                                .map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)),
-                        );
-                    }
-                    if let Some(trait_ref) = entry.fn_mut_trait_ref {
-                        traits.entry(trait_ref).or_default();
+                        first = false;
                     }
-                    if let Some(trait_ref) = entry.fn_trait_ref {
-                        traits.entry(trait_ref).or_default();
+                    // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
+                    // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
+                    _ => {
+                        if entry.has_fn_once {
+                            traits.entry(fn_once_trait_ref).or_default().extend(
+                                // Group the return ty with its def id, if we had one.
+                                entry
+                                    .return_ty
+                                    .map(|ty| (tcx.lang_items().fn_once_output().unwrap(), ty)),
+                            );
+                        }
+                        if let Some(trait_ref) = entry.fn_mut_trait_ref {
+                            traits.entry(trait_ref).or_default();
+                        }
+                        if let Some(trait_ref) = entry.fn_trait_ref {
+                            traits.entry(trait_ref).or_default();
+                        }
                     }
                 }
-            }
+
+                Ok(cx)
+            })?;
         }
 
         // Print the rest of the trait types (that aren't Fn* family of traits)
         for (trait_ref, assoc_items) in traits {
-            p!(
-                write("{}", if first { " " } else { " + " }),
-                print(trait_ref.skip_binder().print_only_trait_name())
-            );
+            write!(self, "{}", if first { "" } else { " + " })?;
+
+            self = self.wrap_binder(&trait_ref, |trait_ref, mut cx| {
+                define_scoped_cx!(cx);
+                p!(print(trait_ref.print_only_trait_name()));
 
-            let generics = self.tcx().generics_of(trait_ref.def_id());
-            let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs);
+                let generics = tcx.generics_of(trait_ref.def_id);
+                let args = generics.own_substs_no_defaults(tcx, trait_ref.substs);
 
-            if !args.is_empty() || !assoc_items.is_empty() {
-                let mut first = true;
+                if !args.is_empty() || !assoc_items.is_empty() {
+                    let mut first = true;
 
-                for ty in args {
-                    if first {
-                        p!("<");
-                        first = false;
-                    } else {
-                        p!(", ");
+                    for ty in args {
+                        if first {
+                            p!("<");
+                            first = false;
+                        } else {
+                            p!(", ");
+                        }
+                        p!(print(ty));
                     }
-                    p!(print(trait_ref.rebind(*ty)));
-                }
 
-                for (assoc_item_def_id, term) in assoc_items {
-                    // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
-                    // unless we can find out what generator return type it comes from.
-                    let term = if let Some(ty) = term.skip_binder().ty()
-                        && let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind()
-                        && Some(*item_def_id) == self.tcx().lang_items().generator_return()
-                    {
-                        if let ty::Generator(_, substs, _) = substs.type_at(0).kind() {
-                            let return_ty = substs.as_generator().return_ty();
-                            if !return_ty.is_ty_infer() {
-                                return_ty.into()
+                    for (assoc_item_def_id, term) in assoc_items {
+                        // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
+                        // unless we can find out what generator return type it comes from.
+                        let term = if let Some(ty) = term.skip_binder().ty()
+                            && let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind()
+                            && Some(*item_def_id) == tcx.lang_items().generator_return()
+                        {
+                            if let ty::Generator(_, substs, _) = substs.type_at(0).kind() {
+                                let return_ty = substs.as_generator().return_ty();
+                                if !return_ty.is_ty_infer() {
+                                    return_ty.into()
+                                } else {
+                                    continue;
+                                }
                             } else {
                                 continue;
                             }
                         } else {
-                            continue;
-                        }
-                    } else {
-                        term.skip_binder()
-                    };
+                            term.skip_binder()
+                        };
 
-                    if first {
-                        p!("<");
-                        first = false;
-                    } else {
-                        p!(", ");
-                    }
+                        if first {
+                            p!("<");
+                            first = false;
+                        } else {
+                            p!(", ");
+                        }
 
-                    p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).name));
+                        p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
 
-                    match term {
-                        Term::Ty(ty) => {
-                            p!(print(ty))
-                        }
-                        Term::Const(c) => {
-                            p!(print(c));
-                        }
-                    };
-                }
+                        match term {
+                            Term::Ty(ty) => {
+                                p!(print(ty))
+                            }
+                            Term::Const(c) => {
+                                p!(print(c));
+                            }
+                        };
+                    }
 
-                if !first {
-                    p!(">");
+                    if !first {
+                        p!(">");
+                    }
                 }
-            }
 
-            first = false;
+                first = false;
+                Ok(cx)
+            })?;
         }
 
         if !is_sized {
-            p!(write("{}?Sized", if first { " " } else { " + " }));
+            write!(self, "{}?Sized", if first { "" } else { " + " })?;
         } else if first {
-            p!(" Sized");
+            write!(self, "Sized")?;
         }
 
         Ok(self)
@@ -1869,7 +1876,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         self.pretty_in_binder(value)
     }
 
-    fn wrap_binder<T, C: Fn(&T, Self) -> Result<Self, Self::Error>>(
+    fn wrap_binder<T, C: FnOnce(&T, Self) -> Result<Self, Self::Error>>(
         self,
         value: &ty::Binder<'tcx, T>,
         f: C,
@@ -2256,7 +2263,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         Ok(inner)
     }
 
-    pub fn pretty_wrap_binder<T, C: Fn(&T, Self) -> Result<Self, fmt::Error>>(
+    pub fn pretty_wrap_binder<T, C: FnOnce(&T, Self) -> Result<Self, fmt::Error>>(
         self,
         value: &ty::Binder<'tcx, T>,
         f: C,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 81bab0e3513c9..2c43563b10474 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -7,6 +7,7 @@ use super::{
 };
 use crate::maybe_recover_from_interpolated_ty_qpath;
 
+use core::mem;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::Spacing;
@@ -26,7 +27,6 @@ use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::source_map::{self, Span, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Pos};
-use std::mem;
 
 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
 /// dropped into the token stream, which happens while parsing the result of
@@ -2343,7 +2343,9 @@ impl<'a> Parser<'a> {
 
     /// Parses the condition of a `if` or `while` expression.
     fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
-        let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
+        let cond = self.with_let_management(true, |local_self| {
+            local_self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)
+        })?;
 
         if let ExprKind::Let(..) = cond.kind {
             // Remove the last feature gating of a `let` expression since it's stable.
@@ -2356,6 +2358,13 @@ impl<'a> Parser<'a> {
     /// Parses a `let $pat = $expr` pseudo-expression.
     /// The `let` token has already been eaten.
     fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+        if !self.let_expr_allowed {
+            self.struct_span_err(
+                self.prev_token.span,
+                "expected expression, found `let` statement",
+            )
+            .emit();
+        }
         let lo = self.prev_token.span;
         let pat = self.parse_pat_allow_top_alt(
             None,
@@ -2672,6 +2681,8 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
+        // Used to check the `let_chains` and `if_let_guard` features mostly by scaning
+        // `&&` tokens.
         fn check_let_expr(expr: &Expr) -> (bool, bool) {
             match expr.kind {
                 ExprKind::Binary(_, ref lhs, ref rhs) => {
@@ -2694,7 +2705,7 @@ impl<'a> Parser<'a> {
             )?;
             let guard = if this.eat_keyword(kw::If) {
                 let if_span = this.prev_token.span;
-                let cond = this.parse_expr()?;
+                let cond = this.with_let_management(true, |local_this| local_this.parse_expr())?;
                 let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
                 if has_let_expr {
                     if does_not_have_bin_op {
@@ -3256,4 +3267,17 @@ impl<'a> Parser<'a> {
             Ok((res, trailing))
         })
     }
+
+    // Calls `f` with the internal `let_expr_allowed` set to `let_expr_allowed` and then
+    // sets the internal `let_expr_allowed` back to its original value.
+    fn with_let_management<T>(
+        &mut self,
+        let_expr_allowed: bool,
+        f: impl FnOnce(&mut Self) -> T,
+    ) -> T {
+        let last_let_expr_allowed = mem::replace(&mut self.let_expr_allowed, let_expr_allowed);
+        let rslt = f(self);
+        self.let_expr_allowed = last_let_expr_allowed;
+        rslt
+    }
 }
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 6d6667717f0a3..acdf121522ad9 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -147,12 +147,15 @@ pub struct Parser<'a> {
     /// This allows us to recover when the user forget to add braces around
     /// multiple statements in the closure body.
     pub current_closure: Option<ClosureSpans>,
+    /// Used to track where `let`s are allowed. For example, `if true && let 1 = 1` is valid
+    /// but `[1, 2, 3][let _ = ()]` is not.
+    let_expr_allowed: bool,
 }
 
 // This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
 // it doesn't unintentionally get bigger.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Parser<'_>, 328);
+rustc_data_structures::static_assert_size!(Parser<'_>, 336);
 
 /// Stores span information about a closure.
 #[derive(Clone)]
@@ -455,6 +458,7 @@ impl<'a> Parser<'a> {
                 inner_attr_ranges: Default::default(),
             },
             current_closure: None,
+            let_expr_allowed: false,
         };
 
         // Make parser point to the first token.
diff --git a/library/std/src/sys/itron/abi.rs b/library/std/src/sys/itron/abi.rs
index f99ee4fa897ea..5eb14bb7e534b 100644
--- a/library/std/src/sys/itron/abi.rs
+++ b/library/std/src/sys/itron/abi.rs
@@ -30,15 +30,32 @@ pub type ER = int_t;
 /// Error code type, `ID` on success
 pub type ER_ID = int_t;
 
+/// Service call operational mode
+pub type MODE = uint_t;
+
+/// OR waiting condition for an eventflag
+pub const TWF_ORW: MODE = 0x01;
+
+/// Object attributes
+pub type ATR = uint_t;
+
+/// FIFO wait order
+pub const TA_FIFO: ATR = 0;
+/// Only one task is allowed to be in the waiting state for the eventflag
+pub const TA_WSGL: ATR = 0;
+/// The eventflag’s bit pattern is cleared when a task is released from the
+/// waiting state for that eventflag.
+pub const TA_CLR: ATR = 0x04;
+
+/// Bit pattern of an eventflag
+pub type FLGPTN = uint_t;
+
 /// Task or interrupt priority
 pub type PRI = int_t;
 
 /// The special value of `PRI` representing the current task's priority.
 pub const TPRI_SELF: PRI = 0;
 
-/// Object attributes
-pub type ATR = uint_t;
-
 /// Use the priority inheritance protocol
 #[cfg(target_os = "solid_asp3")]
 pub const TA_INHERIT: ATR = 0x02;
@@ -90,6 +107,13 @@ pub struct T_CSEM {
     pub maxsem: uint_t,
 }
 
+#[derive(Clone, Copy)]
+#[repr(C)]
+pub struct T_CFLG {
+    pub flgatr: ATR,
+    pub iflgptn: FLGPTN,
+}
+
 #[derive(Clone, Copy)]
 #[repr(C)]
 pub struct T_CMTX {
@@ -139,6 +163,24 @@ extern "C" {
     pub fn sns_dsp() -> bool_t;
     #[link_name = "__asp3_get_tim"]
     pub fn get_tim(p_systim: *mut SYSTIM) -> ER;
+    #[link_name = "__asp3_acre_flg"]
+    pub fn acre_flg(pk_cflg: *const T_CFLG) -> ER_ID;
+    #[link_name = "__asp3_del_flg"]
+    pub fn del_flg(flgid: ID) -> ER;
+    #[link_name = "__asp3_set_flg"]
+    pub fn set_flg(flgid: ID, setptn: FLGPTN) -> ER;
+    #[link_name = "__asp3_clr_flg"]
+    pub fn clr_flg(flgid: ID, clrptn: FLGPTN) -> ER;
+    #[link_name = "__asp3_wai_flg"]
+    pub fn wai_flg(flgid: ID, waiptn: FLGPTN, wfmode: MODE, p_flgptn: *mut FLGPTN) -> ER;
+    #[link_name = "__asp3_twai_flg"]
+    pub fn twai_flg(
+        flgid: ID,
+        waiptn: FLGPTN,
+        wfmode: MODE,
+        p_flgptn: *mut FLGPTN,
+        tmout: TMO,
+    ) -> ER;
     #[link_name = "__asp3_acre_mtx"]
     pub fn acre_mtx(pk_cmtx: *const T_CMTX) -> ER_ID;
     #[link_name = "__asp3_del_mtx"]
diff --git a/library/std/src/sys/itron/wait_flag.rs b/library/std/src/sys/itron/wait_flag.rs
new file mode 100644
index 0000000000000..e432edd207754
--- /dev/null
+++ b/library/std/src/sys/itron/wait_flag.rs
@@ -0,0 +1,72 @@
+use crate::mem::MaybeUninit;
+use crate::time::Duration;
+
+use super::{
+    abi,
+    error::{expect_success, fail},
+    time::with_tmos,
+};
+
+const CLEAR: abi::FLGPTN = 0;
+const RAISED: abi::FLGPTN = 1;
+
+/// A thread parking primitive that is not susceptible to race conditions,
+/// but provides no atomic ordering guarantees and allows only one `raise` per wait.
+pub struct WaitFlag {
+    flag: abi::ID,
+}
+
+impl WaitFlag {
+    /// Creates a new wait flag.
+    pub fn new() -> WaitFlag {
+        let flag = expect_success(
+            unsafe {
+                abi::acre_flg(&abi::T_CFLG {
+                    flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR,
+                    iflgptn: CLEAR,
+                })
+            },
+            &"acre_flg",
+        );
+
+        WaitFlag { flag }
+    }
+
+    /// Wait for the wait flag to be raised.
+    pub fn wait(&self) {
+        let mut token = MaybeUninit::uninit();
+        expect_success(
+            unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) },
+            &"wai_flg",
+        );
+    }
+
+    /// Wait for the wait flag to be raised or the timeout to occur.
+    ///
+    /// Returns whether the flag was raised (`true`) or the operation timed out (`false`).
+    pub fn wait_timeout(&self, dur: Duration) -> bool {
+        let mut token = MaybeUninit::uninit();
+        let res = with_tmos(dur, |tmout| unsafe {
+            abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout)
+        });
+
+        match res {
+            abi::E_OK => true,
+            abi::E_TMOUT => false,
+            error => fail(error, &"twai_flg"),
+        }
+    }
+
+    /// Raise the wait flag.
+    ///
+    /// Calls to this function should be balanced with the number of successful waits.
+    pub fn raise(&self) {
+        expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg");
+    }
+}
+
+impl Drop for WaitFlag {
+    fn drop(&mut self) {
+        expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg");
+    }
+}
diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs
index 5ffa381f2e50f..2d21e4764fc21 100644
--- a/library/std/src/sys/solid/mod.rs
+++ b/library/std/src/sys/solid/mod.rs
@@ -15,6 +15,7 @@ mod itron {
     pub mod thread;
     pub(super) mod time;
     use super::unsupported;
+    pub mod wait_flag;
 }
 
 pub mod alloc;
@@ -43,6 +44,7 @@ pub mod memchr;
 pub mod thread_local_dtor;
 pub mod thread_local_key;
 pub mod time;
+pub use self::itron::wait_flag;
 
 mod rwlock;
 
diff --git a/library/std/src/sys_common/thread_parker/mod.rs b/library/std/src/sys_common/thread_parker/mod.rs
index 7e8bfb2565e45..cbd7832eb7a4c 100644
--- a/library/std/src/sys_common/thread_parker/mod.rs
+++ b/library/std/src/sys_common/thread_parker/mod.rs
@@ -10,9 +10,10 @@ cfg_if::cfg_if! {
     ))] {
         mod futex;
         pub use futex::Parker;
-    } else if #[cfg(windows)] {
-        pub use crate::sys::thread_parker::Parker;
-    } else if #[cfg(target_family = "unix")] {
+    } else if #[cfg(target_os = "solid_asp3")] {
+        mod wait_flag;
+        pub use wait_flag::Parker;
+    } else if #[cfg(any(windows, target_family = "unix"))] {
         pub use crate::sys::thread_parker::Parker;
     } else {
         mod generic;
diff --git a/library/std/src/sys_common/thread_parker/wait_flag.rs b/library/std/src/sys_common/thread_parker/wait_flag.rs
new file mode 100644
index 0000000000000..6561c186655a5
--- /dev/null
+++ b/library/std/src/sys_common/thread_parker/wait_flag.rs
@@ -0,0 +1,102 @@
+//! A wait-flag-based thread parker.
+//!
+//! Some operating systems provide low-level parking primitives like wait counts,
+//! event flags or semaphores which are not susceptible to race conditions (meaning
+//! the wakeup can occur before the wait operation). To implement the `std` thread
+//! parker on top of these primitives, we only have to ensure that parking is fast
+//! when the thread token is available, the atomic ordering guarantees are maintained
+//! and spurious wakeups are minimized.
+//!
+//! To achieve this, this parker uses an atomic variable with three states: `EMPTY`,
+//! `PARKED` and `NOTIFIED`:
+//! * `EMPTY` means the token has not been made available, but the thread is not
+//!    currently waiting on it.
+//! * `PARKED` means the token is not available and the thread is parked.
+//! * `NOTIFIED` means the token is available.
+//!
+//! `park` and `park_timeout` change the state from `EMPTY` to `PARKED` and from
+//! `NOTIFIED` to `EMPTY`. If the state was `NOTIFIED`, the thread was unparked and
+//! execution can continue without calling into the OS. If the state was `EMPTY`,
+//! the token is not available and the thread waits on the primitive (here called
+//! "wait flag").
+//!
+//! `unpark` changes the state to `NOTIFIED`. If the state was `PARKED`, the thread
+//! is or will be sleeping on the wait flag, so we raise it.
+
+use crate::pin::Pin;
+use crate::sync::atomic::AtomicI8;
+use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release};
+use crate::sys::wait_flag::WaitFlag;
+use crate::time::Duration;
+
+const EMPTY: i8 = 0;
+const PARKED: i8 = -1;
+const NOTIFIED: i8 = 1;
+
+pub struct Parker {
+    state: AtomicI8,
+    wait_flag: WaitFlag,
+}
+
+impl Parker {
+    /// Construct a parker for the current thread. The UNIX parker
+    /// implementation requires this to happen in-place.
+    pub unsafe fn new(parker: *mut Parker) {
+        parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() })
+    }
+
+    // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
+    pub unsafe fn park(self: Pin<&Self>) {
+        match self.state.fetch_sub(1, Acquire) {
+            // NOTIFIED => EMPTY
+            NOTIFIED => return,
+            // EMPTY => PARKED
+            EMPTY => (),
+            _ => panic!("inconsistent park state"),
+        }
+
+        // Avoid waking up from spurious wakeups (these are quite likely, see below).
+        loop {
+            self.wait_flag.wait();
+
+            match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) {
+                Ok(_) => return,
+                Err(PARKED) => (),
+                Err(_) => panic!("inconsistent park state"),
+            }
+        }
+    }
+
+    // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
+    pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
+        match self.state.fetch_sub(1, Acquire) {
+            NOTIFIED => return,
+            EMPTY => (),
+            _ => panic!("inconsistent park state"),
+        }
+
+        self.wait_flag.wait_timeout(dur);
+
+        // Either a wakeup or a timeout occurred. Wakeups may be spurious, as there can be
+        // a race condition when `unpark` is performed between receiving the timeout and
+        // resetting the state, resulting in the eventflag being set unnecessarily. `park`
+        // is protected against this by looping until the token is actually given, but
+        // here we cannot easily tell.
+
+        // Use `swap` to provide acquire ordering.
+        match self.state.swap(EMPTY, Acquire) {
+            NOTIFIED => (),
+            PARKED => (),
+            _ => panic!("inconsistent park state"),
+        }
+    }
+
+    // This implementation doesn't require `Pin`, but other implementations do.
+    pub fn unpark(self: Pin<&Self>) {
+        let state = self.state.swap(NOTIFIED, Release);
+
+        if state == PARKED {
+            self.wait_flag.raise();
+        }
+    }
+}
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index b4b7790eebba1..5d0756d30fb53 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -983,42 +983,51 @@ table,
 	font-weight: normal;
 }
 
-body.blur > :not(#help) {
-	filter: blur(8px);
-	-webkit-filter: blur(8px);
-	opacity: .7;
+.popover {
+	font-size: 1rem;
+	position: absolute;
+	right: 0;
+	z-index: 2;
+	display: block;
+	margin-top: 7px;
+	border-radius: 3px;
+	border: 1px solid;
+	font-size: 1rem;
 }
 
-#help {
-	width: 100%;
-	height: 100vh;
-	position: fixed;
-	top: 0;
-	left: 0;
-	display: flex;
-	justify-content: center;
-	align-items: center;
+/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */
+.popover::before {
+	content: '';
+	position: absolute;
+	right: 11px;
+	border: solid;
+	border-width: 1px 1px 0 0;
+	display: inline-block;
+	padding: 4px;
+	transform: rotate(-45deg);
+	top: -5px;
 }
-#help > div {
-	flex: 0 0 auto;
-	box-shadow: 0 0 6px rgba(0,0,0,.2);
-	width: 550px;
-	height: auto;
-	border: 1px solid;
+
+#help-button .popover {
+	max-width: 600px;
 }
-#help dt {
+
+#help-button .popover::before {
+	right: 48px;
+}
+
+#help-button dt {
 	float: left;
 	clear: left;
 	display: block;
 	margin-right: 0.5rem;
 }
-#help span.top, #help span.bottom {
+#help-button span.top, #help-button span.bottom {
 	text-align: center;
 	display: block;
 	font-size: 1.125rem;
-
 }
-#help span.top {
+#help-button span.top {
 	text-align: center;
 	display: block;
 	margin: 10px 0;
@@ -1026,17 +1035,17 @@ body.blur > :not(#help) {
 	padding-bottom: 4px;
 	margin-bottom: 6px;
 }
-#help span.bottom {
+#help-button span.bottom {
 	clear: both;
 	border-top: 1px solid;
 }
-#help dd { margin: 5px 35px; }
-#help .infos { padding-left: 0; }
-#help h1, #help h2 { margin-top: 0; }
-#help > div div {
+.side-by-side {
+	text-align: initial;
+}
+.side-by-side > div {
 	width: 50%;
 	float: left;
-	padding: 0 20px 20px 17px;;
+	padding: 0 20px 20px 17px;
 }
 
 .item-info .stab {
@@ -1391,7 +1400,7 @@ pre.rust {
 #copy-path {
 	height: 34px;
 }
-#settings-menu > a, #help-button, #copy-path {
+#settings-menu > a, #help-button > button, #copy-path {
 	padding: 5px;
 	width: 33px;
 	border: 1px solid;
@@ -1401,9 +1410,8 @@ pre.rust {
 #settings-menu {
 	padding: 0;
 }
-#settings-menu > a {
+#settings-menu > a, #help-button > button {
 	padding: 5px;
-	width: 100%;
 	height: 100%;
 	display: block;
 }
@@ -1420,7 +1428,7 @@ pre.rust {
 	animation: rotating 2s linear infinite;
 }
 
-#help-button {
+#help-button > button {
 	font-family: "Fira Sans", Arial, sans-serif;
 	text-align: center;
 	/* Rare exception to specifying font sizes in rem. Since this is acting
diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css
index 1cd8e39e03648..e531e6ce6bbde 100644
--- a/src/librustdoc/html/static/css/settings.css
+++ b/src/librustdoc/html/static/css/settings.css
@@ -86,27 +86,6 @@ input:checked + .slider:before {
 	display: block;
 }
 
-div#settings {
-	position: absolute;
-	right: 0;
-	z-index: 1;
-	display: block;
-	margin-top: 7px;
-	border-radius: 3px;
-	border: 1px solid;
-}
 #settings .setting-line {
 	margin: 1.2em 0.6em;
 }
-/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */
-div#settings::before {
-	content: '';
-	position: absolute;
-	right: 11px;
-	border: solid;
-	border-width: 1px 1px 0 0;
-	display: inline-block;
-	padding: 4px;
-	transform: rotate(-45deg);
-	top: -5px;
-}
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 8e0521d9ad6a1..d27294657192c 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -5,7 +5,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
 
 /* General structure and fonts */
 
-body, #settings-menu #settings, #settings-menu #settings::before {
+body, .popover, .popover::before {
 	background-color: #0f1419;
 	color: #c5c5c5;
 }
@@ -567,7 +567,7 @@ kbd {
 	box-shadow: inset 0 -1px 0 #5c6773;
 }
 
-#settings-menu > a, #help-button {
+#settings-menu > a, #help-button > button {
 	border-color: #5c6773;
 	background-color: #0f1419;
 	color: #fff;
@@ -577,7 +577,8 @@ kbd {
 	filter: invert(100);
 }
 
-#settings-menu #settings, #settings-menu #settings::before {
+.popover, .popover::before,
+#help-button span.top, #help-button span.bottom {
 	border-color: #5c6773;
 }
 
@@ -592,7 +593,7 @@ kbd {
 }
 
 #settings-menu > a:hover, #settings-menu > a:focus,
-#help-button:hover, #help-button:focus {
+#help-button > button:hover, #help-button > button:focus {
 	border-color: #e0e0e0;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 071ad006ed350..48079ea2f3041 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -1,4 +1,4 @@
-body, #settings-menu #settings, #settings-menu #settings::before {
+body, .popover, .popover::before {
 	background-color: #353535;
 	color: #ddd;
 }
@@ -442,18 +442,19 @@ kbd {
 	box-shadow: inset 0 -1px 0 #c6cbd1;
 }
 
-#settings-menu > a, #help-button {
+#settings-menu > a, #help-button > button {
 	border-color: #e0e0e0;
 	background: #f0f0f0;
 	color: #000;
 }
 
 #settings-menu > a:hover, #settings-menu > a:focus,
-#help-button:hover, #help-button:focus {
+#help-button > button:hover, #help-button > button:focus {
 	border-color: #ffb900;
 }
 
-#settings-menu #settings, #settings-menu #settings::before {
+.popover, .popover::before,
+#help-button span.top, #help-button span.bottom {
 	border-color: #d2d2d2;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 5c3789bf4630a..f4016be967963 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -1,6 +1,6 @@
 /* General structure and fonts */
 
-body, #settings-menu #settings, #settings-menu #settings::before {
+body, .popover, .popover::before {
 	background-color: white;
 	color: black;
 }
@@ -427,17 +427,18 @@ kbd {
 	box-shadow: inset 0 -1px 0 #c6cbd1;
 }
 
-#settings-menu > a, #help-button {
+#settings-menu > a, #help-button > button {
 	border-color: #e0e0e0;
 	background-color: #fff;
 }
 
 #settings-menu > a:hover, #settings-menu > a:focus,
-#help-button:hover, #help-button:focus {
+#help-button > button:hover, #help-button > button:focus {
 	border-color: #717171;
 }
 
-#settings-menu #settings, #settings-menu #settings::before {
+.popover, .popover::before,
+#help-button span.top, #help-button span.bottom {
 	border-color: #DDDDDD;
 }
 
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index b320db9104612..70dbfd4442540 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -63,6 +63,24 @@ function showMain() {
     removeClass(document.getElementById(MAIN_ID), "hidden");
 }
 
+function elemIsInParent(elem, parent) {
+    while (elem && elem !== document.body) {
+        if (elem === parent) {
+            return true;
+        }
+        elem = elem.parentElement;
+    }
+    return false;
+}
+
+function blurHandler(event, parentElem, hideCallback) {
+    if (!elemIsInParent(document.activeElement, parentElem) &&
+        !elemIsInParent(event.relatedTarget, parentElem)
+    ) {
+        hideCallback();
+    }
+}
+
 (function() {
     window.rootPath = getVar("root-path");
     window.currentCrate = getVar("current-crate");
@@ -104,20 +122,21 @@ const MAIN_ID = "main-content";
 const SETTINGS_BUTTON_ID = "settings-menu";
 const ALTERNATIVE_DISPLAY_ID = "alternative-display";
 const NOT_DISPLAYED_ID = "not-displayed";
+const HELP_BUTTON_ID = "help-button";
 
 function getSettingsButton() {
     return document.getElementById(SETTINGS_BUTTON_ID);
 }
 
+function getHelpButton() {
+    return document.getElementById(HELP_BUTTON_ID);
+}
+
 // Returns the current URL without any query parameter or hash.
 function getNakedUrl() {
     return window.location.href.split("?")[0].split("#")[0];
 }
 
-window.hideSettings = () => {
-    // Does nothing by default.
-};
-
 /**
  * This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode`
  * doesn't have a parent node.
@@ -381,55 +400,16 @@ function loadCss(cssFileName) {
         openParentDetails(document.getElementById(id));
     }
 
-    function getHelpElement(build) {
-        if (build) {
-            buildHelperPopup();
-        }
-        return document.getElementById("help");
-    }
-
-    /**
-     * Show the help popup.
-     *
-     * @param {boolean} display    - Whether to show or hide the popup
-     * @param {Event}   ev         - The event that triggered this call
-     * @param {Element} [help]     - The help element if it already exists
-     */
-    function displayHelp(display, ev, help) {
-        if (display) {
-            help = help ? help : getHelpElement(true);
-            if (hasClass(help, "hidden")) {
-                ev.preventDefault();
-                removeClass(help, "hidden");
-                addClass(document.body, "blur");
-            }
-        } else {
-            // No need to build the help popup if we want to hide it in case it hasn't been
-            // built yet...
-            help = help ? help : getHelpElement(false);
-            if (help && !hasClass(help, "hidden")) {
-                ev.preventDefault();
-                addClass(help, "hidden");
-                removeClass(document.body, "blur");
-            }
-        }
-    }
-
     function handleEscape(ev) {
         searchState.clearInputTimeout();
-        const help = getHelpElement(false);
-        if (help && !hasClass(help, "hidden")) {
-            displayHelp(false, ev, help);
-        } else {
-            switchDisplayedElement(null);
-            if (browserSupportsHistoryApi()) {
-                history.replaceState(null, window.currentCrate + " - Rust",
-                    getNakedUrl() + window.location.hash);
-            }
-            ev.preventDefault();
+        switchDisplayedElement(null);
+        if (browserSupportsHistoryApi()) {
+            history.replaceState(null, window.currentCrate + " - Rust",
+                getNakedUrl() + window.location.hash);
         }
+        ev.preventDefault();
         searchState.defocus();
-        window.hideSettings();
+        window.hidePopoverMenus();
     }
 
     const disableShortcuts = getSettingValue("disable-shortcuts") === "true";
@@ -453,7 +433,6 @@ function loadCss(cssFileName) {
 
             case "s":
             case "S":
-                displayHelp(false, ev);
                 ev.preventDefault();
                 searchState.focus();
                 break;
@@ -465,7 +444,7 @@ function loadCss(cssFileName) {
                 break;
 
             case "?":
-                displayHelp(true, ev);
+                showHelp();
                 break;
 
             default:
@@ -796,9 +775,6 @@ function loadCss(cssFileName) {
             elem.addEventListener("click", f);
         }
     }
-    handleClick("help-button", ev => {
-        displayHelp(true, ev);
-    });
     handleClick(MAIN_ID, () => {
         hideSidebar();
     });
@@ -842,24 +818,16 @@ function loadCss(cssFileName) {
         });
     }
 
-    let buildHelperPopup = () => {
-        const popup = document.createElement("aside");
-        addClass(popup, "hidden");
-        popup.id = "help";
-
-        popup.addEventListener("click", ev => {
-            if (ev.target === popup) {
-                // Clicked the blurred zone outside the help popup; dismiss help.
-                displayHelp(false, ev);
-            }
-        });
+    function helpBlurHandler(event) {
+        blurHandler(event, getHelpButton(), window.hidePopoverMenus);
+    }
 
+    function buildHelpMenu() {
         const book_info = document.createElement("span");
         book_info.className = "top";
         book_info.innerHTML = "You can find more information in \
             <a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
 
-        const container = document.createElement("div");
         const shortcuts = [
             ["?", "Show this help dialog"],
             ["S", "Focus the search field"],
@@ -895,24 +863,85 @@ function loadCss(cssFileName) {
         addClass(div_infos, "infos");
         div_infos.innerHTML = "<h2>Search Tricks</h2>" + infos;
 
-        container.appendChild(book_info);
-        container.appendChild(div_shortcuts);
-        container.appendChild(div_infos);
-
         const rustdoc_version = document.createElement("span");
         rustdoc_version.className = "bottom";
         const rustdoc_version_code = document.createElement("code");
         rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version");
         rustdoc_version.appendChild(rustdoc_version_code);
 
+        const container = document.createElement("div");
+        container.className = "popover";
+        container.style.display = "none";
+
+        const side_by_side = document.createElement("div");
+        side_by_side.className = "side-by-side";
+        side_by_side.appendChild(div_shortcuts);
+        side_by_side.appendChild(div_infos);
+
+        container.appendChild(book_info);
+        container.appendChild(side_by_side);
         container.appendChild(rustdoc_version);
 
-        popup.appendChild(container);
-        insertAfter(popup, document.querySelector("main"));
-        // So that it's only built once and then it'll do nothing when called!
-        buildHelperPopup = () => {};
+        const help_button = getHelpButton();
+        help_button.appendChild(container);
+
+        container.onblur = helpBlurHandler;
+        container.onclick = event => {
+            event.preventDefault();
+        };
+        help_button.onblur = helpBlurHandler;
+        help_button.children[0].onblur = helpBlurHandler;
+
+        return container;
+    }
+
+    /**
+     * Hide all the popover menus.
+     */
+    window.hidePopoverMenus = function() {
+        onEachLazy(document.querySelectorAll(".search-container .popover"), elem => {
+            elem.style.display = "none";
+        });
     };
 
+    /**
+     * Returns the help menu element (not the button).
+     *
+     * @param {boolean} buildNeeded - If this argument is `false`, the help menu element won't be
+     *                                built if it doesn't exist.
+     *
+     * @return {HTMLElement}
+     */
+    function getHelpMenu(buildNeeded) {
+        let menu = getHelpButton().querySelector(".popover");
+        if (!menu && buildNeeded) {
+            menu = buildHelpMenu();
+        }
+        return menu;
+    }
+
+    /**
+     * Show the help popup menu.
+     */
+    function showHelp() {
+        const menu = getHelpMenu(true);
+        if (menu.style.display === "none") {
+            menu.style.display = "";
+        }
+    }
+
+    document.querySelector(`#${HELP_BUTTON_ID} > button`).addEventListener("click", event => {
+        const target = event.target;
+        if (target.tagName !== "BUTTON" || target.parentElement.id !== HELP_BUTTON_ID) {
+            return;
+        }
+        const menu = getHelpMenu(true);
+        const shouldShowHelp = menu.style.display === "none";
+        if (shouldShowHelp) {
+            showHelp();
+        }
+    });
+
     setMobileTopbar();
     addSidebarItems();
     addSidebarCrates();
diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js
index 41bf0ec895580..797b931afc643 100644
--- a/src/librustdoc/html/static/js/settings.js
+++ b/src/librustdoc/html/static/js/settings.js
@@ -1,6 +1,6 @@
 // Local js definitions:
 /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */
-/* global addClass, removeClass, onEach, onEachLazy */
+/* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */
 /* global MAIN_ID, getVar, getSettingsButton */
 
 "use strict";
@@ -209,6 +209,7 @@
         const innerHTML = `<div class="settings">${buildSettingsPageSections(settings)}</div>`;
         const el = document.createElement(elementKind);
         el.id = "settings";
+        el.className = "popover";
         el.innerHTML = innerHTML;
 
         if (isSettingsPage) {
@@ -226,23 +227,8 @@
         settingsMenu.style.display = "";
     }
 
-    function elemIsInParent(elem, parent) {
-        while (elem && elem !== document.body) {
-            if (elem === parent) {
-                return true;
-            }
-            elem = elem.parentElement;
-        }
-        return false;
-    }
-
-    function blurHandler(event) {
-        const settingsButton = getSettingsButton();
-        if (!elemIsInParent(document.activeElement, settingsButton) &&
-            !elemIsInParent(event.relatedTarget, settingsButton)
-        ) {
-            window.hideSettings();
-        }
+    function settingsBlurHandler(event) {
+        blurHandler(event, getSettingsButton(), window.hidePopoverMenus);
     }
 
     if (isSettingsPage) {
@@ -254,26 +240,24 @@
         // We replace the existing "onclick" callback.
         const settingsButton = getSettingsButton();
         const settingsMenu = document.getElementById("settings");
-        window.hideSettings = function() {
-            settingsMenu.style.display = "none";
-        };
         settingsButton.onclick = function(event) {
             if (elemIsInParent(event.target, settingsMenu)) {
                 return;
             }
             event.preventDefault();
-            if (settingsMenu.style.display !== "none") {
-                window.hideSettings();
-            } else {
+            const shouldDisplaySettings = settingsMenu.style.display === "none";
+
+            window.hidePopoverMenus();
+            if (shouldDisplaySettings) {
                 displaySettings();
             }
         };
-        settingsButton.onblur = blurHandler;
-        settingsButton.querySelector("a").onblur = blurHandler;
+        settingsButton.onblur = settingsBlurHandler;
+        settingsButton.querySelector("a").onblur = settingsBlurHandler;
         onEachLazy(settingsMenu.querySelectorAll("input"), el => {
-            el.onblur = blurHandler;
+            el.onblur = settingsBlurHandler;
         });
-        settingsMenu.onblur = blurHandler;
+        settingsMenu.onblur = settingsBlurHandler;
     }
 
     // We now wait a bit for the web browser to end re-computing the DOM...
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index c4999e2c74fce..dfb3e4e6a2ccd 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -119,7 +119,9 @@ <h2 class="location"></h2>
                                 spellcheck="false" {# -#}
                                 placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
                                 type="search"> {#- -#}
-                            <button type="button" id="help-button" title="help">?</button> {#- -#}
+                            <div id="help-button" title="help" tabindex="-1"> {#- -#}
+                                <button type="button">?</button> {#- -#}
+                            </div> {#- -#}
                             <div id="settings-menu" tabindex="-1">
                                 <a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
                                     <img width="22" height="22" alt="Change settings" {# -#}
diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml
index 8713bf65c8432..d083b0ae0c931 100644
--- a/src/test/rustdoc-gui/escape-key.goml
+++ b/src/test/rustdoc-gui/escape-key.goml
@@ -21,17 +21,6 @@ wait-for: "#alternative-display #search"
 assert-attribute: ("#main-content", {"class": "content hidden"})
 assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH)
 
-// Now let's check that when the help popup is displayed and we press Escape, it doesn't
-// hide the search results too.
-click: "#help-button"
-assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH])
-assert-attribute: ("#help", {"class": ""})
-press-key: "Escape"
-wait-for: "#alternative-display #search"
-assert-attribute: ("#help", {"class": "hidden"})
-assert-attribute: ("#main-content", {"class": "content hidden"})
-assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH])
-
 // Check that Escape hides the search results when a search result is focused.
 focus: ".search-input"
 assert: ".search-input:focus"
@@ -39,7 +28,6 @@ press-key: "ArrowDown"
 assert-false: ".search-input:focus"
 assert: "#results a:focus"
 press-key: "Escape"
-assert-attribute: ("#help", {"class": "hidden"})
 wait-for: "#not-displayed #search"
 assert-false: "#alternative-display #search"
 assert-attribute: ("#main-content", {"class": "content"})
diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml
new file mode 100644
index 0000000000000..ba2986e969a35
--- /dev/null
+++ b/src/test/rustdoc-gui/pocket-menu.goml
@@ -0,0 +1,72 @@
+// This test ensures that the "pocket menus" are working as expected.
+goto: file://|DOC_PATH|/test_docs/index.html
+// First we check that the help menu doesn't exist yet.
+assert-false: "#help-button .popover"
+// Then we display the help menu.
+click: "#help-button"
+assert: "#help-button .popover"
+assert-css: ("#help-button .popover", {"display": "block"})
+
+// Now we click somewhere else on the page to ensure it is handling the blur event
+// correctly.
+click: ".sidebar"
+assert-css: ("#help-button .popover", {"display": "none"})
+
+// Now we will check that we cannot have two "pocket menus" displayed at the same time.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "block"})
+click: "#settings-menu"
+assert-css: ("#help-button .popover", {"display": "none"})
+assert-css: ("#settings-menu .popover", {"display": "block"})
+
+// Now the other way.
+click: "#help-button"
+assert-css: ("#help-button .popover", {"display": "block"})
+assert-css: ("#settings-menu .popover", {"display": "none"})
+
+// We check the borders color now:
+
+// Ayu theme
+local-storage: {
+    "rustdoc-theme": "ayu",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+    "#help-button .popover",
+    {"display": "block", "border-color": "rgb(92, 103, 115)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Dark theme
+local-storage: {
+    "rustdoc-theme": "dark",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+    "#help-button .popover",
+    {"display": "block", "border-color": "rgb(210, 210, 210)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
+
+// Light theme
+local-storage: {
+    "rustdoc-theme": "light",
+    "rustdoc-use-system-theme": "false",
+}
+reload:
+
+click: "#help-button"
+assert-css: (
+    "#help-button .popover",
+    {"display": "block", "border-color": "rgb(221, 221, 221)"},
+)
+compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"])
+compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"])
diff --git a/src/test/rustdoc-gui/shortcuts.goml b/src/test/rustdoc-gui/shortcuts.goml
index 37a7c1662949d..1f20a0eaa9982 100644
--- a/src/test/rustdoc-gui/shortcuts.goml
+++ b/src/test/rustdoc-gui/shortcuts.goml
@@ -8,7 +8,6 @@ press-key: "Escape"
 assert-false: "input.search-input:focus"
 // We now check for the help popup.
 press-key: "?"
-assert-css: ("#help", {"display": "flex"})
-assert-false: "#help.hidden"
+assert-css: ("#help-button .popover", {"display": "block"})
 press-key: "Escape"
-assert-css: ("#help.hidden", {"display": "none"})
+assert-css: ("#help-button .popover", {"display": "none"})
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 474478f6a88e1..6190e0b52f4e9 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 181ecaf585585..e9c93fea561a8 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/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
index 43b7cb8cece36..e9b76b19dc407 100644
--- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
+++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
@@ -22,7 +22,7 @@ LL |   async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
 LL | |
 LL | | }
    | |_^
-   = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
+   = note: required because it captures the following types: `ResumeTy`, `impl for<'r, 's, 't0> Future<Output = ()>`, `()`
 note: required because it's used within this `async` block
   --> $DIR/issue-70935-complex-spans.rs:23:16
    |
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 24070fe33083c..c4d81bf83a3c4 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 f5991f4bccac9..12c15bf56ce22 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 8a98a4b0f6bb4..7577aee3fb7d6 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 9a510c22c4b1e..6a0eeffb94611 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/backtrace.rs b/src/test/ui/backtrace.rs
index c2d9e222b84a4..01b276d67ed87 100644
--- a/src/test/ui/backtrace.rs
+++ b/src/test/ui/backtrace.rs
@@ -43,6 +43,7 @@ fn expected(fn_name: &str) -> String {
     format!(" backtrace::{}", fn_name)
 }
 
+#[cfg(not(panic = "abort"))]
 fn contains_verbose_expected(s: &str, fn_name: &str) -> bool {
     // HACK(eddyb) work around the fact that verbosely demangled stack traces
     // (from `RUST_BACKTRACE=full`, or, as is the case here, panic-in-panic)
diff --git a/src/test/ui/borrowck/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.stderr
index 40f1aae092dc6..1ed92865da55b 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 f11d44e2217ba..eeb4f05d60c96 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 d2c7473c036b8..7f3d27d6091d8 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 1e7306acaee98..8d13b25a35756 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 578f89df46ce1..e720db1c6961b 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 126d991a51c6e..3abca33a84add 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 b134f5cc2d8e3..23ea1a2de7fc7 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 8ccb21ae8eebf..824f91dbc62c2 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 652d7d3076fbd..2b9b0a190f6c8 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 50edfb6ba2db1..03edf445ee97b 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 bb4d2f06016b9..e009f5913edd0 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 0000000000000..f619c045b250f
--- /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 0000000000000..c08c93f361726
--- /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 f59bcad6f61d7..534d771be1dfa 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 3e9d3d4f6d513..9eafc2c2a86e6 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 c13318b16c2fa..69d450c59891a 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 53b8a6bba2c76..3f0fe291ca250 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 9905e420f948d..e6476b9c1bef7 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 2d1d9bc8fa41d..e8a2fbc91ea64 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 7dd3396c8c2cb..7eb204a0d1672 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 fd8b90eda6032..1e950d6a20def 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 d7ec2ed75c85c..c07957ab13973 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 f01afe1466aef..83a3e3e0e3ae0 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 784eb8cf85b8a..3d08c1b81a79b 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 6c88778ae0e5a..74704b2abfee8 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 d9d20a2a9c148..2a52a3f4e5eb1 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 fe09c8581df0e..7542576d636be 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 81b0b80bf11b5..079cf899e6dbf 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 6c757759f7134..0bc24f1b6932f 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 5e5a8cdf4232b..a43a1936678ff 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 218c4f2de5bc7..d12a482cb69a9 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 8c623356f6c6b..a63ffcff732ee 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 bc74e8e343848..1c916e223175c 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 8e4932142f0db..2cea4392d6adb 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 e9a389657c8fd..e97ce6aa407ed 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 f7f069b81be02..588b1b0c9729c 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 7951a5b1b5d70..6a38a79891970 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 20350d61d5bb6..92c3692bd2f69 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 f2036df3ce92a..744cb14e662b3 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 0ccea49f329bb..c36b9707d2287 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 d99a50df75b8c..c486cb6dd0cd3 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 017b955a39535..5d0ebabb00872 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 effc209e81659..d5566691a8200 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 3cc71e7cece0e..bbe9f22aac307 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 bd9ec5e579ca9..b7ff5f3955ee5 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 d1b396aba8257..459cf1398b750 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 ca5227c98c862..942ed4fc6cabf 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 24897a0f2dc9c..f3289e239818a 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 48e4221470221..7100b713031d2 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 fc144a066bb27..44674febf4973 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 b3ec20711c12b..62a9bdd202055 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 92937a9c5730e..e41c1c55e6024 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 6b3220c7d8591..f49a778eb6bbe 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 a1f8f64725dcd..c45235990c383 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 7043cb3a164e7..17de40d5ba967 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 8d5b39341c109..9a84c6fefae59 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 d6809ee4143b0..c419c5840d9a8 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 e29cf7a1a7519..d436e8ff9096c 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 f031a144443b3..205ea10c90bf0 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 22c6c3964edc1..2a0eba396f144 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 660d9e85ef54e..50d0c40fdf6f5 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 5f9c978c342f6..67a62583057f6 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 f8efa8c891eb3..93ce34d2fe535 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 0eca447b55159..f5d2eecfa91a3 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 f09db378a75b4..e6b25573e7040 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 0eae2c71e4a19..a3885b5f5caea 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 f55e1a27f475e..49c81adad4937 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 0f288ffa95a87..69cf920de9478 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 e55fb7ce4bbe9..fea5441ec673d 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 bb5a2f1766f1b..e64adacac9fd2 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 6c25019b0ceb3..c62f1d1d23061 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 b85e612992549..82d2d7c21d859 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 734266a3453b5..f5b1123e7f343 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 2e7855328ecbf..59d5ef202051a 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 cdc58180c37b4..48fa2bfa975c0 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 8b75721420351..65d9e6d39ca5a 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 66b86488eaec7..3f9f1c046ba4b 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/impl-trait/printing-binder.rs b/src/test/ui/impl-trait/printing-binder.rs
new file mode 100644
index 0000000000000..273b5dcdb0985
--- /dev/null
+++ b/src/test/ui/impl-trait/printing-binder.rs
@@ -0,0 +1,14 @@
+trait Trait<'a> {}
+impl<T> Trait<'_> for T {}
+fn whatever() -> impl for<'a> Trait<'a> + for<'b> Trait<'b> {}
+
+fn whatever2() -> impl for<'c> Fn(&'c ()) {
+    |_: &()| {}
+}
+
+fn main() {
+    let x: u32 = whatever();
+    //~^ ERROR mismatched types
+    let x2: u32 = whatever2();
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/impl-trait/printing-binder.stderr b/src/test/ui/impl-trait/printing-binder.stderr
new file mode 100644
index 0000000000000..5ffec8af10289
--- /dev/null
+++ b/src/test/ui/impl-trait/printing-binder.stderr
@@ -0,0 +1,31 @@
+error[E0308]: mismatched types
+  --> $DIR/printing-binder.rs:10:18
+   |
+LL | fn whatever() -> impl for<'a> Trait<'a> + for<'b> Trait<'b> {}
+   |                  ------------------------------------------ the found opaque type
+...
+LL |     let x: u32 = whatever();
+   |            ---   ^^^^^^^^^^ expected `u32`, found opaque type
+   |            |
+   |            expected due to this
+   |
+   = note:     expected type `u32`
+           found opaque type `impl for<'a> Trait<'a> + for<'b> Trait<'b>`
+
+error[E0308]: mismatched types
+  --> $DIR/printing-binder.rs:12:19
+   |
+LL | fn whatever2() -> impl for<'c> Fn(&'c ()) {
+   |                   ----------------------- the found opaque type
+...
+LL |     let x2: u32 = whatever2();
+   |             ---   ^^^^^^^^^^^ expected `u32`, found opaque type
+   |             |
+   |             expected due to this
+   |
+   = note:     expected type `u32`
+           found opaque type `impl for<'c> Fn(&'c ())`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/loops/loop-proper-liveness.rs b/src/test/ui/loops/loop-proper-liveness.rs
index b242ec4296d66..6546e397785ca 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 20d5c66a3f205..7504103173652 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 c44dd51a5ec86..fc7341a563bb2 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 80d5fc7ec672c..d8154f8d2cbc4 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/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs
index d2bbb4f110114..635050f376c8a 100644
--- a/src/test/ui/mir/issue-92893.rs
+++ b/src/test/ui/mir/issue-92893.rs
@@ -1,6 +1,7 @@
 struct Bug<A = [(); (let a = (), 1).1]> {
     //~^ `let` expressions are not supported here
-    //~^^ `let` expressions in this position are unstable [E0658]
+    //~| `let` expressions in this position are unstable [E0658]
+    //~| expected expression, found `let` statement
     a: A
 }
 
diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr
index 063b5d66feb45..4a0fcce31d7c7 100644
--- a/src/test/ui/mir/issue-92893.stderr
+++ b/src/test/ui/mir/issue-92893.stderr
@@ -1,3 +1,9 @@
+error: expected expression, found `let` statement
+  --> $DIR/issue-92893.rs:1:22
+   |
+LL | struct Bug<A = [(); (let a = (), 1).1]> {
+   |                      ^^^
+
 error: `let` expressions are not supported here
   --> $DIR/issue-92893.rs:1:22
    |
@@ -15,6 +21,6 @@ LL | struct Bug<A = [(); (let a = (), 1).1]> {
    = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
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 e6bc4e22ec22c..d76b69ecdc8bb 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 076d3dff14086..c7373b5be9d8d 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 2d0ff58526393..0b8d76def872c 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 5f20ccfeddf48..344a6bbf0c92c 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 f2f64e43cd2de..19fd7028692d4 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 ce8fb0283165c..e75f2b1c0894c 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 ebea6d3d9d1ea..46a156d2af9ee 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 1b66e034d3785..63f230be7d4b3 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 1836f766cc7ef..4cd1e406f9440 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 77fa484c21d7e..947c9e29b4508 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 2e6d675fb641e..252f7f8ba07cf 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 4b3817929fd84..250aa482e5c67 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 2121b59b02da3..664f36f695cf3 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-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
index 4a36515b99128..bb1aff70d8995 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
@@ -58,8 +58,10 @@ fn _macros() {
     }
     use_expr!((let 0 = 1 && 0 == 0));
     //~^ ERROR `let` expressions in this position are unstable
+    //~| ERROR expected expression, found `let` statement
     use_expr!((let 0 = 1));
     //~^ ERROR `let` expressions in this position are unstable
+    //~| ERROR expected expression, found `let` statement
     match () {
         #[cfg(FALSE)]
         () if let 0 = 1 => {}
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index 8d93fb87f7ad1..370a57318fdd0 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -1,5 +1,17 @@
+error: expected expression, found `let` statement
+  --> $DIR/feature-gate.rs:59:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/feature-gate.rs:62:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+
 error: no rules expected the token `let`
-  --> $DIR/feature-gate.rs:69:15
+  --> $DIR/feature-gate.rs:71:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -58,7 +70,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`
 
 error[E0658]: `if let` guards are experimental
-  --> $DIR/feature-gate.rs:65:12
+  --> $DIR/feature-gate.rs:67:12
    |
 LL |         () if let 0 = 1 => {}
    |            ^^^^^^^^^^^^
@@ -203,7 +215,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:61:16
+  --> $DIR/feature-gate.rs:62:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
@@ -211,6 +223,6 @@ LL |     use_expr!((let 0 = 1));
    = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
-error: aborting due to 23 previous errors
+error: aborting due to 25 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
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 a7e108d72d1ff..e0dded1521760 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 3c47040cc8c24..30d5a6779fcd7 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/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
index 1bd8b74240eac..36b730505c29e 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -81,9 +81,11 @@ fn _macros() {
     use_expr!((let 0 = 1 && 0 == 0));
     //~^ ERROR `let` expressions are not supported here
     //~| ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
     use_expr!((let 0 = 1));
     //~^ ERROR `let` expressions are not supported here
     //~| ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
 }
 
 fn nested_within_if_expr() {
@@ -147,7 +149,8 @@ fn nested_within_if_expr() {
     //~| ERROR mismatched types
     //~| ERROR mismatched types
 
-    if let true = let true = true {} //~ ERROR `let` expressions are not supported here
+    if let true = let true = true {}
+    //~^ ERROR `let` expressions are not supported here
 }
 
 fn nested_within_while_expr() {
@@ -211,7 +214,8 @@ fn nested_within_while_expr() {
     //~| ERROR mismatched types
     //~| ERROR mismatched types
 
-    while let true = let true = true {} //~ ERROR `let` expressions are not supported here
+    while let true = let true = true {}
+    //~^ ERROR `let` expressions are not supported here
 }
 
 fn not_error_because_clarified_intent() {
@@ -225,45 +229,85 @@ fn not_error_because_clarified_intent() {
 }
 
 fn outside_if_and_while_expr() {
-    &let 0 = 0; //~ ERROR `let` expressions are not supported here
+    &let 0 = 0;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
 
-    !let 0 = 0; //~ ERROR `let` expressions are not supported here
-    *let 0 = 0; //~ ERROR `let` expressions are not supported here
-    //~^ ERROR type `bool` cannot be dereferenced
-    -let 0 = 0; //~ ERROR `let` expressions are not supported here
-    //~^ ERROR cannot apply unary operator `-` to type `bool`
+    !let 0 = 0;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
+    *let 0 = 0;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR type `bool` cannot be dereferenced
+    //~| ERROR expected expression, found `let` statement
+    -let 0 = 0;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR cannot apply unary operator `-` to type `bool`
+    //~| ERROR expected expression, found `let` statement
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         let 0 = 0?;
         //~^ ERROR the `?` operator can only be applied to values that implement `Try`
         Ok(())
     }
-    (let 0 = 0)?; //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the `?` operator can only be used in a function that returns `Result`
+    (let 0 = 0)?;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR the `?` operator can only be used in a function that returns `Result`
     //~| ERROR the `?` operator can only be applied to values that implement `Try`
+    //~| ERROR expected expression, found `let` statement
 
-    true || let 0 = 0; //~ ERROR `let` expressions are not supported here
-    (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
-    true && (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
+    true || let 0 = 0;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
+    (true || let 0 = 0);
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
+    true && (true || let 0 = 0);
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
 
     let mut x = true;
-    x = let 0 = 0; //~ ERROR `let` expressions are not supported here
+    x = let 0 = 0;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
 
-    true..(let 0 = 0); //~ ERROR `let` expressions are not supported here
-    ..(let 0 = 0); //~ ERROR `let` expressions are not supported here
-    (let 0 = 0)..; //~ ERROR `let` expressions are not supported here
+    true..(let 0 = 0);
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
+    ..(let 0 = 0);
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
+    (let 0 = 0)..;
+    //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
 
     (let Range { start: _, end: _ } = true..true || false);
     //~^ ERROR `let` expressions are not supported here
     //~| ERROR mismatched types
+    //~| ERROR expected expression, found `let` statement
 
     (let true = let true = true);
     //~^ ERROR `let` expressions are not supported here
+    //~| ERROR expected expression, found `let` statement
+    //~| ERROR expected expression, found `let` statement
+
+    {
+        #[cfg(FALSE)]
+        let x = true && let y = 1;
+        //~^ ERROR expected expression, found `let` statement
+    }
+
+    #[cfg(FALSE)]
+    {
+        [1, 2, 3][let _ = ()]
+        //~^ ERROR expected expression, found `let` statement
+    }
 
     // Check function tail position.
     &let 0 = 0
     //~^ ERROR `let` expressions are not supported here
     //~| ERROR mismatched types
+    //~| ERROR expected expression, found `let` statement
 }
 
 // Let's make sure that `let` inside const generic arguments are considered.
@@ -335,4 +379,14 @@ fn with_parenthesis() {
     let fun = || true;
     if let true = (true && fun()) && (true) {
     }
+
+    #[cfg(FALSE)]
+    let x = (true && let y = 1);
+    //~^ ERROR expected expression, found `let` statement
+
+    #[cfg(FALSE)]
+    {
+        ([1, 2, 3][let _ = ()])
+        //~^ ERROR expected expression, found `let` statement
+    }
 }
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index f7f39bd0b9a07..5cf06cf4b27cd 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -1,5 +1,113 @@
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:232:6
+   |
+LL |     &let 0 = 0;
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:236:6
+   |
+LL |     !let 0 = 0;
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:239:6
+   |
+LL |     *let 0 = 0;
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:243:6
+   |
+LL |     -let 0 = 0;
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:253:6
+   |
+LL |     (let 0 = 0)?;
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:259:13
+   |
+LL |     true || let 0 = 0;
+   |             ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:262:14
+   |
+LL |     (true || let 0 = 0);
+   |              ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:265:22
+   |
+LL |     true && (true || let 0 = 0);
+   |                      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:270:9
+   |
+LL |     x = let 0 = 0;
+   |         ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:274:12
+   |
+LL |     true..(let 0 = 0);
+   |            ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:277:8
+   |
+LL |     ..(let 0 = 0);
+   |        ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:280:6
+   |
+LL |     (let 0 = 0)..;
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:284:6
+   |
+LL |     (let Range { start: _, end: _ } = true..true || false);
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:289:6
+   |
+LL |     (let true = let true = true);
+   |      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:289:17
+   |
+LL |     (let true = let true = true);
+   |                 ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:296:25
+   |
+LL |         let x = true && let y = 1;
+   |                         ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:302:19
+   |
+LL |         [1, 2, 3][let _ = ()]
+   |                   ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:307:6
+   |
+LL |     &let 0 = 0
+   |      ^^^
+
 error: expressions must be enclosed in braces to be used as const generic arguments
-  --> $DIR/disallowed-positions.rs:293:9
+  --> $DIR/disallowed-positions.rs:337:9
    |
 LL |         true && let 1 = 1
    |         ^^^^^^^^^^^^^^^^^
@@ -9,6 +117,30 @@ help: enclose the `const` expression in braces
 LL |         { true && let 1 = 1 }
    |         +                   +
 
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:384:22
+   |
+LL |     let x = (true && let y = 1);
+   |                      ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:389:20
+   |
+LL |         ([1, 2, 3][let _ = ()])
+   |                    ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:81:16
+   |
+LL |     use_expr!((let 0 = 1 && 0 == 0));
+   |                ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/disallowed-positions.rs:85:16
+   |
+LL |     use_expr!((let 0 = 1));
+   |                ^^^
+
 error: `let` expressions are not supported here
   --> $DIR/disallowed-positions.rs:29:9
    |
@@ -270,33 +402,33 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:84:16
+  --> $DIR/disallowed-positions.rs:85:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:84:16
+  --> $DIR/disallowed-positions.rs:85:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:84:16
+  --> $DIR/disallowed-positions.rs:85:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:84:16
+  --> $DIR/disallowed-positions.rs:85:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:90:9
+  --> $DIR/disallowed-positions.rs:92:9
    |
 LL |     if &let 0 = 0 {}
    |         ^^^^^^^^^
@@ -304,7 +436,7 @@ LL |     if &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:93:9
+  --> $DIR/disallowed-positions.rs:95:9
    |
 LL |     if !let 0 = 0 {}
    |         ^^^^^^^^^
@@ -312,7 +444,7 @@ LL |     if !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:94:9
+  --> $DIR/disallowed-positions.rs:96:9
    |
 LL |     if *let 0 = 0 {}
    |         ^^^^^^^^^
@@ -320,7 +452,7 @@ LL |     if *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:96:9
+  --> $DIR/disallowed-positions.rs:98:9
    |
 LL |     if -let 0 = 0 {}
    |         ^^^^^^^^^
@@ -328,72 +460,72 @@ LL |     if -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:104:9
+  --> $DIR/disallowed-positions.rs:106:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:104:9
+  --> $DIR/disallowed-positions.rs:106:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:108:16
+  --> $DIR/disallowed-positions.rs:110:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:108:13
+  --> $DIR/disallowed-positions.rs:110:13
    |
 LL |     if true || let 0 = 0 {}
    |             ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:109:17
+  --> $DIR/disallowed-positions.rs:111:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:109:14
+  --> $DIR/disallowed-positions.rs:111:14
    |
 LL |     if (true || let 0 = 0) {}
    |              ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:110:25
+  --> $DIR/disallowed-positions.rs:112:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:110:22
+  --> $DIR/disallowed-positions.rs:112:22
    |
 LL |     if true && (true || let 0 = 0) {}
    |                      ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:111:25
+  --> $DIR/disallowed-positions.rs:113:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:111:17
+  --> $DIR/disallowed-positions.rs:113:17
    |
 LL |     if true || (true && let 0 = 0) {}
    |                 ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:114:12
+  --> $DIR/disallowed-positions.rs:116:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^^^^^^^
@@ -401,46 +533,46 @@ LL |     if x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:117:15
+  --> $DIR/disallowed-positions.rs:119:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:117:15
+  --> $DIR/disallowed-positions.rs:119:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:119:11
+  --> $DIR/disallowed-positions.rs:121:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:119:11
+  --> $DIR/disallowed-positions.rs:121:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:121:9
+  --> $DIR/disallowed-positions.rs:123:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:121:9
+  --> $DIR/disallowed-positions.rs:123:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:125:8
+  --> $DIR/disallowed-positions.rs:127:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -448,7 +580,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:129:8
+  --> $DIR/disallowed-positions.rs:131:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -456,7 +588,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:136:8
+  --> $DIR/disallowed-positions.rs:138:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -464,7 +596,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:144:8
+  --> $DIR/disallowed-positions.rs:146:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -472,7 +604,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:150:19
+  --> $DIR/disallowed-positions.rs:152:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^^^^^^^^^^^^^
@@ -480,7 +612,7 @@ LL |     if let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:154:12
+  --> $DIR/disallowed-positions.rs:157:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -488,7 +620,7 @@ LL |     while &let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:157:12
+  --> $DIR/disallowed-positions.rs:160:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -496,7 +628,7 @@ LL |     while !let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:158:12
+  --> $DIR/disallowed-positions.rs:161:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -504,7 +636,7 @@ LL |     while *let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:160:12
+  --> $DIR/disallowed-positions.rs:163:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -512,72 +644,72 @@ LL |     while -let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:168:12
+  --> $DIR/disallowed-positions.rs:171:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:168:12
+  --> $DIR/disallowed-positions.rs:171:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:172:19
+  --> $DIR/disallowed-positions.rs:175:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:172:16
+  --> $DIR/disallowed-positions.rs:175:16
    |
 LL |     while true || let 0 = 0 {}
    |                ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:173:20
+  --> $DIR/disallowed-positions.rs:176:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:173:17
+  --> $DIR/disallowed-positions.rs:176:17
    |
 LL |     while (true || let 0 = 0) {}
    |                 ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:174:28
+  --> $DIR/disallowed-positions.rs:177:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:174:25
+  --> $DIR/disallowed-positions.rs:177:25
    |
 LL |     while true && (true || let 0 = 0) {}
    |                         ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:175:28
+  --> $DIR/disallowed-positions.rs:178:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:175:20
+  --> $DIR/disallowed-positions.rs:178:20
    |
 LL |     while true || (true && let 0 = 0) {}
    |                    ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:178:15
+  --> $DIR/disallowed-positions.rs:181:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^^^^^^^
@@ -585,46 +717,46 @@ LL |     while x = let 0 = 0 {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:181:18
+  --> $DIR/disallowed-positions.rs:184:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:181:18
+  --> $DIR/disallowed-positions.rs:184:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:183:14
+  --> $DIR/disallowed-positions.rs:186:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:183:14
+  --> $DIR/disallowed-positions.rs:186:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:185:12
+  --> $DIR/disallowed-positions.rs:188:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:185:12
+  --> $DIR/disallowed-positions.rs:188:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:189:11
+  --> $DIR/disallowed-positions.rs:192:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -632,7 +764,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:193:11
+  --> $DIR/disallowed-positions.rs:196:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -640,7 +772,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:200:11
+  --> $DIR/disallowed-positions.rs:203:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -648,7 +780,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:208:11
+  --> $DIR/disallowed-positions.rs:211:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -656,7 +788,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:214:22
+  --> $DIR/disallowed-positions.rs:217:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^^^^^^^^^^^^^
@@ -664,7 +796,7 @@ LL |     while let true = let true = true {}
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:228:6
+  --> $DIR/disallowed-positions.rs:232:6
    |
 LL |     &let 0 = 0;
    |      ^^^^^^^^^
@@ -672,7 +804,7 @@ LL |     &let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:230:6
+  --> $DIR/disallowed-positions.rs:236:6
    |
 LL |     !let 0 = 0;
    |      ^^^^^^^^^
@@ -680,7 +812,7 @@ LL |     !let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:231:6
+  --> $DIR/disallowed-positions.rs:239:6
    |
 LL |     *let 0 = 0;
    |      ^^^^^^^^^
@@ -688,7 +820,7 @@ LL |     *let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:233:6
+  --> $DIR/disallowed-positions.rs:243:6
    |
 LL |     -let 0 = 0;
    |      ^^^^^^^^^
@@ -696,59 +828,59 @@ LL |     -let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:241:6
+  --> $DIR/disallowed-positions.rs:253:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:241:6
+  --> $DIR/disallowed-positions.rs:253:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:245:13
+  --> $DIR/disallowed-positions.rs:259:13
    |
 LL |     true || let 0 = 0;
    |             ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:245:10
+  --> $DIR/disallowed-positions.rs:259:10
    |
 LL |     true || let 0 = 0;
    |          ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:246:14
+  --> $DIR/disallowed-positions.rs:262:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:246:11
+  --> $DIR/disallowed-positions.rs:262:11
    |
 LL |     (true || let 0 = 0);
    |           ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:247:22
+  --> $DIR/disallowed-positions.rs:265:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `||` operators are not supported in let chain expressions
-  --> $DIR/disallowed-positions.rs:247:19
+  --> $DIR/disallowed-positions.rs:265:19
    |
 LL |     true && (true || let 0 = 0);
    |                   ^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:250:9
+  --> $DIR/disallowed-positions.rs:270:9
    |
 LL |     x = let 0 = 0;
    |         ^^^^^^^^^
@@ -756,46 +888,46 @@ LL |     x = let 0 = 0;
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:252:12
+  --> $DIR/disallowed-positions.rs:274:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:252:12
+  --> $DIR/disallowed-positions.rs:274:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:253:8
+  --> $DIR/disallowed-positions.rs:277:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:253:8
+  --> $DIR/disallowed-positions.rs:277:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:254:6
+  --> $DIR/disallowed-positions.rs:280:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:254:6
+  --> $DIR/disallowed-positions.rs:280:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:256:6
+  --> $DIR/disallowed-positions.rs:284:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -803,20 +935,20 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:260:6
+  --> $DIR/disallowed-positions.rs:289:6
    |
 LL |     (let true = let true = true);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:260:6
+  --> $DIR/disallowed-positions.rs:289:6
    |
 LL |     (let true = let true = true);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:264:6
+  --> $DIR/disallowed-positions.rs:307:6
    |
 LL |     &let 0 = 0
    |      ^^^^^^^^^
@@ -824,7 +956,7 @@ LL |     &let 0 = 0
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:275:17
+  --> $DIR/disallowed-positions.rs:319:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -832,7 +964,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:279:17
+  --> $DIR/disallowed-positions.rs:323:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -840,7 +972,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:283:17
+  --> $DIR/disallowed-positions.rs:327:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -848,7 +980,7 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:293:17
+  --> $DIR/disallowed-positions.rs:337:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -856,124 +988,124 @@ LL |         true && let 1 = 1
    = note: only supported directly in conditions of `if` and `while` expressions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:302:9
+  --> $DIR/disallowed-positions.rs:346:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:302:9
+  --> $DIR/disallowed-positions.rs:346:9
    |
 LL |     if (let Some(a) = opt && true) {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:306:9
+  --> $DIR/disallowed-positions.rs:350:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:306:9
+  --> $DIR/disallowed-positions.rs:350:9
    |
 LL |     if (let Some(a) = opt) && true {
    |         ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:309:9
+  --> $DIR/disallowed-positions.rs:353:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:309:9
+  --> $DIR/disallowed-positions.rs:353:9
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |         ^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:309:32
+  --> $DIR/disallowed-positions.rs:353:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:309:32
+  --> $DIR/disallowed-positions.rs:353:32
    |
 LL |     if (let Some(a) = opt) && (let Some(b) = a) {
    |                                ^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:316:9
+  --> $DIR/disallowed-positions.rs:360:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:316:9
+  --> $DIR/disallowed-positions.rs:360:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:316:31
+  --> $DIR/disallowed-positions.rs:360:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:316:31
+  --> $DIR/disallowed-positions.rs:360:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && b == 1 {
    |                               ^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:320:9
+  --> $DIR/disallowed-positions.rs:364:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:320:9
+  --> $DIR/disallowed-positions.rs:364:9
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:320:31
+  --> $DIR/disallowed-positions.rs:364:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:320:31
+  --> $DIR/disallowed-positions.rs:364:31
    |
 LL |     if (let Some(a) = opt && (let Some(b) = a)) && true {
    |                               ^^^^^^^^^^^^^^^
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:324:9
+  --> $DIR/disallowed-positions.rs:368:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^
    |
    = note: only supported directly in conditions of `if` and `while` expressions
 note: `let`s wrapped in parentheses are not supported in a context with let chains
-  --> $DIR/disallowed-positions.rs:324:9
+  --> $DIR/disallowed-positions.rs:368:9
    |
 LL |     if (let Some(a) = opt && (true)) && true {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:90:8
+  --> $DIR/disallowed-positions.rs:92:8
    |
 LL |     if &let 0 = 0 {}
    |        ^^^^^^^^^^ expected `bool`, found `&bool`
@@ -985,19 +1117,19 @@ LL +     if let 0 = 0 {}
    |
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:94:8
+  --> $DIR/disallowed-positions.rs:96:8
    |
 LL |     if *let 0 = 0 {}
    |        ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:96:8
+  --> $DIR/disallowed-positions.rs:98:8
    |
 LL |     if -let 0 = 0 {}
    |        ^^^^^^^^^^ cannot apply unary operator `-`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:104:8
+  --> $DIR/disallowed-positions.rs:106:8
    |
 LL |     if (let 0 = 0)? {}
    |        ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1005,7 +1137,7 @@ LL |     if (let 0 = 0)? {}
    = help: the trait `Try` is not implemented for `bool`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
-  --> $DIR/disallowed-positions.rs:104:19
+  --> $DIR/disallowed-positions.rs:106:19
    |
 LL | / fn nested_within_if_expr() {
 LL | |     if &let 0 = 0 {}
@@ -1015,14 +1147,14 @@ LL | |
 LL | |     if (let 0 = 0)? {}
    | |                   ^ cannot use the `?` operator in a function that returns `()`
 ...  |
-LL | |     if let true = let true = true {}
+LL | |
 LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:114:8
+  --> $DIR/disallowed-positions.rs:116:8
    |
 LL |     if x = let 0 = 0 {}
    |        ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -1033,7 +1165,7 @@ LL |     if x == let 0 = 0 {}
    |          ~~
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:117:8
+  --> $DIR/disallowed-positions.rs:119:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1042,7 +1174,7 @@ LL |     if true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:119:8
+  --> $DIR/disallowed-positions.rs:121:8
    |
 LL |     if ..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
@@ -1051,7 +1183,7 @@ LL |     if ..(let 0 = 0) {}
             found struct `RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:121:8
+  --> $DIR/disallowed-positions.rs:123:8
    |
 LL |     if (let 0 = 0).. {}
    |        ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
@@ -1060,7 +1192,7 @@ LL |     if (let 0 = 0).. {}
             found struct `RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:125:12
+  --> $DIR/disallowed-positions.rs:127:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1071,7 +1203,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:125:8
+  --> $DIR/disallowed-positions.rs:127:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1080,7 +1212,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:129:12
+  --> $DIR/disallowed-positions.rs:131:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1091,7 +1223,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:129:8
+  --> $DIR/disallowed-positions.rs:131:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1100,7 +1232,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:136:12
+  --> $DIR/disallowed-positions.rs:138:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1111,20 +1243,20 @@ LL |     if let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:136:41
+  --> $DIR/disallowed-positions.rs:138:41
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |                                         ^^^^^^^ expected `bool`, found closure
    |
    = note: expected type `bool`
-           found closure `[closure@$DIR/disallowed-positions.rs:136:41: 136:48]`
+           found closure `[closure@$DIR/disallowed-positions.rs:138:41: 138:48]`
 help: use parentheses to call this closure
    |
 LL |     if let Range { start: F, end } = F..(|| true)() {}
    |                                         +       +++
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:136:8
+  --> $DIR/disallowed-positions.rs:138:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1133,7 +1265,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:144:12
+  --> $DIR/disallowed-positions.rs:146:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1144,7 +1276,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:144:44
+  --> $DIR/disallowed-positions.rs:146:44
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |                                            ^^^^^^^ expected `bool`, found `&&bool`
@@ -1156,7 +1288,7 @@ LL +     if let Range { start: true, end } = t..false {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:144:8
+  --> $DIR/disallowed-positions.rs:146:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1165,7 +1297,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<bool>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:100:20
+  --> $DIR/disallowed-positions.rs:102:20
    |
 LL |         if let 0 = 0? {}
    |                    ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1173,7 +1305,7 @@ LL |         if let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:154:11
+  --> $DIR/disallowed-positions.rs:157:11
    |
 LL |     while &let 0 = 0 {}
    |           ^^^^^^^^^^ expected `bool`, found `&bool`
@@ -1185,19 +1317,19 @@ LL +     while let 0 = 0 {}
    |
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:158:11
+  --> $DIR/disallowed-positions.rs:161:11
    |
 LL |     while *let 0 = 0 {}
    |           ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:160:11
+  --> $DIR/disallowed-positions.rs:163:11
    |
 LL |     while -let 0 = 0 {}
    |           ^^^^^^^^^^ cannot apply unary operator `-`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:168:11
+  --> $DIR/disallowed-positions.rs:171:11
    |
 LL |     while (let 0 = 0)? {}
    |           ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1205,7 +1337,7 @@ LL |     while (let 0 = 0)? {}
    = help: the trait `Try` is not implemented for `bool`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
-  --> $DIR/disallowed-positions.rs:168:22
+  --> $DIR/disallowed-positions.rs:171:22
    |
 LL | / fn nested_within_while_expr() {
 LL | |     while &let 0 = 0 {}
@@ -1215,14 +1347,14 @@ LL | |
 LL | |     while (let 0 = 0)? {}
    | |                      ^ cannot use the `?` operator in a function that returns `()`
 ...  |
-LL | |     while let true = let true = true {}
+LL | |
 LL | | }
    | |_- this function should return `Result` or `Option` to accept `?`
    |
    = help: the trait `FromResidual<_>` is not implemented for `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:178:11
+  --> $DIR/disallowed-positions.rs:181:11
    |
 LL |     while x = let 0 = 0 {}
    |           ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -1233,7 +1365,7 @@ LL |     while x == let 0 = 0 {}
    |             ~~
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:181:11
+  --> $DIR/disallowed-positions.rs:184:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1242,7 +1374,7 @@ LL |     while true..(let 0 = 0) {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:183:11
+  --> $DIR/disallowed-positions.rs:186:11
    |
 LL |     while ..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo`
@@ -1251,7 +1383,7 @@ LL |     while ..(let 0 = 0) {}
             found struct `RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:185:11
+  --> $DIR/disallowed-positions.rs:188:11
    |
 LL |     while (let 0 = 0).. {}
    |           ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom`
@@ -1260,7 +1392,7 @@ LL |     while (let 0 = 0).. {}
             found struct `RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:189:15
+  --> $DIR/disallowed-positions.rs:192:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1271,7 +1403,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:189:11
+  --> $DIR/disallowed-positions.rs:192:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1280,7 +1412,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:193:15
+  --> $DIR/disallowed-positions.rs:196:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1291,7 +1423,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:193:11
+  --> $DIR/disallowed-positions.rs:196:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1300,7 +1432,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:200:15
+  --> $DIR/disallowed-positions.rs:203:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `fn() -> bool`
@@ -1311,20 +1443,20 @@ LL |     while let Range { start: F, end } = F..|| true {}
                   found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:200:44
+  --> $DIR/disallowed-positions.rs:203:44
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |                                            ^^^^^^^ expected `bool`, found closure
    |
    = note: expected type `bool`
-           found closure `[closure@$DIR/disallowed-positions.rs:200:44: 200:51]`
+           found closure `[closure@$DIR/disallowed-positions.rs:203:44: 203:51]`
 help: use parentheses to call this closure
    |
 LL |     while let Range { start: F, end } = F..(|| true)() {}
    |                                            +       +++
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:200:11
+  --> $DIR/disallowed-positions.rs:203:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1333,7 +1465,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
             found struct `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:208:15
+  --> $DIR/disallowed-positions.rs:211:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this expression has type `&&bool`
@@ -1344,7 +1476,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:208:47
+  --> $DIR/disallowed-positions.rs:211:47
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |                                               ^^^^^^^ expected `bool`, found `&&bool`
@@ -1356,7 +1488,7 @@ LL +     while let Range { start: true, end } = t..false {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:208:11
+  --> $DIR/disallowed-positions.rs:211:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range`
@@ -1365,7 +1497,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
             found struct `std::ops::Range<bool>`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:164:23
+  --> $DIR/disallowed-positions.rs:167:23
    |
 LL |         while let 0 = 0? {}
    |                       ^^ the `?` operator cannot be applied to type `{integer}`
@@ -1373,19 +1505,19 @@ LL |         while let 0 = 0? {}
    = help: the trait `Try` is not implemented for `{integer}`
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:231:5
+  --> $DIR/disallowed-positions.rs:239:5
    |
 LL |     *let 0 = 0;
    |     ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:233:5
+  --> $DIR/disallowed-positions.rs:243:5
    |
 LL |     -let 0 = 0;
    |     ^^^^^^^^^^ cannot apply unary operator `-`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:241:5
+  --> $DIR/disallowed-positions.rs:253:5
    |
 LL |     (let 0 = 0)?;
    |     ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
@@ -1393,12 +1525,12 @@ LL |     (let 0 = 0)?;
    = help: the trait `Try` is not implemented for `bool`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
-  --> $DIR/disallowed-positions.rs:241:16
+  --> $DIR/disallowed-positions.rs:253:16
    |
 LL | / fn outside_if_and_while_expr() {
 LL | |     &let 0 = 0;
 LL | |
-LL | |     !let 0 = 0;
+LL | |
 ...  |
 LL | |     (let 0 = 0)?;
    | |                ^ cannot use the `?` operator in a function that returns `()`
@@ -1410,7 +1542,7 @@ LL | | }
    = help: the trait `FromResidual<_>` is not implemented for `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:256:10
+  --> $DIR/disallowed-positions.rs:284:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this expression has type `bool`
@@ -1421,7 +1553,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
             found struct `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:264:5
+  --> $DIR/disallowed-positions.rs:307:5
    |
 LL | fn outside_if_and_while_expr() {
    |                                - help: try adding a return type: `-> &bool`
@@ -1430,14 +1562,14 @@ LL |     &let 0 = 0
    |     ^^^^^^^^^^ expected `()`, found `&bool`
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/disallowed-positions.rs:237:17
+  --> $DIR/disallowed-positions.rs:249:17
    |
 LL |         let 0 = 0?;
    |                 ^^ the `?` operator cannot be applied to type `{integer}`
    |
    = help: the trait `Try` is not implemented for `{integer}`
 
-error: aborting due to 134 previous errors
+error: aborting due to 156 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0600, E0614.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
index e66caa19ec96b..12befc637c787 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs
@@ -17,6 +17,7 @@ fn main() {
     //~| ERROR `let` expressions are not supported here
     //~| ERROR mismatched types
     //~| ERROR mismatched types
+    //~| ERROR expected expression, found `let` statement
         return;
     };
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
index eea8ed0c9633e..498a112fa9bb3 100644
--- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr
@@ -9,6 +9,12 @@ help: wrap the expression in parentheses
 LL |     let Some(n) = (opt && n == 1) else {
    |                   +             +
 
+error: expected expression, found `let` statement
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:26
+   |
+LL |     let Some(n) = opt && let another = n else {
+   |                          ^^^
+
 error: a `&&` expression cannot be directly assigned in `let...else`
   --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
    |
@@ -21,43 +27,43 @@ LL |     let Some(n) = (opt && let another = n) else {
    |                   +                      +
 
 error: this `if` expression is missing a block after the condition
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:5
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:5
    |
 LL |     if let Some(n) = opt else {
    |     ^^
    |
 help: add a block here
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:25
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:25
    |
 LL |     if let Some(n) = opt else {
    |                         ^
 
 error: this `if` expression is missing a block after the condition
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:5
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:5
    |
 LL |     if let Some(n) = opt && n == 1 else {
    |     ^^
    |
 help: add a block here
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:35
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:35
    |
 LL |     if let Some(n) = opt && n == 1 else {
    |                                   ^
 
 error: this `if` expression is missing a block after the condition
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:5
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:5
    |
 LL |     if let Some(n) = opt && let another = n else {
    |     ^^
    |
 help: add a block here
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:44
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:44
    |
 LL |     if let Some(n) = opt && let another = n else {
    |                                            ^
 
 error: expected `{`, found keyword `else`
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:38:33
    |
 LL |         while let Some(n) = opt else {
    |         ----- ----------------- ^^^^ expected `{`
@@ -66,7 +72,7 @@ LL |         while let Some(n) = opt else {
    |         while parsing the body of this `while` expression
 
 error: expected `{`, found keyword `else`
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:43:43
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:44:43
    |
 LL |         while let Some(n) = opt && n == 1 else {
    |         ----- --------------------------- ^^^^ expected `{`
@@ -75,7 +81,7 @@ LL |         while let Some(n) = opt && n == 1 else {
    |         while parsing the body of this `while` expression
 
 error: expected `{`, found keyword `else`
-  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:49:52
+  --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:50:52
    |
 LL |         while let Some(n) = opt && let another = n else {
    |         ----- ------------------------------------ ^^^^ expected `{`
@@ -131,6 +137,6 @@ LL |     let Some(n) = opt && let another = n else {
    = note: expected type `bool`
               found enum `Option<_>`
 
-error: aborting due to 13 previous errors
+error: aborting due to 14 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
index ac60bc7e57fd4..8771821130848 100644
--- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs
@@ -39,6 +39,7 @@ fn _macros() {
 
     noop_expr!((let 0 = 1));
     //~^ ERROR `let` expressions in this position are unstable [E0658]
+    //~| ERROR expected expression, found `let` statement
 
     macro_rules! use_expr {
         ($e:expr) => {
@@ -48,9 +49,9 @@ fn _macros() {
     }
     #[cfg(FALSE)] (let 0 = 1);
     //~^ ERROR `let` expressions in this position are unstable [E0658]
+    //~| ERROR expected expression, found `let` statement
     use_expr!(let 0 = 1);
     //~^ ERROR no rules expected the token `let`
-    // ^--- FIXME(53667): Consider whether `Let` can be added to `ident_can_begin_expr`.
 }
 
 fn main() {}
diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
index 1eabee47c64ac..bcea8bbaa730b 100644
--- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr
@@ -1,5 +1,17 @@
+error: expected expression, found `let` statement
+  --> $DIR/feature-gate.rs:50:20
+   |
+LL |     #[cfg(FALSE)] (let 0 = 1);
+   |                    ^^^
+
+error: expected expression, found `let` statement
+  --> $DIR/feature-gate.rs:40:17
+   |
+LL |     noop_expr!((let 0 = 1));
+   |                 ^^^
+
 error: no rules expected the token `let`
-  --> $DIR/feature-gate.rs:51:15
+  --> $DIR/feature-gate.rs:53:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -62,7 +74,7 @@ LL |     while let Range { start: _, end: _ } = (true..true) && false {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are unstable
-  --> $DIR/feature-gate.rs:49:20
+  --> $DIR/feature-gate.rs:50:20
    |
 LL |     #[cfg(FALSE)] (let 0 = 1);
    |                    ^^^^^^^^^
@@ -79,6 +91,6 @@ LL |     noop_expr!((let 0 = 1));
    = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
-error: aborting due to 9 previous errors
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
new file mode 100644
index 0000000000000..6cc53a1935b95
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs
@@ -0,0 +1,17 @@
+// check-pass
+// known-bug
+
+#![feature(let_chains)]
+
+fn main() {
+    let _opt = Some(1i32);
+
+    #[cfg(FALSE)]
+    {
+        if let Some(elem) = _opt && {
+            [1, 2, 3][let _ = ()];
+            true
+        } {
+        }
+    }
+}
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 ef10b47fd1305..f4f45abcc75b1 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 bd145fd64e765..c397385017ff4 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 b37ec2696de2f..2764bb563d307 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 fb1953411685e..95c209f47c92a 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
 
diff --git a/src/tools/rls b/src/tools/rls
index 27f4044df03d1..ece09b88c0365 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 27f4044df03d15c7c38a483c3e4635cf4f51807d
+Subproject commit ece09b88c0365947af79c0ffdeea02bc6c1eec25
diff --git a/x.py b/x.py
index 4f64ea9fae8b8..0289056fdcb16 100755
--- a/x.py
+++ b/x.py
@@ -1,5 +1,25 @@
-#!/usr/bin/env python
+#!/usr/bin/env bash
 
+# Modern Linux and macOS systems commonly only have a thing called `python3` and
+# not `python`, while Windows commonly does not have `python3`, so we cannot
+# directly use python in the shebang and have it consistently work. Instead we
+# embed some bash to look for a python to run the rest of the script.
+#
+# On Windows, `py -3` sometimes works. We need to try it first because `python3`
+# sometimes tries to launch the app store on Windows.
+'''':
+for PYTHON in "py -3" python3 python python2; do
+    if command -v $PYTHON >/dev/null; then
+        exec $PYTHON "$0" "$@"
+        break
+    fi
+done
+echo "$0: error: did not find python installed" >&2
+exit 1
+'''
+
+# The rest of this file is Python.
+#
 # This file is only a "symlink" to bootstrap.py, all logic should go there.
 
 import os
@@ -7,11 +27,12 @@
 
 # If this is python2, check if python3 is available and re-execute with that
 # interpreter.
+#
+# `./x.py` would not normally benefit from this because the bash above tries
+# python3 before 2, but this matters if someone ran `python x.py` and their
+# system's `python` is python2.
 if sys.version_info.major < 3:
     try:
-        # On Windows, `py -3` sometimes works.
-        # Try this first, because 'python3' sometimes tries to launch the app
-        # store on Windows
         os.execvp("py", ["py", "-3"] + sys.argv)
     except OSError:
         try: