about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/library_tracking_issue.md4
-rw-r--r--compiler/rustc_borrowck/src/constraint_generation.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/mod.rs51
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs37
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs127
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs48
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs38
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs19
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs160
-rw-r--r--compiler/rustc_const_eval/src/interpret/traits.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs18
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs49
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_driver/src/lib.rs20
-rw-r--r--compiler/rustc_expand/src/build.rs13
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs107
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs8
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs20
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs12
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs2
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs17
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs25
-rw-r--r--compiler/rustc_middle/src/query/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/consts/int.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs14
-rw-r--r--compiler/rustc_passes/src/entry.rs26
-rw-r--r--compiler/rustc_session/src/config.rs5
-rw-r--r--compiler/rustc_session/src/options.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs27
-rw-r--r--compiler/rustc_type_ir/src/lib.rs1
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs27
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs18
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs11
-rw-r--r--compiler/rustc_typeck/src/check/writeback.rs2
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs27
-rw-r--r--library/std/src/net/tcp.rs7
-rw-r--r--src/bootstrap/Cargo.lock102
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/bin/main.rs18
-rw-r--r--src/bootstrap/bin/rustdoc.rs4
-rw-r--r--src/bootstrap/bootstrap.py41
-rw-r--r--src/bootstrap/builder.rs1
-rw-r--r--src/bootstrap/doc.rs34
-rw-r--r--src/bootstrap/lib.rs3
-rw-r--r--src/bootstrap/test.rs9
-rw-r--r--src/bootstrap/util.rs3
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/shared.sh12
-rwxr-xr-xsrc/ci/init_repo.sh83
-rwxr-xr-xsrc/ci/scripts/checkout-submodules.sh72
-rw-r--r--src/librustdoc/clean/utils.rs93
-rw-r--r--src/librustdoc/config.rs22
-rw-r--r--src/librustdoc/html/format.rs12
-rw-r--r--src/librustdoc/html/render/mod.rs4
-rw-r--r--src/librustdoc/html/render/print_item.rs9
-rw-r--r--src/librustdoc/html/static/.eslintrc.js1
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css59
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css5
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css5
-rw-r--r--src/librustdoc/html/static/css/themes/light.css6
-rw-r--r--src/librustdoc/html/static/js/source-script.js37
-rw-r--r--src/librustdoc/lib.rs25
-rw-r--r--src/test/incremental/split_debuginfo_mode.rs33
-rw-r--r--src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff112
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt4
-rw-r--r--src/test/run-make/issue-88756-opt-help/Makefile4
-rw-r--r--src/test/run-make/issue-88756-opt-help/README.md1
-rw-r--r--src/test/run-make/issue-88756-opt-help/output-default.stdout193
-rw-r--r--src/test/run-make/issue-88756-opt-help/x.rs1
-rw-r--r--src/test/run-make/native-link-modifier-bundle/Makefile24
-rw-r--r--src/test/rustdoc-gui/sidebar-source-code-display.goml111
-rw-r--r--src/test/rustdoc-gui/source-code-page.goml23
-rw-r--r--src/test/rustdoc-ui/issue-83883-describe-lints.rs4
-rw-r--r--src/test/rustdoc-ui/issue-83883-describe-lints.stdout215
-rw-r--r--src/test/rustdoc/assoc-consts.rs4
-rw-r--r--src/test/rustdoc/assoc-types.rs2
-rw-r--r--src/test/rustdoc/const-value-display.rs4
-rw-r--r--src/test/rustdoc/decl-trailing-whitespace.declaration.html7
-rw-r--r--src/test/rustdoc/decl-trailing-whitespace.rs30
-rw-r--r--src/test/rustdoc/hide-complex-unevaluated-const-arguments.rs82
-rw-r--r--src/test/rustdoc/hide-complex-unevaluated-consts.rs71
-rw-r--r--src/test/rustdoc/show-const-contents.rs2
-rw-r--r--src/test/ui/abi/rustcall-generic.rs3
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.rs7
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout570
-rw-r--r--src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.rs1
-rw-r--r--src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr10
-rw-r--r--src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.rs1
-rw-r--r--src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr10
-rw-r--r--src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs3
-rw-r--r--src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr10
-rw-r--r--src/test/ui/inference/ambiguous_type_parameter.stderr7
-rw-r--r--src/test/ui/inference/cannot-infer-partial-try-return.rs2
-rw-r--r--src/test/ui/inference/cannot-infer-partial-try-return.stderr15
-rw-r--r--src/test/ui/inference/need_type_info/channel.rs19
-rw-r--r--src/test/ui/inference/need_type_info/channel.stderr25
-rw-r--r--src/test/ui/infinite/infinite-struct.rs1
-rw-r--r--src/test/ui/infinite/infinite-struct.stderr14
-rw-r--r--src/test/ui/infinite/infinite-tag-type-recursion.rs1
-rw-r--r--src/test/ui/infinite/infinite-tag-type-recursion.stderr14
-rw-r--r--src/test/ui/issues/issue-23041.stderr9
-rw-r--r--src/test/ui/issues/issue-24013.stderr9
-rw-r--r--src/test/ui/issues/issue-25368.rs4
-rw-r--r--src/test/ui/issues/issue-25368.stderr14
-rw-r--r--src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr6
-rw-r--r--src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs14
-rw-r--r--src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr15
-rw-r--r--src/test/ui/recursion/issue-86784.rs2597
-rw-r--r--src/test/ui/specialization/min_specialization/repeated_projection_type.stderr6
-rw-r--r--src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr4
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_super_trait.stderr4
-rw-r--r--src/test/ui/specialization/min_specialization/specialization_trait.stderr4
-rw-r--r--src/test/ui/specialization/min_specialization/specialize_on_trait.stderr4
-rw-r--r--src/test/ui/suggestions/suggest-on-bare-closure-call.rs7
-rw-r--r--src/test/ui/suggestions/suggest-on-bare-closure-call.stderr17
-rw-r--r--src/tools/compiletest/src/common.rs4
-rw-r--r--src/tools/compiletest/src/header.rs1
-rw-r--r--src/tools/compiletest/src/main.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs31
-rw-r--r--src/tools/tidy/src/bins.rs23
-rw-r--r--src/tools/tidy/src/main.rs9
123 files changed, 4470 insertions, 1602 deletions
diff --git a/.github/ISSUE_TEMPLATE/library_tracking_issue.md b/.github/ISSUE_TEMPLATE/library_tracking_issue.md
index 32fccfcfb16..91c06402ca1 100644
--- a/.github/ISSUE_TEMPLATE/library_tracking_issue.md
+++ b/.github/ISSUE_TEMPLATE/library_tracking_issue.md
@@ -50,7 +50,7 @@ If the feature is changed later, please add those PRs here as well.
 -->
 
 - [ ] Implementation: #...
-- [ ] Final comment period (FCP)
+- [ ] Final comment period (FCP)[^1]
 - [ ] Stabilization PR
 
 <!--
@@ -81,3 +81,5 @@ Zulip, or the internals forum) here.
 -->
 
 - None yet.
+
+[^1]: https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html
diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs
index e4ffae38c33..d34c6d9dee5 100644
--- a/compiler/rustc_borrowck/src/constraint_generation.rs
+++ b/compiler/rustc_borrowck/src/constraint_generation.rs
@@ -149,7 +149,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
     fn visit_ascribe_user_ty(
         &mut self,
         _place: &Place<'tcx>,
-        _variance: &ty::Variance,
+        _variance: ty::Variance,
         _user_ty: &UserTypeProjection,
         _location: Location,
     ) {
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index ac8670a5138..d5c401ae1c6 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -1,11 +1,11 @@
+use itertools::{Either, Itertools};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::{Body, Local};
 use rustc_middle::ty::{RegionVid, TyCtxt};
-use std::rc::Rc;
-
 use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
 use rustc_mir_dataflow::move_paths::MoveData;
 use rustc_mir_dataflow::ResultsCursor;
+use std::rc::Rc;
 
 use crate::{
     constraints::OutlivesConstraintSet,
@@ -46,7 +46,8 @@ pub(super) fn generate<'mir, 'tcx>(
         &typeck.borrowck_context.universal_regions,
         &typeck.borrowck_context.constraints.outlives_constraints,
     );
-    let live_locals = compute_live_locals(typeck.tcx(), &free_regions, &body);
+    let (relevant_live_locals, boring_locals) =
+        compute_relevant_live_locals(typeck.tcx(), &free_regions, &body);
     let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
 
     let polonius_drop_used = if facts_enabled {
@@ -57,48 +58,44 @@ pub(super) fn generate<'mir, 'tcx>(
         None
     };
 
-    if !live_locals.is_empty() || facts_enabled {
-        trace::trace(
-            typeck,
-            body,
-            elements,
-            flow_inits,
-            move_data,
-            live_locals,
-            polonius_drop_used,
-        );
-    }
+    trace::trace(
+        typeck,
+        body,
+        elements,
+        flow_inits,
+        move_data,
+        relevant_live_locals,
+        boring_locals,
+        polonius_drop_used,
+    );
 }
 
-// The purpose of `compute_live_locals` is to define the subset of `Local`
+// The purpose of `compute_relevant_live_locals` is to define the subset of `Local`
 // variables for which we need to do a liveness computation. We only need
 // to compute whether a variable `X` is live if that variable contains
 // some region `R` in its type where `R` is not known to outlive a free
 // region (i.e., where `R` may be valid for just a subset of the fn body).
-fn compute_live_locals<'tcx>(
+fn compute_relevant_live_locals<'tcx>(
     tcx: TyCtxt<'tcx>,
     free_regions: &FxHashSet<RegionVid>,
     body: &Body<'tcx>,
-) -> Vec<Local> {
-    let live_locals: Vec<Local> = body
-        .local_decls
-        .iter_enumerated()
-        .filter_map(|(local, local_decl)| {
+) -> (Vec<Local>, Vec<Local>) {
+    let (boring_locals, relevant_live_locals): (Vec<_>, Vec<_>) =
+        body.local_decls.iter_enumerated().partition_map(|(local, local_decl)| {
             if tcx.all_free_regions_meet(&local_decl.ty, |r| {
                 free_regions.contains(&r.to_region_vid())
             }) {
-                None
+                Either::Left(local)
             } else {
-                Some(local)
+                Either::Right(local)
             }
-        })
-        .collect();
+        });
 
     debug!("{} total variables", body.local_decls.len());
-    debug!("{} variables need liveness", live_locals.len());
+    debug!("{} variables need liveness", relevant_live_locals.len());
     debug!("{} regions outlive free regions", free_regions.len());
 
-    live_locals
+    (relevant_live_locals, boring_locals)
 }
 
 /// Computes all regions that are (currently) known to outlive free
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 169de23facc..a69eec47c7b 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -41,12 +41,13 @@ pub(super) fn trace<'mir, 'tcx>(
     elements: &Rc<RegionValueElements>,
     flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
     move_data: &MoveData<'tcx>,
-    live_locals: Vec<Local>,
+    relevant_live_locals: Vec<Local>,
+    boring_locals: Vec<Local>,
     polonius_drop_used: Option<Vec<(Local, Location)>>,
 ) {
     debug!("trace()");
 
-    let local_use_map = &LocalUseMap::build(&live_locals, elements, body);
+    let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body);
 
     let cx = LivenessContext {
         typeck,
@@ -61,10 +62,12 @@ pub(super) fn trace<'mir, 'tcx>(
     let mut results = LivenessResults::new(cx);
 
     if let Some(drop_used) = polonius_drop_used {
-        results.add_extra_drop_facts(drop_used, live_locals.iter().copied().collect())
+        results.add_extra_drop_facts(drop_used, relevant_live_locals.iter().copied().collect())
     }
 
-    results.compute_for_all_locals(live_locals);
+    results.compute_for_all_locals(relevant_live_locals);
+
+    results.dropck_boring_locals(boring_locals);
 }
 
 /// Contextual state for the type-liveness generator.
@@ -133,8 +136,8 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
         }
     }
 
-    fn compute_for_all_locals(&mut self, live_locals: Vec<Local>) {
-        for local in live_locals {
+    fn compute_for_all_locals(&mut self, relevant_live_locals: Vec<Local>) {
+        for local in relevant_live_locals {
             self.reset_local_state();
             self.add_defs_for(local);
             self.compute_use_live_points_for(local);
@@ -157,6 +160,24 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
         }
     }
 
+    // Runs dropck for locals whose liveness isn't relevant. This is
+    // necessary to eagerly detect unbound recursion during drop glue computation.
+    fn dropck_boring_locals(&mut self, boring_locals: Vec<Local>) {
+        for local in boring_locals {
+            let local_ty = self.cx.body.local_decls[local].ty;
+            let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({
+                let typeck = &mut self.cx.typeck;
+                move || LivenessContext::compute_drop_data(typeck, local_ty)
+            });
+
+            drop_data.dropck_result.report_overflows(
+                self.cx.typeck.infcx.tcx,
+                self.cx.body.local_decls[local].source_info.span,
+                local_ty,
+            );
+        }
+    }
+
     /// Add extra drop facts needed for Polonius.
     ///
     /// Add facts for all locals with free regions, since regions may outlive
@@ -164,12 +185,12 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
     fn add_extra_drop_facts(
         &mut self,
         drop_used: Vec<(Local, Location)>,
-        live_locals: FxHashSet<Local>,
+        relevant_live_locals: FxHashSet<Local>,
     ) {
         let locations = IntervalSet::new(self.cx.elements.num_points());
 
         for (local, location) in drop_used {
-            if !live_locals.contains(&local) {
+            if !relevant_live_locals.contains(&local) {
                 let local_ty = self.cx.body.local_decls[local].ty;
                 if local_ty.has_free_regions() {
                     self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index ff431c8de5d..2a9e37081e0 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -66,7 +66,7 @@
 //!
 //! # "`cs`" functions
 //!
-//! The `cs_...` functions ("combine substructure) are designed to
+//! The `cs_...` functions ("combine substructure") are designed to
 //! make life easier by providing some pre-made recipes for common
 //! threads; mostly calling the function being derived on all the
 //! arguments and then combining them back together in some way (or
@@ -429,6 +429,7 @@ impl<'a> TraitDef<'a> {
                         generics,
                         from_scratch,
                         use_temporaries,
+                        is_packed,
                     ),
                     ast::ItemKind::Enum(ref enum_def, ref generics) => {
                         // We ignore `use_temporaries` here, because
@@ -448,6 +449,7 @@ impl<'a> TraitDef<'a> {
                                 generics,
                                 from_scratch,
                                 use_temporaries,
+                                is_packed,
                             )
                         } else {
                             cx.span_err(mitem.span, "this trait cannot be derived for unions");
@@ -729,6 +731,7 @@ impl<'a> TraitDef<'a> {
         generics: &Generics,
         from_scratch: bool,
         use_temporaries: bool,
+        is_packed: bool,
     ) -> P<ast::Item> {
         let field_tys: Vec<P<ast::Ty>> =
             struct_def.fields().iter().map(|field| field.ty.clone()).collect();
@@ -757,6 +760,7 @@ impl<'a> TraitDef<'a> {
                         &self_args,
                         &nonself_args,
                         use_temporaries,
+                        is_packed,
                     )
                 };
 
@@ -945,6 +949,7 @@ impl<'a> MethodDef<'a> {
         })
     }
 
+    /// The normal case uses field access.
     /// ```
     /// #[derive(PartialEq)]
     /// # struct Dummy;
@@ -953,33 +958,21 @@ impl<'a> MethodDef<'a> {
     /// // equivalent to:
     /// impl PartialEq for A {
     ///     fn eq(&self, other: &A) -> bool {
-    ///         match *self {
-    ///             A {x: ref __self_0_0, y: ref __self_0_1} => {
-    ///                 match *other {
-    ///                     A {x: ref __self_1_0, y: ref __self_1_1} => {
-    ///                         __self_0_0.eq(__self_1_0) && __self_0_1.eq(__self_1_1)
-    ///                     }
-    ///                 }
-    ///             }
-    ///         }
+    ///         self.x == other.x && self.y == other.y
     ///     }
     /// }
     /// ```
-    /// or if A is repr(packed) - note fields are matched by-value
-    /// instead of by-reference.
+    /// But if the struct is `repr(packed)`, we can't use something like
+    /// `&self.x` on a packed type (as required for e.g. `Debug` and `Hash`)
+    /// because that might cause an unaligned ref. So we use let-destructuring
+    /// instead.
     /// ```
     /// # struct A { x: i32, y: i32 }
     /// impl PartialEq for A {
     ///     fn eq(&self, other: &A) -> bool {
-    ///         match *self {
-    ///             A {x: __self_0_0, y: __self_0_1} => {
-    ///                 match other {
-    ///                     A {x: __self_1_0, y: __self_1_1} => {
-    ///                         __self_0_0.eq(&__self_1_0) && __self_0_1.eq(&__self_1_1)
-    ///                     }
-    ///                 }
-    ///             }
-    ///         }
+    ///         let Self { x: ref __self_0_0, y: ref __self_0_1 } = *self;
+    ///         let Self { x: ref __self_1_0, y: ref __self_1_1 } = *other;
+    ///         *__self_0_0 == *__self_1_0 && *__self_0_1 == *__self_1_1
     ///     }
     /// }
     /// ```
@@ -992,24 +985,33 @@ impl<'a> MethodDef<'a> {
         self_args: &[P<Expr>],
         nonself_args: &[P<Expr>],
         use_temporaries: bool,
+        is_packed: bool,
     ) -> P<Expr> {
         let mut raw_fields = Vec::new(); // Vec<[fields of self], [fields of next Self arg], [etc]>
         let span = trait_.span;
         let mut patterns = Vec::new();
-        for i in 0..self_args.len() {
-            // We could use `type_ident` instead of `Self`, but in the case of a type parameter
-            // shadowing the struct name, that causes a second, unnecessary E0578 error. #97343
-            let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]);
-            let (pat, ident_expr) = trait_.create_struct_pattern(
-                cx,
-                struct_path,
-                struct_def,
-                &format!("__self_{}", i),
-                ast::Mutability::Not,
-                use_temporaries,
-            );
-            patterns.push(pat);
-            raw_fields.push(ident_expr);
+
+        for (i, self_arg) in self_args.iter().enumerate() {
+            let ident_exprs = if !is_packed {
+                trait_.create_struct_field_accesses(cx, self_arg, struct_def)
+            } else {
+                // Get the pattern for the let-destructuring.
+                //
+                // We could use `type_ident` instead of `Self`, but in the case of a type parameter
+                // shadowing the struct name, that causes a second, unnecessary E0578 error. #97343
+                let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]);
+                let (pat, ident_exprs) = trait_.create_struct_pattern(
+                    cx,
+                    struct_path,
+                    struct_def,
+                    &format!("__self_{}", i),
+                    ast::Mutability::Not,
+                    use_temporaries,
+                );
+                patterns.push(pat);
+                ident_exprs
+            };
+            raw_fields.push(ident_exprs);
         }
 
         // transpose raw_fields
@@ -1036,7 +1038,6 @@ impl<'a> MethodDef<'a> {
             cx.span_bug(span, "no `self` parameter for method in generic `derive`")
         };
 
-        // body of the inner most destructuring match
         let mut body = self.call_substructure_method(
             cx,
             trait_,
@@ -1045,14 +1046,18 @@ impl<'a> MethodDef<'a> {
             &Struct(struct_def, fields),
         );
 
-        // make a series of nested matches, to destructure the
-        // structs. This is actually right-to-left, but it shouldn't
-        // matter.
-        for (arg_expr, pat) in iter::zip(self_args, patterns) {
-            body = cx.expr_match(span, arg_expr.clone(), vec![cx.arm(span, pat.clone(), body)])
-        }
+        if !is_packed {
+            body.span = span;
+            body
+        } else {
+            // Do the let-destructuring.
+            let mut stmts: Vec<_> = iter::zip(self_args, patterns)
+                .map(|(arg_expr, pat)| cx.stmt_let_pat(span, pat, arg_expr.clone()))
+                .collect();
+            stmts.push(cx.stmt_expr(body));
 
-        body
+            cx.expr_block(cx.block(span, stmts))
+        }
     }
 
     fn expand_static_struct_method_body(
@@ -1522,8 +1527,6 @@ impl<'a> TraitDef<'a> {
             paths.push(ident.with_span_pos(sp));
             let val = cx.expr_path(cx.path_ident(sp, ident));
             let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
-            let val = cx.expr(sp, ast::ExprKind::Paren(val));
-
             ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
         }
 
@@ -1555,6 +1558,39 @@ impl<'a> TraitDef<'a> {
         (pattern, ident_exprs)
     }
 
+    fn create_struct_field_accesses(
+        &self,
+        cx: &mut ExtCtxt<'_>,
+        mut self_arg: &P<Expr>,
+        struct_def: &'a VariantData,
+    ) -> Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])> {
+        let mut ident_exprs = Vec::new();
+        for (i, struct_field) in struct_def.fields().iter().enumerate() {
+            let sp = struct_field.span.with_ctxt(self.span.ctxt());
+
+            // We don't the need the deref, if there is one.
+            if let ast::ExprKind::Unary(ast::UnOp::Deref, inner) = &self_arg.kind {
+                self_arg = inner;
+            }
+
+            // Note: we must use `struct_field.span` rather than `span` in the
+            // `unwrap_or_else` case otherwise the hygiene is wrong and we get
+            // "field `0` of struct `Point` is private" errors on tuple
+            // structs.
+            let val = cx.expr(
+                sp,
+                ast::ExprKind::Field(
+                    self_arg.clone(),
+                    struct_field.ident.unwrap_or_else(|| {
+                        Ident::from_str_and_span(&i.to_string(), struct_field.span)
+                    }),
+                ),
+            );
+            ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
+        }
+        ident_exprs
+    }
+
     fn create_enum_variant_pattern(
         &self,
         cx: &mut ExtCtxt<'_>,
@@ -1643,7 +1679,6 @@ where
 /// fields.
 /// When the `substructure` is an `EnumNonMatchingCollapsed`, the result of `enum_nonmatch_f`
 /// is returned. Statics may not be folded over.
-/// See `cs_op` in `partial_ord.rs` for a model example.
 pub fn cs_fold1<F, B>(
     use_foldl: bool,
     f: F,
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 66c73624501..031d508d70f 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -808,7 +808,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             self.stack_mut().pop().expect("tried to pop a stack frame, but there were none");
 
         if !unwinding {
-            let op = self.access_local(&frame, mir::RETURN_PLACE, None)?;
+            let op = self.local_to_op(&frame, mir::RETURN_PLACE, None)?;
             self.copy_op_transmute(&op, &frame.return_place)?;
             trace!("{:?}", self.dump_place(*frame.return_place));
         }
@@ -981,8 +981,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
                     LocalValue::Live(Operand::Indirect(mplace)) => {
                         write!(
                             fmt,
-                            " by align({}){} ref {:?}:",
-                            mplace.align.bytes(),
+                            " by {} ref {:?}:",
                             match mplace.meta {
                                 MemPlaceMeta::Meta(meta) => format!(" meta({:?})", meta),
                                 MemPlaceMeta::Poison | MemPlaceMeta::None => String::new(),
@@ -1011,13 +1010,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
                 write!(fmt, ": {:?}", self.ecx.dump_allocs(allocs.into_iter().flatten().collect()))
             }
             Place::Ptr(mplace) => match mplace.ptr.provenance.and_then(Provenance::get_alloc_id) {
-                Some(alloc_id) => write!(
-                    fmt,
-                    "by align({}) ref {:?}: {:?}",
-                    mplace.align.bytes(),
-                    mplace.ptr,
-                    self.ecx.dump_alloc(alloc_id)
-                ),
+                Some(alloc_id) => {
+                    write!(fmt, "by ref {:?}: {:?}", mplace.ptr, self.ecx.dump_alloc(alloc_id))
+                }
                 ptr => write!(fmt, " integral by ref: {:?}", ptr),
             },
         }
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index c2a5b71b8f9..509fe576893 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -276,7 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         kind: MemoryKind<M::MemoryKind>,
     ) -> InterpResult<'tcx> {
         let (alloc_id, offset, tag) = self.ptr_get_alloc_id(ptr)?;
-        trace!("deallocating: {}", alloc_id);
+        trace!("deallocating: {alloc_id:?}");
 
         if offset.bytes() != 0 {
             throw_ub_format!(
@@ -289,10 +289,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // Deallocating global memory -- always an error
             return Err(match self.tcx.get_global_alloc(alloc_id) {
                 Some(GlobalAlloc::Function(..)) => {
-                    err_ub_format!("deallocating {}, which is a function", alloc_id)
+                    err_ub_format!("deallocating {alloc_id:?}, which is a function")
                 }
                 Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => {
-                    err_ub_format!("deallocating {}, which is static memory", alloc_id)
+                    err_ub_format!("deallocating {alloc_id:?}, which is static memory")
                 }
                 None => err_ub!(PointerUseAfterFree(alloc_id)),
             }
@@ -302,21 +302,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         debug!(?alloc);
 
         if alloc.mutability == Mutability::Not {
-            throw_ub_format!("deallocating immutable allocation {}", alloc_id);
+            throw_ub_format!("deallocating immutable allocation {alloc_id:?}");
         }
         if alloc_kind != kind {
             throw_ub_format!(
-                "deallocating {}, which is {} memory, using {} deallocation operation",
-                alloc_id,
-                alloc_kind,
-                kind
+                "deallocating {alloc_id:?}, which is {alloc_kind} memory, using {kind} deallocation operation"
             );
         }
         if let Some((size, align)) = old_size_and_align {
             if size != alloc.size() || align != alloc.align {
                 throw_ub_format!(
-                    "incorrect layout on deallocation: {} has size {} and alignment {}, but gave size {} and alignment {}",
-                    alloc_id,
+                    "incorrect layout on deallocation: {alloc_id:?} has size {} and alignment {}, but gave size {} and alignment {}",
                     alloc.size().bytes(),
                     alloc.align.bytes(),
                     size.bytes(),
@@ -815,7 +811,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
                 continue;
             }
 
-            write!(fmt, "{}", id)?;
+            write!(fmt, "{id:?}")?;
             match self.ecx.memory.alloc_map.get(id) {
                 Some(&(kind, ref alloc)) => {
                     // normal alloc
@@ -859,25 +855,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a,
 
 /// Reading and writing.
 impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
+    /// `range` is relative to this allocation reference, not the base of the allocation.
     pub fn write_scalar(
         &mut self,
         range: AllocRange,
         val: ScalarMaybeUninit<Tag>,
     ) -> InterpResult<'tcx> {
         let range = self.range.subrange(range);
-        debug!(
-            "write_scalar in {} at {:#x}, size {}: {:?}",
-            self.alloc_id,
-            range.start.bytes(),
-            range.size.bytes(),
-            val
-        );
+        debug!("write_scalar at {:?}{range:?}: {val:?}", self.alloc_id);
         Ok(self
             .alloc
             .write_scalar(&self.tcx, range, val)
             .map_err(|e| e.to_interp_error(self.alloc_id))?)
     }
 
+    /// `offset` is relative to this allocation reference, not the base of the allocation.
     pub fn write_ptr_sized(
         &mut self,
         offset: Size,
@@ -896,6 +888,7 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
 }
 
 impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
+    /// `range` is relative to this allocation reference, not the base of the allocation.
     pub fn read_scalar(
         &self,
         range: AllocRange,
@@ -906,24 +899,16 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
             .alloc
             .read_scalar(&self.tcx, range, read_provenance)
             .map_err(|e| e.to_interp_error(self.alloc_id))?;
-        debug!(
-            "read_scalar in {} at {:#x}, size {}: {:?}",
-            self.alloc_id,
-            range.start.bytes(),
-            range.size.bytes(),
-            res
-        );
+        debug!("read_scalar at {:?}{range:?}: {res:?}", self.alloc_id);
         Ok(res)
     }
 
-    pub fn read_integer(
-        &self,
-        offset: Size,
-        size: Size,
-    ) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
-        self.read_scalar(alloc_range(offset, size), /*read_provenance*/ false)
+    /// `range` is relative to this allocation reference, not the base of the allocation.
+    pub fn read_integer(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
+        self.read_scalar(range, /*read_provenance*/ false)
     }
 
+    /// `offset` is relative to this allocation reference, not the base of the allocation.
     pub fn read_pointer(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
         self.read_scalar(
             alloc_range(offset, self.tcx.data_layout().pointer_size),
@@ -931,6 +916,7 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
         )
     }
 
+    /// `range` is relative to this allocation reference, not the base of the allocation.
     pub fn check_bytes(
         &self,
         range: AllocRange,
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index e7a08e05275..d48f6521ba2 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -10,7 +10,7 @@ use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
 use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty};
 use rustc_middle::{mir, ty};
-use rustc_target::abi::{self, Abi, HasDataLayout, Size, TagEncoding};
+use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding};
 use rustc_target::abi::{VariantIdx, Variants};
 
 use super::{
@@ -177,10 +177,18 @@ pub enum Operand<Tag: Provenance = AllocId> {
 pub struct OpTy<'tcx, Tag: Provenance = AllocId> {
     op: Operand<Tag>, // Keep this private; it helps enforce invariants.
     pub layout: TyAndLayout<'tcx>,
+    /// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct:
+    /// it needs to have a different alignment than the field type would usually have.
+    /// So we represent this here with a separate field that "overwrites" `layout.align`.
+    /// This means `layout.align` should never be used for an `OpTy`!
+    /// `None` means "alignment does not matter since this is a by-value operand"
+    /// (`Operand::Immediate`); this field is only relevant for `Operand::Indirect`.
+    /// Also CTFE ignores alignment anyway, so this is for Miri only.
+    pub align: Option<Align>,
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(OpTy<'_>, 80);
+rustc_data_structures::static_assert_size!(OpTy<'_>, 88);
 
 impl<'tcx, Tag: Provenance> std::ops::Deref for OpTy<'tcx, Tag> {
     type Target = Operand<Tag>;
@@ -193,28 +201,28 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for OpTy<'tcx, Tag> {
 impl<'tcx, Tag: Provenance> From<MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
     #[inline(always)]
     fn from(mplace: MPlaceTy<'tcx, Tag>) -> Self {
-        OpTy { op: Operand::Indirect(*mplace), layout: mplace.layout }
+        OpTy { op: Operand::Indirect(*mplace), layout: mplace.layout, align: Some(mplace.align) }
     }
 }
 
 impl<'tcx, Tag: Provenance> From<&'_ MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
     #[inline(always)]
     fn from(mplace: &MPlaceTy<'tcx, Tag>) -> Self {
-        OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout }
+        OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout, align: Some(mplace.align) }
     }
 }
 
 impl<'tcx, Tag: Provenance> From<&'_ mut MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
     #[inline(always)]
     fn from(mplace: &mut MPlaceTy<'tcx, Tag>) -> Self {
-        OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout }
+        OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout, align: Some(mplace.align) }
     }
 }
 
 impl<'tcx, Tag: Provenance> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
     #[inline(always)]
     fn from(val: ImmTy<'tcx, Tag>) -> Self {
-        OpTy { op: Operand::Immediate(val.imm), layout: val.layout }
+        OpTy { op: Operand::Immediate(val.imm), layout: val.layout, align: None }
     }
 }
 
@@ -450,7 +458,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             ),
         };
 
-        Ok(OpTy { op: Operand::Immediate(field_val), layout: field_layout })
+        Ok(OpTy { op: Operand::Immediate(field_val), layout: field_layout, align: None })
     }
 
     pub fn operand_index(
@@ -522,7 +530,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ///
     /// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an
     /// OpTy from a local
-    pub fn access_local(
+    pub fn local_to_op(
         &self,
         frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
         local: mir::Local,
@@ -535,7 +543,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         } else {
             M::access_local(&self, frame, local)?
         };
-        Ok(OpTy { op, layout })
+        Ok(OpTy { op, layout, align: Some(layout.align.abi) })
     }
 
     /// Every place can be read from, so we can turn them into an operand.
@@ -549,10 +557,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let op = match **place {
             Place::Ptr(mplace) => Operand::Indirect(mplace),
             Place::Local { frame, local } => {
-                *self.access_local(&self.stack()[frame], local, None)?
+                *self.local_to_op(&self.stack()[frame], local, None)?
             }
         };
-        Ok(OpTy { op, layout: place.layout })
+        Ok(OpTy { op, layout: place.layout, align: Some(place.align) })
     }
 
     /// Evaluate a place with the goal of reading from it.  This lets us sometimes
@@ -566,7 +574,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // here is not the entire place.
         let layout = if place.projection.is_empty() { layout } else { None };
 
-        let base_op = self.access_local(self.frame(), place.local, layout)?;
+        let base_op = self.local_to_op(self.frame(), place.local, layout)?;
 
         let op = place
             .projection
@@ -603,11 +611,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             Constant(ref constant) => {
                 let val =
                     self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?;
+
                 // This can still fail:
                 // * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
                 //   checked yet.
                 // * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
-
                 self.mir_const_to_op(&val, layout)?
             }
         };
@@ -683,7 +691,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // We rely on mutability being set correctly in that allocation to prevent writes
                 // where none should happen.
                 let ptr = self.global_base_pointer(Pointer::new(id, offset))?;
-                Operand::Indirect(MemPlace::from_ptr(ptr.into(), layout.align.abi))
+                Operand::Indirect(MemPlace::from_ptr(ptr.into()))
             }
             ConstValue::Scalar(x) => Operand::Immediate(tag_scalar(x)?.into()),
             ConstValue::Slice { data, start, end } => {
@@ -700,7 +708,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 ))
             }
         };
-        Ok(OpTy { op, layout })
+        Ok(OpTy { op, layout, align: Some(layout.align.abi) })
     }
 
     /// Read discriminant, return the runtime value as well as the variant index.
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 85ee88e9e47..dec7fa8c4aa 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -5,6 +5,7 @@ use rustc_middle::mir;
 use rustc_middle::mir::interpret::{InterpResult, Scalar};
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, FloatTy, Ty};
+use rustc_target::abi::Abi;
 
 use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy};
 
@@ -25,8 +26,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             "type mismatch for result of {:?}",
             op,
         );
-        let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
-        self.write_immediate(val, dest)
+        if let Abi::ScalarPair(..) = dest.layout.abi {
+            // We can use the optimized path and avoid `place_field` (which might do
+            // `force_allocation`).
+            let pair = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
+            self.write_immediate(pair, dest)?;
+        } else {
+            assert!(self.tcx.sess.opts.debugging_opts.randomize_layout);
+            // With randomized layout, `(int, bool)` might cease to be a `ScalarPair`, so we have to
+            // do a component-wise write here. This code path is slower than the above because
+            // `place_field` will have to `force_allocate` locals here.
+            let val_field = self.place_field(&dest, 0)?;
+            self.write_scalar(val, &val_field)?;
+            let overflowed_field = self.place_field(&dest, 1)?;
+            self.write_scalar(Scalar::from_bool(overflowed), &overflowed_field)?;
+        }
+        Ok(())
     }
 
     /// Applies the binary operation `op` to the arguments and writes the result to the
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 337fcd28c66..98a3a50afaa 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -57,7 +57,6 @@ impl<Tag: Provenance> MemPlaceMeta<Tag> {
 pub struct MemPlace<Tag: Provenance = AllocId> {
     /// The pointer can be a pure integer, with the `None` tag.
     pub ptr: Pointer<Option<Tag>>,
-    pub align: Align,
     /// Metadata for unsized places. Interpretation is up to the type.
     /// Must not be present for sized types, but can be missing for unsized types
     /// (e.g., `extern type`).
@@ -65,7 +64,7 @@ pub struct MemPlace<Tag: Provenance = AllocId> {
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(MemPlace, 48);
+rustc_data_structures::static_assert_size!(MemPlace, 40);
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, HashStable, Debug)]
 pub enum Place<Tag: Provenance = AllocId> {
@@ -78,12 +77,17 @@ pub enum Place<Tag: Provenance = AllocId> {
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Place, 56);
+rustc_data_structures::static_assert_size!(Place, 48);
 
 #[derive(Copy, Clone, Debug)]
 pub struct PlaceTy<'tcx, Tag: Provenance = AllocId> {
     place: Place<Tag>, // Keep this private; it helps enforce invariants.
     pub layout: TyAndLayout<'tcx>,
+    /// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct:
+    /// it needs to have a different alignment than the field type would usually have.
+    /// So we represent this here with a separate field that "overwrites" `layout.align`.
+    /// This means `layout.align` should never be used for a `PlaceTy`!
+    pub align: Align,
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -102,6 +106,11 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for PlaceTy<'tcx, Tag> {
 pub struct MPlaceTy<'tcx, Tag: Provenance = AllocId> {
     mplace: MemPlace<Tag>,
     pub layout: TyAndLayout<'tcx>,
+    /// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct:
+    /// it needs to have a different alignment than the field type would usually have.
+    /// So we represent this here with a separate field that "overwrites" `layout.align`.
+    /// This means `layout.align` should never be used for a `MPlaceTy`!
+    pub align: Align,
 }
 
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
@@ -118,28 +127,28 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for MPlaceTy<'tcx, Tag> {
 impl<'tcx, Tag: Provenance> From<MPlaceTy<'tcx, Tag>> for PlaceTy<'tcx, Tag> {
     #[inline(always)]
     fn from(mplace: MPlaceTy<'tcx, Tag>) -> Self {
-        PlaceTy { place: Place::Ptr(*mplace), layout: mplace.layout }
+        PlaceTy { place: Place::Ptr(*mplace), layout: mplace.layout, align: mplace.align }
     }
 }
 
 impl<'tcx, Tag: Provenance> From<&'_ MPlaceTy<'tcx, Tag>> for PlaceTy<'tcx, Tag> {
     #[inline(always)]
     fn from(mplace: &MPlaceTy<'tcx, Tag>) -> Self {
-        PlaceTy { place: Place::Ptr(**mplace), layout: mplace.layout }
+        PlaceTy { place: Place::Ptr(**mplace), layout: mplace.layout, align: mplace.align }
     }
 }
 
 impl<'tcx, Tag: Provenance> From<&'_ mut MPlaceTy<'tcx, Tag>> for PlaceTy<'tcx, Tag> {
     #[inline(always)]
     fn from(mplace: &mut MPlaceTy<'tcx, Tag>) -> Self {
-        PlaceTy { place: Place::Ptr(**mplace), layout: mplace.layout }
+        PlaceTy { place: Place::Ptr(**mplace), layout: mplace.layout, align: mplace.align }
     }
 }
 
 impl<Tag: Provenance> MemPlace<Tag> {
     #[inline(always)]
-    pub fn from_ptr(ptr: Pointer<Option<Tag>>, align: Align) -> Self {
-        MemPlace { ptr, align, meta: MemPlaceMeta::None }
+    pub fn from_ptr(ptr: Pointer<Option<Tag>>) -> Self {
+        MemPlace { ptr, meta: MemPlaceMeta::None }
     }
 
     /// Adjust the provenance of the main pointer (metadata is unaffected).
@@ -170,11 +179,7 @@ impl<Tag: Provenance> MemPlace<Tag> {
         meta: MemPlaceMeta<Tag>,
         cx: &impl HasDataLayout,
     ) -> InterpResult<'tcx, Self> {
-        Ok(MemPlace {
-            ptr: self.ptr.offset(offset, cx)?,
-            align: self.align.restrict_for_offset(offset),
-            meta,
-        })
+        Ok(MemPlace { ptr: self.ptr.offset(offset, cx)?, meta })
     }
 }
 
@@ -185,7 +190,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
         let align = layout.align.abi;
         let ptr = Pointer::new(None, Size::from_bytes(align.bytes())); // no provenance, absolute address
         // `Poison` this to make sure that the pointer value `ptr` is never observable by the program.
-        MPlaceTy { mplace: MemPlace { ptr, align, meta: MemPlaceMeta::Poison }, layout }
+        MPlaceTy { mplace: MemPlace { ptr, meta: MemPlaceMeta::Poison }, layout, align }
     }
 
     #[inline]
@@ -196,12 +201,16 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
         layout: TyAndLayout<'tcx>,
         cx: &impl HasDataLayout,
     ) -> InterpResult<'tcx, Self> {
-        Ok(MPlaceTy { mplace: self.mplace.offset(offset, meta, cx)?, layout })
+        Ok(MPlaceTy {
+            mplace: self.mplace.offset(offset, meta, cx)?,
+            align: self.align.restrict_for_offset(offset),
+            layout,
+        })
     }
 
     #[inline]
     pub fn from_aligned_ptr(ptr: Pointer<Option<Tag>>, layout: TyAndLayout<'tcx>) -> Self {
-        MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align.abi), layout }
+        MPlaceTy { mplace: MemPlace::from_ptr(ptr), layout, align: layout.align.abi }
     }
 
     #[inline]
@@ -210,10 +219,10 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
         layout: TyAndLayout<'tcx>,
         meta: MemPlaceMeta<Tag>,
     ) -> Self {
-        let mut mplace = MemPlace::from_ptr(ptr, layout.align.abi);
+        let mut mplace = MemPlace::from_ptr(ptr);
         mplace.meta = meta;
 
-        MPlaceTy { mplace, layout }
+        MPlaceTy { mplace, layout, align: layout.align.abi }
     }
 
     #[inline]
@@ -250,7 +259,9 @@ impl<'tcx, Tag: Provenance> OpTy<'tcx, Tag> {
     /// read from the resulting mplace, not to get its address back.
     pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Tag>, ImmTy<'tcx, Tag>> {
         match **self {
-            Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }),
+            Operand::Indirect(mplace) => {
+                Ok(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() })
+            }
             Operand::Immediate(_) if self.layout.is_zst() => Ok(MPlaceTy::dangling(self.layout)),
             Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)),
         }
@@ -264,20 +275,19 @@ impl<'tcx, Tag: Provenance> OpTy<'tcx, Tag> {
     }
 }
 
-impl<Tag: Provenance> Place<Tag> {
+impl<'tcx, Tag: Provenance> PlaceTy<'tcx, Tag> {
+    /// A place is either an mplace or some local.
     #[inline]
-    pub fn assert_mem_place(self) -> MemPlace<Tag> {
-        match self {
-            Place::Ptr(mplace) => mplace,
-            _ => bug!("assert_mem_place: expected Place::Ptr, got {:?}", self),
+    pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Tag>, (usize, mir::Local)> {
+        match **self {
+            Place::Ptr(mplace) => Ok(MPlaceTy { mplace, layout: self.layout, align: self.align }),
+            Place::Local { frame, local } => Err((frame, local)),
         }
     }
-}
 
-impl<'tcx, Tag: Provenance> PlaceTy<'tcx, Tag> {
     #[inline]
     pub fn assert_mem_place(self) -> MPlaceTy<'tcx, Tag> {
-        MPlaceTy { mplace: self.place.assert_mem_place(), layout: self.layout }
+        self.try_as_mplace().unwrap()
     }
 }
 
@@ -306,16 +316,10 @@ where
             Immediate::ScalarPair(ptr, meta) => (ptr, MemPlaceMeta::Meta(meta.check_init()?)),
         };
 
-        let mplace = MemPlace {
-            ptr: self.scalar_to_ptr(ptr.check_init()?)?,
-            // We could use the run-time alignment here. For now, we do not, because
-            // the point of tracking the alignment here is to make sure that the *static*
-            // alignment information emitted with the loads is correct. The run-time
-            // alignment can only be more restrictive.
-            align: layout.align.abi,
-            meta,
-        };
-        Ok(MPlaceTy { mplace, layout })
+        let mplace = MemPlace { ptr: self.scalar_to_ptr(ptr.check_init()?)?, meta };
+        // When deref'ing a pointer, the *static* alignment given by the type is what matters.
+        let align = layout.align.abi;
+        Ok(MPlaceTy { mplace, layout, align })
     }
 
     /// Take an operand, representing a pointer, and dereference it to a place -- that
@@ -368,7 +372,7 @@ where
         let (size, align) = self
             .size_and_align_of_mplace(&mplace)?
             .unwrap_or((mplace.layout.size, mplace.layout.align.abi));
-        assert!(mplace.mplace.align <= align, "dynamic alignment less strict than static one?");
+        assert!(mplace.align <= align, "dynamic alignment less strict than static one?");
         let align = M::enforce_alignment(self).then_some(align);
         self.check_ptr_access_align(mplace.ptr, size, align.unwrap_or(Align::ONE), msg)?;
         Ok(())
@@ -533,7 +537,7 @@ where
 
             Index(local) => {
                 let layout = self.layout_of(self.tcx.types.usize)?;
-                let n = self.access_local(self.frame(), local, Some(layout))?;
+                let n = self.local_to_op(self.frame(), local, Some(layout))?;
                 let n = self.read_scalar(&n)?;
                 let n = n.to_machine_usize(self)?;
                 self.mplace_index(base, n)?
@@ -608,11 +612,9 @@ where
         variant: VariantIdx,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
         // Downcast just changes the layout
-        Ok(match base.place {
-            Place::Ptr(mplace) => {
-                self.mplace_downcast(&MPlaceTy { mplace, layout: base.layout }, variant)?.into()
-            }
-            Place::Local { .. } => {
+        Ok(match base.try_as_mplace() {
+            Ok(mplace) => self.mplace_downcast(&mplace, variant)?.into(),
+            Err(..) => {
                 let layout = base.layout.for_variant(self, variant);
                 PlaceTy { layout, ..*base }
             }
@@ -649,6 +651,16 @@ where
         self.mplace_to_simd(&mplace)
     }
 
+    pub fn local_to_place(
+        &self,
+        frame: usize,
+        local: mir::Local,
+    ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
+        let layout = self.layout_of_local(&self.stack()[frame], local, None)?;
+        let place = Place::Local { frame, local };
+        Ok(PlaceTy { place, layout, align: layout.align.abi })
+    }
+
     /// Computes a place. You should only use this if you intend to write into this
     /// place; for reading, a more efficient alternative is `eval_place_to_op`.
     #[instrument(skip(self), level = "debug")]
@@ -656,11 +668,7 @@ where
         &mut self,
         place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
-        let mut place_ty = PlaceTy {
-            // This works even for dead/uninitialized locals; we check further when writing
-            place: Place::Local { frame: self.frame_idx(), local: place.local },
-            layout: self.layout_of_local(self.frame(), place.local, None)?,
-        };
+        let mut place_ty = self.local_to_place(self.frame_idx(), place.local)?;
 
         for elem in place.projection.iter() {
             place_ty = self.place_projection(&place_ty, &elem)?
@@ -668,14 +676,19 @@ where
 
         trace!("{:?}", self.dump_place(place_ty.place));
         // Sanity-check the type we ended up with.
-        debug_assert!(mir_assign_valid_types(
-            *self.tcx,
-            self.param_env,
-            self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions(
-                place.ty(&self.frame().body.local_decls, *self.tcx).ty
-            )?)?,
-            place_ty.layout,
-        ));
+        debug_assert!(
+            mir_assign_valid_types(
+                *self.tcx,
+                self.param_env,
+                self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions(
+                    place.ty(&self.frame().body.local_decls, *self.tcx).ty
+                )?)?,
+                place_ty.layout,
+            ),
+            "eval_place of a MIR place with type {:?} produced an interpret place with type {:?}",
+            place.ty(&self.frame().body.local_decls, *self.tcx).ty,
+            place_ty.layout.ty,
+        );
         Ok(place_ty)
     }
 
@@ -746,7 +759,7 @@ where
             }
             Place::Ptr(mplace) => mplace, // already referring to memory
         };
-        let dest = MPlaceTy { mplace, layout: dest.layout };
+        let dest = MPlaceTy { mplace, layout: dest.layout, align: dest.align };
 
         // This is already in memory, write there.
         self.write_immediate_to_mplace_no_validate(src, &dest)
@@ -808,9 +821,9 @@ where
     }
 
     pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
-        let mplace = match dest.place {
-            Place::Ptr(mplace) => MPlaceTy { mplace, layout: dest.layout },
-            Place::Local { frame, local } => {
+        let mplace = match dest.try_as_mplace() {
+            Ok(mplace) => mplace,
+            Err((frame, local)) => {
                 match M::access_local_mut(self, frame, local)? {
                     Ok(local) => match dest.layout.abi {
                         Abi::Scalar(_) => {
@@ -830,7 +843,7 @@ where
                     },
                     Err(mplace) => {
                         // The local is in memory, go on below.
-                        MPlaceTy { mplace, layout: dest.layout }
+                        MPlaceTy { mplace, layout: dest.layout, align: dest.align }
                     }
                 }
             }
@@ -948,7 +961,7 @@ where
         let dest = self.force_allocation(dest)?;
         self.copy_op_no_validate(
             src,
-            &PlaceTy::from(MPlaceTy { mplace: *dest, layout: src.layout }),
+            &PlaceTy::from(MPlaceTy { mplace: *dest, layout: src.layout, align: dest.align }),
         )?;
 
         if M::enforce_validity(self) {
@@ -989,12 +1002,16 @@ where
                             .size_and_align_of(&meta, &local_layout)?
                             .expect("Cannot allocate for non-dyn-sized type");
                         let ptr = self.allocate_ptr(size, align, MemoryKind::Stack)?;
-                        let mplace = MemPlace { ptr: ptr.into(), align, meta };
+                        let mplace = MemPlace { ptr: ptr.into(), meta };
                         if let LocalValue::Live(Operand::Immediate(value)) = local_val {
                             // Preserve old value.
                             // We don't have to validate as we can assume the local
                             // was already valid for its type.
-                            let mplace = MPlaceTy { mplace, layout: local_layout };
+                            let mplace = MPlaceTy {
+                                mplace,
+                                layout: local_layout,
+                                align: local_layout.align.abi,
+                            };
                             self.write_immediate_to_mplace_no_validate(value, &mplace)?;
                         }
                         // Now we can call `access_mut` again, asserting it goes well,
@@ -1009,7 +1026,7 @@ where
             Place::Ptr(mplace) => (mplace, None),
         };
         // Return with the original layout, so that the caller can go on
-        Ok((MPlaceTy { mplace, layout: place.layout }, size))
+        Ok((MPlaceTy { mplace, layout: place.layout, align: place.align }, size))
     }
 
     #[inline(always)]
@@ -1038,15 +1055,14 @@ where
     ) -> MPlaceTy<'tcx, M::PointerTag> {
         let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl);
         let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self);
-        let mplace =
-            MemPlace { ptr: ptr.into(), align: Align::ONE, meta: MemPlaceMeta::Meta(meta) };
+        let mplace = MemPlace { ptr: ptr.into(), meta: MemPlaceMeta::Meta(meta) };
 
         let ty = self.tcx.mk_ref(
             self.tcx.lifetimes.re_static,
             ty::TypeAndMut { ty: self.tcx.types.str_, mutbl },
         );
         let layout = self.layout_of(ty).unwrap();
-        MPlaceTy { mplace, layout }
+        MPlaceTy { mplace, layout, align: layout.align.abi }
     }
 
     /// Writes the discriminant of the given variant.
@@ -1166,7 +1182,11 @@ where
             assert_eq!(align, layout.align.abi);
         }
 
-        let mplace = MPlaceTy { mplace: MemPlace { meta: MemPlaceMeta::None, ..**mplace }, layout };
+        let mplace = MPlaceTy {
+            mplace: MemPlace { meta: MemPlaceMeta::None, ..**mplace },
+            layout,
+            align: layout.align.abi,
+        };
         Ok((instance, mplace))
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs
index 9c48f3e8337..22c23df7b1a 100644
--- a/compiler/rustc_const_eval/src/interpret/traits.rs
+++ b/compiler/rustc_const_eval/src/interpret/traits.rs
@@ -1,6 +1,6 @@
 use std::convert::TryFrom;
 
-use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic};
+use rustc_middle::mir::interpret::{alloc_range, InterpResult, Pointer, PointerArithmetic};
 use rustc_middle::ty::{
     self, Ty, TyCtxt, COMMON_VTABLE_ENTRIES_ALIGN, COMMON_VTABLE_ENTRIES_DROPINPLACE,
     COMMON_VTABLE_ENTRIES_SIZE,
@@ -102,18 +102,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             )?
             .expect("cannot be a ZST");
         let size = vtable
-            .read_integer(
+            .read_integer(alloc_range(
                 pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_SIZE).unwrap(),
                 pointer_size,
-            )?
+            ))?
             .check_init()?;
         let size = size.to_machine_usize(self)?;
         let size = Size::from_bytes(size);
         let align = vtable
-            .read_integer(
+            .read_integer(alloc_range(
                 pointer_size * u64::try_from(COMMON_VTABLE_ENTRIES_ALIGN).unwrap(),
                 pointer_size,
-            )?
+            ))?
             .check_init()?;
         let align = align.to_machine_usize(self)?;
         let align = Align::from_bytes(align).map_err(|e| err_ub!(InvalidVtableAlignment(e)))?;
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 847694cbd10..0bf78446e37 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -593,16 +593,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
                 self.check_safe_pointer(value, "reference")?;
                 Ok(true)
             }
-            ty::Adt(def, ..) if def.is_box() => {
-                let unique = self.ecx.operand_field(value, 0)?;
-                let nonnull = self.ecx.operand_field(&unique, 0)?;
-                let ptr = self.ecx.operand_field(&nonnull, 0)?;
-                self.check_safe_pointer(&ptr, "box")?;
-
-                // Check other fields of Box
-                self.walk_value(value)?;
-                Ok(true)
-            }
             ty::FnPtr(_sig) => {
                 let value = try_validation!(
                     self.ecx.read_scalar(value).and_then(|v| v.check_init()),
@@ -814,6 +804,12 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
     }
 
     #[inline]
+    fn visit_box(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
+        self.check_safe_pointer(op, "box")?;
+        Ok(())
+    }
+
+    #[inline]
     fn visit_value(&mut self, op: &OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
         trace!("visit_value: {:?}, {:?}", *op, op.layout);
 
@@ -821,8 +817,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
         if self.try_visit_primitive(op)? {
             return Ok(());
         }
-        // Sanity check: `builtin_deref` does not know any pointers that are not primitive.
-        assert!(op.layout.ty.builtin_deref(true).is_none());
 
         // Special check preventing `UnsafeCell` in the inner part of constants
         if let Some(def) = op.layout.ty.ty_adt_def() {
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index 2b77ed89893..ded4c6a557a 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -151,6 +151,14 @@ macro_rules! make_value_visitor {
             {
                 Ok(())
             }
+            /// Visits the given value as the pointer of a `Box`. There is nothing to recurse into.
+            /// The type of `v` will be a raw pointer, but this is a field of `Box<T>` and the
+            /// pointee type is the actual `T`.
+            #[inline(always)]
+            fn visit_box(&mut self, _v: &Self::V) -> InterpResult<'tcx>
+            {
+                Ok(())
+            }
             /// Visits this value as an aggregate, you are getting an iterator yielding
             /// all the fields (still in an `InterpResult`, you have to do error handling yourself).
             /// Recurses into the fields.
@@ -221,6 +229,47 @@ macro_rules! make_value_visitor {
                     // Slices do not need special handling here: they have `Array` field
                     // placement with length 0, so we enter the `Array` case below which
                     // indirectly uses the metadata to determine the actual length.
+
+                    // However, `Box`... let's talk about `Box`.
+                    ty::Adt(def, ..) if def.is_box() => {
+                        // `Box` is a hybrid primitive-library-defined type that one the one hand is
+                        // a dereferenceable pointer, on the other hand has *basically arbitrary
+                        // user-defined layout* since the user controls the 'allocator' field. So it
+                        // cannot be treated like a normal pointer, since it does not fit into an
+                        // `Immediate`. Yeah, it is quite terrible. But many visitors want to do
+                        // something with "all boxed pointers", so we handle this mess for them.
+                        //
+                        // When we hit a `Box`, we do not do the usual `visit_aggregate`; instead,
+                        // we (a) call `visit_box` on the pointer value, and (b) recurse on the
+                        // allocator field. We also assert tons of things to ensure we do not miss
+                        // any other fields.
+
+                        // `Box` has two fields: the pointer we care about, and the allocator.
+                        assert_eq!(v.layout().fields.count(), 2, "`Box` must have exactly 2 fields");
+                        let (unique_ptr, alloc) =
+                            (v.project_field(self.ecx(), 0)?, v.project_field(self.ecx(), 1)?);
+                        // Unfortunately there is some type junk in the way here: `unique_ptr` is a `Unique`...
+                        // (which means another 2 fields, the second of which is a `PhantomData`)
+                        assert_eq!(unique_ptr.layout().fields.count(), 2);
+                        let (nonnull_ptr, phantom) = (
+                            unique_ptr.project_field(self.ecx(), 0)?,
+                            unique_ptr.project_field(self.ecx(), 1)?,
+                        );
+                        assert!(
+                            phantom.layout().ty.ty_adt_def().is_some_and(|adt| adt.is_phantom_data()),
+                            "2nd field of `Unique` should be PhantomData but is {:?}",
+                            phantom.layout().ty,
+                        );
+                        // ... that contains a `NonNull`... (gladly, only a single field here)
+                        assert_eq!(nonnull_ptr.layout().fields.count(), 1);
+                        let raw_ptr = nonnull_ptr.project_field(self.ecx(), 0)?; // the actual raw ptr
+                        // ... whose only field finally is a raw ptr we can dereference.
+                        self.visit_box(&raw_ptr)?;
+
+                        // The second `Box` field is the allocator, which we recursively check for validity
+                        // like in regular structs.
+                        self.visit_field(v, 1, &alloc)?;
+                    }
                     _ => {},
                 };
 
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 5bf91879066..2d42ae236ad 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -21,6 +21,7 @@ Rust MIR: a lowered representation of Rust.
 #![feature(trusted_step)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
+#![feature(is_some_with)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
 
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index 3096af90d47..b71cdad718a 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -849,10 +849,10 @@ Available lint options:
     };
 
     println!("Lint checks provided by rustc:\n");
-    println!("    {}  {:7.7}  {}", padded("name"), "default", "meaning");
-    println!("    {}  {:7.7}  {}", padded("----"), "-------", "-------");
 
     let print_lints = |lints: Vec<&Lint>| {
+        println!("    {}  {:7.7}  {}", padded("name"), "default", "meaning");
+        println!("    {}  {:7.7}  {}", padded("----"), "-------", "-------");
         for lint in lints {
             let name = lint.name_lower().replace('_', "-");
             println!(
@@ -884,11 +884,15 @@ Available lint options:
     };
 
     println!("Lint groups provided by rustc:\n");
-    println!("    {}  sub-lints", padded("name"));
-    println!("    {}  ---------", padded("----"));
-    println!("    {}  all lints that are set to issue warnings", padded("warnings"));
 
-    let print_lint_groups = |lints: Vec<(&'static str, Vec<LintId>)>| {
+    let print_lint_groups = |lints: Vec<(&'static str, Vec<LintId>)>, all_warnings| {
+        println!("    {}  sub-lints", padded("name"));
+        println!("    {}  ---------", padded("----"));
+
+        if all_warnings {
+            println!("    {}  all lints that are set to issue warnings", padded("warnings"));
+        }
+
         for (name, to) in lints {
             let name = name.to_lowercase().replace('_', "-");
             let desc = to
@@ -901,7 +905,7 @@ Available lint options:
         println!("\n");
     };
 
-    print_lint_groups(builtin_groups);
+    print_lint_groups(builtin_groups, true);
 
     match (loaded_plugins, plugin.len(), plugin_groups.len()) {
         (false, 0, _) | (false, _, 0) => {
@@ -916,7 +920,7 @@ Available lint options:
             }
             if g > 0 {
                 println!("Lint groups provided by plugins loaded by this crate:\n");
-                print_lint_groups(plugin_groups);
+                print_lint_groups(plugin_groups, false);
             }
         }
     }
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 1694a8865dd..74e9bbeeeaf 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -152,6 +152,19 @@ impl<'a> ExtCtxt<'a> {
         ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
     }
 
+    pub fn stmt_let_pat(&self, sp: Span, pat: P<ast::Pat>, ex: P<ast::Expr>) -> ast::Stmt {
+        let local = P(ast::Local {
+            pat,
+            ty: None,
+            id: ast::DUMMY_NODE_ID,
+            kind: LocalKind::Init(ex),
+            span: sp,
+            attrs: AttrVec::new(),
+            tokens: None,
+        });
+        self.stmt_local(local, sp)
+    }
+
     pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
         self.stmt_let_ty(sp, mutbl, ident, None, ex)
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 07dcf3876c8..4d29fc46946 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -315,8 +315,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         body_id: Option<hir::BodyId>,
         failure_span: Span,
         arg: GenericArg<'tcx>,
-        // FIXME(#94483): Either use this or remove it.
-        _impl_candidates: Vec<ty::TraitRef<'tcx>>,
         error_code: TypeAnnotationNeeded,
         should_label_span: bool,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
@@ -534,6 +532,23 @@ enum InferSourceKind<'tcx> {
     },
 }
 
+impl<'tcx> InferSource<'tcx> {
+    fn from_expansion(&self) -> bool {
+        let source_from_expansion = match self.kind {
+            InferSourceKind::LetBinding { insert_span, .. }
+            | InferSourceKind::ClosureArg { insert_span, .. }
+            | InferSourceKind::GenericArg { insert_span, .. } => insert_span.from_expansion(),
+            InferSourceKind::FullyQualifiedMethodCall { receiver, .. } => {
+                receiver.span.from_expansion()
+            }
+            InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
+                data.span().from_expansion() || should_wrap_expr.map_or(false, Span::from_expansion)
+            }
+        };
+        source_from_expansion || self.span.from_expansion()
+    }
+}
+
 impl<'tcx> InferSourceKind<'tcx> {
     fn ty_msg(&self, infcx: &InferCtxt<'_, 'tcx>) -> String {
         match *self {
@@ -604,43 +619,65 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
     /// Sources with a small cost are prefer and should result
     /// in a clearer and idiomatic suggestion.
     fn source_cost(&self, source: &InferSource<'tcx>) -> usize {
-        let tcx = self.infcx.tcx;
-
-        fn arg_cost<'tcx>(arg: GenericArg<'tcx>) -> usize {
-            match arg.unpack() {
-                GenericArgKind::Lifetime(_) => 0, // erased
-                GenericArgKind::Type(ty) => ty_cost(ty),
-                GenericArgKind::Const(_) => 3, // some non-zero value
-            }
+        #[derive(Clone, Copy)]
+        struct CostCtxt<'tcx> {
+            tcx: TyCtxt<'tcx>,
         }
-        fn ty_cost<'tcx>(ty: Ty<'tcx>) -> usize {
-            match ty.kind() {
-                ty::Closure(..) => 100,
-                ty::FnDef(..) => 20,
-                ty::FnPtr(..) => 10,
-                ty::Infer(..) => 0,
-                _ => 1,
+        impl<'tcx> CostCtxt<'tcx> {
+            fn arg_cost(self, arg: GenericArg<'tcx>) -> usize {
+                match arg.unpack() {
+                    GenericArgKind::Lifetime(_) => 0, // erased
+                    GenericArgKind::Type(ty) => self.ty_cost(ty),
+                    GenericArgKind::Const(_) => 3, // some non-zero value
+                }
+            }
+            fn ty_cost(self, ty: Ty<'tcx>) -> usize {
+                match *ty.kind() {
+                    ty::Closure(..) => 1000,
+                    ty::FnDef(..) => 150,
+                    ty::FnPtr(..) => 30,
+                    ty::Adt(def, substs) => {
+                        5 + self
+                            .tcx
+                            .generics_of(def.did())
+                            .own_substs_no_defaults(self.tcx, substs)
+                            .iter()
+                            .map(|&arg| self.arg_cost(arg))
+                            .sum::<usize>()
+                    }
+                    ty::Tuple(args) => 5 + args.iter().map(|arg| self.ty_cost(arg)).sum::<usize>(),
+                    ty::Ref(_, ty, _) => 2 + self.ty_cost(ty),
+                    ty::Infer(..) => 0,
+                    _ => 1,
+                }
             }
         }
 
         // The sources are listed in order of preference here.
-        match source.kind {
-            InferSourceKind::LetBinding { ty, .. } => ty_cost(ty),
-            InferSourceKind::ClosureArg { ty, .. } => 5 + ty_cost(ty),
+        let tcx = self.infcx.tcx;
+        let ctx = CostCtxt { tcx };
+        let base_cost = match source.kind {
+            InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
+            InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
             InferSourceKind::GenericArg { def_id, generic_args, .. } => {
                 let variant_cost = match tcx.def_kind(def_id) {
-                    DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15, // `None::<u32>` and friends are ugly.
-                    _ => 12,
+                    // `None::<u32>` and friends are ugly.
+                    DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15,
+                    _ => 10,
                 };
-                variant_cost + generic_args.iter().map(|&arg| arg_cost(arg)).sum::<usize>()
+                variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::<usize>()
             }
             InferSourceKind::FullyQualifiedMethodCall { substs, .. } => {
-                20 + substs.iter().map(|arg| arg_cost(arg)).sum::<usize>()
+                20 + substs.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>()
             }
             InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
-                30 + ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
+                30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
             }
-        }
+        };
+
+        let suggestion_may_apply = if source.from_expansion() { 10000 } else { 0 };
+
+        base_cost + suggestion_may_apply
     }
 
     /// Uses `fn source_cost` to determine whether this inference source is preferable to
@@ -648,6 +685,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn update_infer_source(&mut self, new_source: InferSource<'tcx>) {
         let cost = self.source_cost(&new_source) + self.attempt;
+        debug!(?cost);
         self.attempt += 1;
         if cost < self.infer_source_cost {
             self.infer_source_cost = cost;
@@ -655,6 +693,11 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
         }
     }
 
+    fn node_substs_opt(&self, hir_id: HirId) -> Option<SubstsRef<'tcx>> {
+        let substs = self.typeck_results.node_substs_opt(hir_id);
+        self.infcx.resolve_vars_if_possible(substs)
+    }
+
     fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
         let ty = self.typeck_results.node_type_opt(hir_id);
         self.infcx.resolve_vars_if_possible(ty)
@@ -737,7 +780,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
         let tcx = self.infcx.tcx;
         match expr.kind {
             hir::ExprKind::Path(ref path) => {
-                if let Some(substs) = self.typeck_results.node_substs_opt(expr.hir_id) {
+                if let Some(substs) = self.node_substs_opt(expr.hir_id) {
                     return self.path_inferred_subst_iter(expr.hir_id, substs, path);
                 }
             }
@@ -765,7 +808,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                         if generics.has_impl_trait() {
                             None?
                         }
-                        let substs = self.typeck_results.node_substs_opt(expr.hir_id)?;
+                        let substs = self.node_substs_opt(expr.hir_id)?;
                         let span = tcx.hir().span(segment.hir_id?);
                         let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
                         InsertableGenericArgs {
@@ -980,8 +1023,10 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             debug!(?args);
             let InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } = args;
             let generics = tcx.generics_of(generics_def_id);
-            if let Some(argument_index) =
-                generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
+            if let Some(argument_index) = generics
+                .own_substs(substs)
+                .iter()
+                .position(|&arg| self.generic_arg_contains_target(arg))
             {
                 let substs = self.infcx.resolve_vars_if_possible(substs);
                 let generic_args = &generics.own_substs_no_defaults(tcx, substs)
@@ -1037,7 +1082,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             .any(|generics| generics.has_impl_trait())
         };
         if let ExprKind::MethodCall(path, args, span) = expr.kind
-            && let Some(substs) = self.typeck_results.node_substs_opt(expr.hir_id)
+            && let Some(substs) = self.node_substs_opt(expr.hir_id)
             && substs.iter().any(|arg| self.generic_arg_contains_target(arg))
             && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
             && self.infcx.tcx.trait_of_item(def_id).is_some()
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 1e2b53040d2..1bbd71c3f1f 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -160,12 +160,18 @@ impl AllocError {
 }
 
 /// The information that makes up a memory access: offset and size.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone)]
 pub struct AllocRange {
     pub start: Size,
     pub size: Size,
 }
 
+impl fmt::Debug for AllocRange {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "[{:#x}..{:#x}]", self.start.bytes(), self.end().bytes())
+    }
+}
+
 /// Free-starting constructor for less syntactic overhead.
 #[inline(always)]
 pub fn alloc_range(start: Size, size: Size) -> AllocRange {
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index a33a2921f57..f30769248c0 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -334,36 +334,30 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
                 p,
             ),
             PointerUseAfterFree(a) => {
-                write!(f, "pointer to {} was dereferenced after this allocation got freed", a)
+                write!(f, "pointer to {a:?} was dereferenced after this allocation got freed")
             }
             PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size: Size::ZERO, msg } => {
                 write!(
                     f,
-                    "{}{alloc_id} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds",
-                    msg,
-                    alloc_id = alloc_id,
+                    "{msg}{alloc_id:?} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds",
                     alloc_size = alloc_size.bytes(),
-                    ptr_offset = ptr_offset,
                 )
             }
             PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => write!(
                 f,
-                "{}{alloc_id} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds",
-                msg,
-                alloc_id = alloc_id,
+                "{msg}{alloc_id:?} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds",
                 alloc_size = alloc_size.bytes(),
                 ptr_size = ptr_size.bytes(),
                 ptr_size_p = pluralize!(ptr_size.bytes()),
-                ptr_offset = ptr_offset,
             ),
             DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => {
                 write!(f, "null pointer is not a valid pointer for this operation")
             }
             DanglingIntPointer(0, msg) => {
-                write!(f, "{}null pointer is not a valid pointer", msg)
+                write!(f, "{msg}null pointer is not a valid pointer")
             }
             DanglingIntPointer(i, msg) => {
-                write!(f, "{}0x{:x} is not a valid pointer", msg, i)
+                write!(f, "{msg}{i:#x} is not a valid pointer")
             }
             AlignmentCheckFailed { required, has } => write!(
                 f,
@@ -371,8 +365,8 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
                 has.bytes(),
                 required.bytes()
             ),
-            WriteToReadOnly(a) => write!(f, "writing to {} which is read-only", a),
-            DerefFunctionPointer(a) => write!(f, "accessing {} which contains a function", a),
+            WriteToReadOnly(a) => write!(f, "writing to {a:?} which is read-only"),
+            DerefFunctionPointer(a) => write!(f, "accessing {a:?} which contains a function"),
             ValidationFailure { path: None, msg } => {
                 write!(f, "constructing invalid value: {}", msg)
             }
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 8733a85ef3f..698024b2330 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -190,11 +190,7 @@ impl fmt::Debug for AllocId {
     }
 }
 
-impl fmt::Display for AllocId {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Debug::fmt(self, f)
-    }
-}
+// No "Display" since AllocIds are not usually user-visible.
 
 #[derive(TyDecodable, TyEncodable)]
 enum AllocDiscriminant {
@@ -470,7 +466,7 @@ impl<'tcx> TyCtxt<'tcx> {
             return alloc_id;
         }
         let id = alloc_map.reserve();
-        debug!("creating alloc {:?} with id {}", alloc, id);
+        debug!("creating alloc {alloc:?} with id {id:?}");
         alloc_map.alloc_map.insert(id, alloc.clone());
         alloc_map.dedup.insert(alloc, id);
         id
@@ -538,7 +534,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> {
         match self.get_global_alloc(id) {
             Some(alloc) => alloc,
-            None => bug!("could not find allocation for {}", id),
+            None => bug!("could not find allocation for {id:?}"),
         }
     }
 
@@ -546,7 +542,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// call this function twice, even with the same `Allocation` will ICE the compiler.
     pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) {
         if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
-            bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
+            bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
         }
     }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index 26da93b9dce..81d744107fd 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -144,7 +144,7 @@ impl Provenance for AllocId {
         }
         // Print offset only if it is non-zero.
         if ptr.offset.bytes() > 0 {
-            write!(f, "+0x{:x}", ptr.offset.bytes())?;
+            write!(f, "+{:#x}", ptr.offset.bytes())?;
         }
         Ok(())
     }
@@ -181,7 +181,7 @@ impl<Tag: Provenance> fmt::Debug for Pointer<Option<Tag>> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.provenance {
             Some(tag) => Provenance::fmt(&Pointer::new(tag, self.offset), f),
-            None => write!(f, "0x{:x}", self.offset.bytes()),
+            None => write!(f, "{:#x}", self.offset.bytes()),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index e80918d5e5d..8ecbb5ab0b3 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -167,7 +167,7 @@ impl<Tag: Provenance> fmt::LowerHex for Scalar<Tag> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             Scalar::Ptr(ptr, _size) => write!(f, "pointer to {:?}", ptr),
-            Scalar::Int(int) => write!(f, "0x{:x}", int),
+            Scalar::Int(int) => write!(f, "{:#x}", int),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 462c0ada3cf..24c6cd91d0a 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -716,12 +716,12 @@ pub fn write_allocations<'tcx>(
                 }
                 write!(w, "{}", display_allocation(tcx, alloc.inner()))
             };
-        write!(w, "\n{}", id)?;
+        write!(w, "\n{id:?}")?;
         match tcx.get_global_alloc(id) {
             // This can't really happen unless there are bugs, but it doesn't cost us anything to
             // gracefully handle it and allow buggy rustc to be debugged via allocation printing.
             None => write!(w, " (deallocated)")?,
-            Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?,
+            Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {inst})")?,
             Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
                 match tcx.eval_static_initializer(did) {
                     Ok(alloc) => {
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index f8ee59f306f..3b7eb820df8 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -311,6 +311,7 @@ pub enum StatementKind<'tcx> {
 
 /// Describes what kind of retag is to be performed.
 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, HashStable)]
+#[rustc_pass_by_value]
 pub enum RetagKind {
     /// The initial retag when entering a function.
     FnEntry,
@@ -990,11 +991,19 @@ pub enum Rvalue<'tcx> {
     ///   matching types and return a value of that type.
     BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
 
-    /// Same as `BinaryOp`, but yields `(T, bool)` instead of `T`. In addition to performing the
-    /// same computation as the matching `BinaryOp`, checks if the infinite precison result would be
-    /// unequal to the actual result and sets the `bool` if this is the case.
+    /// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
     ///
-    /// This only supports addition, subtraction, multiplication, and shift operations on integers.
+    /// When overflow checking is disabled, the error condition is false. Otherwise, the error
+    /// condition is determined as described below.
+    ///
+    /// For addition, subtraction, and multiplication on integers the error condition is set when
+    /// the infinite precision result would be unequal to the actual result.
+    ///
+    /// For shift operations on integers the error condition is set when the value of right-hand
+    /// side is greater than or equal to the number of bits in the type of the left-hand side, or
+    /// when the value of right-hand side is negative.
+    ///
+    /// Other combinations of types and operators are unsupported.
     CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
 
     /// Computes a value as described by the operation.
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 9285246eb79..d1477f9e2ae 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -147,7 +147,7 @@ macro_rules! make_mir_visitor {
             fn visit_ascribe_user_ty(
                 &mut self,
                 place: & $($mutability)? Place<'tcx>,
-                variance: & $($mutability)? ty::Variance,
+                variance: $(& $mutability)? ty::Variance,
                 user_ty: & $($mutability)? UserTypeProjection,
                 location: Location,
             ) {
@@ -164,7 +164,7 @@ macro_rules! make_mir_visitor {
 
             fn visit_retag(
                 &mut self,
-                kind: & $($mutability)? RetagKind,
+                kind: $(& $mutability)? RetagKind,
                 place: & $($mutability)? Place<'tcx>,
                 location: Location,
             ) {
@@ -425,7 +425,7 @@ macro_rules! make_mir_visitor {
                 self.visit_source_info(source_info);
                 match kind {
                     StatementKind::Assign(
-                        box(ref $($mutability)? place, ref $($mutability)? rvalue)
+                        box (place, rvalue)
                     ) => {
                         self.visit_assign(place, rvalue, location);
                     }
@@ -465,13 +465,13 @@ macro_rules! make_mir_visitor {
                         );
                     }
                     StatementKind::Retag(kind, place) => {
-                        self.visit_retag(kind, place, location);
+                        self.visit_retag($(& $mutability)? *kind, place, location);
                     }
                     StatementKind::AscribeUserType(
-                        box(ref $($mutability)? place, ref $($mutability)? user_ty),
+                        box (place, user_ty),
                         variance
                     ) => {
-                        self.visit_ascribe_user_ty(place, variance, user_ty, location);
+                        self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location);
                     }
                     StatementKind::Coverage(coverage) => {
                         self.visit_coverage(
@@ -480,9 +480,9 @@ macro_rules! make_mir_visitor {
                         )
                     }
                     StatementKind::CopyNonOverlapping(box crate::mir::CopyNonOverlapping{
-                      ref $($mutability)? src,
-                      ref $($mutability)? dst,
-                      ref $($mutability)? count,
+                        src,
+                        dst,
+                        count,
                     }) => {
                       self.visit_operand(src, location);
                       self.visit_operand(dst, location);
@@ -517,8 +517,7 @@ macro_rules! make_mir_visitor {
                     TerminatorKind::GeneratorDrop |
                     TerminatorKind::Unreachable |
                     TerminatorKind::FalseEdge { .. } |
-                    TerminatorKind::FalseUnwind { .. } => {
-                    }
+                    TerminatorKind::FalseUnwind { .. } => {}
 
                     TerminatorKind::Return => {
                         // `return` logically moves from the return place `_0`. Note that the place
@@ -830,7 +829,7 @@ macro_rules! make_mir_visitor {
 
             fn super_ascribe_user_ty(&mut self,
                                      place: & $($mutability)? Place<'tcx>,
-                                     _variance: & $($mutability)? ty::Variance,
+                                     _variance: $(& $mutability)? ty::Variance,
                                      user_ty: & $($mutability)? UserTypeProjection,
                                      location: Location) {
                 self.visit_place(
@@ -847,7 +846,7 @@ macro_rules! make_mir_visitor {
             }
 
             fn super_retag(&mut self,
-                           _kind: & $($mutability)? RetagKind,
+                           _kind: $(& $mutability)? RetagKind,
                            place: & $($mutability)? Place<'tcx>,
                            location: Location) {
                 self.visit_place(
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 294f56d16b1..b8bb93891c2 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1825,7 +1825,8 @@ rustc_queries! {
         remap_env_constness
     }
 
-    /// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead.
+    /// Do not call this query directly:
+    /// invoke `DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx)` instead.
     query dropck_outlives(
         goal: CanonicalTyGoal<'tcx>
     ) -> Result<
diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs
index 51e51a63fd0..c7c2692281e 100644
--- a/compiler/rustc_middle/src/ty/consts/int.rs
+++ b/compiler/rustc_middle/src/ty/consts/int.rs
@@ -452,6 +452,10 @@ impl fmt::Debug for ScalarInt {
 impl fmt::LowerHex for ScalarInt {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.check_data();
+        if f.alternate() {
+            // Like regular ints, alternate flag adds leading `0x`.
+            write!(f, "0x")?;
+        }
         // Format as hex number wide enough to fit any value of the given `size`.
         // So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
         // Using a block `{self.data}` here to force a copy instead of using `self.data`
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index ce387cb4453..12f5764152e 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -180,16 +180,20 @@ impl<'tcx> Inliner<'tcx> {
             return Err("failed to normalize return type");
         }
         if callsite.fn_sig.abi() == Abi::RustCall {
-            let mut args = args.into_iter();
-            let _ = args.next(); // Skip `self` argument.
-            let arg_tuple_ty = args.next().unwrap().ty(&caller_body.local_decls, self.tcx);
-            assert!(args.next().is_none());
+            let (arg_tuple, skipped_args) = match &args[..] {
+                [arg_tuple] => (arg_tuple, 0),
+                [_, arg_tuple] => (arg_tuple, 1),
+                _ => bug!("Expected `rust-call` to have 1 or 2 args"),
+            };
 
+            let arg_tuple_ty = arg_tuple.ty(&caller_body.local_decls, self.tcx);
             let ty::Tuple(arg_tuple_tys) = arg_tuple_ty.kind() else {
                 bug!("Closure arguments are not passed as a tuple");
             };
 
-            for (arg_ty, input) in arg_tuple_tys.iter().zip(callee_body.args_iter().skip(1)) {
+            for (arg_ty, input) in
+                arg_tuple_tys.iter().zip(callee_body.args_iter().skip(skipped_args))
+            {
                 let input_type = callee_body.local_decls[input].ty;
                 if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) {
                     trace!(?arg_ty, ?input_type);
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index f9e67310452..1add91fc9c5 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,4 +1,4 @@
-use rustc_ast::entry::EntryPointType;
+use rustc_ast::{entry::EntryPointType, Attribute};
 use rustc_errors::struct_span_err;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -7,9 +7,8 @@ use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{DefIdTree, TyCtxt};
 use rustc_session::config::{CrateType, EntryFnType};
 use rustc_session::parse::feature_err;
-use rustc_session::Session;
 use rustc_span::symbol::sym;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{Span, Symbol, DUMMY_SP};
 
 struct EntryContext<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -72,9 +71,16 @@ fn entry_point_type(ctxt: &EntryContext<'_>, id: ItemId, at_root: bool) -> Entry
     }
 }
 
-fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
-    sess.struct_span_err(span, &format!("`{}` attribute can only be used on functions", attr))
-        .emit();
+fn err_if_attr_found(ctxt: &EntryContext<'_>, attrs: &[Attribute], sym: Symbol) {
+    if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym) {
+        ctxt.tcx
+            .sess
+            .struct_span_err(
+                attr.span,
+                &format!("`{}` attribute can only be used on functions", sym.as_str()),
+            )
+            .emit();
+    }
 }
 
 fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
@@ -84,12 +90,8 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
         EntryPointType::None => (),
         _ if !matches!(ctxt.tcx.def_kind(id.def_id), DefKind::Fn) => {
             let attrs = ctxt.tcx.hir().attrs(id.hir_id());
-            if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::start) {
-                throw_attr_err(&ctxt.tcx.sess, attr.span, "start");
-            }
-            if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::rustc_main) {
-                throw_attr_err(&ctxt.tcx.sess, attr.span, "rustc_main");
-            }
+            err_if_attr_found(ctxt, attrs, sym::start);
+            err_if_attr_found(ctxt, attrs, sym::rustc_main);
         }
         EntryPointType::MainNamed => (),
         EntryPointType::OtherMain => {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 74cd88ea0dd..e7717f1367c 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2724,8 +2724,8 @@ pub(crate) mod dep_tracking {
     use super::{
         BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType,
         InstrumentCoverage, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel,
-        OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath,
-        SymbolManglingVersion, TrimmedDefPaths,
+        OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, SplitDwarfKind,
+        SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths,
     };
     use crate::lint;
     use crate::options::WasiExecModel;
@@ -2812,6 +2812,7 @@ pub(crate) mod dep_tracking {
         Edition,
         LinkerPluginLto,
         SplitDebuginfo,
+        SplitDwarfKind,
         StackProtector,
         SwitchWithOptPath,
         SymbolManglingVersion,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 441e1f9f6a2..be70ea5d5e4 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1496,7 +1496,7 @@ options! {
         "control if mem::uninitialized and mem::zeroed panic on more UB"),
     strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
         "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
-    split_dwarf_kind: SplitDwarfKind = (SplitDwarfKind::Split, parse_split_dwarf_kind, [UNTRACKED],
+    split_dwarf_kind: SplitDwarfKind = (SplitDwarfKind::Split, parse_split_dwarf_kind, [TRACKED],
         "split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
         (default: `split`)
 
@@ -1504,7 +1504,7 @@ options! {
                  file which is ignored by the linker
         `single`: sections which do not require relocation are written into object file but ignored
                   by the linker"),
-    split_dwarf_inlining: bool = (true, parse_bool, [UNTRACKED],
+    split_dwarf_inlining: bool = (true, parse_bool, [TRACKED],
         "provide minimal debug info in the object/executable to facilitate online \
          symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"),
     symbol_mangling_version: Option<SymbolManglingVersion> = (None,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index fa56219b409..88b09f4de0a 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1980,7 +1980,6 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                             body_id,
                             span,
                             trait_ref.self_ty().skip_binder().into(),
-                            vec![],
                             ErrorCode::E0282,
                             false,
                         )
@@ -2005,19 +2004,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts());
 
                 let mut err = if let Some(subst) = subst {
-                    let impl_candidates = self
-                        .find_similar_impl_candidates(trait_ref)
-                        .into_iter()
-                        .map(|candidate| candidate.trait_ref)
-                        .collect();
-                    self.emit_inference_failure_err(
-                        body_id,
-                        span,
-                        subst,
-                        impl_candidates,
-                        ErrorCode::E0283,
-                        true,
-                    )
+                    self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true)
                 } else {
                     struct_span_err!(
                         self.tcx.sess,
@@ -2117,7 +2104,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                     return;
                 }
 
-                self.emit_inference_failure_err(body_id, span, arg, vec![], ErrorCode::E0282, false)
+                self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282, false)
             }
 
             ty::PredicateKind::Subtype(data) => {
@@ -2131,14 +2118,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                 let SubtypePredicate { a_is_expected: _, a, b } = data;
                 // both must be type variables, or the other would've been instantiated
                 assert!(a.is_ty_var() && b.is_ty_var());
-                self.emit_inference_failure_err(
-                    body_id,
-                    span,
-                    a.into(),
-                    vec![],
-                    ErrorCode::E0282,
-                    true,
-                )
+                self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
             }
             ty::PredicateKind::Projection(data) => {
                 if predicate.references_error() || self.is_tainted_by_errors() {
@@ -2155,7 +2135,6 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                         body_id,
                         span,
                         subst,
-                        vec![],
                         ErrorCode::E0284,
                         true,
                     );
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index f9708d6d919..6744536338c 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -599,6 +599,7 @@ impl UnifyKey for FloatVid {
 }
 
 #[derive(Copy, Clone, PartialEq, Decodable, Encodable, Hash)]
+#[rustc_pass_by_value]
 pub enum Variance {
     Covariant,     // T<A> <: T<B> iff A <: B -- e.g., function return type
     Invariant,     // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 83a8c5ea021..96b1847f8bb 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -280,15 +280,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         callee_node: &hir::ExprKind<'_>,
         callee_span: Span,
     ) {
-        let hir_id = self.tcx.hir().get_parent_node(hir_id);
-        let parent_node = self.tcx.hir().get(hir_id);
+        let hir = self.tcx.hir();
+        let parent_hir_id = hir.get_parent_node(hir_id);
+        let parent_node = hir.get(parent_hir_id);
         if let (
             hir::Node::Expr(hir::Expr {
-                kind: hir::ExprKind::Closure { fn_decl_span, .. }, ..
+                kind: hir::ExprKind::Closure { fn_decl_span, body, .. },
+                ..
             }),
             hir::ExprKind::Block(..),
         ) = (parent_node, callee_node)
         {
+            let fn_decl_span = if hir.body(*body).generator_kind
+                == Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure))
+            {
+                // Actually need to unwrap a few more layers of HIR to get to
+                // the _real_ closure...
+                let async_closure = hir.get_parent_node(hir.get_parent_node(parent_hir_id));
+                if let hir::Node::Expr(hir::Expr {
+                    kind: hir::ExprKind::Closure { fn_decl_span, .. },
+                    ..
+                }) = hir.get(async_closure)
+                {
+                    *fn_decl_span
+                } else {
+                    return;
+                }
+            } else {
+                *fn_decl_span
+            };
+
             let start = fn_decl_span.shrink_to_lo();
             let end = callee_span.shrink_to_hi();
             err.multipart_suggestion(
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index ed3b9f2db1f..a4013e10525 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -8,8 +8,6 @@ use rustc_middle::ty::subst::SubstsRef;
 use rustc_middle::ty::util::IgnoreRegions;
 use rustc_middle::ty::{self, Predicate, Ty, TyCtxt};
 use rustc_span::Span;
-use rustc_trait_selection::traits::query::dropck_outlives::AtExt;
-use rustc_trait_selection::traits::ObligationCause;
 
 /// This function confirms that the `Drop` implementation identified by
 /// `drop_impl_did` is not any more specialized than the type it is
@@ -234,18 +232,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
 /// This function is not only checking that the dropck obligations are met for
 /// the given type, but it's also currently preventing non-regular recursion in
 /// types from causing stack overflows (dropck_no_diverge_on_nonregular_*.rs).
+///
+/// FIXME: Completely rip out dropck and regionck.
 pub(crate) fn check_drop_obligations<'a, 'tcx>(
-    rcx: &mut RegionCtxt<'a, 'tcx>,
-    ty: Ty<'tcx>,
-    span: Span,
-    body_id: hir::HirId,
+    _rcx: &mut RegionCtxt<'a, 'tcx>,
+    _ty: Ty<'tcx>,
+    _span: Span,
+    _body_id: hir::HirId,
 ) {
-    debug!("check_drop_obligations typ: {:?}", ty);
-
-    let cause = &ObligationCause::misc(span, body_id);
-    let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
-    debug!("dropck_outlives = {:#?}", infer_ok);
-    rcx.fcx.register_infer_ok_obligations(infer_ok);
 }
 
 // This is an implementation of the TypeRelation trait with the
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index bce2e85de84..5297c48b4c3 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -1538,15 +1538,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ty
         } else {
             if !self.is_tainted_by_errors() {
-                self.emit_inference_failure_err(
-                    (**self).body_id,
-                    sp,
-                    ty.into(),
-                    vec![],
-                    E0282,
-                    true,
-                )
-                .emit();
+                self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
+                    .emit();
             }
             let err = self.tcx.ty_error();
             self.demand_suptype(sp, err, ty);
diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs
index 67160b98b9d..16e5639096c 100644
--- a/compiler/rustc_typeck/src/check/writeback.rs
+++ b/compiler/rustc_typeck/src/check/writeback.rs
@@ -692,7 +692,6 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                     Some(self.body.id()),
                     self.span.to_span(self.tcx),
                     t.into(),
-                    vec![],
                     E0282,
                     false,
                 )
@@ -707,7 +706,6 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                     Some(self.body.id()),
                     self.span.to_span(self.tcx),
                     c.into(),
-                    vec![],
                     E0282,
                     false,
                 )
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index f07396ce74f..4d22e168bb6 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -279,11 +279,16 @@ fn check_predicates<'tcx>(
     span: Span,
 ) {
     let tcx = infcx.tcx;
-    let impl1_predicates: Vec<_> = traits::elaborate_predicates(
+    let instantiated = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs);
+    let impl1_predicates: Vec<_> = traits::elaborate_predicates_with_span(
         tcx,
-        tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs).predicates.into_iter(),
+        std::iter::zip(
+            instantiated.predicates,
+            // Don't drop predicates (unsound!) because `spans` is too short
+            instantiated.spans.into_iter().chain(std::iter::repeat(span)),
+        ),
     )
-    .map(|obligation| obligation.predicate)
+    .map(|obligation| (obligation.predicate, obligation.cause.span))
     .collect();
 
     let mut impl2_predicates = if impl2_node.is_from_trait() {
@@ -321,7 +326,7 @@ fn check_predicates<'tcx>(
     // which is sound because we forbid impls like the following
     //
     // impl<D: Debug> AlwaysApplicable for D { }
-    let always_applicable_traits = impl1_predicates.iter().copied().filter(|&predicate| {
+    let always_applicable_traits = impl1_predicates.iter().copied().filter(|&(predicate, _)| {
         matches!(
             trait_predicate_kind(tcx, predicate),
             Some(TraitSpecializationKind::AlwaysApplicable)
@@ -345,11 +350,11 @@ fn check_predicates<'tcx>(
         }
     }
     impl2_predicates.extend(
-        traits::elaborate_predicates(tcx, always_applicable_traits)
+        traits::elaborate_predicates_with_span(tcx, always_applicable_traits)
             .map(|obligation| obligation.predicate),
     );
 
-    for predicate in impl1_predicates {
+    for (predicate, span) in impl1_predicates {
         if !impl2_predicates.contains(&predicate) {
             check_specialization_on(tcx, predicate, span)
         }
@@ -384,9 +389,17 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
                     .emit();
             }
         }
+        ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
+            tcx.sess
+                .struct_span_err(
+                    span,
+                    &format!("cannot specialize on associated type `{projection_ty} == {term}`",),
+                )
+                .emit();
+        }
         _ => {
             tcx.sess
-                .struct_span_err(span, &format!("cannot specialize on `{:?}`", predicate))
+                .struct_span_err(span, &format!("cannot specialize on predicate `{}`", predicate))
                 .emit();
         }
     }
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index 06300035633..69b72a81c5b 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -7,6 +7,7 @@ use crate::io::prelude::*;
 
 use crate::fmt;
 use crate::io::{self, IoSlice, IoSliceMut};
+use crate::iter::FusedIterator;
 use crate::net::{Shutdown, SocketAddr, ToSocketAddrs};
 use crate::sys_common::net as net_imp;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
@@ -1009,6 +1010,9 @@ impl<'a> Iterator for Incoming<'a> {
     }
 }
 
+#[stable(feature = "tcp_listener_incoming_fused_iterator", since = "1.64.0")]
+impl FusedIterator for Incoming<'_> {}
+
 #[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
 impl Iterator for IntoIncoming {
     type Item = io::Result<TcpStream>;
@@ -1017,6 +1021,9 @@ impl Iterator for IntoIncoming {
     }
 }
 
+#[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
+impl FusedIterator for IntoIncoming {}
+
 impl AsInner<net_imp::TcpListener> for TcpListener {
     fn as_inner(&self) -> &net_imp::TcpListener {
         &self.0
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 6fcbd7a2156..664ffa1ddd2 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -47,6 +47,7 @@ version = "0.0.0"
 dependencies = [
  "cc",
  "cmake",
+ "fd-lock",
  "filetime",
  "getopts",
  "hex",
@@ -202,6 +203,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
 [[package]]
+name = "errno"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "fd-lock"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e11dcc7e4d79a8c89b9ab4c6f5c30b1fc4a83c420792da3542fd31179ed5f517"
+dependencies = [
+ "cfg-if",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
 name = "filetime"
 version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -285,6 +318,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "io-lifetimes"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24c3f4eff5495aee4c0399d7b6a0dc2b6e81be84242ffbfcf253ebacccc1d0cb"
+
+[[package]]
 name = "itoa"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -303,6 +342,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.0.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
+
+[[package]]
 name = "log"
 version = "0.4.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -474,6 +519,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
 
 [[package]]
+name = "rustix"
+version = "0.35.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef258c11e17f5c01979a10543a30a4e12faef6aab217a74266e747eefa3aed88"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
 name = "ryu"
 version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -658,6 +717,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
 [[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+
+[[package]]
 name = "xattr"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index b9bd3d0cf78..84f6aaf99c1 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -36,6 +36,7 @@ test = false
 
 [dependencies]
 cmake = "0.1.38"
+fd-lock = "3.0.6"
 filetime = "0.2"
 num_cpus = "1.0"
 getopts = "0.2.19"
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index 9c41ab69c8b..9b4861ccd95 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -7,12 +7,28 @@
 
 use std::env;
 
-use bootstrap::{Build, Config, Subcommand, VERSION};
+use bootstrap::{t, Build, Config, Subcommand, VERSION};
 
 fn main() {
     let args = env::args().skip(1).collect::<Vec<_>>();
     let config = Config::parse(&args);
 
+    let mut build_lock;
+    let _build_lock_guard;
+    if cfg!(any(unix, windows)) {
+        build_lock = fd_lock::RwLock::new(t!(std::fs::File::create(config.out.join("lock"))));
+        _build_lock_guard = match build_lock.try_write() {
+            Ok(lock) => lock,
+            err => {
+                println!("warning: build directory locked, waiting for lock");
+                drop(err);
+                t!(build_lock.write())
+            }
+        };
+    } else {
+        println!("warning: file locking not supported for target, not locking build directory");
+    }
+
     // check_version warnings are not printed during setup
     let changelog_suggestion =
         if matches!(config.cmd, Subcommand::Setup { .. }) { None } else { check_version(&config) };
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 5f85fc5aa59..87c1d22e771 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -31,9 +31,7 @@ fn main() {
 
     let mut cmd = Command::new(rustdoc);
 
-    // cfg(bootstrap)
-    // NOTE: the `--test` special-casing can be removed when https://github.com/rust-lang/cargo/pull/10594 lands on beta.
-    if target.is_some() || args.iter().any(|x| x == "--test") {
+    if target.is_some() {
         // The stage0 compiler has a special sysroot distinct from what we
         // actually downloaded, so we just always pass the `--sysroot` option,
         // unless one is already set.
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 6ead79ef040..3c2f1bdb142 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -15,44 +15,6 @@ import tempfile
 
 from time import time, sleep
 
-# Acquire a lock on the build directory to make sure that
-# we don't cause a race condition while building
-# Lock is created in `build_dir/lock.db`
-def acquire_lock(build_dir):
-    try:
-        import sqlite3
-
-        path = os.path.join(build_dir, "lock.db")
-        try:
-            con = sqlite3.Connection(path, timeout=0)
-            curs = con.cursor()
-            curs.execute("BEGIN EXCLUSIVE")
-            # The lock is released when the cursor is dropped
-            return curs
-        # If the database is busy then lock has already been acquired
-        # so we wait for the lock.
-        # We retry every quarter second so that execution is passed back to python
-        # so that it can handle signals
-        except sqlite3.OperationalError:
-            del con
-            del curs
-            print("Waiting for lock on build directory")
-            con = sqlite3.Connection(path, timeout=0.25)
-            curs = con.cursor()
-            while True:
-                try:
-                    curs.execute("BEGIN EXCLUSIVE")
-                    break
-                except sqlite3.OperationalError:
-                    pass
-                sleep(0.25)
-            return curs
-    except ImportError:
-        print("warning: sqlite3 not available in python, skipping build directory lock")
-        print("please file an issue on rust-lang/rust")
-        print("this is not a problem for non-concurrent x.py invocations")
-        return None
-
 def support_xz():
     try:
         with tempfile.NamedTemporaryFile(delete=False) as temp_file:
@@ -928,11 +890,8 @@ def bootstrap(help_triggered):
 
     build.build = args.build or build.build_triple()
 
-    # Acquire the lock before doing any build actions
-    # The lock is released when `lock` is dropped
     if not os.path.exists(build.build_dir):
         os.makedirs(build.build_dir)
-    lock = acquire_lock(build.build_dir)
 
     # Fetch/build the bootstrap
     build.download_toolchain()
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 755c532ab32..fa2a530d9db 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -694,6 +694,7 @@ impl<'a> Builder<'a> {
                 doc::RustcBook,
                 doc::CargoBook,
                 doc::Clippy,
+                doc::Miri,
                 doc::EmbeddedBook,
                 doc::EditionGuide,
             ),
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index be6655ddb61..3cf0f9b9f99 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -643,7 +643,7 @@ impl Step for Rustc {
 }
 
 macro_rules! tool_doc {
-    ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(,)?) => {
+    ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?], in_tree = $in_tree:expr $(,)?) => {
         #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
         pub struct $tool {
             target: TargetSelection,
@@ -699,6 +699,12 @@ macro_rules! tool_doc {
                 t!(fs::create_dir_all(&out_dir));
                 t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
+                let source_type = if $in_tree == true {
+                    SourceType::InTree
+                } else {
+                    SourceType::Submodule
+                };
+
                 // Build cargo command.
                 let mut cargo = prepare_tool_cargo(
                     builder,
@@ -707,7 +713,7 @@ macro_rules! tool_doc {
                     target,
                     "doc",
                     $path,
-                    SourceType::InTree,
+                    source_type,
                     &[],
                 );
 
@@ -723,20 +729,38 @@ macro_rules! tool_doc {
                 cargo.rustdocflag("--show-type-layout");
                 cargo.rustdocflag("--generate-link-to-definition");
                 cargo.rustdocflag("-Zunstable-options");
-                builder.run(&mut cargo.into());
+                if $in_tree == true {
+                    builder.run(&mut cargo.into());
+                } else {
+                    // Allow out-of-tree docs to fail (since the tool might be in a broken state).
+                    if !builder.try_run(&mut cargo.into()) {
+                        builder.info(&format!(
+                            "WARNING: tool {} failed to document; ignoring failure because it is an out-of-tree tool",
+                            stringify!($tool).to_lowercase(),
+                        ));
+                    }
+                }
             }
         }
     }
 }
 
-tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"]);
+tool_doc!(
+    Rustdoc,
+    "rustdoc-tool",
+    "src/tools/rustdoc",
+    ["rustdoc", "rustdoc-json-types"],
+    in_tree = true
+);
 tool_doc!(
     Rustfmt,
     "rustfmt-nightly",
     "src/tools/rustfmt",
     ["rustfmt-nightly", "rustfmt-config_proc_macro"],
+    in_tree = true
 );
-tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]);
+tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"], in_tree = true);
+tool_doc!(Miri, "miri", "src/tools/miri", ["miri"], in_tree = false);
 
 #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 40ff0381c8b..73bd588472d 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -118,8 +118,7 @@ use once_cell::sync::OnceCell;
 use crate::builder::Kind;
 use crate::config::{LlvmLibunwind, TargetSelection};
 use crate::util::{
-    check_run, exe, libdir, mtime, output, run, run_suppressed, t, try_run, try_run_suppressed,
-    CiEnv,
+    check_run, exe, libdir, mtime, output, run, run_suppressed, try_run, try_run_suppressed, CiEnv,
 };
 
 mod builder;
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 9958306b576..f3395507bb0 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1363,13 +1363,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the
         if let Some(ref npm) = builder.config.npm {
             cmd.arg("--npm").arg(npm);
         }
-
-        let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
-        if !is_rustdoc {
-            if builder.config.rust_optimize_tests {
-                flags.push("-O".to_string());
-            }
+        if builder.config.rust_optimize_tests {
+            cmd.arg("--optimize-tests");
         }
+        let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
         flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
         flags.push(builder.config.cmd.rustc_args().join(" "));
 
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 4b2b058a780..6f4266a7f29 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -22,6 +22,7 @@ use crate::config::{Config, TargetSelection};
 ///
 /// This is currently used judiciously throughout the build system rather than
 /// using a `Result` with `try!`, but this may change one day...
+#[macro_export]
 macro_rules! t {
     ($e:expr) => {
         match $e {
@@ -37,7 +38,7 @@ macro_rules! t {
         }
     };
 }
-pub(crate) use t;
+pub use t;
 
 /// Given an executable called `name`, return the filename for the
 /// executable for a particular target.
diff --git a/src/ci/docker/host-x86_64/dist-various-2/shared.sh b/src/ci/docker/host-x86_64/dist-various-2/shared.sh
index 267d8b79cc2..291f26bdaeb 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/shared.sh
+++ b/src/ci/docker/host-x86_64/dist-various-2/shared.sh
@@ -33,15 +33,3 @@ function retry {
     }
   done
 }
-
-# Copied from ../../init_repo.sh
-function fetch_github_commit_archive {
-    local module=$1
-    local cached="download-${module//\//-}.tar.gz"
-    retry sh -c "rm -f $cached && \
-        curl -f -sSL -o $cached $2"
-    mkdir $module
-    touch "$module/.git"
-    tar -C $module --strip-components=1 -xf $cached
-    rm $cached
-}
diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh
deleted file mode 100755
index e8c1e2b0f59..00000000000
--- a/src/ci/init_repo.sh
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env bash
-
-set -o errexit
-set -o pipefail
-set -o nounset
-
-ci_dir=$(cd $(dirname $0) && pwd)
-. "$ci_dir/shared.sh"
-
-REPO_DIR="$1"
-CACHE_DIR="$2"
-
-cache_src_dir="$CACHE_DIR/src"
-
-if [ ! -d "$REPO_DIR" -o ! -d "$REPO_DIR/.git" ]; then
-    echo "Error: $REPO_DIR does not exist or is not a git repo"
-    exit 1
-fi
-cd $REPO_DIR
-if [ ! -d "$CACHE_DIR" ]; then
-    echo "Error: $CACHE_DIR does not exist or is not an absolute path"
-    exit 1
-fi
-
-rm -rf "$CACHE_DIR"
-mkdir "$CACHE_DIR"
-
-# On the beta channel we'll be automatically calculating the prerelease version
-# via the git history, so unshallow our shallow clone from CI.
-if [ "$(releaseChannel)" = "beta" ]; then
-  git fetch origin --unshallow beta master
-fi
-
-# Duplicated in docker/dist-various-2/shared.sh
-function fetch_github_commit_archive {
-    local module=$1
-    local cached="download-${module//\//-}.tar.gz"
-    retry sh -c "rm -f $cached && \
-        curl -f -sSL -o $cached $2"
-    mkdir $module
-    touch "$module/.git"
-    # On Windows, the default behavior is to emulate symlinks by copying
-    # files. However, that ends up being order-dependent while extracting,
-    # which can cause a failure if the symlink comes first. This env var
-    # causes tar to use real symlinks instead, which are allowed to dangle.
-    export MSYS=winsymlinks:nativestrict
-    tar -C $module --strip-components=1 -xf $cached
-    rm $cached
-}
-
-# Archive downloads are temporarily disabled due to sudden 504
-# gateway timeout errors.
-# included="src/llvm-project src/doc/book src/doc/rust-by-example"
-included=""
-modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
-modules=($modules)
-use_git=""
-urls="$(git config --file .gitmodules --get-regexp '\.url$' | cut -d' ' -f2)"
-urls=($urls)
-# shellcheck disable=SC2068
-for i in ${!modules[@]}; do
-    module=${modules[$i]}
-    if [[ " $included " = *" $module "* ]]; then
-        commit="$(git ls-tree HEAD $module | awk '{print $3}')"
-        git rm $module
-        url=${urls[$i]}
-        url=${url/\.git/}
-        fetch_github_commit_archive $module "$url/archive/$commit.tar.gz" &
-        bg_pids[${i}]=$!
-        continue
-    else
-        use_git="$use_git $module"
-    fi
-done
-retry sh -c "git submodule deinit -f $use_git && \
-    git submodule sync && \
-    git submodule update -j 16 --init --recursive --depth 1 $use_git"
-# STATUS=0
-# for pid in ${bg_pids[*]}
-# do
-#     wait $pid || STATUS=1
-# done
-# exit ${STATUS}
diff --git a/src/ci/scripts/checkout-submodules.sh b/src/ci/scripts/checkout-submodules.sh
index 0b44ea3c90b..3eb4b8f9058 100755
--- a/src/ci/scripts/checkout-submodules.sh
+++ b/src/ci/scripts/checkout-submodules.sh
@@ -2,16 +2,70 @@
 # Check out all our submodules, but more quickly than using git by using one of
 # our custom scripts
 
-set -euo pipefail
-IFS=$'\n\t'
+set -o errexit
+set -o pipefail
+set -o nounset
 
-source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
+if [ ! -d ".git" ]; then
+    echo "Error: This must run in the root of the repository"
+    exit 1
+fi
+
+ci_dir=$(cd $(dirname $0) && pwd)/..
+. "$ci_dir/shared.sh"
 
-if isWindows; then
-    path="/c/cache/rustsrc"
-else
-    path="${HOME}/rustsrc"
+# On the beta channel we'll be automatically calculating the prerelease version
+# via the git history, so unshallow our shallow clone from CI.
+if [ "$(releaseChannel)" = "beta" ]; then
+  git fetch origin --unshallow beta master
 fi
 
-mkdir -p "${path}"
-"$(cd "$(dirname "$0")" && pwd)/../init_repo.sh" . "${path}"
+function fetch_github_commit_archive {
+    local module=$1
+    local cached="download-${module//\//-}.tar.gz"
+    retry sh -c "rm -f $cached && \
+        curl -f -sSL -o $cached $2"
+    mkdir $module
+    touch "$module/.git"
+    # On Windows, the default behavior is to emulate symlinks by copying
+    # files. However, that ends up being order-dependent while extracting,
+    # which can cause a failure if the symlink comes first. This env var
+    # causes tar to use real symlinks instead, which are allowed to dangle.
+    export MSYS=winsymlinks:nativestrict
+    tar -C $module --strip-components=1 -xf $cached
+    rm $cached
+}
+
+# Archive downloads are temporarily disabled due to sudden 504
+# gateway timeout errors.
+# included="src/llvm-project src/doc/book src/doc/rust-by-example"
+included=""
+modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
+modules=($modules)
+use_git=""
+urls="$(git config --file .gitmodules --get-regexp '\.url$' | cut -d' ' -f2)"
+urls=($urls)
+# shellcheck disable=SC2068
+for i in ${!modules[@]}; do
+    module=${modules[$i]}
+    if [[ " $included " = *" $module "* ]]; then
+        commit="$(git ls-tree HEAD $module | awk '{print $3}')"
+        git rm $module
+        url=${urls[$i]}
+        url=${url/\.git/}
+        fetch_github_commit_archive $module "$url/archive/$commit.tar.gz" &
+        bg_pids[${i}]=$!
+        continue
+    else
+        use_git="$use_git $module"
+    fi
+done
+retry sh -c "git submodule deinit -f $use_git && \
+    git submodule sync && \
+    git submodule update -j 16 --init --recursive --depth 1 $use_git"
+# STATUS=0
+# for pid in ${bg_pids[*]}
+# do
+#     wait $pid || STATUS=1
+# done
+# exit ${STATUS}
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 16574f94c00..22b1e2335fd 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -340,17 +340,98 @@ pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
     false
 }
 
+/// Build a textual representation of an unevaluated constant expression.
+///
+/// If the const expression is too complex, an underscore `_` is returned.
+/// For const arguments, it's `{ _ }` to be precise.
+/// This means that the output is not necessarily valid Rust code.
+///
+/// Currently, only
+///
+/// * literals (optionally with a leading `-`)
+/// * unit `()`
+/// * blocks (`{ … }`) around simple expressions and
+/// * paths without arguments
+///
+/// are considered simple enough. Simple blocks are included since they are
+/// necessary to disambiguate unit from the unit type.
+/// This list might get extended in the future.
+///
+/// Without this censoring, in a lot of cases the output would get too large
+/// and verbose. Consider `match` expressions, blocks and deeply nested ADTs.
+/// Further, private and `doc(hidden)` fields of structs would get leaked
+/// since HIR datatypes like the `body` parameter do not contain enough
+/// semantic information for this function to be able to hide them –
+/// at least not without significant performance overhead.
+///
+/// Whenever possible, prefer to evaluate the constant first and try to
+/// use a different method for pretty-printing. Ideally this function
+/// should only ever be used as a fallback.
 pub(crate) fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
     let hir = tcx.hir();
     let value = &hir.body(body).value;
 
-    let snippet = if !value.span.from_expansion() {
-        tcx.sess.source_map().span_to_snippet(value.span).ok()
-    } else {
-        None
-    };
+    #[derive(PartialEq, Eq)]
+    enum Classification {
+        Literal,
+        Simple,
+        Complex,
+    }
 
-    snippet.unwrap_or_else(|| rustc_hir_pretty::id_to_string(&hir, body.hir_id))
+    use Classification::*;
+
+    fn classify(expr: &hir::Expr<'_>) -> Classification {
+        match &expr.kind {
+            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => {
+                if matches!(expr.kind, hir::ExprKind::Lit(_)) { Literal } else { Complex }
+            }
+            hir::ExprKind::Lit(_) => Literal,
+            hir::ExprKind::Tup([]) => Simple,
+            hir::ExprKind::Block(hir::Block { stmts: [], expr: Some(expr), .. }, _) => {
+                if classify(expr) == Complex { Complex } else { Simple }
+            }
+            // Paths with a self-type or arguments are too “complex” following our measure since
+            // they may leak private fields of structs (with feature `adt_const_params`).
+            // Consider: `<Self as Trait<{ Struct { private: () } }>>::CONSTANT`.
+            // Paths without arguments are definitely harmless though.
+            hir::ExprKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) => {
+                if segments.iter().all(|segment| segment.args.is_none()) { Simple } else { Complex }
+            }
+            // FIXME: Claiming that those kinds of QPaths are simple is probably not true if the Ty
+            //        contains const arguments. Is there a *concise* way to check for this?
+            hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => Simple,
+            // FIXME: Can they contain const arguments and thus leak private struct fields?
+            hir::ExprKind::Path(hir::QPath::LangItem(..)) => Simple,
+            _ => Complex,
+        }
+    }
+
+    let classification = classify(value);
+
+    if classification == Literal
+    && !value.span.from_expansion()
+    && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) {
+        // For literals, we avoid invoking the pretty-printer and use the source snippet instead to
+        // preserve certain stylistic choices the user likely made for the sake legibility like
+        //
+        // * hexadecimal notation
+        // * underscores
+        // * character escapes
+        //
+        // FIXME: This passes through `-/*spacer*/0` verbatim.
+        snippet
+    } else if classification == Simple {
+        // Otherwise we prefer pretty-printing to get rid of extraneous whitespace, comments and
+        // other formatting artifacts.
+        rustc_hir_pretty::id_to_string(&hir, body.hir_id)
+    } else if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
+        // FIXME: Omit the curly braces if the enclosing expression is an array literal
+        //        with a repeated element (an `ExprKind::Repeat`) as in such case it
+        //        would not actually need any disambiguation.
+        "{ _ }".to_owned()
+    } else {
+        "_".to_owned()
+    }
 }
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 50d154dd278..04638aa1af6 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -353,11 +353,7 @@ impl Options {
             print_flag_list("-C", config::CG_OPTIONS);
             return Err(0);
         }
-        let w_flags = matches.opt_strs("W");
-        if w_flags.iter().any(|x| *x == "help") {
-            print_flag_list("-W", config::DB_OPTIONS);
-            return Err(0);
-        }
+
         if matches.opt_strs("passes") == ["list"] {
             println!("Available passes for running rustdoc:");
             for pass in passes::PASSES {
@@ -439,15 +435,19 @@ impl Options {
             return Err(0);
         }
 
-        if matches.free.is_empty() {
+        let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
+
+        let input = PathBuf::from(if describe_lints {
+            "" // dummy, this won't be used
+        } else if matches.free.is_empty() {
             diag.struct_err("missing file operand").emit();
             return Err(1);
-        }
-        if matches.free.len() > 1 {
+        } else if matches.free.len() > 1 {
             diag.struct_err("too many file operands").emit();
             return Err(1);
-        }
-        let input = PathBuf::from(&matches.free[0]);
+        } else {
+            &matches.free[0]
+        });
 
         let libs = matches
             .opt_strs("L")
@@ -698,8 +698,6 @@ impl Options {
         let with_examples = matches.opt_strs("with-examples");
         let call_locations = crate::scrape_examples::load_call_locations(with_examples, &diag)?;
 
-        let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
-
         Ok(Options {
             input,
             proc_macro_crate,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 056eda089c1..5584ecd287a 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1283,10 +1283,6 @@ impl clean::FnDecl {
         let mut args = Buffer::html();
         let mut args_plain = Buffer::new();
         for (i, input) in self.inputs.values.iter().enumerate() {
-            if i == 0 {
-                args.push_str("<br>");
-            }
-
             if let Some(selfty) = input.to_self() {
                 match selfty {
                     clean::SelfValue => {
@@ -1312,8 +1308,7 @@ impl clean::FnDecl {
                 }
             } else {
                 if i > 0 {
-                    args.push_str(" <br>");
-                    args_plain.push_str(" ");
+                    args.push_str("<br>");
                 }
                 if input.is_const {
                     args.push_str("const ");
@@ -1360,13 +1355,14 @@ impl clean::FnDecl {
             let full_pad = format!("<br>{}", "&nbsp;".repeat(indent + 4));
             let close_pad = format!("<br>{}", "&nbsp;".repeat(indent));
             format!(
-                "({args}{close}){arrow}",
+                "({pad}{args}{close}){arrow}",
+                pad = if self.inputs.values.is_empty() { "" } else { &full_pad },
                 args = args.replace("<br>", &full_pad),
                 close = close_pad,
                 arrow = arrow
             )
         } else {
-            format!("({args}){arrow}", args = args.replace("<br>", ""), arrow = arrow)
+            format!("({args}){arrow}", args = args.replace("<br>", " "), arrow = arrow)
         };
 
         if f.alternate() {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 1ef41d62e5e..548f6c3a987 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -716,12 +716,14 @@ fn assoc_const(
         ty = ty.print(cx),
     );
     if let Some(default) = default {
+        write!(w, " = ");
+
         // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
         //        hood which adds noisy underscores and a type suffix to number literals.
         //        This hurts readability in this context especially when more complex expressions
         //        are involved and it doesn't add much of value.
         //        Find a way to print constants here without all that jazz.
-        write!(w, " = {}", default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx())));
+        write!(w, "{}", Escape(&default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx()))));
     }
 }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 0fe99463f1d..fe00f952e04 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1360,6 +1360,15 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
                 typ = c.type_.print(cx),
             );
 
+            // FIXME: The code below now prints
+            //            ` = _; // 100i32`
+            //        if the expression is
+            //            `50 + 50`
+            //        which looks just wrong.
+            //        Should we print
+            //            ` = 100i32;`
+            //        instead?
+
             let value = c.value(cx.tcx());
             let is_literal = c.is_literal(cx.tcx());
             let expr = c.expr(cx.tcx());
diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js
index 2817a8fe144..fcd925bb358 100644
--- a/src/librustdoc/html/static/.eslintrc.js
+++ b/src/librustdoc/html/static/.eslintrc.js
@@ -91,5 +91,6 @@ module.exports = {
         "no-script-url": "error",
         "no-sequences": "error",
         "no-throw-literal": "error",
+        "no-div-regex": "error",
     }
 };
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index f7b4fdb736c..8d99b85bebe 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -418,7 +418,7 @@ nav.sub {
 	background-color: var(--sidebar-background-color);
 }
 
-#sidebar-toggle:hover {
+#sidebar-toggle > button:hover, #sidebar-toggle > button:focus {
 	background-color: var(--sidebar-background-color-hover);
 }
 
@@ -1401,7 +1401,6 @@ pre.rust {
 	position: sticky;
 	top: 0;
 	left: 0;
-	cursor: pointer;
 	font-weight: bold;
 	font-size: 1.25rem;
 	border-bottom: 1px solid;
@@ -1422,7 +1421,24 @@ pre.rust {
 	border-bottom: 1px solid;
 	margin-bottom: 6px;
 }
-
+#sidebar-toggle > button {
+	background: none;
+	color: inherit;
+	cursor: pointer;
+	text-align: center;
+	border: none;
+	outline: none;
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	/* work around button layout strangeness: https://stackoverflow.com/q/7271561 */
+	width: 100%;
+	/* iOS button gradient: https://stackoverflow.com/q/5438567 */
+	-webkit-appearance: none;
+	opacity: 1;
+}
 #settings-menu, #help-button {
 	margin-left: 4px;
 	outline: none;
@@ -1578,38 +1594,23 @@ kbd {
 	margin-bottom: 1em;
 }
 
-div.children {
-	padding-left: 27px;
-	display: none;
+details.dir-entry {
+	padding-left: 4px;
 }
-div.name {
+
+details.dir-entry > summary {
+	margin: 0 0 0 13px;
+	list-style-position: outside;
 	cursor: pointer;
-	position: relative;
-	margin-left: 16px;
 }
-div.files > a {
-	display: block;
-	padding: 0 3px;
-}
-div.files > a:hover, div.name:hover {
-	background-color: #a14b4b;
+
+details.dir-entry div.folders, details.dir-entry div.files {
+	padding-left: 23px;
 }
-div.name.expand + .children {
+
+details.dir-entry a {
 	display: block;
 }
-div.name::before {
-	content: "\25B6";
-	padding-left: 4px;
-	font-size: 0.625rem;
-	position: absolute;
-	left: -16px;
-	top: 4px;
-}
-div.name.expand::before {
-	transform: rotate(90deg);
-	left: -15px;
-	top: 2px;
-}
 
 /* The hideme class is used on summary tags that contain a span with
 	placeholder text shown only when the toggle is closed. For instance,
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index 7756e877ef7..b25f5e9fdb1 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -575,11 +575,12 @@ kbd {
 	color: #fff;
 	border-bottom-color: #5c6773;
 }
-#source-sidebar div.files > a:hover, div.name:hover {
+#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
 	background-color: #14191f;
 	color: #ffb44c;
 }
-#source-sidebar div.files > .selected {
+#source-sidebar div.files > a.selected {
 	background-color: #14191f;
 	color: #ffb44c;
 }
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index 04d5778f59c..a678ec1e1c1 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -432,10 +432,11 @@ kbd {
 #source-sidebar > .title {
 	border-bottom-color: #ccc;
 }
-#source-sidebar div.files > a:hover, div.name:hover {
+#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
 	background-color: #444;
 }
-#source-sidebar div.files > .selected {
+#source-sidebar div.files > a.selected {
 	background-color: #333;
 }
 
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 5310736037a..e8770ac2124 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -414,13 +414,13 @@ kbd {
 #source-sidebar > .title {
 	border-bottom-color: #ccc;
 }
-#source-sidebar div.files > a:hover, div.name:hover {
+#source-sidebar div.files > a:hover, details.dir-entry summary:hover,
+#source-sidebar div.files > a:focus, details.dir-entry summary:focus {
 	background-color: #E0E0E0;
 }
-#source-sidebar div.files > .selected {
+#source-sidebar div.files > a.selected {
 	background-color: #fff;
 }
-
 .scraped-example-list .scrape-help {
 	border-color: #555;
 	color: #333;
diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js
index acb1d8d7b5c..45e70c9a7c7 100644
--- a/src/librustdoc/html/static/js/source-script.js
+++ b/src/librustdoc/html/static/js/source-script.js
@@ -2,7 +2,7 @@
 /* global sourcesIndex */
 
 // Local js definitions:
-/* global addClass, getCurrentValue, hasClass, onEachLazy, removeClass, browserSupportsHistoryApi */
+/* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */
 /* global updateLocalStorage */
 
 "use strict";
@@ -13,33 +13,27 @@ const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-p
 let oldScrollPosition = 0;
 
 function createDirEntry(elem, parent, fullPath, hasFoundFile) {
-    const name = document.createElement("div");
-    name.className = "name";
+    const dirEntry = document.createElement("details");
+    const summary = document.createElement("summary");
+
+    dirEntry.className = "dir-entry";
 
     fullPath += elem["name"] + "/";
 
-    name.onclick = ev => {
-        if (hasClass(ev.target, "expand")) {
-            removeClass(ev.target, "expand");
-        } else {
-            addClass(ev.target, "expand");
-        }
-    };
-    name.innerText = elem["name"];
+    summary.innerText = elem["name"];
+    dirEntry.appendChild(summary);
 
-    const children = document.createElement("div");
-    children.className = "children";
     const folders = document.createElement("div");
     folders.className = "folders";
     if (elem.dirs) {
         for (const dir of elem.dirs) {
             if (createDirEntry(dir, folders, fullPath, hasFoundFile)) {
-                addClass(name, "expand");
+                dirEntry.open = true;
                 hasFoundFile = true;
             }
         }
     }
-    children.appendChild(folders);
+    dirEntry.appendChild(folders);
 
     const files = document.createElement("div");
     files.className = "files";
@@ -51,20 +45,19 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) {
             const w = window.location.href.split("#")[0];
             if (!hasFoundFile && w === file.href) {
                 file.className = "selected";
-                addClass(name, "expand");
+                dirEntry.open = true;
                 hasFoundFile = true;
             }
             files.appendChild(file);
         }
     }
-    children.appendChild(files);
-    parent.appendChild(name);
-    parent.appendChild(children);
+    dirEntry.appendChild(files);
+    parent.appendChild(dirEntry);
     return hasFoundFile;
 }
 
 function toggleSidebar() {
-    const child = this.children[0];
+    const child = this.parentNode.children[0];
     if (child.innerText === ">") {
         if (window.innerWidth < 701) {
             // This is to keep the scroll position on mobile.
@@ -93,15 +86,15 @@ function toggleSidebar() {
 function createSidebarToggle() {
     const sidebarToggle = document.createElement("div");
     sidebarToggle.id = "sidebar-toggle";
-    sidebarToggle.onclick = toggleSidebar;
 
-    const inner = document.createElement("div");
+    const inner = document.createElement("button");
 
     if (getCurrentValue("source-sidebar-show") === "true") {
         inner.innerText = "<";
     } else {
         inner.innerText = ">";
     }
+    inner.onclick = toggleSidebar;
 
     sidebarToggle.appendChild(inner);
     return sidebarToggle;
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 25a66ee23a0..ded3d9951bd 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -75,7 +75,7 @@ use std::env::{self, VarError};
 use std::io;
 use std::process;
 
-use rustc_driver::{abort_on_err, describe_lints};
+use rustc_driver::abort_on_err;
 use rustc_errors::ErrorGuaranteed;
 use rustc_interface::interface;
 use rustc_middle::ty::TyCtxt;
@@ -770,15 +770,24 @@ fn main_options(options: config::Options) -> MainResult {
     let config = core::create_config(options);
 
     interface::create_compiler_and_run(config, |compiler| {
-        compiler.enter(|queries| {
-            let sess = compiler.session();
+        let sess = compiler.session();
 
-            if sess.opts.describe_lints {
-                let (_, lint_store) = &*queries.register_plugins()?.peek();
-                describe_lints(sess, lint_store, true);
-                return Ok(());
-            }
+        if sess.opts.describe_lints {
+            let mut lint_store = rustc_lint::new_lint_store(
+                sess.opts.debugging_opts.no_interleave_lints,
+                sess.unstable_options(),
+            );
+            let registered_lints = if let Some(register_lints) = compiler.register_lints() {
+                register_lints(sess, &mut lint_store);
+                true
+            } else {
+                false
+            };
+            rustc_driver::describe_lints(sess, &lint_store, registered_lints);
+            return Ok(());
+        }
 
+        compiler.enter(|queries| {
             // We need to hold on to the complete resolver, so we cause everything to be
             // cloned for the analysis passes to use. Suboptimal, but necessary in the
             // current architecture.
diff --git a/src/test/incremental/split_debuginfo_mode.rs b/src/test/incremental/split_debuginfo_mode.rs
new file mode 100644
index 00000000000..f2533e4146a
--- /dev/null
+++ b/src/test/incremental/split_debuginfo_mode.rs
@@ -0,0 +1,33 @@
+// This test case makes sure that changing split-debuginfo commandline options triggers a full re-compilation.
+// We only test on x86_64-unknown-linux-gnu because there all combinations split-debuginfo settings are valid
+// and the test is platform-independent otherwise.
+
+// ignore-tidy-linelength
+// only-x86_64-unknown-linux-gnu
+// revisions:rpass1 rpass2 rpass3 rpass4
+
+// [rpass1]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on
+// [rpass2]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single -Zsplit-dwarf-inlining=on
+// [rpass3]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=on
+// [rpass4]compile-flags: -Zquery-dep-graph -Zunstable-options -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split -Zsplit-dwarf-inlining=off
+
+#![feature(rustc_attrs)]
+// For rpass2 we change -Csplit-debuginfo and thus expect every CGU to be recompiled
+#![rustc_partition_codegened(module = "split_debuginfo_mode", cfg = "rpass2")]
+#![rustc_partition_codegened(module = "split_debuginfo_mode-another_module", cfg = "rpass2")]
+// For rpass3 we change -Zsplit-dwarf-kind and thus also expect every CGU to be recompiled
+#![rustc_partition_codegened(module = "split_debuginfo_mode", cfg = "rpass3")]
+#![rustc_partition_codegened(module = "split_debuginfo_mode-another_module", cfg = "rpass3")]
+// For rpass4 we change -Zsplit-dwarf-inlining and thus also expect every CGU to be recompiled
+#![rustc_partition_codegened(module = "split_debuginfo_mode", cfg = "rpass4")]
+#![rustc_partition_codegened(module = "split_debuginfo_mode-another_module", cfg = "rpass4")]
+
+mod another_module {
+    pub fn foo() -> &'static str {
+        "hello world"
+    }
+}
+
+pub fn main() {
+    println!("{}", another_module::foo());
+}
diff --git a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
index fdc016a95d5..b1ff480324f 100644
--- a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
+++ b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff
@@ -4,98 +4,78 @@
   fn <impl at $DIR/combine_clone_of_primitives.rs:6:10: 6:15>::clone(_1: &MyThing<T>) -> MyThing<T> {
       debug self => _1;                    // in scope 0 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
       let mut _0: MyThing<T>;              // return place in scope 0 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
-      let _2: &T;                          // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-      let _3: &u64;                        // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-      let _4: &[f32; 3];                   // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-      let mut _5: T;                       // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-      let mut _6: &T;                      // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-      let _7: &T;                          // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-      let mut _8: u64;                     // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-      let mut _9: &u64;                    // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-      let _10: &u64;                       // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-      let mut _11: [f32; 3];               // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-      let mut _12: &[f32; 3];              // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-      let _13: &[f32; 3];                  // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-      scope 1 {
-          debug __self_0_0 => _2;          // in scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-          debug __self_0_1 => _3;          // in scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-          debug __self_0_2 => _4;          // in scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-      }
+      let mut _2: T;                       // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+      let mut _3: &T;                      // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+      let _4: &T;                          // in scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+      let mut _5: u64;                     // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+      let mut _6: &u64;                    // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+      let _7: &u64;                        // in scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+      let mut _8: [f32; 3];                // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+      let mut _9: &[f32; 3];               // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+      let _10: &[f32; 3];                  // in scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
   
       bb0: {
           StorageLive(_2);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-          _2 = &((*_1).0: T);              // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-          StorageLive(_3);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-          _3 = &((*_1).1: u64);            // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-          StorageLive(_4);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-          _4 = &((*_1).2: [f32; 3]);       // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-          StorageLive(_5);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-          StorageLive(_6);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-          StorageLive(_7);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
--         _7 = &(*_2);                     // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
--         _6 = &(*_7);                     // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-+         _7 = _2;                         // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-+         _6 = _7;                         // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
-          _5 = <T as Clone>::clone(move _6) -> bb1; // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+          StorageLive(_3);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+          StorageLive(_4);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+          _4 = &((*_1).0: T);              // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+-         _3 = &(*_4);                     // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
++         _3 = _4;                         // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+          _2 = <T as Clone>::clone(move _3) -> bb1; // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
                                            // mir::Constant
                                            // + span: $DIR/combine_clone_of_primitives.rs:8:5: 8:9
                                            // + literal: Const { ty: for<'r> fn(&'r T) -> T {<T as Clone>::clone}, val: Value(Scalar(<ZST>)) }
       }
   
       bb1: {
-          StorageDead(_6);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9
-          StorageLive(_8);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-          StorageLive(_9);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-          StorageLive(_10);                // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
--         _10 = &(*_3);                    // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
--         _9 = &(*_10);                    // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
--         _8 = <u64 as Clone>::clone(move _9) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+          StorageDead(_3);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9
+          StorageLive(_5);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+          StorageLive(_6);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+          StorageLive(_7);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+          _7 = &((*_1).1: u64);            // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+-         _6 = &(*_7);                     // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
+-         _5 = <u64 as Clone>::clone(move _6) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
 -                                          // mir::Constant
 -                                          // + span: $DIR/combine_clone_of_primitives.rs:9:5: 9:11
 -                                          // + literal: Const { ty: for<'r> fn(&'r u64) -> u64 {<u64 as Clone>::clone}, val: Value(Scalar(<ZST>)) }
-+         _10 = _3;                        // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-+         _9 = _10;                        // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-+         _8 = (*_9);                      // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
-+         goto -> bb2;                     // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++         _6 = _7;                         // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++         _5 = (*_6);                      // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
++         goto -> bb2;                     // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
       }
   
       bb2: {
-          StorageDead(_9);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11
-          StorageLive(_11);                // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-          StorageLive(_12);                // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-          StorageLive(_13);                // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
--         _13 = &(*_4);                    // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
--         _12 = &(*_13);                   // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
--         _11 = <[f32; 3] as Clone>::clone(move _12) -> [return: bb3, unwind: bb4]; // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+          StorageDead(_6);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11
+          StorageLive(_8);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+          StorageLive(_9);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+          StorageLive(_10);                // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+          _10 = &((*_1).2: [f32; 3]);      // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+-         _9 = &(*_10);                    // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
+-         _8 = <[f32; 3] as Clone>::clone(move _9) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
 -                                          // mir::Constant
 -                                          // + span: $DIR/combine_clone_of_primitives.rs:10:5: 10:16
 -                                          // + literal: Const { ty: for<'r> fn(&'r [f32; 3]) -> [f32; 3] {<[f32; 3] as Clone>::clone}, val: Value(Scalar(<ZST>)) }
-+         _13 = _4;                        // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-+         _12 = _13;                       // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-+         _11 = (*_12);                    // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
-+         goto -> bb3;                     // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++         _9 = _10;                        // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++         _8 = (*_9);                      // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
++         goto -> bb3;                     // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
       }
   
       bb3: {
-          StorageDead(_12);                // scope 1 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16
-          Deinit(_0);                      // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
-          (_0.0: T) = move _5;             // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
-          (_0.1: u64) = move _8;           // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
-          (_0.2: [f32; 3]) = move _11;     // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
-          StorageDead(_13);                // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_11);                // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_10);                // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_8);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_7);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_5);                 // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_4);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
-          StorageDead(_3);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
+          StorageDead(_9);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16
+          Deinit(_0);                      // scope 0 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
+          (_0.0: T) = move _2;             // scope 0 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
+          (_0.1: u64) = move _5;           // scope 0 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
+          (_0.2: [f32; 3]) = move _8;      // scope 0 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
+          StorageDead(_8);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
+          StorageDead(_5);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
           StorageDead(_2);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
+          StorageDead(_10);                // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
+          StorageDead(_7);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
+          StorageDead(_4);                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
           return;                          // scope 0 at $DIR/combine_clone_of_primitives.rs:6:15: 6:15
       }
   
       bb4 (cleanup): {
-          drop(_5) -> bb5;                 // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
+          drop(_2) -> bb5;                 // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
       }
   
       bb5 (cleanup): {
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
index 55a49548cb5..65eb1008dd8 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.uses_crate.txt
@@ -36,12 +36,12 @@
    22|      2|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
    23|      2|}
   ------------------
-  | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
+  | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
   |   21|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
   |   22|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
   |   23|      1|}
   ------------------
-  | used_crate::used_only_from_this_lib_crate_generic_function::<alloc::vec::Vec<i32>>:
+  | used_crate::used_only_from_this_lib_crate_generic_function::<&str>:
   |   21|      1|pub fn used_only_from_this_lib_crate_generic_function<T: Debug>(arg: T) {
   |   22|      1|    println!("used_only_from_this_lib_crate_generic_function with {:?}", arg);
   |   23|      1|}
diff --git a/src/test/run-make/issue-88756-opt-help/Makefile b/src/test/run-make/issue-88756-opt-help/Makefile
deleted file mode 100644
index 8ababbf5b4e..00000000000
--- a/src/test/run-make/issue-88756-opt-help/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
--include ../../run-make-fulldeps/tools.mk
-
-all:
-	$(RUSTDOC) -W help 2>&1 | diff - output-default.stdout
diff --git a/src/test/run-make/issue-88756-opt-help/README.md b/src/test/run-make/issue-88756-opt-help/README.md
deleted file mode 100644
index 9b742753f25..00000000000
--- a/src/test/run-make/issue-88756-opt-help/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This is a test to verify that `rustdoc` behaves the same as rustc and prints out help output for its options like -W (#88756).
diff --git a/src/test/run-make/issue-88756-opt-help/output-default.stdout b/src/test/run-make/issue-88756-opt-help/output-default.stdout
deleted file mode 100644
index 5cb7ecb649a..00000000000
--- a/src/test/run-make/issue-88756-opt-help/output-default.stdout
+++ /dev/null
@@ -1,193 +0,0 @@
-    -W                          allow-features=val -- only allow the listed language features to be enabled in code (space separated)
-    -W                       always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no)
-    -W               assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no)
-    -W                            asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
-    -W                       assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
-    -W                      binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
-    -W                       branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
-    -W                           cf-protection=val -- instrument control-flow architecture protection
-    -W               cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
-    -W                                   chalk=val -- enable the experimental Chalk-based trait solving engine
-    -W                         codegen-backend=val -- the backend to use
-    -W                             combine-cgu=val -- combine CGUs into a single one
-    -W                              crate-attr=val -- inject the given attribute in the crate
-    -W                debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO
-    -W                            debug-macros=val -- emit line numbers debug info inside macros (default: no)
-    -W                 deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes)
-    -W                  dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
-    -W                               dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no)
-    -W                                 dlltool=val -- import library generation tool (windows-gnu only)
-    -W                 dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
-    -W                           drop-tracking=val -- enables drop tracking in generators (default: no)
-    -W                        dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no)
-    -W                          dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
-    -W                                dump-mir=val -- dump MIR state to file.
-        `val` is used to select which passes and functions to dump. For example:
-        `all` matches all passes and functions,
-        `foo` matches all passes for functions whose name contains 'foo',
-        `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
-        `foo | bar` all passes for function names containing 'foo' or 'bar'.
-    -W                       dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)
-    -W                            dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`)
-    -W            dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
-    -W                       dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
-    -W                       dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
-    -W                        emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
-    -W                             fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
-    -W              force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
-    -W                                    fuel=val -- set the optimization fuel quota for a crate
-    -W                       function-sections=val -- whether each function should go in its own section
-    -W                    future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no)
-    -W                                  gcc-ld=val -- implementation of ld used by cc
-    -W                      graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no)
-    -W                           graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)
-    -W                               hir-stats=val -- print some statistics about AST and HIR (default: no)
-    -W                human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no)
-    -W                        identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no)
-    -W                incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no)
-    -W                        incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
-    -W              incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
-    -W                  incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
-    -W                              inline-mir=val -- enable MIR inlining (default: no)
-    -W                    inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
-    -W               inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
-    -W                      inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs
-    -W                             input-stats=val -- gather statistics about the input (default: no)
-    -W                     instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are:
-        `=all` (implicit value)
-        `=except-unused-generics`
-        `=except-unused-functions`
-        `=off` (default)
-    -W                       instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no)
-    -W                       keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
-    -W                   link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
-    -W                               link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
-    -W                            llvm-plugins=val -- a list LLVM plugins to enable (space separated)
-    -W                         llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
-    -W                         location-detail=val -- comma separated list of location details to be tracked when using caller_location valid options are `file`, `line`, and `column` (default: all)
-    -W                                      ls=val -- list the symbols defined by a library crate (default: no)
-    -W                         macro-backtrace=val -- show macro backtraces (default: no)
-    -W                         merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
-    -W                              meta-stats=val -- gather metadata statistics (default: no)
-    -W                          mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
-    -W                       mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual.
-    -W                           mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
-    -W                         move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
-    -W                         mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
-    -W                   new-llvm-pass-manager=val -- use new LLVM pass manager (default: no)
-    -W                               nll-facts=val -- dump facts from NLL analysis into side files (default: no)
-    -W                           nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
-    -W                             no-analysis=val -- parse and expand the source, but run no analysis
-    -W                              no-codegen=val -- run all passes except codegen; no output
-    -W              no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
-    -W                     no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints
-    -W                           no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
-    -W                                 no-link=val -- compile without linking
-    -W                        no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
-    -W                 no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used
-    -W                     no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate
-    -W                          normalize-docs=val -- normalize associated items in rustdoc when generating documentation
-    -W                                     oom=val -- panic strategy for out-of-memory handling
-    -W                  osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
-    -W                       panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
-    -W                           panic-in-drop=val -- panic strategy for panics in drops
-    -W                              parse-only=val -- parse only; do not compile, assemble, or link (default: no)
-    -W                              perf-stats=val -- print some performance-related statistics (default: no)
-    -W pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes)
-    -W                                     plt=val -- whether to use the PLT when calling into shared libraries;
-        only has effect for PIC code on systems with ELF binaries
-        (default: PLT is disabled if full relro is enabled)
-    -W                                polonius=val -- enable polonius-based borrow-checker (default: no)
-    -W                            polymorphize=val -- perform polymorphization analysis
-    -W                            pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times)
-    -W                           pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated)
-    -W           precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
-    -W                              print-fuel=val -- make rustc print the total optimization fuel used by a crate
-    -W                       print-llvm-passes=val -- print the LLVM optimization passes being run (default: no)
-    -W                        print-mono-items=val -- print the result of the monomorphization collection pass
-    -W                        print-type-sizes=val -- print layout information for each type encountered (default: no)
-    -W                    proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no)
-    -W                                 profile=val -- insert profiling code (default: no)
-    -W                        profile-closures=val -- profile size of closures
-    -W                            profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
-    -W                        profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
-    -W                      profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
-    -W                         query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no)
-    -W                        randomize-layout=val -- randomize the layout of types (default: no)
-    -W                             layout-seed=val -- seed layout randomization
-    -W                   relax-elf-relocations=val -- whether ELF relocations can be relaxed
-    -W                             relro-level=val -- choose which RELRO level to use
-    -W                        remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix
-    -W         simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
-    -W                     report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no)
-    -W                               sanitizer=val -- use a sanitizer
-    -W          sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer
-    -W                       sanitizer-recover=val -- enable recovery for selected sanitizers
-    -W                  saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
-    -W                           save-analysis=val -- write syntax and type analysis (in JSON format) information, in addition to normal output (default: no)
-    -W                            self-profile=val -- run the self profiler and output the raw event data
-    -W                     self-profile-events=val -- specify the events recorded by the self profiler;
-        for example: `-Z self-profile-events=default,query-keys`
-        all options: none, all, default, generic-activity, query-provider, query-cache-hit
-                     query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes
-    -W                    self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of:
-        `wall-time` (monotonic clock, i.e. `std::time::Instant`)
-        `instructions:u` (retired instructions, userspace-only)
-        `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)
-    -W                          share-generics=val -- make the current crate share its generic instantiations
-    -W                               show-span=val -- show spans for compiler debugging (expr|pat|ty)
-    -W                              span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span`
-    -W                       span-free-formats=val -- exclude spans when debug-printing compiler state (default: no)
-    -W                      src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)
-    -W                         stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)
-    -W                      strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB
-    -W                                   strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)
-    -W                        split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
-        (default: `split`)
-
-        `split`: sections which do not require relocation are written into a DWARF object (`.dwo`)
-                 file which is ignored by the linker
-        `single`: sections which do not require relocation are written into object file but ignored
-                  by the linker
-    -W                    split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
-    -W                 symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0')
-    -W                                   teach=val -- show extended diagnostic help (default: no)
-    -W                               temps-dir=val -- the directory the intermediate files are written to
-    -W                          terminal-width=val -- set the current terminal width
-    -W                          translate-lang=val -- language identifier for diagnostic output
-    -W                translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
-    -W        translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
-    -W                                tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details)
-    -W                                 thinlto=val -- enable ThinLTO when possible
-    -W                           thir-unsafeck=val -- use the THIR unsafety checker (default: no)
-    -W                                 threads=val -- use a thread pool with N threads
-    -W                                    time=val -- measure time of rustc processes (default: no)
-    -W                        time-llvm-passes=val -- measure time of each LLVM pass (default: no)
-    -W                             time-passes=val -- measure time of each rustc pass (default: no)
-    -W                               tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
-    -W                            trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
-    -W   translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes)
-    -W                        trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
-    -W                        treat-err-as-bug=val -- treat error number `val` that occurs as bug
-    -W                   trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items
-    -W                              ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no)
-    -W            uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
-    -W          unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no)
-    -W                                unpretty=val -- present the input source, unstable (and less-pretty) variants;
-        `normal`, `identified`,
-        `expanded`, `expanded,identified`,
-        `expanded,hygiene` (with internal representations),
-        `ast-tree` (raw AST before expansion),
-        `ast-tree,expanded` (raw AST after expansion),
-        `hir` (the HIR), `hir,identified`,
-        `hir,typed` (HIR with types for each node),
-        `hir-tree` (dump the raw HIR),
-        `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)
-    -W                        unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no)
-    -W                        unstable-options=val -- adds unstable command line options to rustc interface (default: no)
-    -W                       use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array
-    -W                            validate-mir=val -- validate MIR after each transformation
-    -W                                 verbose=val -- in general, enable more debug printouts (default: no)
-    -W                          verify-llvm-ir=val -- verify LLVM IR (default: no)
-    -W            virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]`
-    -W                         wasi-exec-model=val -- whether to build a wasi command or reactor
diff --git a/src/test/run-make/issue-88756-opt-help/x.rs b/src/test/run-make/issue-88756-opt-help/x.rs
deleted file mode 100644
index 5df7576133a..00000000000
--- a/src/test/run-make/issue-88756-opt-help/x.rs
+++ /dev/null
@@ -1 +0,0 @@
-// nothing to see here
diff --git a/src/test/run-make/native-link-modifier-bundle/Makefile b/src/test/run-make/native-link-modifier-bundle/Makefile
index 723bb4689fe..e4b0f74ac26 100644
--- a/src/test/run-make/native-link-modifier-bundle/Makefile
+++ b/src/test/run-make/native-link-modifier-bundle/Makefile
@@ -3,27 +3,31 @@
 
 -include ../../run-make-fulldeps/tools.mk
 
+# We're using the llvm-nm instead of the system nm to ensure it is compatible
+# with the LLVM bitcode generated by rustc.
+NM = "$(LLVM_BIN_DIR)"/llvm-nm
+
 all: $(call NATIVE_STATICLIB,native-staticlib)
 	# Build a staticlib and a rlib, the `native_func` symbol will be bundled into them
 	$(RUSTC) bundled.rs --crate-type=staticlib --crate-type=rlib
-	nm $(TMPDIR)/libbundled.a | $(CGREP) -e "T _*native_func"
-	nm $(TMPDIR)/libbundled.a | $(CGREP) -e "U _*native_func"
-	nm $(TMPDIR)/libbundled.rlib | $(CGREP) -e "T _*native_func"
-	nm $(TMPDIR)/libbundled.rlib | $(CGREP) -e "U _*native_func"
+	$(NM) $(TMPDIR)/libbundled.a | $(CGREP) -e "T _*native_func"
+	$(NM) $(TMPDIR)/libbundled.a | $(CGREP) -e "U _*native_func"
+	$(NM) $(TMPDIR)/libbundled.rlib | $(CGREP) -e "T _*native_func"
+	$(NM) $(TMPDIR)/libbundled.rlib | $(CGREP) -e "U _*native_func"
 
 	# Build a staticlib and a rlib, the `native_func` symbol will not be bundled into it
 	$(RUSTC) non-bundled.rs --crate-type=staticlib --crate-type=rlib
-	nm $(TMPDIR)/libnon_bundled.a | $(CGREP) -ve "T _*native_func"
-	nm $(TMPDIR)/libnon_bundled.a | $(CGREP) -e "U _*native_func"
-	nm $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -ve "T _*native_func"
-	nm $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -e "U _*native_func"
+	$(NM) $(TMPDIR)/libnon_bundled.a | $(CGREP) -ve "T _*native_func"
+	$(NM) $(TMPDIR)/libnon_bundled.a | $(CGREP) -e "U _*native_func"
+	$(NM) $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -ve "T _*native_func"
+	$(NM) $(TMPDIR)/libnon_bundled.rlib | $(CGREP) -e "U _*native_func"
 
 	# Build a cdylib, `native-staticlib` will not appear on the linker line because it was bundled previously
 	# The cdylib will contain the `native_func` symbol in the end
 	$(RUSTC) cdylib-bundled.rs --crate-type=cdylib --print link-args | $(CGREP) -ve '-l[" ]*native-staticlib'
-	nm $(call DYLIB,cdylib_bundled) | $(CGREP) -e "[Tt] _*native_func"
+	$(NM) $(call DYLIB,cdylib_bundled) | $(CGREP) -e "[Tt] _*native_func"
 
 	# Build a cdylib, `native-staticlib` will appear on the linker line because it was not bundled previously
 	# The cdylib will contain the `native_func` symbol in the end
 	$(RUSTC) cdylib-non-bundled.rs --crate-type=cdylib --print link-args | $(CGREP) -e '-l[" ]*native-staticlib'
-	nm $(call DYLIB,cdylib_non_bundled) | $(CGREP) -e "[Tt] _*native_func"
+	$(NM) $(call DYLIB,cdylib_non_bundled) | $(CGREP) -e "[Tt] _*native_func"
diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml
index c441f84a821..25699d82e61 100644
--- a/src/test/rustdoc-gui/sidebar-source-code-display.goml
+++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml
@@ -27,29 +27,52 @@ reload:
 // Waiting for the sidebar to be displayed...
 wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
 assert-css: (
-    "#source-sidebar .expand + .children a.selected",
+    "#source-sidebar details[open] > .files a.selected",
     {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
 )
+// Without hover or focus.
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
+// With focus.
+focus: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
 // Without hover.
 assert-css: (
-    "#source-sidebar .expand + .children > .files a:not(.selected)",
+    "#source-sidebar details[open] > .files a:not(.selected)",
     {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
 )
+// With focus.
+focus: "#source-sidebar details[open] > .files a:not(.selected)"
+wait-for-css: (
+    "#source-sidebar details[open] > .files a:not(.selected)",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+)
+focus: ".search-input"
 // With hover.
-move-cursor-to: "#source-sidebar .expand + .children > .files a:not(.selected)"
+move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
 assert-css: (
-    "#source-sidebar .expand + .children > .files a:not(.selected)",
+    "#source-sidebar details[open] > .files a:not(.selected)",
     {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
 )
 // Without hover.
 assert-css: (
-    "#source-sidebar .expand + .children .folders .name",
+    "#source-sidebar details[open] > .folders > details > summary",
     {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
 )
+// With focus.
+focus: "#source-sidebar details[open] > .folders > details > summary"
+wait-for-css: (
+    "#source-sidebar details[open] > .folders > details > summary",
+    {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
+)
+focus: ".search-input"
 // With hover.
-move-cursor-to: "#source-sidebar .expand + .children .folders .name"
+move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
 assert-css: (
-    "#source-sidebar .expand + .children .folders .name",
+    "#source-sidebar details[open] > .folders > details > summary",
     {"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
 )
 
@@ -59,29 +82,52 @@ reload:
 // Waiting for the sidebar to be displayed...
 wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
 assert-css: (
-    "#source-sidebar .expand + .children a.selected",
+    "#source-sidebar details[open] > .files > a.selected",
     {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
 )
+// Without hover or focus.
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
+// With focus.
+focus: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
 // Without hover.
 assert-css: (
-    "#source-sidebar .expand + .children > .files a:not(.selected)",
+    "#source-sidebar details[open] > .files > a:not(.selected)",
     {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
 )
+// With focus.
+focus: "#source-sidebar details[open] > .files a:not(.selected)"
+wait-for-css: (
+    "#source-sidebar details[open] > .files a:not(.selected)",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
+)
+focus: ".search-input"
 // With hover.
-move-cursor-to: "#source-sidebar .expand + .children > .files a:not(.selected)"
+move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
 assert-css: (
-    "#source-sidebar .expand + .children > .files a:not(.selected)",
+    "#source-sidebar details[open] > .files a:not(.selected)",
     {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
 )
 // Without hover.
 assert-css: (
-    "#source-sidebar .expand + .children .folders .name",
+    "#source-sidebar details[open] > .folders > details > summary",
     {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
 )
+// With focus.
+focus: "#source-sidebar details[open] > .folders > details > summary"
+wait-for-css: (
+    "#source-sidebar details[open] > .folders > details > summary",
+    {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
+)
+focus: ".search-input"
 // With hover.
-move-cursor-to: "#source-sidebar .expand + .children .folders .name"
+move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
 assert-css: (
-    "#source-sidebar .expand + .children .folders .name",
+    "#source-sidebar details[open] > .folders > details > summary",
     {"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
 )
 
@@ -91,29 +137,52 @@ reload:
 // Waiting for the sidebar to be displayed...
 wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
 assert-css: (
-    "#source-sidebar .expand + .children a.selected",
+    "#source-sidebar details[open] > .files a.selected",
     {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
 )
+// Without hover or focus.
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
+// With focus.
+focus: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
+focus: ".search-input"
+// With hover.
+move-cursor-to: "#sidebar-toggle > button"
+assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
 // Without hover.
 assert-css: (
-    "#source-sidebar .expand + .children > .files a:not(.selected)",
+    "#source-sidebar details[open] > .files a:not(.selected)",
     {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
 )
+// With focus.
+focus: "#source-sidebar details[open] > .files a:not(.selected)"
+wait-for-css: (
+    "#source-sidebar details[open] > .files a:not(.selected)",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+focus: ".search-input"
 // With hover.
-move-cursor-to: "#source-sidebar .expand + .children > .files a:not(.selected)"
+move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
 assert-css: (
-    "#source-sidebar .expand + .children > .files a:not(.selected)",
+    "#source-sidebar details[open] > .files a:not(.selected)",
     {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
 )
 // Without hover.
 assert-css: (
-    "#source-sidebar .expand + .children .folders .name",
+    "#source-sidebar details[open] > .folders > details > summary",
     {"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
 )
+// With focus.
+focus: "#source-sidebar details[open] > .folders > details > summary"
+wait-for-css: (
+    "#source-sidebar details[open] > .folders > details > summary",
+    {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
+)
+focus: ".search-input"
 // With hover.
-move-cursor-to: "#source-sidebar .expand + .children .folders .name"
+move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
 assert-css: (
-    "#source-sidebar .expand + .children .folders .name",
+    "#source-sidebar details[open] > .folders > details > summary",
     {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
 )
 
diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml
index b45512601f2..581f826a3d9 100644
--- a/src/test/rustdoc-gui/source-code-page.goml
+++ b/src/test/rustdoc-gui/source-code-page.goml
@@ -34,19 +34,16 @@ assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
 click: "#sidebar-toggle"
 assert: ".source-sidebar-expanded"
 
-// We check that the first entry of the sidebar is collapsed (which, for whatever reason,
-// is number 2 and not 1...).
-assert-attribute: ("#source-sidebar .name:nth-child(2)", {"class": "name"})
-assert-text: ("#source-sidebar .name:nth-child(2)", "implementors")
-// We also check its children are hidden too.
-assert-css: ("#source-sidebar .name:nth-child(2) + .children", {"display": "none"})
+// We check that the first entry of the sidebar is collapsed
+assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
+assert-text: ("#source-sidebar details:first-of-type > summary", "implementors")
 // We now click on it.
-click: "#source-sidebar .name:nth-child(2)"
-assert-attribute: ("#source-sidebar .name:nth-child(2)", {"class": "name expand"})
-// Checking that its children are displayed as well.
-assert-css: ("#source-sidebar .name:nth-child(2) + .children", {"display": "block"})
+click: "#source-sidebar details:first-of-type > summary"
+assert-property: ("#source-sidebar details:first-of-type", {"open": "true"})
 
 // And now we collapse it again.
-click: "#source-sidebar .name:nth-child(2)"
-assert-attribute: ("#source-sidebar .name:nth-child(2)", {"class": "name"})
-assert-css: ("#source-sidebar .name:nth-child(2) + .children", {"display": "none"})
+click: "#source-sidebar details:first-of-type > summary"
+assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
+
+// Check the spacing.
+assert-css: ("#source-sidebar > details.dir-entry", {"padding-left": "4px"})
diff --git a/src/test/rustdoc-ui/issue-83883-describe-lints.rs b/src/test/rustdoc-ui/issue-83883-describe-lints.rs
index a261b782d48..0474d6c143e 100644
--- a/src/test/rustdoc-ui/issue-83883-describe-lints.rs
+++ b/src/test/rustdoc-ui/issue-83883-describe-lints.rs
@@ -1,8 +1,10 @@
 // compile-flags: -W help
 // check-pass
+// check-stdout
+// error-pattern:Lint checks provided
+// error-pattern:rustdoc::broken-intra-doc-links
 //
 // ignore-tidy-linelength
 //
 // normalize-stdout-test: "( +name  default  meaning\n +----  -------  -------\n)?( *[[:word:]:-]+  (allow  |warn   |deny   |forbid )  [^\n]+\n)+" -> "    $$NAMES  $$LEVELS  $$MEANINGS"
 // normalize-stdout-test: " +name  sub-lints\n +----  ---------\n( *[[:word:]:-]+  [^\n]+\n)+" -> "    $$NAMES  $$SUB_LINTS"
-// normalize-stdout-test: " +rustdoc::all(  (rustdoc::[[:word:]-]+, )*rustdoc::[[:word:]-]+)?" -> "    rustdoc::all  $$GROUPS$4"
diff --git a/src/test/rustdoc-ui/issue-83883-describe-lints.stdout b/src/test/rustdoc-ui/issue-83883-describe-lints.stdout
index 5cb7ecb649a..bbf66a31583 100644
--- a/src/test/rustdoc-ui/issue-83883-describe-lints.stdout
+++ b/src/test/rustdoc-ui/issue-83883-describe-lints.stdout
@@ -1,193 +1,24 @@
-    -W                          allow-features=val -- only allow the listed language features to be enabled in code (space separated)
-    -W                       always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no)
-    -W               assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no)
-    -W                            asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
-    -W                       assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
-    -W                      binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
-    -W                       branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
-    -W                           cf-protection=val -- instrument control-flow architecture protection
-    -W               cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use
-    -W                                   chalk=val -- enable the experimental Chalk-based trait solving engine
-    -W                         codegen-backend=val -- the backend to use
-    -W                             combine-cgu=val -- combine CGUs into a single one
-    -W                              crate-attr=val -- inject the given attribute in the crate
-    -W                debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO
-    -W                            debug-macros=val -- emit line numbers debug info inside macros (default: no)
-    -W                 deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes)
-    -W                  dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no)
-    -W                               dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no)
-    -W                                 dlltool=val -- import library generation tool (windows-gnu only)
-    -W                 dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no)
-    -W                           drop-tracking=val -- enables drop tracking in generators (default: no)
-    -W                        dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no)
-    -W                          dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no)
-    -W                                dump-mir=val -- dump MIR state to file.
-        `val` is used to select which passes and functions to dump. For example:
-        `all` matches all passes and functions,
-        `foo` matches all passes for functions whose name contains 'foo',
-        `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
-        `foo | bar` all passes for function names containing 'foo' or 'bar'.
-    -W                       dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no)
-    -W                            dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`)
-    -W            dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no)
-    -W                       dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no)
-    -W                       dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans.
-    -W                        emit-stack-sizes=val -- emit a section containing stack size metadata (default: no)
-    -W                             fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no)
-    -W              force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no)
-    -W                                    fuel=val -- set the optimization fuel quota for a crate
-    -W                       function-sections=val -- whether each function should go in its own section
-    -W                    future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no)
-    -W                                  gcc-ld=val -- implementation of ld used by cc
-    -W                      graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no)
-    -W                           graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)
-    -W                               hir-stats=val -- print some statistics about AST and HIR (default: no)
-    -W                human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no)
-    -W                        identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no)
-    -W                incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no)
-    -W                        incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no)
-    -W              incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no)
-    -W                  incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no)
-    -W                              inline-mir=val -- enable MIR inlining (default: no)
-    -W                    inline-mir-threshold=val -- a default MIR inlining threshold (default: 50)
-    -W               inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100)
-    -W                      inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs
-    -W                             input-stats=val -- gather statistics about the input (default: no)
-    -W                     instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are:
-        `=all` (implicit value)
-        `=except-unused-generics`
-        `=except-unused-functions`
-        `=off` (default)
-    -W                       instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no)
-    -W                       keep-hygiene-data=val -- keep hygiene data after analysis (default: no)
-    -W                   link-native-libraries=val -- link native libraries in the linker invocation (default: yes)
-    -W                               link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no)
-    -W                            llvm-plugins=val -- a list LLVM plugins to enable (space separated)
-    -W                         llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no)
-    -W                         location-detail=val -- comma separated list of location details to be tracked when using caller_location valid options are `file`, `line`, and `column` (default: all)
-    -W                                      ls=val -- list the symbols defined by a library crate (default: no)
-    -W                         macro-backtrace=val -- show macro backtraces (default: no)
-    -W                         merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
-    -W                              meta-stats=val -- gather metadata statistics (default: no)
-    -W                          mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
-    -W                       mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual.
-    -W                           mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
-    -W                         move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
-    -W                         mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
-    -W                   new-llvm-pass-manager=val -- use new LLVM pass manager (default: no)
-    -W                               nll-facts=val -- dump facts from NLL analysis into side files (default: no)
-    -W                           nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
-    -W                             no-analysis=val -- parse and expand the source, but run no analysis
-    -W                              no-codegen=val -- run all passes except codegen; no output
-    -W              no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
-    -W                     no-interleave-lints=val -- execute lints separately; allows benchmarking individual lints
-    -W                           no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
-    -W                                 no-link=val -- compile without linking
-    -W                        no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)
-    -W                 no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used
-    -W                     no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate
-    -W                          normalize-docs=val -- normalize associated items in rustdoc when generating documentation
-    -W                                     oom=val -- panic strategy for out-of-memory handling
-    -W                  osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
-    -W                       panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
-    -W                           panic-in-drop=val -- panic strategy for panics in drops
-    -W                              parse-only=val -- parse only; do not compile, assemble, or link (default: no)
-    -W                              perf-stats=val -- print some performance-related statistics (default: no)
-    -W pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes)
-    -W                                     plt=val -- whether to use the PLT when calling into shared libraries;
-        only has effect for PIC code on systems with ELF binaries
-        (default: PLT is disabled if full relro is enabled)
-    -W                                polonius=val -- enable polonius-based borrow-checker (default: no)
-    -W                            polymorphize=val -- perform polymorphization analysis
-    -W                            pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times)
-    -W                           pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated)
-    -W           precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551.
-    -W                              print-fuel=val -- make rustc print the total optimization fuel used by a crate
-    -W                       print-llvm-passes=val -- print the LLVM optimization passes being run (default: no)
-    -W                        print-mono-items=val -- print the result of the monomorphization collection pass
-    -W                        print-type-sizes=val -- print layout information for each type encountered (default: no)
-    -W                    proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no)
-    -W                                 profile=val -- insert profiling code (default: no)
-    -W                        profile-closures=val -- profile size of closures
-    -W                            profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path)
-    -W                        profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`)
-    -W                      profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)
-    -W                         query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no)
-    -W                        randomize-layout=val -- randomize the layout of types (default: no)
-    -W                             layout-seed=val -- seed layout randomization
-    -W                   relax-elf-relocations=val -- whether ELF relocations can be relaxed
-    -W                             relro-level=val -- choose which RELRO level to use
-    -W                        remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix
-    -W         simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes
-    -W                     report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no)
-    -W                               sanitizer=val -- use a sanitizer
-    -W          sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer
-    -W                       sanitizer-recover=val -- enable recovery for selected sanitizers
-    -W                  saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes)
-    -W                           save-analysis=val -- write syntax and type analysis (in JSON format) information, in addition to normal output (default: no)
-    -W                            self-profile=val -- run the self profiler and output the raw event data
-    -W                     self-profile-events=val -- specify the events recorded by the self profiler;
-        for example: `-Z self-profile-events=default,query-keys`
-        all options: none, all, default, generic-activity, query-provider, query-cache-hit
-                     query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes
-    -W                    self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of:
-        `wall-time` (monotonic clock, i.e. `std::time::Instant`)
-        `instructions:u` (retired instructions, userspace-only)
-        `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)
-    -W                          share-generics=val -- make the current crate share its generic instantiations
-    -W                               show-span=val -- show spans for compiler debugging (expr|pat|ty)
-    -W                              span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span`
-    -W                       span-free-formats=val -- exclude spans when debug-printing compiler state (default: no)
-    -W                      src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)
-    -W                         stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details)
-    -W                      strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB
-    -W                                   strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)
-    -W                        split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform)
-        (default: `split`)
 
-        `split`: sections which do not require relocation are written into a DWARF object (`.dwo`)
-                 file which is ignored by the linker
-        `single`: sections which do not require relocation are written into object file but ignored
-                  by the linker
-    -W                    split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
-    -W                 symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0')
-    -W                                   teach=val -- show extended diagnostic help (default: no)
-    -W                               temps-dir=val -- the directory the intermediate files are written to
-    -W                          terminal-width=val -- set the current terminal width
-    -W                          translate-lang=val -- language identifier for diagnostic output
-    -W                translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation)
-    -W        translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics
-    -W                                tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details)
-    -W                                 thinlto=val -- enable ThinLTO when possible
-    -W                           thir-unsafeck=val -- use the THIR unsafety checker (default: no)
-    -W                                 threads=val -- use a thread pool with N threads
-    -W                                    time=val -- measure time of rustc processes (default: no)
-    -W                        time-llvm-passes=val -- measure time of each LLVM pass (default: no)
-    -W                             time-passes=val -- measure time of each rustc pass (default: no)
-    -W                               tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details)
-    -W                            trace-macros=val -- for every macro invocation, print its name and arguments (default: no)
-    -W   translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes)
-    -W                        trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes)
-    -W                        treat-err-as-bug=val -- treat error number `val` that occurs as bug
-    -W                   trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items
-    -W                              ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no)
-    -W            uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16)
-    -W          unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no)
-    -W                                unpretty=val -- present the input source, unstable (and less-pretty) variants;
-        `normal`, `identified`,
-        `expanded`, `expanded,identified`,
-        `expanded,hygiene` (with internal representations),
-        `ast-tree` (raw AST before expansion),
-        `ast-tree,expanded` (raw AST after expansion),
-        `hir` (the HIR), `hir,identified`,
-        `hir,typed` (HIR with types for each node),
-        `hir-tree` (dump the raw HIR),
-        `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)
-    -W                        unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no)
-    -W                        unstable-options=val -- adds unstable command line options to rustc interface (default: no)
-    -W                       use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array
-    -W                            validate-mir=val -- validate MIR after each transformation
-    -W                                 verbose=val -- in general, enable more debug printouts (default: no)
-    -W                          verify-llvm-ir=val -- verify LLVM IR (default: no)
-    -W            virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]`
-    -W                         wasi-exec-model=val -- whether to build a wasi command or reactor
+Available lint options:
+    -W <foo>           Warn about <foo>
+    -A <foo>           Allow <foo>
+    -D <foo>           Deny <foo>
+    -F <foo>           Forbid <foo> (deny <foo> and all attempts to override)
+
+
+Lint checks provided by rustc:
+
+    $NAMES  $LEVELS  $MEANINGS
+
+Lint groups provided by rustc:
+
+    $NAMES  $SUB_LINTS
+
+Lint checks provided by plugins loaded by this crate:
+
+    $NAMES  $LEVELS  $MEANINGS
+
+Lint groups provided by plugins loaded by this crate:
+
+    $NAMES  $SUB_LINTS
+
diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs
index 0ac6dc763df..a79e93145ba 100644
--- a/src/test/rustdoc/assoc-consts.rs
+++ b/src/test/rustdoc/assoc-consts.rs
@@ -27,6 +27,10 @@ impl Bar {
     // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.BAR"]' \
     //      'const BAR: usize'
     pub const BAR: usize = 3;
+
+    // @has - '//*[@id="associatedconstant.BAR_ESCAPED"]' \
+    //      "const BAR_ESCAPED: &'static str = \"<em>markup</em>\""
+    pub const BAR_ESCAPED: &'static str = "<em>markup</em>";
 }
 
 pub struct Baz<'a, U: 'a, T>(T, &'a [U]);
diff --git a/src/test/rustdoc/assoc-types.rs b/src/test/rustdoc/assoc-types.rs
index d9e4ffab1c7..a9e5b8d0019 100644
--- a/src/test/rustdoc/assoc-types.rs
+++ b/src/test/rustdoc/assoc-types.rs
@@ -2,7 +2,7 @@
 
 // @has assoc_types/trait.Index.html
 pub trait Index<I: ?Sized> {
-        // @has - '//*[@id="associatedtype.Output"]//h4[@class="code-header"]' 'type Output: ?Sized'
+    // @has - '//*[@id="associatedtype.Output"]//h4[@class="code-header"]' 'type Output: ?Sized'
     type Output: ?Sized;
     // @has - '//*[@id="tymethod.index"]//h4[@class="code-header"]' \
     //      "fn index<'a>(&'a self, index: I) -> &'a Self::Output"
diff --git a/src/test/rustdoc/const-value-display.rs b/src/test/rustdoc/const-value-display.rs
index 0ae52592b64..5b2f3c48d57 100644
--- a/src/test/rustdoc/const-value-display.rs
+++ b/src/test/rustdoc/const-value-display.rs
@@ -1,9 +1,9 @@
 #![crate_name = "foo"]
 
 // @has 'foo/constant.HOUR_IN_SECONDS.html'
-// @has - '//*[@class="docblock item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = 60 * 60; // 3_600u64'
+// @has - '//*[@class="docblock item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = _; // 3_600u64'
 pub const HOUR_IN_SECONDS: u64 = 60 * 60;
 
 // @has 'foo/constant.NEGATIVE.html'
-// @has - '//*[@class="docblock item-decl"]//code' 'pub const NEGATIVE: i64 = -60 * 60; // -3_600i64'
+// @has - '//*[@class="docblock item-decl"]//code' 'pub const NEGATIVE: i64 = _; // -3_600i64'
 pub const NEGATIVE: i64 = -60 * 60;
diff --git a/src/test/rustdoc/decl-trailing-whitespace.declaration.html b/src/test/rustdoc/decl-trailing-whitespace.declaration.html
new file mode 100644
index 00000000000..e60caaeff38
--- /dev/null
+++ b/src/test/rustdoc/decl-trailing-whitespace.declaration.html
@@ -0,0 +1,7 @@
+<code>pub trait Write {
+    fn <a href="#tymethod.poll_write" class="fnname">poll_write</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;buf: &amp;mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+<span class="item-spacer" />    fn <a href="#tymethod.poll_flush" class="fnname">poll_flush</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+<span class="item-spacer" />    fn <a href="#tymethod.poll_close" class="fnname">poll_close</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
+
+    fn <a href="#method.poll_write_vectored" class="fnname">poll_write_vectored</a>(<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;self: <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;bufs: &amp;[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]<br />&#160;&#160;&#160;&#160;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt; { ... }
+}</code>
diff --git a/src/test/rustdoc/decl-trailing-whitespace.rs b/src/test/rustdoc/decl-trailing-whitespace.rs
new file mode 100644
index 00000000000..46a2307abef
--- /dev/null
+++ b/src/test/rustdoc/decl-trailing-whitespace.rs
@@ -0,0 +1,30 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/98803>.
+
+#![crate_name = "foo"]
+
+pub struct Error;
+
+// @has 'foo/trait.Write.html'
+
+pub trait Write {
+    // @snapshot 'declaration' - '//*[@class="docblock item-decl"]//code'
+    fn poll_write(
+        self: Option<String>,
+        cx: &mut Option<String>,
+        buf: &mut [usize]
+    ) -> Option<Result<usize, Error>>;
+    fn poll_flush(
+        self: Option<String>,
+        cx: &mut Option<String>
+    ) -> Option<Result<(), Error>>;
+    fn poll_close(
+        self: Option<String>,
+        cx: &mut Option<String>,
+    ) -> Option<Result<(), Error>>;
+
+    fn poll_write_vectored(
+        self: Option<String>,
+        cx: &mut Option<String>,
+        bufs: &[usize]
+    ) -> Option<Result<usize, Error>> {}
+}
diff --git a/src/test/rustdoc/hide-complex-unevaluated-const-arguments.rs b/src/test/rustdoc/hide-complex-unevaluated-const-arguments.rs
new file mode 100644
index 00000000000..644a6e1cf33
--- /dev/null
+++ b/src/test/rustdoc/hide-complex-unevaluated-const-arguments.rs
@@ -0,0 +1,82 @@
+// Test that certain unevaluated constant expression arguments that are
+// deemed too verbose or complex and that may leak private or
+// `doc(hidden)` struct fields are not displayed in the documentation.
+//
+// Read the documentation of `rustdoc::clean::utils::print_const_expr`
+// for further details.
+#![feature(const_trait_impl, generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// @has hide_complex_unevaluated_const_arguments/trait.Stage.html
+pub trait Stage {
+    // A helper constant that prevents const expressions containing it
+    // from getting fully evaluated since it doesn't have a body and
+    // thus is non-reducible. This allows us to specifically test the
+    // pretty-printing of *unevaluated* consts.
+    const ABSTRACT: usize;
+
+    // Currently considered "overly complex" by the `generic_const_exprs`
+    // feature. If / once this expression kind gets supported, this
+    // unevaluated const expression could leak the private struct field.
+    //
+    // FIXME: Once the line below compiles, make this a test that
+    //        ensures that the private field is not printed.
+    //
+    //const ARRAY0: [u8; Struct { private: () } + Self::ABSTRACT];
+
+    // This assoc. const could leak the private assoc. function `Struct::new`.
+    // Ensure that this does not happen.
+    //
+    // @has - '//*[@id="associatedconstant.ARRAY1"]' \
+    //        'const ARRAY1: [u8; { _ }]'
+    const ARRAY1: [u8; Struct::new(/* ... */) + Self::ABSTRACT * 1_000];
+
+    // @has - '//*[@id="associatedconstant.VERBOSE"]' \
+    //        'const VERBOSE: [u16; { _ }]'
+    const VERBOSE: [u16; compute("thing", 9 + 9) * Self::ABSTRACT];
+
+    // Check that we do not leak the private struct field contained within
+    // the path. The output could definitely be improved upon
+    // (e.g. printing sth. akin to `<Self as Helper<{ _ }>>::OUT`) but
+    // right now “safe is safe”.
+    //
+    // @has - '//*[@id="associatedconstant.PATH"]' \
+    //        'const PATH: usize = _'
+    const PATH: usize = <Self as Helper<{ Struct { private: () } }>>::OUT;
+}
+
+const fn compute(input: &str, extra: usize) -> usize {
+    input.len() + extra
+}
+
+pub trait Helper<const S: Struct> {
+    const OUT: usize;
+}
+
+impl<const S: Struct, St: Stage + ?Sized> Helper<S> for St {
+    const OUT: usize = St::ABSTRACT;
+}
+
+// Currently in rustdoc, const arguments are not evaluated in this position
+// and therefore they fall under the realm of `print_const_expr`.
+// If rustdoc gets patched to evaluate const arguments, it is fine to replace
+// this test as long as one can ensure that private fields are not leaked!
+//
+// @has hide_complex_unevaluated_const_arguments/trait.Sub.html \
+//      '//*[@class="rust trait"]' \
+//      'pub trait Sub: Sup<{ _ }, { _ }> { }'
+pub trait Sub: Sup<{ 90 * 20 * 4 }, { Struct { private: () } }> {}
+
+pub trait Sup<const N: usize, const S: Struct> {}
+
+pub struct Struct { private: () }
+
+impl Struct {
+    const fn new() -> Self { Self { private: () } }
+}
+
+impl const std::ops::Add<usize> for Struct {
+    type Output = usize;
+
+    fn add(self, _: usize) -> usize { 0 }
+}
diff --git a/src/test/rustdoc/hide-complex-unevaluated-consts.rs b/src/test/rustdoc/hide-complex-unevaluated-consts.rs
new file mode 100644
index 00000000000..ba623246a01
--- /dev/null
+++ b/src/test/rustdoc/hide-complex-unevaluated-consts.rs
@@ -0,0 +1,71 @@
+// Regression test for issue #97933.
+//
+// Test that certain unevaluated constant expressions that are
+// deemed too verbose or complex and that may leak private or
+// `doc(hidden)` struct fields are not displayed in the documentation.
+//
+// Read the documentation of `rustdoc::clean::utils::print_const_expr`
+// for further details.
+
+// @has hide_complex_unevaluated_consts/trait.Container.html
+pub trait Container {
+    // A helper constant that prevents const expressions containing it
+    // from getting fully evaluated since it doesn't have a body and
+    // thus is non-reducible. This allows us to specifically test the
+    // pretty-printing of *unevaluated* consts.
+    const ABSTRACT: i32;
+
+    // Ensure that the private field does not get leaked:
+    //
+    // @has - '//*[@id="associatedconstant.STRUCT0"]' \
+    //        'const STRUCT0: Struct = _'
+    const STRUCT0: Struct = Struct { private: () };
+
+    // @has - '//*[@id="associatedconstant.STRUCT1"]' \
+    //        'const STRUCT1: (Struct,) = _'
+    const STRUCT1: (Struct,) = (Struct{private: /**/()},);
+
+    // Although the struct field is public here, check that it is not
+    // displayed. In a future version of rustdoc, we definitely want to
+    // show it. However for the time being, the printing logic is a bit
+    // conservative.
+    //
+    // @has - '//*[@id="associatedconstant.STRUCT2"]' \
+    //        'const STRUCT2: Record = _'
+    const STRUCT2: Record = Record { public: 5 };
+
+    // Test that we do not show the incredibly verbose match expr:
+    //
+    // @has - '//*[@id="associatedconstant.MATCH0"]' \
+    //        'const MATCH0: i32 = _'
+    const MATCH0: i32 = match 234 {
+        0 => 1,
+        _ => Self::ABSTRACT,
+    };
+
+    // @has - '//*[@id="associatedconstant.MATCH1"]' \
+    //        'const MATCH1: bool = _'
+    const MATCH1: bool = match Self::ABSTRACT {
+        _ => true,
+    };
+
+    // Check that we hide complex (arithmetic) operations.
+    // In this case, it is a bit unfortunate since the expression
+    // is not *that* verbose and it might be quite useful to the reader.
+    //
+    // However in general, the expression might be quite large and
+    // contain match expressions and structs with private fields.
+    // We would need to recurse over the whole expression and even more
+    // importantly respect operator precedence when pretty-printing
+    // the potentially partially censored expression.
+    // For now, the implementation is quite simple and the choices
+    // rather conservative.
+    //
+    // @has - '//*[@id="associatedconstant.ARITH_OPS"]' \
+    //        'const ARITH_OPS: i32 = _'
+    const ARITH_OPS: i32 = Self::ABSTRACT * 2 + 1;
+}
+
+pub struct Struct { private: () }
+
+pub struct Record { pub public: i32 }
diff --git a/src/test/rustdoc/show-const-contents.rs b/src/test/rustdoc/show-const-contents.rs
index f5a356bcae6..48b60885974 100644
--- a/src/test/rustdoc/show-const-contents.rs
+++ b/src/test/rustdoc/show-const-contents.rs
@@ -21,7 +21,7 @@ pub const CONST_NEG_I32: i32 = -42;
 // @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
 pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;
 
-// @has show_const_contents/constant.CONST_CALC_I32.html '= 42 + 1; // 43i32'
+// @has show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
 pub const CONST_CALC_I32: i32 = 42 + 1;
 
 // @!has show_const_contents/constant.CONST_REF_I32.html '= &42;'
diff --git a/src/test/ui/abi/rustcall-generic.rs b/src/test/ui/abi/rustcall-generic.rs
index 2fa41a7e35a..411c98e1031 100644
--- a/src/test/ui/abi/rustcall-generic.rs
+++ b/src/test/ui/abi/rustcall-generic.rs
@@ -1,4 +1,7 @@
+// revisions: normal opt
 // check-pass
+//[opt] compile-flags: -Zmir-opt-level=3
+
 #![feature(unboxed_closures)]
 
 extern "rust-call" fn foo<T>(_: T) {}
diff --git a/src/test/ui/deriving/deriving-all-codegen.rs b/src/test/ui/deriving/deriving-all-codegen.rs
index 2f6ef74ac49..028ed9c2305 100644
--- a/src/test/ui/deriving/deriving-all-codegen.rs
+++ b/src/test/ui/deriving/deriving-all-codegen.rs
@@ -28,12 +28,17 @@ struct Point {
     y: u32,
 }
 
-// A long struct.
+// A large struct.
 #[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
 struct Big {
     b1: u32, b2: u32, b3: u32, b4: u32, b5: u32, b6: u32, b7: u32, b8:u32,
 }
 
+// A packed tuple struct.
+#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(packed)]
+struct Packed(u32);
+
 // A C-like, fieldless enum.
 #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
 enum Fieldless {
diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout
index faa5a3c3ddf..c24ed4237b8 100644
--- a/src/test/ui/deriving/deriving-all-codegen.stdout
+++ b/src/test/ui/deriving/deriving-all-codegen.stdout
@@ -37,7 +37,7 @@ impl ::core::marker::Copy for Empty { }
 #[allow(unused_qualifications)]
 impl ::core::fmt::Debug for Empty {
     fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
-        match *self { Self => ::core::fmt::Formatter::write_str(f, "Empty"), }
+        ::core::fmt::Formatter::write_str(f, "Empty")
     }
 }
 #[automatically_derived]
@@ -49,18 +49,14 @@ impl ::core::default::Default for Empty {
 #[automatically_derived]
 #[allow(unused_qualifications)]
 impl ::core::hash::Hash for Empty {
-    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
-        match *self { Self => {} }
-    }
+    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { {} }
 }
 impl ::core::marker::StructuralPartialEq for Empty {}
 #[automatically_derived]
 #[allow(unused_qualifications)]
 impl ::core::cmp::PartialEq for Empty {
     #[inline]
-    fn eq(&self, other: &Empty) -> bool {
-        match *other { Self => match *self { Self => true, }, }
-    }
+    fn eq(&self, other: &Empty) -> bool { true }
 }
 impl ::core::marker::StructuralEq for Empty {}
 #[automatically_derived]
@@ -77,13 +73,7 @@ impl ::core::cmp::PartialOrd for Empty {
     #[inline]
     fn partial_cmp(&self, other: &Empty)
         -> ::core::option::Option<::core::cmp::Ordering> {
-        match *other {
-            Self =>
-                match *self {
-                    Self =>
-                        ::core::option::Option::Some(::core::cmp::Ordering::Equal),
-                },
-        }
+        ::core::option::Option::Some(::core::cmp::Ordering::Equal)
     }
 }
 #[automatically_derived]
@@ -91,9 +81,7 @@ impl ::core::cmp::PartialOrd for Empty {
 impl ::core::cmp::Ord for Empty {
     #[inline]
     fn cmp(&self, other: &Empty) -> ::core::cmp::Ordering {
-        match *other {
-            Self => match *self { Self => ::core::cmp::Ordering::Equal, },
-        }
+        ::core::cmp::Ordering::Equal
     }
 }
 
@@ -121,11 +109,8 @@ impl ::core::marker::Copy for Point { }
 #[allow(unused_qualifications)]
 impl ::core::fmt::Debug for Point {
     fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
-        match *self {
-            Self { x: ref __self_0_0, y: ref __self_0_1 } =>
-                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Point",
-                    "x", &&(*__self_0_0), "y", &&(*__self_0_1)),
-        }
+        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x",
+            &&self.x, "y", &&self.y)
     }
 }
 #[automatically_derived]
@@ -143,11 +128,9 @@ impl ::core::default::Default for Point {
 #[allow(unused_qualifications)]
 impl ::core::hash::Hash for Point {
     fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
-        match *self {
-            Self { x: ref __self_0_0, y: ref __self_0_1 } => {
-                ::core::hash::Hash::hash(&(*__self_0_0), state);
-                ::core::hash::Hash::hash(&(*__self_0_1), state)
-            }
+        {
+            ::core::hash::Hash::hash(&self.x, state);
+            ::core::hash::Hash::hash(&self.y, state)
         }
     }
 }
@@ -157,25 +140,11 @@ impl ::core::marker::StructuralPartialEq for Point {}
 impl ::core::cmp::PartialEq for Point {
     #[inline]
     fn eq(&self, other: &Point) -> bool {
-        match *other {
-            Self { x: ref __self_1_0, y: ref __self_1_1 } =>
-                match *self {
-                    Self { x: ref __self_0_0, y: ref __self_0_1 } =>
-                        (*__self_0_0) == (*__self_1_0) &&
-                            (*__self_0_1) == (*__self_1_1),
-                },
-        }
+        self.x == other.x && self.y == other.y
     }
     #[inline]
     fn ne(&self, other: &Point) -> bool {
-        match *other {
-            Self { x: ref __self_1_0, y: ref __self_1_1 } =>
-                match *self {
-                    Self { x: ref __self_0_0, y: ref __self_0_1 } =>
-                        (*__self_0_0) != (*__self_1_0) ||
-                            (*__self_0_1) != (*__self_1_1),
-                },
-        }
+        self.x != other.x || self.y != other.y
     }
 }
 impl ::core::marker::StructuralEq for Point {}
@@ -198,24 +167,16 @@ impl ::core::cmp::PartialOrd for Point {
     #[inline]
     fn partial_cmp(&self, other: &Point)
         -> ::core::option::Option<::core::cmp::Ordering> {
-        match *other {
-            Self { x: ref __self_1_0, y: ref __self_1_1 } =>
-                match *self {
-                    Self { x: ref __self_0_0, y: ref __self_0_1 } =>
-                        match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_0),
-                                &(*__self_1_0)) {
-                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
-                                =>
-                                match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_1),
-                                        &(*__self_1_1)) {
-                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
-                                        =>
-                                        ::core::option::Option::Some(::core::cmp::Ordering::Equal),
-                                    cmp => cmp,
-                                },
-                            cmp => cmp,
-                        },
+        match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
+            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+                match ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y)
+                    {
+                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+                        =>
+                        ::core::option::Option::Some(::core::cmp::Ordering::Equal),
+                    cmp => cmp,
                 },
+            cmp => cmp,
         }
     }
 }
@@ -224,27 +185,19 @@ impl ::core::cmp::PartialOrd for Point {
 impl ::core::cmp::Ord for Point {
     #[inline]
     fn cmp(&self, other: &Point) -> ::core::cmp::Ordering {
-        match *other {
-            Self { x: ref __self_1_0, y: ref __self_1_1 } =>
-                match *self {
-                    Self { x: ref __self_0_0, y: ref __self_0_1 } =>
-                        match ::core::cmp::Ord::cmp(&(*__self_0_0), &(*__self_1_0))
-                            {
-                            ::core::cmp::Ordering::Equal =>
-                                match ::core::cmp::Ord::cmp(&(*__self_0_1), &(*__self_1_1))
-                                    {
-                                    ::core::cmp::Ordering::Equal =>
-                                        ::core::cmp::Ordering::Equal,
-                                    cmp => cmp,
-                                },
-                            cmp => cmp,
-                        },
+        match ::core::cmp::Ord::cmp(&self.x, &other.x) {
+            ::core::cmp::Ordering::Equal =>
+                match ::core::cmp::Ord::cmp(&self.y, &other.y) {
+                    ::core::cmp::Ordering::Equal =>
+                        ::core::cmp::Ordering::Equal,
+                    cmp => cmp,
                 },
+            cmp => cmp,
         }
     }
 }
 
-// A long struct.
+// A large struct.
 struct Big {
     b1: u32,
     b2: u32,
@@ -260,26 +213,15 @@ struct Big {
 impl ::core::clone::Clone for Big {
     #[inline]
     fn clone(&self) -> Big {
-        match *self {
-            Self {
-                b1: ref __self_0_0,
-                b2: ref __self_0_1,
-                b3: ref __self_0_2,
-                b4: ref __self_0_3,
-                b5: ref __self_0_4,
-                b6: ref __self_0_5,
-                b7: ref __self_0_6,
-                b8: ref __self_0_7 } =>
-                Big {
-                    b1: ::core::clone::Clone::clone(&(*__self_0_0)),
-                    b2: ::core::clone::Clone::clone(&(*__self_0_1)),
-                    b3: ::core::clone::Clone::clone(&(*__self_0_2)),
-                    b4: ::core::clone::Clone::clone(&(*__self_0_3)),
-                    b5: ::core::clone::Clone::clone(&(*__self_0_4)),
-                    b6: ::core::clone::Clone::clone(&(*__self_0_5)),
-                    b7: ::core::clone::Clone::clone(&(*__self_0_6)),
-                    b8: ::core::clone::Clone::clone(&(*__self_0_7)),
-                },
+        Big {
+            b1: ::core::clone::Clone::clone(&self.b1),
+            b2: ::core::clone::Clone::clone(&self.b2),
+            b3: ::core::clone::Clone::clone(&self.b3),
+            b4: ::core::clone::Clone::clone(&self.b4),
+            b5: ::core::clone::Clone::clone(&self.b5),
+            b6: ::core::clone::Clone::clone(&self.b6),
+            b7: ::core::clone::Clone::clone(&self.b7),
+            b8: ::core::clone::Clone::clone(&self.b8),
         }
     }
 }
@@ -287,25 +229,14 @@ impl ::core::clone::Clone for Big {
 #[allow(unused_qualifications)]
 impl ::core::fmt::Debug for Big {
     fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
-        match *self {
-            Self {
-                b1: ref __self_0_0,
-                b2: ref __self_0_1,
-                b3: ref __self_0_2,
-                b4: ref __self_0_3,
-                b5: ref __self_0_4,
-                b6: ref __self_0_5,
-                b7: ref __self_0_6,
-                b8: ref __self_0_7 } => {
-                let names: &'static _ =
-                    &["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"];
-                let values: &[&dyn ::core::fmt::Debug] =
-                    &[&&(*__self_0_0), &&(*__self_0_1), &&(*__self_0_2),
-                                &&(*__self_0_3), &&(*__self_0_4), &&(*__self_0_5),
-                                &&(*__self_0_6), &&(*__self_0_7)];
-                ::core::fmt::Formatter::debug_struct_fields_finish(f, "Big",
-                    names, values)
-            }
+        {
+            let names: &'static _ =
+                &["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"];
+            let values: &[&dyn ::core::fmt::Debug] =
+                &[&&self.b1, &&self.b2, &&self.b3, &&self.b4, &&self.b5,
+                            &&self.b6, &&self.b7, &&self.b8];
+            ::core::fmt::Formatter::debug_struct_fields_finish(f, "Big",
+                names, values)
         }
     }
 }
@@ -330,25 +261,15 @@ impl ::core::default::Default for Big {
 #[allow(unused_qualifications)]
 impl ::core::hash::Hash for Big {
     fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
-        match *self {
-            Self {
-                b1: ref __self_0_0,
-                b2: ref __self_0_1,
-                b3: ref __self_0_2,
-                b4: ref __self_0_3,
-                b5: ref __self_0_4,
-                b6: ref __self_0_5,
-                b7: ref __self_0_6,
-                b8: ref __self_0_7 } => {
-                ::core::hash::Hash::hash(&(*__self_0_0), state);
-                ::core::hash::Hash::hash(&(*__self_0_1), state);
-                ::core::hash::Hash::hash(&(*__self_0_2), state);
-                ::core::hash::Hash::hash(&(*__self_0_3), state);
-                ::core::hash::Hash::hash(&(*__self_0_4), state);
-                ::core::hash::Hash::hash(&(*__self_0_5), state);
-                ::core::hash::Hash::hash(&(*__self_0_6), state);
-                ::core::hash::Hash::hash(&(*__self_0_7), state)
-            }
+        {
+            ::core::hash::Hash::hash(&self.b1, state);
+            ::core::hash::Hash::hash(&self.b2, state);
+            ::core::hash::Hash::hash(&self.b3, state);
+            ::core::hash::Hash::hash(&self.b4, state);
+            ::core::hash::Hash::hash(&self.b5, state);
+            ::core::hash::Hash::hash(&self.b6, state);
+            ::core::hash::Hash::hash(&self.b7, state);
+            ::core::hash::Hash::hash(&self.b8, state)
         }
     }
 }
@@ -358,69 +279,17 @@ impl ::core::marker::StructuralPartialEq for Big {}
 impl ::core::cmp::PartialEq for Big {
     #[inline]
     fn eq(&self, other: &Big) -> bool {
-        match *other {
-            Self {
-                b1: ref __self_1_0,
-                b2: ref __self_1_1,
-                b3: ref __self_1_2,
-                b4: ref __self_1_3,
-                b5: ref __self_1_4,
-                b6: ref __self_1_5,
-                b7: ref __self_1_6,
-                b8: ref __self_1_7 } =>
-                match *self {
-                    Self {
-                        b1: ref __self_0_0,
-                        b2: ref __self_0_1,
-                        b3: ref __self_0_2,
-                        b4: ref __self_0_3,
-                        b5: ref __self_0_4,
-                        b6: ref __self_0_5,
-                        b7: ref __self_0_6,
-                        b8: ref __self_0_7 } =>
-                        (*__self_0_0) == (*__self_1_0) &&
-                                                    (*__self_0_1) == (*__self_1_1) &&
-                                                (*__self_0_2) == (*__self_1_2) &&
-                                            (*__self_0_3) == (*__self_1_3) &&
-                                        (*__self_0_4) == (*__self_1_4) &&
-                                    (*__self_0_5) == (*__self_1_5) &&
-                                (*__self_0_6) == (*__self_1_6) &&
-                            (*__self_0_7) == (*__self_1_7),
-                },
-        }
+        self.b1 == other.b1 && self.b2 == other.b2 && self.b3 == other.b3 &&
+                            self.b4 == other.b4 && self.b5 == other.b5 &&
+                    self.b6 == other.b6 && self.b7 == other.b7 &&
+            self.b8 == other.b8
     }
     #[inline]
     fn ne(&self, other: &Big) -> bool {
-        match *other {
-            Self {
-                b1: ref __self_1_0,
-                b2: ref __self_1_1,
-                b3: ref __self_1_2,
-                b4: ref __self_1_3,
-                b5: ref __self_1_4,
-                b6: ref __self_1_5,
-                b7: ref __self_1_6,
-                b8: ref __self_1_7 } =>
-                match *self {
-                    Self {
-                        b1: ref __self_0_0,
-                        b2: ref __self_0_1,
-                        b3: ref __self_0_2,
-                        b4: ref __self_0_3,
-                        b5: ref __self_0_4,
-                        b6: ref __self_0_5,
-                        b7: ref __self_0_6,
-                        b8: ref __self_0_7 } =>
-                        (*__self_0_0) != (*__self_1_0) ||
-                                                    (*__self_0_1) != (*__self_1_1) ||
-                                                (*__self_0_2) != (*__self_1_2) ||
-                                            (*__self_0_3) != (*__self_1_3) ||
-                                        (*__self_0_4) != (*__self_1_4) ||
-                                    (*__self_0_5) != (*__self_1_5) ||
-                                (*__self_0_6) != (*__self_1_6) ||
-                            (*__self_0_7) != (*__self_1_7),
-                },
-        }
+        self.b1 != other.b1 || self.b2 != other.b2 || self.b3 != other.b3 ||
+                            self.b4 != other.b4 || self.b5 != other.b5 ||
+                    self.b6 != other.b6 || self.b7 != other.b7 ||
+            self.b8 != other.b8
     }
 }
 impl ::core::marker::StructuralEq for Big {}
@@ -449,63 +318,37 @@ impl ::core::cmp::PartialOrd for Big {
     #[inline]
     fn partial_cmp(&self, other: &Big)
         -> ::core::option::Option<::core::cmp::Ordering> {
-        match *other {
-            Self {
-                b1: ref __self_1_0,
-                b2: ref __self_1_1,
-                b3: ref __self_1_2,
-                b4: ref __self_1_3,
-                b5: ref __self_1_4,
-                b6: ref __self_1_5,
-                b7: ref __self_1_6,
-                b8: ref __self_1_7 } =>
-                match *self {
-                    Self {
-                        b1: ref __self_0_0,
-                        b2: ref __self_0_1,
-                        b3: ref __self_0_2,
-                        b4: ref __self_0_3,
-                        b5: ref __self_0_4,
-                        b6: ref __self_0_5,
-                        b7: ref __self_0_6,
-                        b8: ref __self_0_7 } =>
-                        match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_0),
-                                &(*__self_1_0)) {
+        match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
+            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+                match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
+                        &other.b2) {
+                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
+                        =>
+                        match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
+                                &other.b3) {
                             ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                 =>
-                                match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_1),
-                                        &(*__self_1_1)) {
+                                match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
+                                        &other.b4) {
                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                         =>
-                                        match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_2),
-                                                &(*__self_1_2)) {
+                                        match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
+                                                &other.b5) {
                                             ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                 =>
-                                                match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_3),
-                                                        &(*__self_1_3)) {
+                                                match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
+                                                        &other.b6) {
                                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                         =>
-                                                        match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_4),
-                                                                &(*__self_1_4)) {
+                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
+                                                                &other.b7) {
                                                             ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                 =>
-                                                                match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_5),
-                                                                        &(*__self_1_5)) {
+                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.b8,
+                                                                        &other.b8) {
                                                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                         =>
-                                                                        match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_6),
-                                                                                &(*__self_1_6)) {
-                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
-                                                                                =>
-                                                                                match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0_7),
-                                                                                        &(*__self_1_7)) {
-                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
-                                                                                        =>
-                                                                                        ::core::option::Option::Some(::core::cmp::Ordering::Equal),
-                                                                                    cmp => cmp,
-                                                                                },
-                                                                            cmp => cmp,
-                                                                        },
+                                                                        ::core::option::Option::Some(::core::cmp::Ordering::Equal),
                                                                     cmp => cmp,
                                                                 },
                                                             cmp => cmp,
@@ -518,7 +361,9 @@ impl ::core::cmp::PartialOrd for Big {
                                 },
                             cmp => cmp,
                         },
+                    cmp => cmp,
                 },
+            cmp => cmp,
         }
     }
 }
@@ -527,55 +372,23 @@ impl ::core::cmp::PartialOrd for Big {
 impl ::core::cmp::Ord for Big {
     #[inline]
     fn cmp(&self, other: &Big) -> ::core::cmp::Ordering {
-        match *other {
-            Self {
-                b1: ref __self_1_0,
-                b2: ref __self_1_1,
-                b3: ref __self_1_2,
-                b4: ref __self_1_3,
-                b5: ref __self_1_4,
-                b6: ref __self_1_5,
-                b7: ref __self_1_6,
-                b8: ref __self_1_7 } =>
-                match *self {
-                    Self {
-                        b1: ref __self_0_0,
-                        b2: ref __self_0_1,
-                        b3: ref __self_0_2,
-                        b4: ref __self_0_3,
-                        b5: ref __self_0_4,
-                        b6: ref __self_0_5,
-                        b7: ref __self_0_6,
-                        b8: ref __self_0_7 } =>
-                        match ::core::cmp::Ord::cmp(&(*__self_0_0), &(*__self_1_0))
-                            {
+        match ::core::cmp::Ord::cmp(&self.b1, &other.b1) {
+            ::core::cmp::Ordering::Equal =>
+                match ::core::cmp::Ord::cmp(&self.b2, &other.b2) {
+                    ::core::cmp::Ordering::Equal =>
+                        match ::core::cmp::Ord::cmp(&self.b3, &other.b3) {
                             ::core::cmp::Ordering::Equal =>
-                                match ::core::cmp::Ord::cmp(&(*__self_0_1), &(*__self_1_1))
-                                    {
+                                match ::core::cmp::Ord::cmp(&self.b4, &other.b4) {
                                     ::core::cmp::Ordering::Equal =>
-                                        match ::core::cmp::Ord::cmp(&(*__self_0_2), &(*__self_1_2))
-                                            {
+                                        match ::core::cmp::Ord::cmp(&self.b5, &other.b5) {
                                             ::core::cmp::Ordering::Equal =>
-                                                match ::core::cmp::Ord::cmp(&(*__self_0_3), &(*__self_1_3))
-                                                    {
+                                                match ::core::cmp::Ord::cmp(&self.b6, &other.b6) {
                                                     ::core::cmp::Ordering::Equal =>
-                                                        match ::core::cmp::Ord::cmp(&(*__self_0_4), &(*__self_1_4))
-                                                            {
+                                                        match ::core::cmp::Ord::cmp(&self.b7, &other.b7) {
                                                             ::core::cmp::Ordering::Equal =>
-                                                                match ::core::cmp::Ord::cmp(&(*__self_0_5), &(*__self_1_5))
-                                                                    {
+                                                                match ::core::cmp::Ord::cmp(&self.b8, &other.b8) {
                                                                     ::core::cmp::Ordering::Equal =>
-                                                                        match ::core::cmp::Ord::cmp(&(*__self_0_6), &(*__self_1_6))
-                                                                            {
-                                                                            ::core::cmp::Ordering::Equal =>
-                                                                                match ::core::cmp::Ord::cmp(&(*__self_0_7), &(*__self_1_7))
-                                                                                    {
-                                                                                    ::core::cmp::Ordering::Equal =>
-                                                                                        ::core::cmp::Ordering::Equal,
-                                                                                    cmp => cmp,
-                                                                                },
-                                                                            cmp => cmp,
-                                                                        },
+                                                                        ::core::cmp::Ordering::Equal,
                                                                     cmp => cmp,
                                                                 },
                                                             cmp => cmp,
@@ -588,7 +401,116 @@ impl ::core::cmp::Ord for Big {
                                 },
                             cmp => cmp,
                         },
+                    cmp => cmp,
                 },
+            cmp => cmp,
+        }
+    }
+}
+
+// A packed tuple struct.
+#[repr(packed)]
+struct Packed(u32);
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::clone::Clone for Packed {
+    #[inline]
+    fn clone(&self) -> Packed {
+        { let _: ::core::clone::AssertParamIsClone<u32>; *self }
+    }
+}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::marker::Copy for Packed { }
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::fmt::Debug for Packed {
+    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+        {
+            let Self(__self_0_0) = *self;
+            ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Packed",
+                &&__self_0_0)
+        }
+    }
+}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::default::Default for Packed {
+    #[inline]
+    fn default() -> Packed { Packed(::core::default::Default::default()) }
+}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::hash::Hash for Packed {
+    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
+        {
+            let Self(__self_0_0) = *self;
+            { ::core::hash::Hash::hash(&__self_0_0, state) }
+        }
+    }
+}
+impl ::core::marker::StructuralPartialEq for Packed {}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::cmp::PartialEq for Packed {
+    #[inline]
+    fn eq(&self, other: &Packed) -> bool {
+        {
+            let Self(__self_0_0) = *self;
+            let Self(__self_1_0) = *other;
+            __self_0_0 == __self_1_0
+        }
+    }
+    #[inline]
+    fn ne(&self, other: &Packed) -> bool {
+        {
+            let Self(__self_0_0) = *self;
+            let Self(__self_1_0) = *other;
+            __self_0_0 != __self_1_0
+        }
+    }
+}
+impl ::core::marker::StructuralEq for Packed {}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::cmp::Eq for Packed {
+    #[inline]
+    #[doc(hidden)]
+    #[no_coverage]
+    fn assert_receiver_is_total_eq(&self) -> () {
+        { let _: ::core::cmp::AssertParamIsEq<u32>; }
+    }
+}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::cmp::PartialOrd for Packed {
+    #[inline]
+    fn partial_cmp(&self, other: &Packed)
+        -> ::core::option::Option<::core::cmp::Ordering> {
+        {
+            let Self(__self_0_0) = *self;
+            let Self(__self_1_0) = *other;
+            match ::core::cmp::PartialOrd::partial_cmp(&__self_0_0,
+                    &__self_1_0) {
+                ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
+                    ::core::option::Option::Some(::core::cmp::Ordering::Equal),
+                cmp => cmp,
+            }
+        }
+    }
+}
+#[automatically_derived]
+#[allow(unused_qualifications)]
+impl ::core::cmp::Ord for Packed {
+    #[inline]
+    fn cmp(&self, other: &Packed) -> ::core::cmp::Ordering {
+        {
+            let Self(__self_0_0) = *self;
+            let Self(__self_1_0) = *other;
+            match ::core::cmp::Ord::cmp(&__self_0_0, &__self_1_0) {
+                ::core::cmp::Ordering::Equal => ::core::cmp::Ordering::Equal,
+                cmp => cmp,
+            }
         }
     }
 }
@@ -738,10 +660,10 @@ impl ::core::fmt::Debug for Mixed {
             (&Mixed::Q,) => ::core::fmt::Formatter::write_str(f, "Q"),
             (&Mixed::R(ref __self_0),) =>
                 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "R",
-                    &&(*__self_0)),
+                    &&*__self_0),
             (&Mixed::S { d1: ref __self_0, d2: ref __self_1 },) =>
                 ::core::fmt::Formatter::debug_struct_field2_finish(f, "S",
-                    "d1", &&(*__self_0), "d2", &&(*__self_1)),
+                    "d1", &&*__self_0, "d2", &&*__self_1),
         }
     }
 }
@@ -759,13 +681,13 @@ impl ::core::hash::Hash for Mixed {
             (&Mixed::R(ref __self_0),) => {
                 ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
                     state);
-                ::core::hash::Hash::hash(&(*__self_0), state)
+                ::core::hash::Hash::hash(&*__self_0, state)
             }
             (&Mixed::S { d1: ref __self_0, d2: ref __self_1 },) => {
                 ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
                     state);
-                ::core::hash::Hash::hash(&(*__self_0), state);
-                ::core::hash::Hash::hash(&(*__self_1), state)
+                ::core::hash::Hash::hash(&*__self_0, state);
+                ::core::hash::Hash::hash(&*__self_1, state)
             }
             _ => {
                 ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
@@ -786,10 +708,10 @@ impl ::core::cmp::PartialEq for Mixed {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
-                            (*__self_0) == (*__arg_1_0),
+                            *__self_0 == *__arg_1_0,
                         (&Mixed::S { d1: ref __self_0, d2: ref __self_1 },
                             &Mixed::S { d1: ref __arg_1_0, d2: ref __arg_1_1 }) =>
-                            (*__self_0) == (*__arg_1_0) && (*__self_1) == (*__arg_1_1),
+                            *__self_0 == *__arg_1_0 && *__self_1 == *__arg_1_1,
                         _ => true,
                     }
                 } else { false }
@@ -803,10 +725,10 @@ impl ::core::cmp::PartialEq for Mixed {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
-                            (*__self_0) != (*__arg_1_0),
+                            *__self_0 != *__arg_1_0,
                         (&Mixed::S { d1: ref __self_0, d2: ref __self_1 },
                             &Mixed::S { d1: ref __arg_1_0, d2: ref __arg_1_1 }) =>
-                            (*__self_0) != (*__arg_1_0) || (*__self_1) != (*__arg_1_1),
+                            *__self_0 != *__arg_1_0 || *__self_1 != *__arg_1_1,
                         _ => false,
                     }
                 } else { true }
@@ -840,8 +762,8 @@ impl ::core::cmp::PartialOrd for Mixed {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
-                            match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
-                                    &(*__arg_1_0)) {
+                            match ::core::cmp::PartialOrd::partial_cmp(&*__self_0,
+                                    &*__arg_1_0) {
                                 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                     =>
                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal),
@@ -849,12 +771,12 @@ impl ::core::cmp::PartialOrd for Mixed {
                             },
                         (&Mixed::S { d1: ref __self_0, d2: ref __self_1 },
                             &Mixed::S { d1: ref __arg_1_0, d2: ref __arg_1_1 }) =>
-                            match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
-                                    &(*__arg_1_0)) {
+                            match ::core::cmp::PartialOrd::partial_cmp(&*__self_0,
+                                    &*__arg_1_0) {
                                 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                     =>
-                                    match ::core::cmp::PartialOrd::partial_cmp(&(*__self_1),
-                                            &(*__arg_1_1)) {
+                                    match ::core::cmp::PartialOrd::partial_cmp(&*__self_1,
+                                            &*__arg_1_1) {
                                         ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                             =>
                                             ::core::option::Option::Some(::core::cmp::Ordering::Equal),
@@ -883,16 +805,16 @@ impl ::core::cmp::Ord for Mixed {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Mixed::R(ref __self_0), &Mixed::R(ref __arg_1_0)) =>
-                            match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {
+                            match ::core::cmp::Ord::cmp(&*__self_0, &*__arg_1_0) {
                                 ::core::cmp::Ordering::Equal =>
                                     ::core::cmp::Ordering::Equal,
                                 cmp => cmp,
                             },
                         (&Mixed::S { d1: ref __self_0, d2: ref __self_1 },
                             &Mixed::S { d1: ref __arg_1_0, d2: ref __arg_1_1 }) =>
-                            match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {
+                            match ::core::cmp::Ord::cmp(&*__self_0, &*__arg_1_0) {
                                 ::core::cmp::Ordering::Equal =>
-                                    match ::core::cmp::Ord::cmp(&(*__self_1), &(*__arg_1_1)) {
+                                    match ::core::cmp::Ord::cmp(&*__self_1, &*__arg_1_1) {
                                         ::core::cmp::Ordering::Equal =>
                                             ::core::cmp::Ordering::Equal,
                                         cmp => cmp,
@@ -916,11 +838,11 @@ impl ::core::clone::Clone for Fielded {
     fn clone(&self) -> Fielded {
         match (&*self,) {
             (&Fielded::X(ref __self_0),) =>
-                Fielded::X(::core::clone::Clone::clone(&(*__self_0))),
+                Fielded::X(::core::clone::Clone::clone(&*__self_0)),
             (&Fielded::Y(ref __self_0),) =>
-                Fielded::Y(::core::clone::Clone::clone(&(*__self_0))),
+                Fielded::Y(::core::clone::Clone::clone(&*__self_0)),
             (&Fielded::Z(ref __self_0),) =>
-                Fielded::Z(::core::clone::Clone::clone(&(*__self_0))),
+                Fielded::Z(::core::clone::Clone::clone(&*__self_0)),
         }
     }
 }
@@ -931,13 +853,13 @@ impl ::core::fmt::Debug for Fielded {
         match (&*self,) {
             (&Fielded::X(ref __self_0),) =>
                 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "X",
-                    &&(*__self_0)),
+                    &&*__self_0),
             (&Fielded::Y(ref __self_0),) =>
                 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Y",
-                    &&(*__self_0)),
+                    &&*__self_0),
             (&Fielded::Z(ref __self_0),) =>
                 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Z",
-                    &&(*__self_0)),
+                    &&*__self_0),
         }
     }
 }
@@ -949,17 +871,17 @@ impl ::core::hash::Hash for Fielded {
             (&Fielded::X(ref __self_0),) => {
                 ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
                     state);
-                ::core::hash::Hash::hash(&(*__self_0), state)
+                ::core::hash::Hash::hash(&*__self_0, state)
             }
             (&Fielded::Y(ref __self_0),) => {
                 ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
                     state);
-                ::core::hash::Hash::hash(&(*__self_0), state)
+                ::core::hash::Hash::hash(&*__self_0, state)
             }
             (&Fielded::Z(ref __self_0),) => {
                 ::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
                     state);
-                ::core::hash::Hash::hash(&(*__self_0), state)
+                ::core::hash::Hash::hash(&*__self_0, state)
             }
         }
     }
@@ -976,11 +898,11 @@ impl ::core::cmp::PartialEq for Fielded {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
-                            (*__self_0) == (*__arg_1_0),
+                            *__self_0 == *__arg_1_0,
                         (&Fielded::Y(ref __self_0), &Fielded::Y(ref __arg_1_0)) =>
-                            (*__self_0) == (*__arg_1_0),
+                            *__self_0 == *__arg_1_0,
                         (&Fielded::Z(ref __self_0), &Fielded::Z(ref __arg_1_0)) =>
-                            (*__self_0) == (*__arg_1_0),
+                            *__self_0 == *__arg_1_0,
                         _ => unsafe { ::core::intrinsics::unreachable() }
                     }
                 } else { false }
@@ -994,11 +916,11 @@ impl ::core::cmp::PartialEq for Fielded {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
-                            (*__self_0) != (*__arg_1_0),
+                            *__self_0 != *__arg_1_0,
                         (&Fielded::Y(ref __self_0), &Fielded::Y(ref __arg_1_0)) =>
-                            (*__self_0) != (*__arg_1_0),
+                            *__self_0 != *__arg_1_0,
                         (&Fielded::Z(ref __self_0), &Fielded::Z(ref __arg_1_0)) =>
-                            (*__self_0) != (*__arg_1_0),
+                            *__self_0 != *__arg_1_0,
                         _ => unsafe { ::core::intrinsics::unreachable() }
                     }
                 } else { true }
@@ -1032,24 +954,24 @@ impl ::core::cmp::PartialOrd for Fielded {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
-                            match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
-                                    &(*__arg_1_0)) {
+                            match ::core::cmp::PartialOrd::partial_cmp(&*__self_0,
+                                    &*__arg_1_0) {
                                 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                     =>
                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal),
                                 cmp => cmp,
                             },
                         (&Fielded::Y(ref __self_0), &Fielded::Y(ref __arg_1_0)) =>
-                            match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
-                                    &(*__arg_1_0)) {
+                            match ::core::cmp::PartialOrd::partial_cmp(&*__self_0,
+                                    &*__arg_1_0) {
                                 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                     =>
                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal),
                                 cmp => cmp,
                             },
                         (&Fielded::Z(ref __self_0), &Fielded::Z(ref __arg_1_0)) =>
-                            match ::core::cmp::PartialOrd::partial_cmp(&(*__self_0),
-                                    &(*__arg_1_0)) {
+                            match ::core::cmp::PartialOrd::partial_cmp(&*__self_0,
+                                    &*__arg_1_0) {
                                 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                     =>
                                     ::core::option::Option::Some(::core::cmp::Ordering::Equal),
@@ -1075,19 +997,19 @@ impl ::core::cmp::Ord for Fielded {
             if __self_vi == __arg_1_vi {
                     match (&*self, &*other) {
                         (&Fielded::X(ref __self_0), &Fielded::X(ref __arg_1_0)) =>
-                            match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {
+                            match ::core::cmp::Ord::cmp(&*__self_0, &*__arg_1_0) {
                                 ::core::cmp::Ordering::Equal =>
                                     ::core::cmp::Ordering::Equal,
                                 cmp => cmp,
                             },
                         (&Fielded::Y(ref __self_0), &Fielded::Y(ref __arg_1_0)) =>
-                            match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {
+                            match ::core::cmp::Ord::cmp(&*__self_0, &*__arg_1_0) {
                                 ::core::cmp::Ordering::Equal =>
                                     ::core::cmp::Ordering::Equal,
                                 cmp => cmp,
                             },
                         (&Fielded::Z(ref __self_0), &Fielded::Z(ref __arg_1_0)) =>
-                            match ::core::cmp::Ord::cmp(&(*__self_0), &(*__arg_1_0)) {
+                            match ::core::cmp::Ord::cmp(&*__self_0, &*__arg_1_0) {
                                 ::core::cmp::Ordering::Equal =>
                                     ::core::cmp::Ordering::Equal,
                                 cmp => cmp,
diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.rs b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.rs
index 6ca5f5e3c5f..43c1c775978 100644
--- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.rs
+++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.rs
@@ -23,5 +23,4 @@ enum FingerTree<T:'static> {
 fn main() {
     let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
         FingerTree::Single(1);
-    //~^ ERROR overflow while adding drop-check rules for FingerTree
 }
diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr
index 5df69e4649d..c447e2f7987 100644
--- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr
+++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr
@@ -6,13 +6,5 @@ LL |     let ft =
    |
    = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
-error[E0320]: overflow while adding drop-check rules for FingerTree<i32>
-  --> $DIR/dropck_no_diverge_on_nonregular_1.rs:25:9
-   |
-LL |         FingerTree::Single(1);
-   |         ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.rs b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.rs
index d34f7e326d1..edd07652e53 100644
--- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.rs
+++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.rs
@@ -22,5 +22,4 @@ enum FingerTree<T:'static> {
 fn main() {
     let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
         FingerTree::Single(1);
-    //~^ ERROR overflow while adding drop-check rules for FingerTree
 }
diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr
index d34097d4010..cd4706dd903 100644
--- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr
+++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr
@@ -6,13 +6,5 @@ LL |     let ft =
    |
    = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
-error[E0320]: overflow while adding drop-check rules for FingerTree<i32>
-  --> $DIR/dropck_no_diverge_on_nonregular_2.rs:24:9
-   |
-LL |         FingerTree::Single(1);
-   |         ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<i32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs
index 558b4342da7..af7402ca4a1 100644
--- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs
+++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.rs
@@ -31,6 +31,5 @@ enum Wrapper<T:'static> {
 fn main() {
     let w = //~ ERROR overflow while adding drop-check rules for Option
         Some(Wrapper::Simple::<u32>);
-    //~^ ERROR overflow while adding drop-check rules for Option
-    //~| ERROR overflow while adding drop-check rules for Wrapper
+    //~^ ERROR overflow while adding drop-check rules for Wrapper
 }
diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr
index b24e1d1bf79..18cd1b6cd41 100644
--- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr
+++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr
@@ -6,14 +6,6 @@ LL |     let w =
    |
    = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
-error[E0320]: overflow while adding drop-check rules for Option<Wrapper<u32>>
-  --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:9
-   |
-LL |         Some(Wrapper::Simple::<u32>);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-
 error[E0320]: overflow while adding drop-check rules for Wrapper<u32>
   --> $DIR/dropck_no_diverge_on_nonregular_3.rs:33:14
    |
@@ -22,5 +14,5 @@ LL |         Some(Wrapper::Simple::<u32>);
    |
    = note: overflowed on FingerTree<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<Node<u32>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/inference/ambiguous_type_parameter.stderr b/src/test/ui/inference/ambiguous_type_parameter.stderr
index a08342371b3..9cbe221de13 100644
--- a/src/test/ui/inference/ambiguous_type_parameter.stderr
+++ b/src/test/ui/inference/ambiguous_type_parameter.stderr
@@ -2,7 +2,12 @@ error[E0282]: type annotations needed
   --> $DIR/ambiguous_type_parameter.rs:16:19
    |
 LL |     InMemoryStore.get_raw(&String::default());
-   |                   ^^^^^^^ cannot infer type for type parameter `K`
+   |                   ^^^^^^^
+   |
+help: try using a fully qualified path to specify the expected types
+   |
+LL |     <InMemoryStore as Store<String, HashMap<K, String>>>::get_raw(&InMemoryStore, &String::default());
+   |     +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++             ~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/inference/cannot-infer-partial-try-return.rs b/src/test/ui/inference/cannot-infer-partial-try-return.rs
index 976827a4478..b555697dc34 100644
--- a/src/test/ui/inference/cannot-infer-partial-try-return.rs
+++ b/src/test/ui/inference/cannot-infer-partial-try-return.rs
@@ -16,8 +16,8 @@ fn infallible() -> Result<(), std::convert::Infallible> {
 
 fn main() {
     let x = || -> Result<_, QualifiedError<_>> {
-        //~^ ERROR type annotations needed for `Result<(), QualifiedError<_>>`
         infallible()?;
         Ok(())
+        //~^ ERROR type annotations needed
     };
 }
diff --git a/src/test/ui/inference/cannot-infer-partial-try-return.stderr b/src/test/ui/inference/cannot-infer-partial-try-return.stderr
index c1e43f0b721..2a56aaa44fe 100644
--- a/src/test/ui/inference/cannot-infer-partial-try-return.stderr
+++ b/src/test/ui/inference/cannot-infer-partial-try-return.stderr
@@ -1,16 +1,15 @@
-error[E0282]: type annotations needed for `Result<(), QualifiedError<_>>`
-  --> $DIR/cannot-infer-partial-try-return.rs:18:13
+error[E0282]: type annotations needed
+  --> $DIR/cannot-infer-partial-try-return.rs:20:9
    |
-LL |     let x = || -> Result<_, QualifiedError<_>> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-LL |
 LL |         infallible()?;
    |         ------------- type must be known at this point
+LL |         Ok(())
+   |         ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
    |
-help: try giving this closure an explicit return type
+help: consider specifying the generic arguments
    |
-LL |     let x = || -> Result<(), QualifiedError<_>> {
-   |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |         Ok::<(), QualifiedError<_>>(())
+   |           +++++++++++++++++++++++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/inference/need_type_info/channel.rs b/src/test/ui/inference/need_type_info/channel.rs
new file mode 100644
index 00000000000..e2ba5a94171
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/channel.rs
@@ -0,0 +1,19 @@
+// Test that we suggest specifying the generic argument of `channel`
+// instead of the return type of that function, which is a lot more
+// complex.
+use std::sync::mpsc::channel;
+
+fn no_tuple() {
+    let _data =
+        channel(); //~ ERROR type annotations needed
+}
+
+fn tuple() {
+    let (_sender, _receiver) =
+        channel(); //~ ERROR type annotations needed
+}
+
+fn main() {
+    no_tuple();
+    tuple();
+}
diff --git a/src/test/ui/inference/need_type_info/channel.stderr b/src/test/ui/inference/need_type_info/channel.stderr
new file mode 100644
index 00000000000..e33ace0338d
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/channel.stderr
@@ -0,0 +1,25 @@
+error[E0282]: type annotations needed
+  --> $DIR/channel.rs:8:9
+   |
+LL |         channel();
+   |         ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `channel`
+   |
+help: consider specifying the generic argument
+   |
+LL |         channel::<T>();
+   |                +++++
+
+error[E0282]: type annotations needed
+  --> $DIR/channel.rs:13:9
+   |
+LL |         channel();
+   |         ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `channel`
+   |
+help: consider specifying the generic argument
+   |
+LL |         channel::<T>();
+   |                +++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/infinite/infinite-struct.rs b/src/test/ui/infinite/infinite-struct.rs
index 70a203ea6e8..74185dc597b 100644
--- a/src/test/ui/infinite/infinite-struct.rs
+++ b/src/test/ui/infinite/infinite-struct.rs
@@ -1,6 +1,5 @@
 struct Take(Take);
 //~^ ERROR has infinite size
-//~| ERROR cycle detected
 
 // check that we don't hang trying to find the tail of a recursive struct (#79437)
 fn foo() -> Take {
diff --git a/src/test/ui/infinite/infinite-struct.stderr b/src/test/ui/infinite/infinite-struct.stderr
index 214be091cce..5a6d13786d1 100644
--- a/src/test/ui/infinite/infinite-struct.stderr
+++ b/src/test/ui/infinite/infinite-struct.stderr
@@ -11,16 +11,6 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Take` repre
 LL | struct Take(Box<Take>);
    |             ++++    +
 
-error[E0391]: cycle detected when computing drop-check constraints for `Take`
-  --> $DIR/infinite-struct.rs:1:1
-   |
-LL | struct Take(Take);
-   | ^^^^^^^^^^^
-   |
-   = note: ...which immediately requires computing drop-check constraints for `Take` again
-   = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: Take } }`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0072, E0391.
-For more information about an error, try `rustc --explain E0072`.
+For more information about this error, try `rustc --explain E0072`.
diff --git a/src/test/ui/infinite/infinite-tag-type-recursion.rs b/src/test/ui/infinite/infinite-tag-type-recursion.rs
index 8578c5545bc..87a9e08dd38 100644
--- a/src/test/ui/infinite/infinite-tag-type-recursion.rs
+++ b/src/test/ui/infinite/infinite-tag-type-recursion.rs
@@ -1,5 +1,4 @@
 enum MList { Cons(isize, MList), Nil }
 //~^ ERROR recursive type `MList` has infinite size
-//~| ERROR cycle detected when computing drop-check constraints for `MList`
 
 fn main() { let a = MList::Cons(10, MList::Cons(11, MList::Nil)); }
diff --git a/src/test/ui/infinite/infinite-tag-type-recursion.stderr b/src/test/ui/infinite/infinite-tag-type-recursion.stderr
index 1802c7599a3..d2dad4b9178 100644
--- a/src/test/ui/infinite/infinite-tag-type-recursion.stderr
+++ b/src/test/ui/infinite/infinite-tag-type-recursion.stderr
@@ -11,16 +11,6 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `MList` repr
 LL | enum MList { Cons(isize, Box<MList>), Nil }
    |                          ++++     +
 
-error[E0391]: cycle detected when computing drop-check constraints for `MList`
-  --> $DIR/infinite-tag-type-recursion.rs:1:1
-   |
-LL | enum MList { Cons(isize, MList), Nil }
-   | ^^^^^^^^^^
-   |
-   = note: ...which immediately requires computing drop-check constraints for `MList` again
-   = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, constness: NotConst }, value: MList } }`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0072, E0391.
-For more information about an error, try `rustc --explain E0072`.
+For more information about this error, try `rustc --explain E0072`.
diff --git a/src/test/ui/issues/issue-23041.stderr b/src/test/ui/issues/issue-23041.stderr
index 401086b2044..7b9a1634a0d 100644
--- a/src/test/ui/issues/issue-23041.stderr
+++ b/src/test/ui/issues/issue-23041.stderr
@@ -1,8 +1,13 @@
 error[E0282]: type annotations needed
-  --> $DIR/issue-23041.rs:6:22
+  --> $DIR/issue-23041.rs:6:7
    |
 LL |     b.downcast_ref::<fn(_)->_>();
-   |                      ^^^^^^^^ cannot infer type
+   |       ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `downcast_ref`
+   |
+help: consider specifying the generic arguments
+   |
+LL |     b.downcast_ref::<fn(_) -> _>();
+   |                   ~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24013.stderr b/src/test/ui/issues/issue-24013.stderr
index 4e3cb88297d..863993f4509 100644
--- a/src/test/ui/issues/issue-24013.stderr
+++ b/src/test/ui/issues/issue-24013.stderr
@@ -1,8 +1,13 @@
 error[E0282]: type annotations needed
-  --> $DIR/issue-24013.rs:5:20
+  --> $DIR/issue-24013.rs:5:13
    |
 LL |     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
-   |                    ^^^^^^ cannot infer type
+   |             ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap`
+   |
+help: consider specifying the generic arguments
+   |
+LL |     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
+   |                 ~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-25368.rs b/src/test/ui/issues/issue-25368.rs
index b7f0f613e80..4be83457f7a 100644
--- a/src/test/ui/issues/issue-25368.rs
+++ b/src/test/ui/issues/issue-25368.rs
@@ -5,10 +5,10 @@ use std::marker::PhantomData;
 struct Foo<T> {foo: PhantomData<T>}
 
 fn main() {
-    let (tx, rx) = //~ ERROR type annotations needed
+    let (tx, rx) =
         channel();
-    // FIXME(#89862): Suggest adding a generic argument to `channel` instead
     spawn(move || {
         tx.send(Foo{ foo: PhantomData });
+        //~^ ERROR type annotations needed
     });
 }
diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr
index ffcb7384952..e6ed3aac710 100644
--- a/src/test/ui/issues/issue-25368.stderr
+++ b/src/test/ui/issues/issue-25368.stderr
@@ -1,13 +1,13 @@
-error[E0282]: type annotations needed for `(Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`
-  --> $DIR/issue-25368.rs:8:9
+error[E0282]: type annotations needed
+  --> $DIR/issue-25368.rs:11:27
    |
-LL |     let (tx, rx) =
-   |         ^^^^^^^^
+LL |         tx.send(Foo{ foo: PhantomData });
+   |                           ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData`
    |
-help: consider giving this pattern a type, where the type for type parameter `T` is specified
+help: consider specifying the generic argument
    |
-LL |     let (tx, rx): (Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>) =
-   |                 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+LL |         tx.send(Foo{ foo: PhantomData::<T> });
+   |                                      +++++
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr
index 66e7ada3ac5..e0f8a5447b0 100644
--- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr
+++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr
@@ -13,7 +13,7 @@ error[E0283]: type annotations needed
   --> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7
    |
 LL |     x.foo();
-   |       ^^^ cannot infer type for struct `Vec<_>`
+   |       ^^^
    |
 note: multiple `impl`s satisfying `Vec<_>: Foo` found
   --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1
@@ -23,6 +23,10 @@ LL | impl Foo for Vec<usize> {
 ...
 LL | impl Foo for Vec<isize> {
    | ^^^^^^^^^^^^^^^^^^^^^^^
+help: try using a fully qualified path to specify the expected types
+   |
+LL |     <Vec<T> as Foo>::foo(&x);
+   |     ++++++++++++++++++++++ ~
 
 error[E0308]: mismatched types
   --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20
diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
index c857eb459b8..c9e93174e20 100644
--- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
+++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
@@ -1,18 +1,14 @@
-// Dropck shouldn't hit a recursion limit from checking `S<u32>` since it has
-// no free regions or type parameters.
-// Codegen however, has to error for the infinitely many `drop_in_place`
-// functions it has been asked to create.
-
-// build-fail
-// normalize-stderr-test: ".nll/" -> "/"
-// compile-flags: -Zmir-opt-level=0
+// `S` is infinitely recursing so it's not possible to generate a finite
+// drop impl (ignoring polymorphization).
+//
+// Dropck should therefore detect that this is the case and eagerly error.
 
 struct S<T> {
     t: T,
     s: Box<S<fn(u: T)>>,
 }
 
-fn f(x: S<u32>) {}
+fn f(x: S<u32>) {} //~ ERROR overflow while adding drop-check rules for S<u32>
 
 fn main() {
     // Force instantiation.
diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
index d749ee00c22..1da29be43db 100644
--- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
+++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
@@ -1,15 +1,10 @@
-error: reached the recursion limit while instantiating `std::ptr::drop_in_place::<S<fn(f...)))))))))))))))))))))))))))))>))`
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+error[E0320]: overflow while adding drop-check rules for S<u32>
+  --> $DIR/issue-38591-non-regular-dropck-recursion.rs:11:6
    |
-LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn f(x: S<u32>) {}
+   |      ^
    |
-note: `std::ptr::drop_in_place` defined here
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |
-LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-38591-non-regular-dropck-recursion/issue-38591-non-regular-dropck-recursion.long-type.txt'
+   = note: overflowed on S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/recursion/issue-86784.rs b/src/test/ui/recursion/issue-86784.rs
new file mode 100644
index 00000000000..34f4aaedb32
--- /dev/null
+++ b/src/test/ui/recursion/issue-86784.rs
@@ -0,0 +1,2597 @@
+// build-pass
+
+fn main() {
+    let _temp_1 = 0;
+    let _temp_2 = 0;
+    let _temp_3 = 0;
+    let _temp_4 = 0;
+    let _temp_5 = 0;
+    let _temp_6 = 0;
+    let _temp_7 = 0;
+    let _temp_8 = 0;
+    let _temp_9 = 0;
+    let _temp_10 = 0;
+    let _temp_11 = 0;
+    let _temp_12 = 0;
+    let _temp_13 = 0;
+    let _temp_14 = 0;
+    let _temp_15 = 0;
+    let _temp_16 = 0;
+    let _temp_17 = 0;
+    let _temp_18 = 0;
+    let _temp_19 = 0;
+    let _temp_20 = 0;
+    let _temp_21 = 0;
+    let _temp_22 = 0;
+    let _temp_23 = 0;
+    let _temp_24 = 0;
+    let _temp_25 = 0;
+    let _temp_26 = 0;
+    let _temp_27 = 0;
+    let _temp_28 = 0;
+    let _temp_29 = 0;
+    let _temp_30 = 0;
+    let _temp_31 = 0;
+    let _temp_32 = 0;
+    let _temp_33 = 0;
+    let _temp_34 = 0;
+    let _temp_35 = 0;
+    let _temp_36 = 0;
+    let _temp_37 = 0;
+    let _temp_38 = 0;
+    let _temp_39 = 0;
+    let _temp_40 = 0;
+    let _temp_41 = 0;
+    let _temp_42 = 0;
+    let _temp_43 = 0;
+    let _temp_44 = 0;
+    let _temp_45 = 0;
+    let _temp_46 = 0;
+    let _temp_47 = 0;
+    let _temp_48 = 0;
+    let _temp_49 = 0;
+    let _temp_50 = 0;
+    let _temp_51 = 0;
+    let _temp_52 = 0;
+    let _temp_53 = 0;
+    let _temp_54 = 0;
+    let _temp_55 = 0;
+    let _temp_56 = 0;
+    let _temp_57 = 0;
+    let _temp_58 = 0;
+    let _temp_59 = 0;
+    let _temp_60 = 0;
+    let _temp_61 = 0;
+    let _temp_62 = 0;
+    let _temp_63 = 0;
+    let _temp_64 = 0;
+    let _temp_65 = 0;
+    let _temp_66 = 0;
+    let _temp_67 = 0;
+    let _temp_68 = 0;
+    let _temp_69 = 0;
+    let _temp_70 = 0;
+    let _temp_71 = 0;
+    let _temp_72 = 0;
+    let _temp_73 = 0;
+    let _temp_74 = 0;
+    let _temp_75 = 0;
+    let _temp_76 = 0;
+    let _temp_77 = 0;
+    let _temp_78 = 0;
+    let _temp_79 = 0;
+    let _temp_80 = 0;
+    let _temp_81 = 0;
+    let _temp_82 = 0;
+    let _temp_83 = 0;
+    let _temp_84 = 0;
+    let _temp_85 = 0;
+    let _temp_86 = 0;
+    let _temp_87 = 0;
+    let _temp_88 = 0;
+    let _temp_89 = 0;
+    let _temp_90 = 0;
+    let _temp_91 = 0;
+    let _temp_92 = 0;
+    let _temp_93 = 0;
+    let _temp_94 = 0;
+    let _temp_95 = 0;
+    let _temp_96 = 0;
+    let _temp_97 = 0;
+    let _temp_98 = 0;
+    let _temp_99 = 0;
+    let _temp_100 = 0;
+    let _temp_101 = 0;
+    let _temp_102 = 0;
+    let _temp_103 = 0;
+    let _temp_104 = 0;
+    let _temp_105 = 0;
+    let _temp_106 = 0;
+    let _temp_107 = 0;
+    let _temp_108 = 0;
+    let _temp_109 = 0;
+    let _temp_110 = 0;
+    let _temp_111 = 0;
+    let _temp_112 = 0;
+    let _temp_113 = 0;
+    let _temp_114 = 0;
+    let _temp_115 = 0;
+    let _temp_116 = 0;
+    let _temp_117 = 0;
+    let _temp_118 = 0;
+    let _temp_119 = 0;
+    let _temp_120 = 0;
+    let _temp_121 = 0;
+    let _temp_122 = 0;
+    let _temp_123 = 0;
+    let _temp_124 = 0;
+    let _temp_125 = 0;
+    let _temp_126 = 0;
+    let _temp_127 = 0;
+    let _temp_128 = 0;
+    let _temp_129 = 0;
+    let _temp_130 = 0;
+    let _temp_131 = 0;
+    let _temp_132 = 0;
+    let _temp_133 = 0;
+    let _temp_134 = 0;
+    let _temp_135 = 0;
+    let _temp_136 = 0;
+    let _temp_137 = 0;
+    let _temp_138 = 0;
+    let _temp_139 = 0;
+    let _temp_140 = 0;
+    let _temp_141 = 0;
+    let _temp_142 = 0;
+    let _temp_143 = 0;
+    let _temp_144 = 0;
+    let _temp_145 = 0;
+    let _temp_146 = 0;
+    let _temp_147 = 0;
+    let _temp_148 = 0;
+    let _temp_149 = 0;
+    let _temp_150 = 0;
+    let _temp_151 = 0;
+    let _temp_152 = 0;
+    let _temp_153 = 0;
+    let _temp_154 = 0;
+    let _temp_155 = 0;
+    let _temp_156 = 0;
+    let _temp_157 = 0;
+    let _temp_158 = 0;
+    let _temp_159 = 0;
+    let _temp_160 = 0;
+    let _temp_161 = 0;
+    let _temp_162 = 0;
+    let _temp_163 = 0;
+    let _temp_164 = 0;
+    let _temp_165 = 0;
+    let _temp_166 = 0;
+    let _temp_167 = 0;
+    let _temp_168 = 0;
+    let _temp_169 = 0;
+    let _temp_170 = 0;
+    let _temp_171 = 0;
+    let _temp_172 = 0;
+    let _temp_173 = 0;
+    let _temp_174 = 0;
+    let _temp_175 = 0;
+    let _temp_176 = 0;
+    let _temp_177 = 0;
+    let _temp_178 = 0;
+    let _temp_179 = 0;
+    let _temp_180 = 0;
+    let _temp_181 = 0;
+    let _temp_182 = 0;
+    let _temp_183 = 0;
+    let _temp_184 = 0;
+    let _temp_185 = 0;
+    let _temp_186 = 0;
+    let _temp_187 = 0;
+    let _temp_188 = 0;
+    let _temp_189 = 0;
+    let _temp_190 = 0;
+    let _temp_191 = 0;
+    let _temp_192 = 0;
+    let _temp_193 = 0;
+    let _temp_194 = 0;
+    let _temp_195 = 0;
+    let _temp_196 = 0;
+    let _temp_197 = 0;
+    let _temp_198 = 0;
+    let _temp_199 = 0;
+    let _temp_200 = 0;
+    let _temp_201 = 0;
+    let _temp_202 = 0;
+    let _temp_203 = 0;
+    let _temp_204 = 0;
+    let _temp_205 = 0;
+    let _temp_206 = 0;
+    let _temp_207 = 0;
+    let _temp_208 = 0;
+    let _temp_209 = 0;
+    let _temp_210 = 0;
+    let _temp_211 = 0;
+    let _temp_212 = 0;
+    let _temp_213 = 0;
+    let _temp_214 = 0;
+    let _temp_215 = 0;
+    let _temp_216 = 0;
+    let _temp_217 = 0;
+    let _temp_218 = 0;
+    let _temp_219 = 0;
+    let _temp_220 = 0;
+    let _temp_221 = 0;
+    let _temp_222 = 0;
+    let _temp_223 = 0;
+    let _temp_224 = 0;
+    let _temp_225 = 0;
+    let _temp_226 = 0;
+    let _temp_227 = 0;
+    let _temp_228 = 0;
+    let _temp_229 = 0;
+    let _temp_230 = 0;
+    let _temp_231 = 0;
+    let _temp_232 = 0;
+    let _temp_233 = 0;
+    let _temp_234 = 0;
+    let _temp_235 = 0;
+    let _temp_236 = 0;
+    let _temp_237 = 0;
+    let _temp_238 = 0;
+    let _temp_239 = 0;
+    let _temp_240 = 0;
+    let _temp_241 = 0;
+    let _temp_242 = 0;
+    let _temp_243 = 0;
+    let _temp_244 = 0;
+    let _temp_245 = 0;
+    let _temp_246 = 0;
+    let _temp_247 = 0;
+    let _temp_248 = 0;
+    let _temp_249 = 0;
+    let _temp_250 = 0;
+    let _temp_251 = 0;
+    let _temp_252 = 0;
+    let _temp_253 = 0;
+    let _temp_254 = 0;
+    let _temp_255 = 0;
+    let _temp_256 = 0;
+    let _temp_257 = 0;
+    let _temp_258 = 0;
+    let _temp_259 = 0;
+    let _temp_260 = 0;
+    let _temp_261 = 0;
+    let _temp_262 = 0;
+    let _temp_263 = 0;
+    let _temp_264 = 0;
+    let _temp_265 = 0;
+    let _temp_266 = 0;
+    let _temp_267 = 0;
+    let _temp_268 = 0;
+    let _temp_269 = 0;
+    let _temp_270 = 0;
+    let _temp_271 = 0;
+    let _temp_272 = 0;
+    let _temp_273 = 0;
+    let _temp_274 = 0;
+    let _temp_275 = 0;
+    let _temp_276 = 0;
+    let _temp_277 = 0;
+    let _temp_278 = 0;
+    let _temp_279 = 0;
+    let _temp_280 = 0;
+    let _temp_281 = 0;
+    let _temp_282 = 0;
+    let _temp_283 = 0;
+    let _temp_284 = 0;
+    let _temp_285 = 0;
+    let _temp_286 = 0;
+    let _temp_287 = 0;
+    let _temp_288 = 0;
+    let _temp_289 = 0;
+    let _temp_290 = 0;
+    let _temp_291 = 0;
+    let _temp_292 = 0;
+    let _temp_293 = 0;
+    let _temp_294 = 0;
+    let _temp_295 = 0;
+    let _temp_296 = 0;
+    let _temp_297 = 0;
+    let _temp_298 = 0;
+    let _temp_299 = 0;
+    let _temp_300 = 0;
+    let _temp_301 = 0;
+    let _temp_302 = 0;
+    let _temp_303 = 0;
+    let _temp_304 = 0;
+    let _temp_305 = 0;
+    let _temp_306 = 0;
+    let _temp_307 = 0;
+    let _temp_308 = 0;
+    let _temp_309 = 0;
+    let _temp_310 = 0;
+    let _temp_311 = 0;
+    let _temp_312 = 0;
+    let _temp_313 = 0;
+    let _temp_314 = 0;
+    let _temp_315 = 0;
+    let _temp_316 = 0;
+    let _temp_317 = 0;
+    let _temp_318 = 0;
+    let _temp_319 = 0;
+    let _temp_320 = 0;
+    let _temp_321 = 0;
+    let _temp_322 = 0;
+    let _temp_323 = 0;
+    let _temp_324 = 0;
+    let _temp_325 = 0;
+    let _temp_326 = 0;
+    let _temp_327 = 0;
+    let _temp_328 = 0;
+    let _temp_329 = 0;
+    let _temp_330 = 0;
+    let _temp_331 = 0;
+    let _temp_332 = 0;
+    let _temp_333 = 0;
+    let _temp_334 = 0;
+    let _temp_335 = 0;
+    let _temp_336 = 0;
+    let _temp_337 = 0;
+    let _temp_338 = 0;
+    let _temp_339 = 0;
+    let _temp_340 = 0;
+    let _temp_341 = 0;
+    let _temp_342 = 0;
+    let _temp_343 = 0;
+    let _temp_344 = 0;
+    let _temp_345 = 0;
+    let _temp_346 = 0;
+    let _temp_347 = 0;
+    let _temp_348 = 0;
+    let _temp_349 = 0;
+    let _temp_350 = 0;
+    let _temp_351 = 0;
+    let _temp_352 = 0;
+    let _temp_353 = 0;
+    let _temp_354 = 0;
+    let _temp_355 = 0;
+    let _temp_356 = 0;
+    let _temp_357 = 0;
+    let _temp_358 = 0;
+    let _temp_359 = 0;
+    let _temp_360 = 0;
+    let _temp_361 = 0;
+    let _temp_362 = 0;
+    let _temp_363 = 0;
+    let _temp_364 = 0;
+    let _temp_365 = 0;
+    let _temp_366 = 0;
+    let _temp_367 = 0;
+    let _temp_368 = 0;
+    let _temp_369 = 0;
+    let _temp_370 = 0;
+    let _temp_371 = 0;
+    let _temp_372 = 0;
+    let _temp_373 = 0;
+    let _temp_374 = 0;
+    let _temp_375 = 0;
+    let _temp_376 = 0;
+    let _temp_377 = 0;
+    let _temp_378 = 0;
+    let _temp_379 = 0;
+    let _temp_380 = 0;
+    let _temp_381 = 0;
+    let _temp_382 = 0;
+    let _temp_383 = 0;
+    let _temp_384 = 0;
+    let _temp_385 = 0;
+    let _temp_386 = 0;
+    let _temp_387 = 0;
+    let _temp_388 = 0;
+    let _temp_389 = 0;
+    let _temp_390 = 0;
+    let _temp_391 = 0;
+    let _temp_392 = 0;
+    let _temp_393 = 0;
+    let _temp_394 = 0;
+    let _temp_395 = 0;
+    let _temp_396 = 0;
+    let _temp_397 = 0;
+    let _temp_398 = 0;
+    let _temp_399 = 0;
+    let _temp_400 = 0;
+    let _temp_401 = 0;
+    let _temp_402 = 0;
+    let _temp_403 = 0;
+    let _temp_404 = 0;
+    let _temp_405 = 0;
+    let _temp_406 = 0;
+    let _temp_407 = 0;
+    let _temp_408 = 0;
+    let _temp_409 = 0;
+    let _temp_410 = 0;
+    let _temp_411 = 0;
+    let _temp_412 = 0;
+    let _temp_413 = 0;
+    let _temp_414 = 0;
+    let _temp_415 = 0;
+    let _temp_416 = 0;
+    let _temp_417 = 0;
+    let _temp_418 = 0;
+    let _temp_419 = 0;
+    let _temp_420 = 0;
+    let _temp_421 = 0;
+    let _temp_422 = 0;
+    let _temp_423 = 0;
+    let _temp_424 = 0;
+    let _temp_425 = 0;
+    let _temp_426 = 0;
+    let _temp_427 = 0;
+    let _temp_428 = 0;
+    let _temp_429 = 0;
+    let _temp_430 = 0;
+    let _temp_431 = 0;
+    let _temp_432 = 0;
+    let _temp_433 = 0;
+    let _temp_434 = 0;
+    let _temp_435 = 0;
+    let _temp_436 = 0;
+    let _temp_437 = 0;
+    let _temp_438 = 0;
+    let _temp_439 = 0;
+    let _temp_440 = 0;
+    let _temp_441 = 0;
+    let _temp_442 = 0;
+    let _temp_443 = 0;
+    let _temp_444 = 0;
+    let _temp_445 = 0;
+    let _temp_446 = 0;
+    let _temp_447 = 0;
+    let _temp_448 = 0;
+    let _temp_449 = 0;
+    let _temp_450 = 0;
+    let _temp_451 = 0;
+    let _temp_452 = 0;
+    let _temp_453 = 0;
+    let _temp_454 = 0;
+    let _temp_455 = 0;
+    let _temp_456 = 0;
+    let _temp_457 = 0;
+    let _temp_458 = 0;
+    let _temp_459 = 0;
+    let _temp_460 = 0;
+    let _temp_461 = 0;
+    let _temp_462 = 0;
+    let _temp_463 = 0;
+    let _temp_464 = 0;
+    let _temp_465 = 0;
+    let _temp_466 = 0;
+    let _temp_467 = 0;
+    let _temp_468 = 0;
+    let _temp_469 = 0;
+    let _temp_470 = 0;
+    let _temp_471 = 0;
+    let _temp_472 = 0;
+    let _temp_473 = 0;
+    let _temp_474 = 0;
+    let _temp_475 = 0;
+    let _temp_476 = 0;
+    let _temp_477 = 0;
+    let _temp_478 = 0;
+    let _temp_479 = 0;
+    let _temp_480 = 0;
+    let _temp_481 = 0;
+    let _temp_482 = 0;
+    let _temp_483 = 0;
+    let _temp_484 = 0;
+    let _temp_485 = 0;
+    let _temp_486 = 0;
+    let _temp_487 = 0;
+    let _temp_488 = 0;
+    let _temp_489 = 0;
+    let _temp_490 = 0;
+    let _temp_491 = 0;
+    let _temp_492 = 0;
+    let _temp_493 = 0;
+    let _temp_494 = 0;
+    let _temp_495 = 0;
+    let _temp_496 = 0;
+    let _temp_497 = 0;
+    let _temp_498 = 0;
+    let _temp_499 = 0;
+    let _temp_500 = 0;
+    let _temp_501 = 0;
+    let _temp_502 = 0;
+    let _temp_503 = 0;
+    let _temp_504 = 0;
+    let _temp_505 = 0;
+    let _temp_506 = 0;
+    let _temp_507 = 0;
+    let _temp_508 = 0;
+    let _temp_509 = 0;
+    let _temp_510 = 0;
+    let _temp_511 = 0;
+    let _temp_512 = 0;
+    let _temp_513 = 0;
+    let _temp_514 = 0;
+    let _temp_515 = 0;
+    let _temp_516 = 0;
+    let _temp_517 = 0;
+    let _temp_518 = 0;
+    let _temp_519 = 0;
+    let _temp_520 = 0;
+    let _temp_521 = 0;
+    let _temp_522 = 0;
+    let _temp_523 = 0;
+    let _temp_524 = 0;
+    let _temp_525 = 0;
+    let _temp_526 = 0;
+    let _temp_527 = 0;
+    let _temp_528 = 0;
+    let _temp_529 = 0;
+    let _temp_530 = 0;
+    let _temp_531 = 0;
+    let _temp_532 = 0;
+    let _temp_533 = 0;
+    let _temp_534 = 0;
+    let _temp_535 = 0;
+    let _temp_536 = 0;
+    let _temp_537 = 0;
+    let _temp_538 = 0;
+    let _temp_539 = 0;
+    let _temp_540 = 0;
+    let _temp_541 = 0;
+    let _temp_542 = 0;
+    let _temp_543 = 0;
+    let _temp_544 = 0;
+    let _temp_545 = 0;
+    let _temp_546 = 0;
+    let _temp_547 = 0;
+    let _temp_548 = 0;
+    let _temp_549 = 0;
+    let _temp_550 = 0;
+    let _temp_551 = 0;
+    let _temp_552 = 0;
+    let _temp_553 = 0;
+    let _temp_554 = 0;
+    let _temp_555 = 0;
+    let _temp_556 = 0;
+    let _temp_557 = 0;
+    let _temp_558 = 0;
+    let _temp_559 = 0;
+    let _temp_560 = 0;
+    let _temp_561 = 0;
+    let _temp_562 = 0;
+    let _temp_563 = 0;
+    let _temp_564 = 0;
+    let _temp_565 = 0;
+    let _temp_566 = 0;
+    let _temp_567 = 0;
+    let _temp_568 = 0;
+    let _temp_569 = 0;
+    let _temp_570 = 0;
+    let _temp_571 = 0;
+    let _temp_572 = 0;
+    let _temp_573 = 0;
+    let _temp_574 = 0;
+    let _temp_575 = 0;
+    let _temp_576 = 0;
+    let _temp_577 = 0;
+    let _temp_578 = 0;
+    let _temp_579 = 0;
+    let _temp_580 = 0;
+    let _temp_581 = 0;
+    let _temp_582 = 0;
+    let _temp_583 = 0;
+    let _temp_584 = 0;
+    let _temp_585 = 0;
+    let _temp_586 = 0;
+    let _temp_587 = 0;
+    let _temp_588 = 0;
+    let _temp_589 = 0;
+    let _temp_590 = 0;
+    let _temp_591 = 0;
+    let _temp_592 = 0;
+    let _temp_593 = 0;
+    let _temp_594 = 0;
+    let _temp_595 = 0;
+    let _temp_596 = 0;
+    let _temp_597 = 0;
+    let _temp_598 = 0;
+    let _temp_599 = 0;
+    let _temp_600 = 0;
+    let _temp_601 = 0;
+    let _temp_602 = 0;
+    let _temp_603 = 0;
+    let _temp_604 = 0;
+    let _temp_605 = 0;
+    let _temp_606 = 0;
+    let _temp_607 = 0;
+    let _temp_608 = 0;
+    let _temp_609 = 0;
+    let _temp_610 = 0;
+    let _temp_611 = 0;
+    let _temp_612 = 0;
+    let _temp_613 = 0;
+    let _temp_614 = 0;
+    let _temp_615 = 0;
+    let _temp_616 = 0;
+    let _temp_617 = 0;
+    let _temp_618 = 0;
+    let _temp_619 = 0;
+    let _temp_620 = 0;
+    let _temp_621 = 0;
+    let _temp_622 = 0;
+    let _temp_623 = 0;
+    let _temp_624 = 0;
+    let _temp_625 = 0;
+    let _temp_626 = 0;
+    let _temp_627 = 0;
+    let _temp_628 = 0;
+    let _temp_629 = 0;
+    let _temp_630 = 0;
+    let _temp_631 = 0;
+    let _temp_632 = 0;
+    let _temp_633 = 0;
+    let _temp_634 = 0;
+    let _temp_635 = 0;
+    let _temp_636 = 0;
+    let _temp_637 = 0;
+    let _temp_638 = 0;
+    let _temp_639 = 0;
+    let _temp_640 = 0;
+    let _temp_641 = 0;
+    let _temp_642 = 0;
+    let _temp_643 = 0;
+    let _temp_644 = 0;
+    let _temp_645 = 0;
+    let _temp_646 = 0;
+    let _temp_647 = 0;
+    let _temp_648 = 0;
+    let _temp_649 = 0;
+    let _temp_650 = 0;
+    let _temp_651 = 0;
+    let _temp_652 = 0;
+    let _temp_653 = 0;
+    let _temp_654 = 0;
+    let _temp_655 = 0;
+    let _temp_656 = 0;
+    let _temp_657 = 0;
+    let _temp_658 = 0;
+    let _temp_659 = 0;
+    let _temp_660 = 0;
+    let _temp_661 = 0;
+    let _temp_662 = 0;
+    let _temp_663 = 0;
+    let _temp_664 = 0;
+    let _temp_665 = 0;
+    let _temp_666 = 0;
+    let _temp_667 = 0;
+    let _temp_668 = 0;
+    let _temp_669 = 0;
+    let _temp_670 = 0;
+    let _temp_671 = 0;
+    let _temp_672 = 0;
+    let _temp_673 = 0;
+    let _temp_674 = 0;
+    let _temp_675 = 0;
+    let _temp_676 = 0;
+    let _temp_677 = 0;
+    let _temp_678 = 0;
+    let _temp_679 = 0;
+    let _temp_680 = 0;
+    let _temp_681 = 0;
+    let _temp_682 = 0;
+    let _temp_683 = 0;
+    let _temp_684 = 0;
+    let _temp_685 = 0;
+    let _temp_686 = 0;
+    let _temp_687 = 0;
+    let _temp_688 = 0;
+    let _temp_689 = 0;
+    let _temp_690 = 0;
+    let _temp_691 = 0;
+    let _temp_692 = 0;
+    let _temp_693 = 0;
+    let _temp_694 = 0;
+    let _temp_695 = 0;
+    let _temp_696 = 0;
+    let _temp_697 = 0;
+    let _temp_698 = 0;
+    let _temp_699 = 0;
+    let _temp_700 = 0;
+    let _temp_701 = 0;
+    let _temp_702 = 0;
+    let _temp_703 = 0;
+    let _temp_704 = 0;
+    let _temp_705 = 0;
+    let _temp_706 = 0;
+    let _temp_707 = 0;
+    let _temp_708 = 0;
+    let _temp_709 = 0;
+    let _temp_710 = 0;
+    let _temp_711 = 0;
+    let _temp_712 = 0;
+    let _temp_713 = 0;
+    let _temp_714 = 0;
+    let _temp_715 = 0;
+    let _temp_716 = 0;
+    let _temp_717 = 0;
+    let _temp_718 = 0;
+    let _temp_719 = 0;
+    let _temp_720 = 0;
+    let _temp_721 = 0;
+    let _temp_722 = 0;
+    let _temp_723 = 0;
+    let _temp_724 = 0;
+    let _temp_725 = 0;
+    let _temp_726 = 0;
+    let _temp_727 = 0;
+    let _temp_728 = 0;
+    let _temp_729 = 0;
+    let _temp_730 = 0;
+    let _temp_731 = 0;
+    let _temp_732 = 0;
+    let _temp_733 = 0;
+    let _temp_734 = 0;
+    let _temp_735 = 0;
+    let _temp_736 = 0;
+    let _temp_737 = 0;
+    let _temp_738 = 0;
+    let _temp_739 = 0;
+    let _temp_740 = 0;
+    let _temp_741 = 0;
+    let _temp_742 = 0;
+    let _temp_743 = 0;
+    let _temp_744 = 0;
+    let _temp_745 = 0;
+    let _temp_746 = 0;
+    let _temp_747 = 0;
+    let _temp_748 = 0;
+    let _temp_749 = 0;
+    let _temp_750 = 0;
+    let _temp_751 = 0;
+    let _temp_752 = 0;
+    let _temp_753 = 0;
+    let _temp_754 = 0;
+    let _temp_755 = 0;
+    let _temp_756 = 0;
+    let _temp_757 = 0;
+    let _temp_758 = 0;
+    let _temp_759 = 0;
+    let _temp_760 = 0;
+    let _temp_761 = 0;
+    let _temp_762 = 0;
+    let _temp_763 = 0;
+    let _temp_764 = 0;
+    let _temp_765 = 0;
+    let _temp_766 = 0;
+    let _temp_767 = 0;
+    let _temp_768 = 0;
+    let _temp_769 = 0;
+    let _temp_770 = 0;
+    let _temp_771 = 0;
+    let _temp_772 = 0;
+    let _temp_773 = 0;
+    let _temp_774 = 0;
+    let _temp_775 = 0;
+    let _temp_776 = 0;
+    let _temp_777 = 0;
+    let _temp_778 = 0;
+    let _temp_779 = 0;
+    let _temp_780 = 0;
+    let _temp_781 = 0;
+    let _temp_782 = 0;
+    let _temp_783 = 0;
+    let _temp_784 = 0;
+    let _temp_785 = 0;
+    let _temp_786 = 0;
+    let _temp_787 = 0;
+    let _temp_788 = 0;
+    let _temp_789 = 0;
+    let _temp_790 = 0;
+    let _temp_791 = 0;
+    let _temp_792 = 0;
+    let _temp_793 = 0;
+    let _temp_794 = 0;
+    let _temp_795 = 0;
+    let _temp_796 = 0;
+    let _temp_797 = 0;
+    let _temp_798 = 0;
+    let _temp_799 = 0;
+    let _temp_800 = 0;
+    let _temp_801 = 0;
+    let _temp_802 = 0;
+    let _temp_803 = 0;
+    let _temp_804 = 0;
+    let _temp_805 = 0;
+    let _temp_806 = 0;
+    let _temp_807 = 0;
+    let _temp_808 = 0;
+    let _temp_809 = 0;
+    let _temp_810 = 0;
+    let _temp_811 = 0;
+    let _temp_812 = 0;
+    let _temp_813 = 0;
+    let _temp_814 = 0;
+    let _temp_815 = 0;
+    let _temp_816 = 0;
+    let _temp_817 = 0;
+    let _temp_818 = 0;
+    let _temp_819 = 0;
+    let _temp_820 = 0;
+    let _temp_821 = 0;
+    let _temp_822 = 0;
+    let _temp_823 = 0;
+    let _temp_824 = 0;
+    let _temp_825 = 0;
+    let _temp_826 = 0;
+    let _temp_827 = 0;
+    let _temp_828 = 0;
+    let _temp_829 = 0;
+    let _temp_830 = 0;
+    let _temp_831 = 0;
+    let _temp_832 = 0;
+    let _temp_833 = 0;
+    let _temp_834 = 0;
+    let _temp_835 = 0;
+    let _temp_836 = 0;
+    let _temp_837 = 0;
+    let _temp_838 = 0;
+    let _temp_839 = 0;
+    let _temp_840 = 0;
+    let _temp_841 = 0;
+    let _temp_842 = 0;
+    let _temp_843 = 0;
+    let _temp_844 = 0;
+    let _temp_845 = 0;
+    let _temp_846 = 0;
+    let _temp_847 = 0;
+    let _temp_848 = 0;
+    let _temp_849 = 0;
+    let _temp_850 = 0;
+    let _temp_851 = 0;
+    let _temp_852 = 0;
+    let _temp_853 = 0;
+    let _temp_854 = 0;
+    let _temp_855 = 0;
+    let _temp_856 = 0;
+    let _temp_857 = 0;
+    let _temp_858 = 0;
+    let _temp_859 = 0;
+    let _temp_860 = 0;
+    let _temp_861 = 0;
+    let _temp_862 = 0;
+    let _temp_863 = 0;
+    let _temp_864 = 0;
+    let _temp_865 = 0;
+    let _temp_866 = 0;
+    let _temp_867 = 0;
+    let _temp_868 = 0;
+    let _temp_869 = 0;
+    let _temp_870 = 0;
+    let _temp_871 = 0;
+    let _temp_872 = 0;
+    let _temp_873 = 0;
+    let _temp_874 = 0;
+    let _temp_875 = 0;
+    let _temp_876 = 0;
+    let _temp_877 = 0;
+    let _temp_878 = 0;
+    let _temp_879 = 0;
+    let _temp_880 = 0;
+    let _temp_881 = 0;
+    let _temp_882 = 0;
+    let _temp_883 = 0;
+    let _temp_884 = 0;
+    let _temp_885 = 0;
+    let _temp_886 = 0;
+    let _temp_887 = 0;
+    let _temp_888 = 0;
+    let _temp_889 = 0;
+    let _temp_890 = 0;
+    let _temp_891 = 0;
+    let _temp_892 = 0;
+    let _temp_893 = 0;
+    let _temp_894 = 0;
+    let _temp_895 = 0;
+    let _temp_896 = 0;
+    let _temp_897 = 0;
+    let _temp_898 = 0;
+    let _temp_899 = 0;
+    let _temp_900 = 0;
+    let _temp_901 = 0;
+    let _temp_902 = 0;
+    let _temp_903 = 0;
+    let _temp_904 = 0;
+    let _temp_905 = 0;
+    let _temp_906 = 0;
+    let _temp_907 = 0;
+    let _temp_908 = 0;
+    let _temp_909 = 0;
+    let _temp_910 = 0;
+    let _temp_911 = 0;
+    let _temp_912 = 0;
+    let _temp_913 = 0;
+    let _temp_914 = 0;
+    let _temp_915 = 0;
+    let _temp_916 = 0;
+    let _temp_917 = 0;
+    let _temp_918 = 0;
+    let _temp_919 = 0;
+    let _temp_920 = 0;
+    let _temp_921 = 0;
+    let _temp_922 = 0;
+    let _temp_923 = 0;
+    let _temp_924 = 0;
+    let _temp_925 = 0;
+    let _temp_926 = 0;
+    let _temp_927 = 0;
+    let _temp_928 = 0;
+    let _temp_929 = 0;
+    let _temp_930 = 0;
+    let _temp_931 = 0;
+    let _temp_932 = 0;
+    let _temp_933 = 0;
+    let _temp_934 = 0;
+    let _temp_935 = 0;
+    let _temp_936 = 0;
+    let _temp_937 = 0;
+    let _temp_938 = 0;
+    let _temp_939 = 0;
+    let _temp_940 = 0;
+    let _temp_941 = 0;
+    let _temp_942 = 0;
+    let _temp_943 = 0;
+    let _temp_944 = 0;
+    let _temp_945 = 0;
+    let _temp_946 = 0;
+    let _temp_947 = 0;
+    let _temp_948 = 0;
+    let _temp_949 = 0;
+    let _temp_950 = 0;
+    let _temp_951 = 0;
+    let _temp_952 = 0;
+    let _temp_953 = 0;
+    let _temp_954 = 0;
+    let _temp_955 = 0;
+    let _temp_956 = 0;
+    let _temp_957 = 0;
+    let _temp_958 = 0;
+    let _temp_959 = 0;
+    let _temp_960 = 0;
+    let _temp_961 = 0;
+    let _temp_962 = 0;
+    let _temp_963 = 0;
+    let _temp_964 = 0;
+    let _temp_965 = 0;
+    let _temp_966 = 0;
+    let _temp_967 = 0;
+    let _temp_968 = 0;
+    let _temp_969 = 0;
+    let _temp_970 = 0;
+    let _temp_971 = 0;
+    let _temp_972 = 0;
+    let _temp_973 = 0;
+    let _temp_974 = 0;
+    let _temp_975 = 0;
+    let _temp_976 = 0;
+    let _temp_977 = 0;
+    let _temp_978 = 0;
+    let _temp_979 = 0;
+    let _temp_980 = 0;
+    let _temp_981 = 0;
+    let _temp_982 = 0;
+    let _temp_983 = 0;
+    let _temp_984 = 0;
+    let _temp_985 = 0;
+    let _temp_986 = 0;
+    let _temp_987 = 0;
+    let _temp_988 = 0;
+    let _temp_989 = 0;
+    let _temp_990 = 0;
+    let _temp_991 = 0;
+    let _temp_992 = 0;
+    let _temp_993 = 0;
+    let _temp_994 = 0;
+    let _temp_995 = 0;
+    let _temp_996 = 0;
+    let _temp_997 = 0;
+    let _temp_998 = 0;
+    let _temp_999 = 0;
+    let _temp_1000 = 0;
+    let _temp_1001 = 0;
+    let _temp_1002 = 0;
+    let _temp_1003 = 0;
+    let _temp_1004 = 0;
+    let _temp_1005 = 0;
+    let _temp_1006 = 0;
+    let _temp_1007 = 0;
+    let _temp_1008 = 0;
+    let _temp_1009 = 0;
+    let _temp_1010 = 0;
+    let _temp_1011 = 0;
+    let _temp_1012 = 0;
+    let _temp_1013 = 0;
+    let _temp_1014 = 0;
+    let _temp_1015 = 0;
+    let _temp_1016 = 0;
+    let _temp_1017 = 0;
+    let _temp_1018 = 0;
+    let _temp_1019 = 0;
+    let _temp_1020 = 0;
+    let _temp_1021 = 0;
+    let _temp_1022 = 0;
+    let _temp_1023 = 0;
+    let _temp_1024 = 0;
+    let _temp_1025 = 0;
+    let _temp_1026 = 0;
+    let _temp_1027 = 0;
+    let _temp_1028 = 0;
+    let _temp_1029 = 0;
+    let _temp_1030 = 0;
+    let _temp_1031 = 0;
+    let _temp_1032 = 0;
+    let _temp_1033 = 0;
+    let _temp_1034 = 0;
+    let _temp_1035 = 0;
+    let _temp_1036 = 0;
+    let _temp_1037 = 0;
+    let _temp_1038 = 0;
+    let _temp_1039 = 0;
+    let _temp_1040 = 0;
+    let _temp_1041 = 0;
+    let _temp_1042 = 0;
+    let _temp_1043 = 0;
+    let _temp_1044 = 0;
+    let _temp_1045 = 0;
+    let _temp_1046 = 0;
+    let _temp_1047 = 0;
+    let _temp_1048 = 0;
+    let _temp_1049 = 0;
+    let _temp_1050 = 0;
+    let _temp_1051 = 0;
+    let _temp_1052 = 0;
+    let _temp_1053 = 0;
+    let _temp_1054 = 0;
+    let _temp_1055 = 0;
+    let _temp_1056 = 0;
+    let _temp_1057 = 0;
+    let _temp_1058 = 0;
+    let _temp_1059 = 0;
+    let _temp_1060 = 0;
+    let _temp_1061 = 0;
+    let _temp_1062 = 0;
+    let _temp_1063 = 0;
+    let _temp_1064 = 0;
+    let _temp_1065 = 0;
+    let _temp_1066 = 0;
+    let _temp_1067 = 0;
+    let _temp_1068 = 0;
+    let _temp_1069 = 0;
+    let _temp_1070 = 0;
+    let _temp_1071 = 0;
+    let _temp_1072 = 0;
+    let _temp_1073 = 0;
+    let _temp_1074 = 0;
+    let _temp_1075 = 0;
+    let _temp_1076 = 0;
+    let _temp_1077 = 0;
+    let _temp_1078 = 0;
+    let _temp_1079 = 0;
+    let _temp_1080 = 0;
+    let _temp_1081 = 0;
+    let _temp_1082 = 0;
+    let _temp_1083 = 0;
+    let _temp_1084 = 0;
+    let _temp_1085 = 0;
+    let _temp_1086 = 0;
+    let _temp_1087 = 0;
+    let _temp_1088 = 0;
+    let _temp_1089 = 0;
+    let _temp_1090 = 0;
+    let _temp_1091 = 0;
+    let _temp_1092 = 0;
+    let _temp_1093 = 0;
+    let _temp_1094 = 0;
+    let _temp_1095 = 0;
+    let _temp_1096 = 0;
+    let _temp_1097 = 0;
+    let _temp_1098 = 0;
+    let _temp_1099 = 0;
+    let _temp_1100 = 0;
+    let _temp_1101 = 0;
+    let _temp_1102 = 0;
+    let _temp_1103 = 0;
+    let _temp_1104 = 0;
+    let _temp_1105 = 0;
+    let _temp_1106 = 0;
+    let _temp_1107 = 0;
+    let _temp_1108 = 0;
+    let _temp_1109 = 0;
+    let _temp_1110 = 0;
+    let _temp_1111 = 0;
+    let _temp_1112 = 0;
+    let _temp_1113 = 0;
+    let _temp_1114 = 0;
+    let _temp_1115 = 0;
+    let _temp_1116 = 0;
+    let _temp_1117 = 0;
+    let _temp_1118 = 0;
+    let _temp_1119 = 0;
+    let _temp_1120 = 0;
+    let _temp_1121 = 0;
+    let _temp_1122 = 0;
+    let _temp_1123 = 0;
+    let _temp_1124 = 0;
+    let _temp_1125 = 0;
+    let _temp_1126 = 0;
+    let _temp_1127 = 0;
+    let _temp_1128 = 0;
+    let _temp_1129 = 0;
+    let _temp_1130 = 0;
+    let _temp_1131 = 0;
+    let _temp_1132 = 0;
+    let _temp_1133 = 0;
+    let _temp_1134 = 0;
+    let _temp_1135 = 0;
+    let _temp_1136 = 0;
+    let _temp_1137 = 0;
+    let _temp_1138 = 0;
+    let _temp_1139 = 0;
+    let _temp_1140 = 0;
+    let _temp_1141 = 0;
+    let _temp_1142 = 0;
+    let _temp_1143 = 0;
+    let _temp_1144 = 0;
+    let _temp_1145 = 0;
+    let _temp_1146 = 0;
+    let _temp_1147 = 0;
+    let _temp_1148 = 0;
+    let _temp_1149 = 0;
+    let _temp_1150 = 0;
+    let _temp_1151 = 0;
+    let _temp_1152 = 0;
+    let _temp_1153 = 0;
+    let _temp_1154 = 0;
+    let _temp_1155 = 0;
+    let _temp_1156 = 0;
+    let _temp_1157 = 0;
+    let _temp_1158 = 0;
+    let _temp_1159 = 0;
+    let _temp_1160 = 0;
+    let _temp_1161 = 0;
+    let _temp_1162 = 0;
+    let _temp_1163 = 0;
+    let _temp_1164 = 0;
+    let _temp_1165 = 0;
+    let _temp_1166 = 0;
+    let _temp_1167 = 0;
+    let _temp_1168 = 0;
+    let _temp_1169 = 0;
+    let _temp_1170 = 0;
+    let _temp_1171 = 0;
+    let _temp_1172 = 0;
+    let _temp_1173 = 0;
+    let _temp_1174 = 0;
+    let _temp_1175 = 0;
+    let _temp_1176 = 0;
+    let _temp_1177 = 0;
+    let _temp_1178 = 0;
+    let _temp_1179 = 0;
+    let _temp_1180 = 0;
+    let _temp_1181 = 0;
+    let _temp_1182 = 0;
+    let _temp_1183 = 0;
+    let _temp_1184 = 0;
+    let _temp_1185 = 0;
+    let _temp_1186 = 0;
+    let _temp_1187 = 0;
+    let _temp_1188 = 0;
+    let _temp_1189 = 0;
+    let _temp_1190 = 0;
+    let _temp_1191 = 0;
+    let _temp_1192 = 0;
+    let _temp_1193 = 0;
+    let _temp_1194 = 0;
+    let _temp_1195 = 0;
+    let _temp_1196 = 0;
+    let _temp_1197 = 0;
+    let _temp_1198 = 0;
+    let _temp_1199 = 0;
+    let _temp_1200 = 0;
+    let _temp_1201 = 0;
+    let _temp_1202 = 0;
+    let _temp_1203 = 0;
+    let _temp_1204 = 0;
+    let _temp_1205 = 0;
+    let _temp_1206 = 0;
+    let _temp_1207 = 0;
+    let _temp_1208 = 0;
+    let _temp_1209 = 0;
+    let _temp_1210 = 0;
+    let _temp_1211 = 0;
+    let _temp_1212 = 0;
+    let _temp_1213 = 0;
+    let _temp_1214 = 0;
+    let _temp_1215 = 0;
+    let _temp_1216 = 0;
+    let _temp_1217 = 0;
+    let _temp_1218 = 0;
+    let _temp_1219 = 0;
+    let _temp_1220 = 0;
+    let _temp_1221 = 0;
+    let _temp_1222 = 0;
+    let _temp_1223 = 0;
+    let _temp_1224 = 0;
+    let _temp_1225 = 0;
+    let _temp_1226 = 0;
+    let _temp_1227 = 0;
+    let _temp_1228 = 0;
+    let _temp_1229 = 0;
+    let _temp_1230 = 0;
+    let _temp_1231 = 0;
+    let _temp_1232 = 0;
+    let _temp_1233 = 0;
+    let _temp_1234 = 0;
+    let _temp_1235 = 0;
+    let _temp_1236 = 0;
+    let _temp_1237 = 0;
+    let _temp_1238 = 0;
+    let _temp_1239 = 0;
+    let _temp_1240 = 0;
+    let _temp_1241 = 0;
+    let _temp_1242 = 0;
+    let _temp_1243 = 0;
+    let _temp_1244 = 0;
+    let _temp_1245 = 0;
+    let _temp_1246 = 0;
+    let _temp_1247 = 0;
+    let _temp_1248 = 0;
+    let _temp_1249 = 0;
+    let _temp_1250 = 0;
+    let _temp_1251 = 0;
+    let _temp_1252 = 0;
+    let _temp_1253 = 0;
+    let _temp_1254 = 0;
+    let _temp_1255 = 0;
+    let _temp_1256 = 0;
+    let _temp_1257 = 0;
+    let _temp_1258 = 0;
+    let _temp_1259 = 0;
+    let _temp_1260 = 0;
+    let _temp_1261 = 0;
+    let _temp_1262 = 0;
+    let _temp_1263 = 0;
+    let _temp_1264 = 0;
+    let _temp_1265 = 0;
+    let _temp_1266 = 0;
+    let _temp_1267 = 0;
+    let _temp_1268 = 0;
+    let _temp_1269 = 0;
+    let _temp_1270 = 0;
+    let _temp_1271 = 0;
+    let _temp_1272 = 0;
+    let _temp_1273 = 0;
+    let _temp_1274 = 0;
+    let _temp_1275 = 0;
+    let _temp_1276 = 0;
+    let _temp_1277 = 0;
+    let _temp_1278 = 0;
+    let _temp_1279 = 0;
+    let _temp_1280 = 0;
+    let _temp_1281 = 0;
+    let _temp_1282 = 0;
+    let _temp_1283 = 0;
+    let _temp_1284 = 0;
+    let _temp_1285 = 0;
+    let _temp_1286 = 0;
+    let _temp_1287 = 0;
+    let _temp_1288 = 0;
+    let _temp_1289 = 0;
+    let _temp_1290 = 0;
+    let _temp_1291 = 0;
+    let _temp_1292 = 0;
+    let _temp_1293 = 0;
+    let _temp_1294 = 0;
+    let _temp_1295 = 0;
+    let _temp_1296 = 0;
+    let _temp_1297 = 0;
+    let _temp_1298 = 0;
+    let _temp_1299 = 0;
+    let _temp_1300 = 0;
+    let _temp_1301 = 0;
+    let _temp_1302 = 0;
+    let _temp_1303 = 0;
+    let _temp_1304 = 0;
+    let _temp_1305 = 0;
+    let _temp_1306 = 0;
+    let _temp_1307 = 0;
+    let _temp_1308 = 0;
+    let _temp_1309 = 0;
+    let _temp_1310 = 0;
+    let _temp_1311 = 0;
+    let _temp_1312 = 0;
+    let _temp_1313 = 0;
+    let _temp_1314 = 0;
+    let _temp_1315 = 0;
+    let _temp_1316 = 0;
+    let _temp_1317 = 0;
+    let _temp_1318 = 0;
+    let _temp_1319 = 0;
+    let _temp_1320 = 0;
+    let _temp_1321 = 0;
+    let _temp_1322 = 0;
+    let _temp_1323 = 0;
+    let _temp_1324 = 0;
+    let _temp_1325 = 0;
+    let _temp_1326 = 0;
+    let _temp_1327 = 0;
+    let _temp_1328 = 0;
+    let _temp_1329 = 0;
+    let _temp_1330 = 0;
+    let _temp_1331 = 0;
+    let _temp_1332 = 0;
+    let _temp_1333 = 0;
+    let _temp_1334 = 0;
+    let _temp_1335 = 0;
+    let _temp_1336 = 0;
+    let _temp_1337 = 0;
+    let _temp_1338 = 0;
+    let _temp_1339 = 0;
+    let _temp_1340 = 0;
+    let _temp_1341 = 0;
+    let _temp_1342 = 0;
+    let _temp_1343 = 0;
+    let _temp_1344 = 0;
+    let _temp_1345 = 0;
+    let _temp_1346 = 0;
+    let _temp_1347 = 0;
+    let _temp_1348 = 0;
+    let _temp_1349 = 0;
+    let _temp_1350 = 0;
+    let _temp_1351 = 0;
+    let _temp_1352 = 0;
+    let _temp_1353 = 0;
+    let _temp_1354 = 0;
+    let _temp_1355 = 0;
+    let _temp_1356 = 0;
+    let _temp_1357 = 0;
+    let _temp_1358 = 0;
+    let _temp_1359 = 0;
+    let _temp_1360 = 0;
+    let _temp_1361 = 0;
+    let _temp_1362 = 0;
+    let _temp_1363 = 0;
+    let _temp_1364 = 0;
+    let _temp_1365 = 0;
+    let _temp_1366 = 0;
+    let _temp_1367 = 0;
+    let _temp_1368 = 0;
+    let _temp_1369 = 0;
+    let _temp_1370 = 0;
+    let _temp_1371 = 0;
+    let _temp_1372 = 0;
+    let _temp_1373 = 0;
+    let _temp_1374 = 0;
+    let _temp_1375 = 0;
+    let _temp_1376 = 0;
+    let _temp_1377 = 0;
+    let _temp_1378 = 0;
+    let _temp_1379 = 0;
+    let _temp_1380 = 0;
+    let _temp_1381 = 0;
+    let _temp_1382 = 0;
+    let _temp_1383 = 0;
+    let _temp_1384 = 0;
+    let _temp_1385 = 0;
+    let _temp_1386 = 0;
+    let _temp_1387 = 0;
+    let _temp_1388 = 0;
+    let _temp_1389 = 0;
+    let _temp_1390 = 0;
+    let _temp_1391 = 0;
+    let _temp_1392 = 0;
+    let _temp_1393 = 0;
+    let _temp_1394 = 0;
+    let _temp_1395 = 0;
+    let _temp_1396 = 0;
+    let _temp_1397 = 0;
+    let _temp_1398 = 0;
+    let _temp_1399 = 0;
+    let _temp_1400 = 0;
+    let _temp_1401 = 0;
+    let _temp_1402 = 0;
+    let _temp_1403 = 0;
+    let _temp_1404 = 0;
+    let _temp_1405 = 0;
+    let _temp_1406 = 0;
+    let _temp_1407 = 0;
+    let _temp_1408 = 0;
+    let _temp_1409 = 0;
+    let _temp_1410 = 0;
+    let _temp_1411 = 0;
+    let _temp_1412 = 0;
+    let _temp_1413 = 0;
+    let _temp_1414 = 0;
+    let _temp_1415 = 0;
+    let _temp_1416 = 0;
+    let _temp_1417 = 0;
+    let _temp_1418 = 0;
+    let _temp_1419 = 0;
+    let _temp_1420 = 0;
+    let _temp_1421 = 0;
+    let _temp_1422 = 0;
+    let _temp_1423 = 0;
+    let _temp_1424 = 0;
+    let _temp_1425 = 0;
+    let _temp_1426 = 0;
+    let _temp_1427 = 0;
+    let _temp_1428 = 0;
+    let _temp_1429 = 0;
+    let _temp_1430 = 0;
+    let _temp_1431 = 0;
+    let _temp_1432 = 0;
+    let _temp_1433 = 0;
+    let _temp_1434 = 0;
+    let _temp_1435 = 0;
+    let _temp_1436 = 0;
+    let _temp_1437 = 0;
+    let _temp_1438 = 0;
+    let _temp_1439 = 0;
+    let _temp_1440 = 0;
+    let _temp_1441 = 0;
+    let _temp_1442 = 0;
+    let _temp_1443 = 0;
+    let _temp_1444 = 0;
+    let _temp_1445 = 0;
+    let _temp_1446 = 0;
+    let _temp_1447 = 0;
+    let _temp_1448 = 0;
+    let _temp_1449 = 0;
+    let _temp_1450 = 0;
+    let _temp_1451 = 0;
+    let _temp_1452 = 0;
+    let _temp_1453 = 0;
+    let _temp_1454 = 0;
+    let _temp_1455 = 0;
+    let _temp_1456 = 0;
+    let _temp_1457 = 0;
+    let _temp_1458 = 0;
+    let _temp_1459 = 0;
+    let _temp_1460 = 0;
+    let _temp_1461 = 0;
+    let _temp_1462 = 0;
+    let _temp_1463 = 0;
+    let _temp_1464 = 0;
+    let _temp_1465 = 0;
+    let _temp_1466 = 0;
+    let _temp_1467 = 0;
+    let _temp_1468 = 0;
+    let _temp_1469 = 0;
+    let _temp_1470 = 0;
+    let _temp_1471 = 0;
+    let _temp_1472 = 0;
+    let _temp_1473 = 0;
+    let _temp_1474 = 0;
+    let _temp_1475 = 0;
+    let _temp_1476 = 0;
+    let _temp_1477 = 0;
+    let _temp_1478 = 0;
+    let _temp_1479 = 0;
+    let _temp_1480 = 0;
+    let _temp_1481 = 0;
+    let _temp_1482 = 0;
+    let _temp_1483 = 0;
+    let _temp_1484 = 0;
+    let _temp_1485 = 0;
+    let _temp_1486 = 0;
+    let _temp_1487 = 0;
+    let _temp_1488 = 0;
+    let _temp_1489 = 0;
+    let _temp_1490 = 0;
+    let _temp_1491 = 0;
+    let _temp_1492 = 0;
+    let _temp_1493 = 0;
+    let _temp_1494 = 0;
+    let _temp_1495 = 0;
+    let _temp_1496 = 0;
+    let _temp_1497 = 0;
+    let _temp_1498 = 0;
+    let _temp_1499 = 0;
+    let _temp_1500 = 0;
+    let _temp_1501 = 0;
+    let _temp_1502 = 0;
+    let _temp_1503 = 0;
+    let _temp_1504 = 0;
+    let _temp_1505 = 0;
+    let _temp_1506 = 0;
+    let _temp_1507 = 0;
+    let _temp_1508 = 0;
+    let _temp_1509 = 0;
+    let _temp_1510 = 0;
+    let _temp_1511 = 0;
+    let _temp_1512 = 0;
+    let _temp_1513 = 0;
+    let _temp_1514 = 0;
+    let _temp_1515 = 0;
+    let _temp_1516 = 0;
+    let _temp_1517 = 0;
+    let _temp_1518 = 0;
+    let _temp_1519 = 0;
+    let _temp_1520 = 0;
+    let _temp_1521 = 0;
+    let _temp_1522 = 0;
+    let _temp_1523 = 0;
+    let _temp_1524 = 0;
+    let _temp_1525 = 0;
+    let _temp_1526 = 0;
+    let _temp_1527 = 0;
+    let _temp_1528 = 0;
+    let _temp_1529 = 0;
+    let _temp_1530 = 0;
+    let _temp_1531 = 0;
+    let _temp_1532 = 0;
+    let _temp_1533 = 0;
+    let _temp_1534 = 0;
+    let _temp_1535 = 0;
+    let _temp_1536 = 0;
+    let _temp_1537 = 0;
+    let _temp_1538 = 0;
+    let _temp_1539 = 0;
+    let _temp_1540 = 0;
+    let _temp_1541 = 0;
+    let _temp_1542 = 0;
+    let _temp_1543 = 0;
+    let _temp_1544 = 0;
+    let _temp_1545 = 0;
+    let _temp_1546 = 0;
+    let _temp_1547 = 0;
+    let _temp_1548 = 0;
+    let _temp_1549 = 0;
+    let _temp_1550 = 0;
+    let _temp_1551 = 0;
+    let _temp_1552 = 0;
+    let _temp_1553 = 0;
+    let _temp_1554 = 0;
+    let _temp_1555 = 0;
+    let _temp_1556 = 0;
+    let _temp_1557 = 0;
+    let _temp_1558 = 0;
+    let _temp_1559 = 0;
+    let _temp_1560 = 0;
+    let _temp_1561 = 0;
+    let _temp_1562 = 0;
+    let _temp_1563 = 0;
+    let _temp_1564 = 0;
+    let _temp_1565 = 0;
+    let _temp_1566 = 0;
+    let _temp_1567 = 0;
+    let _temp_1568 = 0;
+    let _temp_1569 = 0;
+    let _temp_1570 = 0;
+    let _temp_1571 = 0;
+    let _temp_1572 = 0;
+    let _temp_1573 = 0;
+    let _temp_1574 = 0;
+    let _temp_1575 = 0;
+    let _temp_1576 = 0;
+    let _temp_1577 = 0;
+    let _temp_1578 = 0;
+    let _temp_1579 = 0;
+    let _temp_1580 = 0;
+    let _temp_1581 = 0;
+    let _temp_1582 = 0;
+    let _temp_1583 = 0;
+    let _temp_1584 = 0;
+    let _temp_1585 = 0;
+    let _temp_1586 = 0;
+    let _temp_1587 = 0;
+    let _temp_1588 = 0;
+    let _temp_1589 = 0;
+    let _temp_1590 = 0;
+    let _temp_1591 = 0;
+    let _temp_1592 = 0;
+    let _temp_1593 = 0;
+    let _temp_1594 = 0;
+    let _temp_1595 = 0;
+    let _temp_1596 = 0;
+    let _temp_1597 = 0;
+    let _temp_1598 = 0;
+    let _temp_1599 = 0;
+    let _temp_1600 = 0;
+    let _temp_1601 = 0;
+    let _temp_1602 = 0;
+    let _temp_1603 = 0;
+    let _temp_1604 = 0;
+    let _temp_1605 = 0;
+    let _temp_1606 = 0;
+    let _temp_1607 = 0;
+    let _temp_1608 = 0;
+    let _temp_1609 = 0;
+    let _temp_1610 = 0;
+    let _temp_1611 = 0;
+    let _temp_1612 = 0;
+    let _temp_1613 = 0;
+    let _temp_1614 = 0;
+    let _temp_1615 = 0;
+    let _temp_1616 = 0;
+    let _temp_1617 = 0;
+    let _temp_1618 = 0;
+    let _temp_1619 = 0;
+    let _temp_1620 = 0;
+    let _temp_1621 = 0;
+    let _temp_1622 = 0;
+    let _temp_1623 = 0;
+    let _temp_1624 = 0;
+    let _temp_1625 = 0;
+    let _temp_1626 = 0;
+    let _temp_1627 = 0;
+    let _temp_1628 = 0;
+    let _temp_1629 = 0;
+    let _temp_1630 = 0;
+    let _temp_1631 = 0;
+    let _temp_1632 = 0;
+    let _temp_1633 = 0;
+    let _temp_1634 = 0;
+    let _temp_1635 = 0;
+    let _temp_1636 = 0;
+    let _temp_1637 = 0;
+    let _temp_1638 = 0;
+    let _temp_1639 = 0;
+    let _temp_1640 = 0;
+    let _temp_1641 = 0;
+    let _temp_1642 = 0;
+    let _temp_1643 = 0;
+    let _temp_1644 = 0;
+    let _temp_1645 = 0;
+    let _temp_1646 = 0;
+    let _temp_1647 = 0;
+    let _temp_1648 = 0;
+    let _temp_1649 = 0;
+    let _temp_1650 = 0;
+    let _temp_1651 = 0;
+    let _temp_1652 = 0;
+    let _temp_1653 = 0;
+    let _temp_1654 = 0;
+    let _temp_1655 = 0;
+    let _temp_1656 = 0;
+    let _temp_1657 = 0;
+    let _temp_1658 = 0;
+    let _temp_1659 = 0;
+    let _temp_1660 = 0;
+    let _temp_1661 = 0;
+    let _temp_1662 = 0;
+    let _temp_1663 = 0;
+    let _temp_1664 = 0;
+    let _temp_1665 = 0;
+    let _temp_1666 = 0;
+    let _temp_1667 = 0;
+    let _temp_1668 = 0;
+    let _temp_1669 = 0;
+    let _temp_1670 = 0;
+    let _temp_1671 = 0;
+    let _temp_1672 = 0;
+    let _temp_1673 = 0;
+    let _temp_1674 = 0;
+    let _temp_1675 = 0;
+    let _temp_1676 = 0;
+    let _temp_1677 = 0;
+    let _temp_1678 = 0;
+    let _temp_1679 = 0;
+    let _temp_1680 = 0;
+    let _temp_1681 = 0;
+    let _temp_1682 = 0;
+    let _temp_1683 = 0;
+    let _temp_1684 = 0;
+    let _temp_1685 = 0;
+    let _temp_1686 = 0;
+    let _temp_1687 = 0;
+    let _temp_1688 = 0;
+    let _temp_1689 = 0;
+    let _temp_1690 = 0;
+    let _temp_1691 = 0;
+    let _temp_1692 = 0;
+    let _temp_1693 = 0;
+    let _temp_1694 = 0;
+    let _temp_1695 = 0;
+    let _temp_1696 = 0;
+    let _temp_1697 = 0;
+    let _temp_1698 = 0;
+    let _temp_1699 = 0;
+    let _temp_1700 = 0;
+    let _temp_1701 = 0;
+    let _temp_1702 = 0;
+    let _temp_1703 = 0;
+    let _temp_1704 = 0;
+    let _temp_1705 = 0;
+    let _temp_1706 = 0;
+    let _temp_1707 = 0;
+    let _temp_1708 = 0;
+    let _temp_1709 = 0;
+    let _temp_1710 = 0;
+    let _temp_1711 = 0;
+    let _temp_1712 = 0;
+    let _temp_1713 = 0;
+    let _temp_1714 = 0;
+    let _temp_1715 = 0;
+    let _temp_1716 = 0;
+    let _temp_1717 = 0;
+    let _temp_1718 = 0;
+    let _temp_1719 = 0;
+    let _temp_1720 = 0;
+    let _temp_1721 = 0;
+    let _temp_1722 = 0;
+    let _temp_1723 = 0;
+    let _temp_1724 = 0;
+    let _temp_1725 = 0;
+    let _temp_1726 = 0;
+    let _temp_1727 = 0;
+    let _temp_1728 = 0;
+    let _temp_1729 = 0;
+    let _temp_1730 = 0;
+    let _temp_1731 = 0;
+    let _temp_1732 = 0;
+    let _temp_1733 = 0;
+    let _temp_1734 = 0;
+    let _temp_1735 = 0;
+    let _temp_1736 = 0;
+    let _temp_1737 = 0;
+    let _temp_1738 = 0;
+    let _temp_1739 = 0;
+    let _temp_1740 = 0;
+    let _temp_1741 = 0;
+    let _temp_1742 = 0;
+    let _temp_1743 = 0;
+    let _temp_1744 = 0;
+    let _temp_1745 = 0;
+    let _temp_1746 = 0;
+    let _temp_1747 = 0;
+    let _temp_1748 = 0;
+    let _temp_1749 = 0;
+    let _temp_1750 = 0;
+    let _temp_1751 = 0;
+    let _temp_1752 = 0;
+    let _temp_1753 = 0;
+    let _temp_1754 = 0;
+    let _temp_1755 = 0;
+    let _temp_1756 = 0;
+    let _temp_1757 = 0;
+    let _temp_1758 = 0;
+    let _temp_1759 = 0;
+    let _temp_1760 = 0;
+    let _temp_1761 = 0;
+    let _temp_1762 = 0;
+    let _temp_1763 = 0;
+    let _temp_1764 = 0;
+    let _temp_1765 = 0;
+    let _temp_1766 = 0;
+    let _temp_1767 = 0;
+    let _temp_1768 = 0;
+    let _temp_1769 = 0;
+    let _temp_1770 = 0;
+    let _temp_1771 = 0;
+    let _temp_1772 = 0;
+    let _temp_1773 = 0;
+    let _temp_1774 = 0;
+    let _temp_1775 = 0;
+    let _temp_1776 = 0;
+    let _temp_1777 = 0;
+    let _temp_1778 = 0;
+    let _temp_1779 = 0;
+    let _temp_1780 = 0;
+    let _temp_1781 = 0;
+    let _temp_1782 = 0;
+    let _temp_1783 = 0;
+    let _temp_1784 = 0;
+    let _temp_1785 = 0;
+    let _temp_1786 = 0;
+    let _temp_1787 = 0;
+    let _temp_1788 = 0;
+    let _temp_1789 = 0;
+    let _temp_1790 = 0;
+    let _temp_1791 = 0;
+    let _temp_1792 = 0;
+    let _temp_1793 = 0;
+    let _temp_1794 = 0;
+    let _temp_1795 = 0;
+    let _temp_1796 = 0;
+    let _temp_1797 = 0;
+    let _temp_1798 = 0;
+    let _temp_1799 = 0;
+    let _temp_1800 = 0;
+    let _temp_1801 = 0;
+    let _temp_1802 = 0;
+    let _temp_1803 = 0;
+    let _temp_1804 = 0;
+    let _temp_1805 = 0;
+    let _temp_1806 = 0;
+    let _temp_1807 = 0;
+    let _temp_1808 = 0;
+    let _temp_1809 = 0;
+    let _temp_1810 = 0;
+    let _temp_1811 = 0;
+    let _temp_1812 = 0;
+    let _temp_1813 = 0;
+    let _temp_1814 = 0;
+    let _temp_1815 = 0;
+    let _temp_1816 = 0;
+    let _temp_1817 = 0;
+    let _temp_1818 = 0;
+    let _temp_1819 = 0;
+    let _temp_1820 = 0;
+    let _temp_1821 = 0;
+    let _temp_1822 = 0;
+    let _temp_1823 = 0;
+    let _temp_1824 = 0;
+    let _temp_1825 = 0;
+    let _temp_1826 = 0;
+    let _temp_1827 = 0;
+    let _temp_1828 = 0;
+    let _temp_1829 = 0;
+    let _temp_1830 = 0;
+    let _temp_1831 = 0;
+    let _temp_1832 = 0;
+    let _temp_1833 = 0;
+    let _temp_1834 = 0;
+    let _temp_1835 = 0;
+    let _temp_1836 = 0;
+    let _temp_1837 = 0;
+    let _temp_1838 = 0;
+    let _temp_1839 = 0;
+    let _temp_1840 = 0;
+    let _temp_1841 = 0;
+    let _temp_1842 = 0;
+    let _temp_1843 = 0;
+    let _temp_1844 = 0;
+    let _temp_1845 = 0;
+    let _temp_1846 = 0;
+    let _temp_1847 = 0;
+    let _temp_1848 = 0;
+    let _temp_1849 = 0;
+    let _temp_1850 = 0;
+    let _temp_1851 = 0;
+    let _temp_1852 = 0;
+    let _temp_1853 = 0;
+    let _temp_1854 = 0;
+    let _temp_1855 = 0;
+    let _temp_1856 = 0;
+    let _temp_1857 = 0;
+    let _temp_1858 = 0;
+    let _temp_1859 = 0;
+    let _temp_1860 = 0;
+    let _temp_1861 = 0;
+    let _temp_1862 = 0;
+    let _temp_1863 = 0;
+    let _temp_1864 = 0;
+    let _temp_1865 = 0;
+    let _temp_1866 = 0;
+    let _temp_1867 = 0;
+    let _temp_1868 = 0;
+    let _temp_1869 = 0;
+    let _temp_1870 = 0;
+    let _temp_1871 = 0;
+    let _temp_1872 = 0;
+    let _temp_1873 = 0;
+    let _temp_1874 = 0;
+    let _temp_1875 = 0;
+    let _temp_1876 = 0;
+    let _temp_1877 = 0;
+    let _temp_1878 = 0;
+    let _temp_1879 = 0;
+    let _temp_1880 = 0;
+    let _temp_1881 = 0;
+    let _temp_1882 = 0;
+    let _temp_1883 = 0;
+    let _temp_1884 = 0;
+    let _temp_1885 = 0;
+    let _temp_1886 = 0;
+    let _temp_1887 = 0;
+    let _temp_1888 = 0;
+    let _temp_1889 = 0;
+    let _temp_1890 = 0;
+    let _temp_1891 = 0;
+    let _temp_1892 = 0;
+    let _temp_1893 = 0;
+    let _temp_1894 = 0;
+    let _temp_1895 = 0;
+    let _temp_1896 = 0;
+    let _temp_1897 = 0;
+    let _temp_1898 = 0;
+    let _temp_1899 = 0;
+    let _temp_1900 = 0;
+    let _temp_1901 = 0;
+    let _temp_1902 = 0;
+    let _temp_1903 = 0;
+    let _temp_1904 = 0;
+    let _temp_1905 = 0;
+    let _temp_1906 = 0;
+    let _temp_1907 = 0;
+    let _temp_1908 = 0;
+    let _temp_1909 = 0;
+    let _temp_1910 = 0;
+    let _temp_1911 = 0;
+    let _temp_1912 = 0;
+    let _temp_1913 = 0;
+    let _temp_1914 = 0;
+    let _temp_1915 = 0;
+    let _temp_1916 = 0;
+    let _temp_1917 = 0;
+    let _temp_1918 = 0;
+    let _temp_1919 = 0;
+    let _temp_1920 = 0;
+    let _temp_1921 = 0;
+    let _temp_1922 = 0;
+    let _temp_1923 = 0;
+    let _temp_1924 = 0;
+    let _temp_1925 = 0;
+    let _temp_1926 = 0;
+    let _temp_1927 = 0;
+    let _temp_1928 = 0;
+    let _temp_1929 = 0;
+    let _temp_1930 = 0;
+    let _temp_1931 = 0;
+    let _temp_1932 = 0;
+    let _temp_1933 = 0;
+    let _temp_1934 = 0;
+    let _temp_1935 = 0;
+    let _temp_1936 = 0;
+    let _temp_1937 = 0;
+    let _temp_1938 = 0;
+    let _temp_1939 = 0;
+    let _temp_1940 = 0;
+    let _temp_1941 = 0;
+    let _temp_1942 = 0;
+    let _temp_1943 = 0;
+    let _temp_1944 = 0;
+    let _temp_1945 = 0;
+    let _temp_1946 = 0;
+    let _temp_1947 = 0;
+    let _temp_1948 = 0;
+    let _temp_1949 = 0;
+    let _temp_1950 = 0;
+    let _temp_1951 = 0;
+    let _temp_1952 = 0;
+    let _temp_1953 = 0;
+    let _temp_1954 = 0;
+    let _temp_1955 = 0;
+    let _temp_1956 = 0;
+    let _temp_1957 = 0;
+    let _temp_1958 = 0;
+    let _temp_1959 = 0;
+    let _temp_1960 = 0;
+    let _temp_1961 = 0;
+    let _temp_1962 = 0;
+    let _temp_1963 = 0;
+    let _temp_1964 = 0;
+    let _temp_1965 = 0;
+    let _temp_1966 = 0;
+    let _temp_1967 = 0;
+    let _temp_1968 = 0;
+    let _temp_1969 = 0;
+    let _temp_1970 = 0;
+    let _temp_1971 = 0;
+    let _temp_1972 = 0;
+    let _temp_1973 = 0;
+    let _temp_1974 = 0;
+    let _temp_1975 = 0;
+    let _temp_1976 = 0;
+    let _temp_1977 = 0;
+    let _temp_1978 = 0;
+    let _temp_1979 = 0;
+    let _temp_1980 = 0;
+    let _temp_1981 = 0;
+    let _temp_1982 = 0;
+    let _temp_1983 = 0;
+    let _temp_1984 = 0;
+    let _temp_1985 = 0;
+    let _temp_1986 = 0;
+    let _temp_1987 = 0;
+    let _temp_1988 = 0;
+    let _temp_1989 = 0;
+    let _temp_1990 = 0;
+    let _temp_1991 = 0;
+    let _temp_1992 = 0;
+    let _temp_1993 = 0;
+    let _temp_1994 = 0;
+    let _temp_1995 = 0;
+    let _temp_1996 = 0;
+    let _temp_1997 = 0;
+    let _temp_1998 = 0;
+    let _temp_1999 = 0;
+    let _temp_2000 = 0;
+    let _temp_2001 = 0;
+    let _temp_2002 = 0;
+    let _temp_2003 = 0;
+    let _temp_2004 = 0;
+    let _temp_2005 = 0;
+    let _temp_2006 = 0;
+    let _temp_2007 = 0;
+    let _temp_2008 = 0;
+    let _temp_2009 = 0;
+    let _temp_2010 = 0;
+    let _temp_2011 = 0;
+    let _temp_2012 = 0;
+    let _temp_2013 = 0;
+    let _temp_2014 = 0;
+    let _temp_2015 = 0;
+    let _temp_2016 = 0;
+    let _temp_2017 = 0;
+    let _temp_2018 = 0;
+    let _temp_2019 = 0;
+    let _temp_2020 = 0;
+    let _temp_2021 = 0;
+    let _temp_2022 = 0;
+    let _temp_2023 = 0;
+    let _temp_2024 = 0;
+    let _temp_2025 = 0;
+    let _temp_2026 = 0;
+    let _temp_2027 = 0;
+    let _temp_2028 = 0;
+    let _temp_2029 = 0;
+    let _temp_2030 = 0;
+    let _temp_2031 = 0;
+    let _temp_2032 = 0;
+    let _temp_2033 = 0;
+    let _temp_2034 = 0;
+    let _temp_2035 = 0;
+    let _temp_2036 = 0;
+    let _temp_2037 = 0;
+    let _temp_2038 = 0;
+    let _temp_2039 = 0;
+    let _temp_2040 = 0;
+    let _temp_2041 = 0;
+    let _temp_2042 = 0;
+    let _temp_2043 = 0;
+    let _temp_2044 = 0;
+    let _temp_2045 = 0;
+    let _temp_2046 = 0;
+    let _temp_2047 = 0;
+    let _temp_2048 = 0;
+    let _temp_2049 = 0;
+    let _temp_2050 = 0;
+    let _temp_2051 = 0;
+    let _temp_2052 = 0;
+    let _temp_2053 = 0;
+    let _temp_2054 = 0;
+    let _temp_2055 = 0;
+    let _temp_2056 = 0;
+    let _temp_2057 = 0;
+    let _temp_2058 = 0;
+    let _temp_2059 = 0;
+    let _temp_2060 = 0;
+    let _temp_2061 = 0;
+    let _temp_2062 = 0;
+    let _temp_2063 = 0;
+    let _temp_2064 = 0;
+    let _temp_2065 = 0;
+    let _temp_2066 = 0;
+    let _temp_2067 = 0;
+    let _temp_2068 = 0;
+    let _temp_2069 = 0;
+    let _temp_2070 = 0;
+    let _temp_2071 = 0;
+    let _temp_2072 = 0;
+    let _temp_2073 = 0;
+    let _temp_2074 = 0;
+    let _temp_2075 = 0;
+    let _temp_2076 = 0;
+    let _temp_2077 = 0;
+    let _temp_2078 = 0;
+    let _temp_2079 = 0;
+    let _temp_2080 = 0;
+    let _temp_2081 = 0;
+    let _temp_2082 = 0;
+    let _temp_2083 = 0;
+    let _temp_2084 = 0;
+    let _temp_2085 = 0;
+    let _temp_2086 = 0;
+    let _temp_2087 = 0;
+    let _temp_2088 = 0;
+    let _temp_2089 = 0;
+    let _temp_2090 = 0;
+    let _temp_2091 = 0;
+    let _temp_2092 = 0;
+    let _temp_2093 = 0;
+    let _temp_2094 = 0;
+    let _temp_2095 = 0;
+    let _temp_2096 = 0;
+    let _temp_2097 = 0;
+    let _temp_2098 = 0;
+    let _temp_2099 = 0;
+    let _temp_2100 = 0;
+    let _temp_2101 = 0;
+    let _temp_2102 = 0;
+    let _temp_2103 = 0;
+    let _temp_2104 = 0;
+    let _temp_2105 = 0;
+    let _temp_2106 = 0;
+    let _temp_2107 = 0;
+    let _temp_2108 = 0;
+    let _temp_2109 = 0;
+    let _temp_2110 = 0;
+    let _temp_2111 = 0;
+    let _temp_2112 = 0;
+    let _temp_2113 = 0;
+    let _temp_2114 = 0;
+    let _temp_2115 = 0;
+    let _temp_2116 = 0;
+    let _temp_2117 = 0;
+    let _temp_2118 = 0;
+    let _temp_2119 = 0;
+    let _temp_2120 = 0;
+    let _temp_2121 = 0;
+    let _temp_2122 = 0;
+    let _temp_2123 = 0;
+    let _temp_2124 = 0;
+    let _temp_2125 = 0;
+    let _temp_2126 = 0;
+    let _temp_2127 = 0;
+    let _temp_2128 = 0;
+    let _temp_2129 = 0;
+    let _temp_2130 = 0;
+    let _temp_2131 = 0;
+    let _temp_2132 = 0;
+    let _temp_2133 = 0;
+    let _temp_2134 = 0;
+    let _temp_2135 = 0;
+    let _temp_2136 = 0;
+    let _temp_2137 = 0;
+    let _temp_2138 = 0;
+    let _temp_2139 = 0;
+    let _temp_2140 = 0;
+    let _temp_2141 = 0;
+    let _temp_2142 = 0;
+    let _temp_2143 = 0;
+    let _temp_2144 = 0;
+    let _temp_2145 = 0;
+    let _temp_2146 = 0;
+    let _temp_2147 = 0;
+    let _temp_2148 = 0;
+    let _temp_2149 = 0;
+    let _temp_2150 = 0;
+    let _temp_2151 = 0;
+    let _temp_2152 = 0;
+    let _temp_2153 = 0;
+    let _temp_2154 = 0;
+    let _temp_2155 = 0;
+    let _temp_2156 = 0;
+    let _temp_2157 = 0;
+    let _temp_2158 = 0;
+    let _temp_2159 = 0;
+    let _temp_2160 = 0;
+    let _temp_2161 = 0;
+    let _temp_2162 = 0;
+    let _temp_2163 = 0;
+    let _temp_2164 = 0;
+    let _temp_2165 = 0;
+    let _temp_2166 = 0;
+    let _temp_2167 = 0;
+    let _temp_2168 = 0;
+    let _temp_2169 = 0;
+    let _temp_2170 = 0;
+    let _temp_2171 = 0;
+    let _temp_2172 = 0;
+    let _temp_2173 = 0;
+    let _temp_2174 = 0;
+    let _temp_2175 = 0;
+    let _temp_2176 = 0;
+    let _temp_2177 = 0;
+    let _temp_2178 = 0;
+    let _temp_2179 = 0;
+    let _temp_2180 = 0;
+    let _temp_2181 = 0;
+    let _temp_2182 = 0;
+    let _temp_2183 = 0;
+    let _temp_2184 = 0;
+    let _temp_2185 = 0;
+    let _temp_2186 = 0;
+    let _temp_2187 = 0;
+    let _temp_2188 = 0;
+    let _temp_2189 = 0;
+    let _temp_2190 = 0;
+    let _temp_2191 = 0;
+    let _temp_2192 = 0;
+    let _temp_2193 = 0;
+    let _temp_2194 = 0;
+    let _temp_2195 = 0;
+    let _temp_2196 = 0;
+    let _temp_2197 = 0;
+    let _temp_2198 = 0;
+    let _temp_2199 = 0;
+    let _temp_2200 = 0;
+    let _temp_2201 = 0;
+    let _temp_2202 = 0;
+    let _temp_2203 = 0;
+    let _temp_2204 = 0;
+    let _temp_2205 = 0;
+    let _temp_2206 = 0;
+    let _temp_2207 = 0;
+    let _temp_2208 = 0;
+    let _temp_2209 = 0;
+    let _temp_2210 = 0;
+    let _temp_2211 = 0;
+    let _temp_2212 = 0;
+    let _temp_2213 = 0;
+    let _temp_2214 = 0;
+    let _temp_2215 = 0;
+    let _temp_2216 = 0;
+    let _temp_2217 = 0;
+    let _temp_2218 = 0;
+    let _temp_2219 = 0;
+    let _temp_2220 = 0;
+    let _temp_2221 = 0;
+    let _temp_2222 = 0;
+    let _temp_2223 = 0;
+    let _temp_2224 = 0;
+    let _temp_2225 = 0;
+    let _temp_2226 = 0;
+    let _temp_2227 = 0;
+    let _temp_2228 = 0;
+    let _temp_2229 = 0;
+    let _temp_2230 = 0;
+    let _temp_2231 = 0;
+    let _temp_2232 = 0;
+    let _temp_2233 = 0;
+    let _temp_2234 = 0;
+    let _temp_2235 = 0;
+    let _temp_2236 = 0;
+    let _temp_2237 = 0;
+    let _temp_2238 = 0;
+    let _temp_2239 = 0;
+    let _temp_2240 = 0;
+    let _temp_2241 = 0;
+    let _temp_2242 = 0;
+    let _temp_2243 = 0;
+    let _temp_2244 = 0;
+    let _temp_2245 = 0;
+    let _temp_2246 = 0;
+    let _temp_2247 = 0;
+    let _temp_2248 = 0;
+    let _temp_2249 = 0;
+    let _temp_2250 = 0;
+    let _temp_2251 = 0;
+    let _temp_2252 = 0;
+    let _temp_2253 = 0;
+    let _temp_2254 = 0;
+    let _temp_2255 = 0;
+    let _temp_2256 = 0;
+    let _temp_2257 = 0;
+    let _temp_2258 = 0;
+    let _temp_2259 = 0;
+    let _temp_2260 = 0;
+    let _temp_2261 = 0;
+    let _temp_2262 = 0;
+    let _temp_2263 = 0;
+    let _temp_2264 = 0;
+    let _temp_2265 = 0;
+    let _temp_2266 = 0;
+    let _temp_2267 = 0;
+    let _temp_2268 = 0;
+    let _temp_2269 = 0;
+    let _temp_2270 = 0;
+    let _temp_2271 = 0;
+    let _temp_2272 = 0;
+    let _temp_2273 = 0;
+    let _temp_2274 = 0;
+    let _temp_2275 = 0;
+    let _temp_2276 = 0;
+    let _temp_2277 = 0;
+    let _temp_2278 = 0;
+    let _temp_2279 = 0;
+    let _temp_2280 = 0;
+    let _temp_2281 = 0;
+    let _temp_2282 = 0;
+    let _temp_2283 = 0;
+    let _temp_2284 = 0;
+    let _temp_2285 = 0;
+    let _temp_2286 = 0;
+    let _temp_2287 = 0;
+    let _temp_2288 = 0;
+    let _temp_2289 = 0;
+    let _temp_2290 = 0;
+    let _temp_2291 = 0;
+    let _temp_2292 = 0;
+    let _temp_2293 = 0;
+    let _temp_2294 = 0;
+    let _temp_2295 = 0;
+    let _temp_2296 = 0;
+    let _temp_2297 = 0;
+    let _temp_2298 = 0;
+    let _temp_2299 = 0;
+    let _temp_2300 = 0;
+    let _temp_2301 = 0;
+    let _temp_2302 = 0;
+    let _temp_2303 = 0;
+    let _temp_2304 = 0;
+    let _temp_2305 = 0;
+    let _temp_2306 = 0;
+    let _temp_2307 = 0;
+    let _temp_2308 = 0;
+    let _temp_2309 = 0;
+    let _temp_2310 = 0;
+    let _temp_2311 = 0;
+    let _temp_2312 = 0;
+    let _temp_2313 = 0;
+    let _temp_2314 = 0;
+    let _temp_2315 = 0;
+    let _temp_2316 = 0;
+    let _temp_2317 = 0;
+    let _temp_2318 = 0;
+    let _temp_2319 = 0;
+    let _temp_2320 = 0;
+    let _temp_2321 = 0;
+    let _temp_2322 = 0;
+    let _temp_2323 = 0;
+    let _temp_2324 = 0;
+    let _temp_2325 = 0;
+    let _temp_2326 = 0;
+    let _temp_2327 = 0;
+    let _temp_2328 = 0;
+    let _temp_2329 = 0;
+    let _temp_2330 = 0;
+    let _temp_2331 = 0;
+    let _temp_2332 = 0;
+    let _temp_2333 = 0;
+    let _temp_2334 = 0;
+    let _temp_2335 = 0;
+    let _temp_2336 = 0;
+    let _temp_2337 = 0;
+    let _temp_2338 = 0;
+    let _temp_2339 = 0;
+    let _temp_2340 = 0;
+    let _temp_2341 = 0;
+    let _temp_2342 = 0;
+    let _temp_2343 = 0;
+    let _temp_2344 = 0;
+    let _temp_2345 = 0;
+    let _temp_2346 = 0;
+    let _temp_2347 = 0;
+    let _temp_2348 = 0;
+    let _temp_2349 = 0;
+    let _temp_2350 = 0;
+    let _temp_2351 = 0;
+    let _temp_2352 = 0;
+    let _temp_2353 = 0;
+    let _temp_2354 = 0;
+    let _temp_2355 = 0;
+    let _temp_2356 = 0;
+    let _temp_2357 = 0;
+    let _temp_2358 = 0;
+    let _temp_2359 = 0;
+    let _temp_2360 = 0;
+    let _temp_2361 = 0;
+    let _temp_2362 = 0;
+    let _temp_2363 = 0;
+    let _temp_2364 = 0;
+    let _temp_2365 = 0;
+    let _temp_2366 = 0;
+    let _temp_2367 = 0;
+    let _temp_2368 = 0;
+    let _temp_2369 = 0;
+    let _temp_2370 = 0;
+    let _temp_2371 = 0;
+    let _temp_2372 = 0;
+    let _temp_2373 = 0;
+    let _temp_2374 = 0;
+    let _temp_2375 = 0;
+    let _temp_2376 = 0;
+    let _temp_2377 = 0;
+    let _temp_2378 = 0;
+    let _temp_2379 = 0;
+    let _temp_2380 = 0;
+    let _temp_2381 = 0;
+    let _temp_2382 = 0;
+    let _temp_2383 = 0;
+    let _temp_2384 = 0;
+    let _temp_2385 = 0;
+    let _temp_2386 = 0;
+    let _temp_2387 = 0;
+    let _temp_2388 = 0;
+    let _temp_2389 = 0;
+    let _temp_2390 = 0;
+    let _temp_2391 = 0;
+    let _temp_2392 = 0;
+    let _temp_2393 = 0;
+    let _temp_2394 = 0;
+    let _temp_2395 = 0;
+    let _temp_2396 = 0;
+    let _temp_2397 = 0;
+    let _temp_2398 = 0;
+    let _temp_2399 = 0;
+    let _temp_2400 = 0;
+    let _temp_2401 = 0;
+    let _temp_2402 = 0;
+    let _temp_2403 = 0;
+    let _temp_2404 = 0;
+    let _temp_2405 = 0;
+    let _temp_2406 = 0;
+    let _temp_2407 = 0;
+    let _temp_2408 = 0;
+    let _temp_2409 = 0;
+    let _temp_2410 = 0;
+    let _temp_2411 = 0;
+    let _temp_2412 = 0;
+    let _temp_2413 = 0;
+    let _temp_2414 = 0;
+    let _temp_2415 = 0;
+    let _temp_2416 = 0;
+    let _temp_2417 = 0;
+    let _temp_2418 = 0;
+    let _temp_2419 = 0;
+    let _temp_2420 = 0;
+    let _temp_2421 = 0;
+    let _temp_2422 = 0;
+    let _temp_2423 = 0;
+    let _temp_2424 = 0;
+    let _temp_2425 = 0;
+    let _temp_2426 = 0;
+    let _temp_2427 = 0;
+    let _temp_2428 = 0;
+    let _temp_2429 = 0;
+    let _temp_2430 = 0;
+    let _temp_2431 = 0;
+    let _temp_2432 = 0;
+    let _temp_2433 = 0;
+    let _temp_2434 = 0;
+    let _temp_2435 = 0;
+    let _temp_2436 = 0;
+    let _temp_2437 = 0;
+    let _temp_2438 = 0;
+    let _temp_2439 = 0;
+    let _temp_2440 = 0;
+    let _temp_2441 = 0;
+    let _temp_2442 = 0;
+    let _temp_2443 = 0;
+    let _temp_2444 = 0;
+    let _temp_2445 = 0;
+    let _temp_2446 = 0;
+    let _temp_2447 = 0;
+    let _temp_2448 = 0;
+    let _temp_2449 = 0;
+    let _temp_2450 = 0;
+    let _temp_2451 = 0;
+    let _temp_2452 = 0;
+    let _temp_2453 = 0;
+    let _temp_2454 = 0;
+    let _temp_2455 = 0;
+    let _temp_2456 = 0;
+    let _temp_2457 = 0;
+    let _temp_2458 = 0;
+    let _temp_2459 = 0;
+    let _temp_2460 = 0;
+    let _temp_2461 = 0;
+    let _temp_2462 = 0;
+    let _temp_2463 = 0;
+    let _temp_2464 = 0;
+    let _temp_2465 = 0;
+    let _temp_2466 = 0;
+    let _temp_2467 = 0;
+    let _temp_2468 = 0;
+    let _temp_2469 = 0;
+    let _temp_2470 = 0;
+    let _temp_2471 = 0;
+    let _temp_2472 = 0;
+    let _temp_2473 = 0;
+    let _temp_2474 = 0;
+    let _temp_2475 = 0;
+    let _temp_2476 = 0;
+    let _temp_2477 = 0;
+    let _temp_2478 = 0;
+    let _temp_2479 = 0;
+    let _temp_2480 = 0;
+    let _temp_2481 = 0;
+    let _temp_2482 = 0;
+    let _temp_2483 = 0;
+    let _temp_2484 = 0;
+    let _temp_2485 = 0;
+    let _temp_2486 = 0;
+    let _temp_2487 = 0;
+    let _temp_2488 = 0;
+    let _temp_2489 = 0;
+    let _temp_2490 = 0;
+    let _temp_2491 = 0;
+    let _temp_2492 = 0;
+    let _temp_2493 = 0;
+    let _temp_2494 = 0;
+    let _temp_2495 = 0;
+    let _temp_2496 = 0;
+    let _temp_2497 = 0;
+    let _temp_2498 = 0;
+    let _temp_2499 = 0;
+    let _temp_2500 = 0;
+    let _temp_2501 = 0;
+    let _temp_2502 = 0;
+    let _temp_2503 = 0;
+    let _temp_2504 = 0;
+    let _temp_2505 = 0;
+    let _temp_2506 = 0;
+    let _temp_2507 = 0;
+    let _temp_2508 = 0;
+    let _temp_2509 = 0;
+    let _temp_2510 = 0;
+    let _temp_2511 = 0;
+    let _temp_2512 = 0;
+    let _temp_2513 = 0;
+    let _temp_2514 = 0;
+    let _temp_2515 = 0;
+    let _temp_2516 = 0;
+    let _temp_2517 = 0;
+    let _temp_2518 = 0;
+    let _temp_2519 = 0;
+    let _temp_2520 = 0;
+    let _temp_2521 = 0;
+    let _temp_2522 = 0;
+    let _temp_2523 = 0;
+    let _temp_2524 = 0;
+    let _temp_2525 = 0;
+    let _temp_2526 = 0;
+    let _temp_2527 = 0;
+    let _temp_2528 = 0;
+    let _temp_2529 = 0;
+    let _temp_2530 = 0;
+    let _temp_2531 = 0;
+    let _temp_2532 = 0;
+    let _temp_2533 = 0;
+    let _temp_2534 = 0;
+    let _temp_2535 = 0;
+    let _temp_2536 = 0;
+    let _temp_2537 = 0;
+    let _temp_2538 = 0;
+    let _temp_2539 = 0;
+    let _temp_2540 = 0;
+    let _temp_2541 = 0;
+    let _temp_2542 = 0;
+    let _temp_2543 = 0;
+    let _temp_2544 = 0;
+    let _temp_2545 = 0;
+    let _temp_2546 = 0;
+    let _temp_2547 = 0;
+    let _temp_2548 = 0;
+    let _temp_2549 = 0;
+    let _temp_2550 = 0;
+    let _temp_2551 = 0;
+    let _temp_2552 = 0;
+    let _temp_2553 = 0;
+    let _temp_2554 = 0;
+    let _temp_2555 = 0;
+    let _temp_2556 = 0;
+    let _temp_2557 = 0;
+    let _temp_2558 = 0;
+    let _temp_2559 = 0;
+    let _temp_2560 = 0;
+    let _temp_2561 = 0;
+    let _temp_2562 = 0;
+    let _temp_2563 = 0;
+    let _temp_2564 = 0;
+    let _temp_2565 = 0;
+    let _temp_2566 = 0;
+    let _temp_2567 = 0;
+    let _temp_2568 = 0;
+    let _temp_2569 = 0;
+    let _temp_2570 = 0;
+    let _temp_2571 = 0;
+    let _temp_2572 = 0;
+    let _temp_2573 = 0;
+    let _temp_2574 = 0;
+    let _temp_2575 = 0;
+    let _temp_2576 = 0;
+    let _temp_2577 = 0;
+    let _temp_2578 = 0;
+    let _temp_2579 = 0;
+    let _temp_2580 = 0;
+    let _temp_2581 = 0;
+    let _temp_2582 = 0;
+    let _temp_2583 = 0;
+    let _temp_2584 = 0;
+    let _temp_2585 = 0;
+    let _temp_2586 = 0;
+    let _temp_2587 = 0;
+    let _temp_2588 = 0;
+    let _temp_2589 = 0;
+    let _temp_2590 = 0;
+    let _temp_2591 = 0;
+    let _temp_2592 = 0;
+    let _temp_2593 = 0;
+}
diff --git a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr
index 450984aacc7..a751ba79347 100644
--- a/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr
+++ b/src/test/ui/specialization/min_specialization/repeated_projection_type.stderr
@@ -1,8 +1,8 @@
-error: cannot specialize on `Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[54ea]::Id::This) }, Ty((I,))), [])`
-  --> $DIR/repeated_projection_type.rs:19:1
+error: cannot specialize on associated type `<V as Id>::This == (I,)`
+  --> $DIR/repeated_projection_type.rs:19:15
    |
 LL | impl<I, V: Id<This = (I,)>> X for V {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr
index b1ab58551e6..ba9d6bbe300 100644
--- a/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr
+++ b/src/test/ui/specialization/min_specialization/spec-marker-supertraits.stderr
@@ -1,8 +1,8 @@
 error: cannot specialize on trait `HasMethod`
-  --> $DIR/spec-marker-supertraits.rs:22:1
+  --> $DIR/spec-marker-supertraits.rs:22:9
    |
 LL | impl<T: Marker> Spec for T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr b/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr
index 1f2ff99d415..e935786624b 100644
--- a/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr
+++ b/src/test/ui/specialization/min_specialization/specialization_super_trait.stderr
@@ -1,8 +1,8 @@
 error: cannot specialize on trait `Default`
-  --> $DIR/specialization_super_trait.rs:13:1
+  --> $DIR/specialization_super_trait.rs:13:9
    |
 LL | impl<T: Default> SpecMarker for T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/min_specialization/specialization_trait.stderr b/src/test/ui/specialization/min_specialization/specialization_trait.stderr
index ecb07ba908e..bc87ae0f8b8 100644
--- a/src/test/ui/specialization/min_specialization/specialization_trait.stderr
+++ b/src/test/ui/specialization/min_specialization/specialization_trait.stderr
@@ -11,10 +11,10 @@ LL | impl<T> SpecMarker for (T, T) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: cannot specialize on trait `Clone`
-  --> $DIR/specialization_trait.rs:21:1
+  --> $DIR/specialization_trait.rs:21:9
    |
 LL | impl<T: Clone> SpecMarker for [T] {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr b/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr
index 92daddbd800..7b79c7eb4ad 100644
--- a/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr
+++ b/src/test/ui/specialization/min_specialization/specialize_on_trait.stderr
@@ -1,8 +1,8 @@
 error: cannot specialize on trait `SpecMarker`
-  --> $DIR/specialize_on_trait.rs:15:1
+  --> $DIR/specialize_on_trait.rs:15:9
    |
 LL | impl<T: SpecMarker> X for T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/suggest-on-bare-closure-call.rs b/src/test/ui/suggestions/suggest-on-bare-closure-call.rs
index 355708c08ec..496c305bc2a 100644
--- a/src/test/ui/suggestions/suggest-on-bare-closure-call.rs
+++ b/src/test/ui/suggestions/suggest-on-bare-closure-call.rs
@@ -1,4 +1,11 @@
+// edition:2021
+
+#![feature(async_closure)]
+
 fn main() {
     let _ = ||{}();
     //~^ ERROR expected function, found `()`
+
+    let _ = async ||{}();
+    //~^ ERROR expected function, found `()`
 }
diff --git a/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr b/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr
index 81f2e498fe5..e65a6eb4939 100644
--- a/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr
+++ b/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr
@@ -1,5 +1,5 @@
 error[E0618]: expected function, found `()`
-  --> $DIR/suggest-on-bare-closure-call.rs:2:15
+  --> $DIR/suggest-on-bare-closure-call.rs:6:15
    |
 LL |     let _ = ||{}();
    |               ^^--
@@ -11,6 +11,19 @@ help: if you meant to create this closure and immediately call it, surround the
 LL |     let _ = (||{})();
    |             +    +
 
-error: aborting due to previous error
+error[E0618]: expected function, found `()`
+  --> $DIR/suggest-on-bare-closure-call.rs:9:21
+   |
+LL |     let _ = async ||{}();
+   |                     ^^--
+   |                     |
+   |                     call expression requires function
+   |
+help: if you meant to create this closure and immediately call it, surround the closure with parentheses
+   |
+LL |     let _ = (async ||{})();
+   |             +          +
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0618`.
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index bdf26d040ad..be81ff881f3 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -269,6 +269,10 @@ pub struct Config {
     /// Flags to pass to the compiler when building for the target
     pub target_rustcflags: Option<String>,
 
+    /// Whether tests should be optimized by default. Individual test-suites and test files may
+    /// override this setting.
+    pub optimize_tests: bool,
+
     /// What panic strategy the target is built with.  Unwind supports Abort, but
     /// not vice versa.
     pub target_panic: PanicStrategy,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 31e979a574b..7cf4a88c470 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -244,6 +244,7 @@ impl TestProps {
 
         // copy over select properties to the aux build:
         props.incremental_dir = self.incremental_dir.clone();
+        props.ignore_pass = true;
         props.load_from(testfile, cfg, config);
 
         props
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 4e8e5afd4bb..a8a151ca114 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -102,6 +102,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         )
         .optmulti("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS")
         .optmulti("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS")
+        .optflag("", "optimize-tests", "run tests with optimizations enabled")
         .optopt("", "target-panic", "what panic strategy the target supports", "unwind | abort")
         .optflag("", "verbose", "run tests verbosely, showing all output")
         .optflag(
@@ -253,6 +254,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         runtool: matches.opt_str("runtool"),
         host_rustcflags: Some(matches.opt_strs("host-rustcflags").join(" ")),
         target_rustcflags: Some(matches.opt_strs("target-rustcflags").join(" ")),
+        optimize_tests: matches.opt_present("optimize-tests"),
         target_panic: match matches.opt_str("target-panic").as_deref() {
             Some("unwind") | None => PanicStrategy::Unwind,
             Some("abort") => PanicStrategy::Abort,
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 160b9785d97..dd9e2a6687e 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1862,6 +1862,31 @@ impl<'test> TestCx<'test> {
             }
         }
 
+        if self.config.optimize_tests && !is_rustdoc {
+            match self.config.mode {
+                Ui => {
+                    // If optimize-tests is true we still only want to optimize tests that actually get
+                    // executed and that don't specify their own optimization levels.
+                    // Note: aux libs don't have a pass-mode, so they won't get optimized
+                    // unless compile-flags are set in the aux file.
+                    if self.config.optimize_tests
+                        && self.props.pass_mode(&self.config) == Some(PassMode::Run)
+                        && !self
+                            .props
+                            .compile_flags
+                            .iter()
+                            .any(|arg| arg == "-O" || arg.contains("opt-level"))
+                    {
+                        rustc.arg("-O");
+                    }
+                }
+                DebugInfo => { /* debuginfo tests must be unoptimized */ }
+                _ => {
+                    rustc.arg("-O");
+                }
+            }
+        }
+
         match self.config.mode {
             Incremental => {
                 // If we are extracting and matching errors in the new
@@ -3245,7 +3270,8 @@ impl<'test> TestCx<'test> {
 
             if !self.props.error_patterns.is_empty() {
                 // "// error-pattern" comments
-                self.check_error_patterns(&proc_res.stderr, &proc_res, pm);
+                let output_to_check = self.get_output(&proc_res);
+                self.check_error_patterns(&output_to_check, &proc_res, pm);
             }
         }
 
@@ -3266,7 +3292,8 @@ impl<'test> TestCx<'test> {
 
             if check_patterns {
                 // "// error-pattern" comments
-                self.check_error_patterns(&proc_res.stderr, &proc_res, pm);
+                let output_to_check = self.get_output(&proc_res);
+                self.check_error_patterns(&output_to_check, &proc_res, pm);
             }
 
             if check_annotations {
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index 503df537047..9615c4db6b4 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -96,9 +96,25 @@ mod os_impl {
 
     #[cfg(unix)]
     pub fn check(path: &Path, bad: &mut bool) {
+        const ALLOWED: &[&str] = &["configure"];
+
         crate::walk_no_read(
             path,
-            &mut |path| crate::filter_dirs(path) || path.ends_with("src/etc"),
+            &mut |path| {
+                crate::filter_dirs(path)
+                    || path.ends_with("src/etc")
+                    // This is a list of directories that we almost certainly
+                    // don't need to walk. A future PR will likely want to
+                    // remove these in favor of crate::walk_no_read using git
+                    // ls-files to discover the paths we should check, which
+                    // would naturally ignore all of these directories. It's
+                    // also likely faster than walking the directory tree
+                    // directly (since git is just reading from a couple files
+                    // to produce the results).
+                    || path.ends_with("target")
+                    || path.ends_with("build")
+                    || path.ends_with(".git")
+            },
             &mut |entry| {
                 let file = entry.path();
                 let filename = file.file_name().unwrap().to_string_lossy();
@@ -110,6 +126,11 @@ mod os_impl {
                 if t!(is_executable(&file), file) {
                     let rel_path = file.strip_prefix(path).unwrap();
                     let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/");
+
+                    if ALLOWED.contains(&git_friendly_path.as_str()) {
+                        return;
+                    }
+
                     let output = Command::new("git")
                         .arg("ls-files")
                         .arg(&git_friendly_path)
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index d555f7c8e34..aa8d8b4f64d 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -78,13 +78,8 @@ fn main() {
         check!(unit_tests, &compiler_path);
         check!(unit_tests, &library_path);
 
-        if bins::check_filesystem_support(
-            &[&src_path, &compiler_path, &library_path],
-            &output_directory,
-        ) {
-            check!(bins, &src_path);
-            check!(bins, &compiler_path);
-            check!(bins, &library_path);
+        if bins::check_filesystem_support(&[&root_path], &output_directory) {
+            check!(bins, &root_path);
         }
 
         check!(style, &src_path);