about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs14
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs8
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/type_of.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs43
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs49
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs79
-rw-r--r--compiler/rustc_const_eval/messages.ftl6
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs3
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs82
-rw-r--r--compiler/rustc_const_eval/src/const_eval/mod.rs39
-rw-r--r--compiler/rustc_const_eval/src/errors.rs20
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs10
-rw-r--r--compiler/rustc_const_eval/src/lib.rs4
-rw-r--r--compiler/rustc_const_eval/src/util/check_validity_requirement.rs8
-rw-r--r--compiler/rustc_data_structures/src/sync.rs11
-rw-r--r--compiler/rustc_feature/src/accepted.rs4
-rw-r--r--compiler/rustc_feature/src/active.rs12
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs4
-rw-r--r--compiler/rustc_feature/src/removed.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs111
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs12
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/builtin.rs12
-rw-r--r--compiler/rustc_lint/src/cast_ref_to_mut.rs72
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs5
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs38
-rw-r--r--compiler/rustc_metadata/src/creader.rs20
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs2
-rw-r--r--compiler/rustc_middle/src/middle/limits.rs11
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs7
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs47
-rw-r--r--compiler/rustc_middle/src/query/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/context.rs10
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs11
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs6
-rw-r--r--compiler/rustc_middle/src/ty/util.rs22
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/lib.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs18
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs311
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs33
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs124
-rw-r--r--compiler/rustc_mir_transform/src/const_goto.rs2
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs38
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs5
-rw-r--r--compiler/rustc_mir_transform/src/required_consts.rs4
-rw-r--r--compiler/rustc_mir_transform/src/separate_const_switch.rs2
-rw-r--r--compiler/rustc_mir_transform/src/sroa.rs50
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs76
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs1183
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/default.rs644
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs673
-rw-r--r--compiler/rustc_session/messages.ftl4
-rw-r--r--compiler/rustc_session/src/config.rs15
-rw-r--r--compiler/rustc_session/src/errors.rs8
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs1
-rw-r--r--compiler/rustc_session/src/session.rs9
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs1
-rw-r--r--compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs110
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs60
-rw-r--r--library/alloc/src/alloc.rs2
-rw-r--r--library/alloc/src/string.rs2
-rw-r--r--library/core/src/array/mod.rs23
-rw-r--r--library/core/src/convert/mod.rs3
-rw-r--r--library/core/src/ffi/c_str.rs6
-rw-r--r--library/core/src/ffi/mod.rs2
-rw-r--r--library/core/src/hash/mod.rs2
-rw-r--r--library/core/src/intrinsics.rs33
-rw-r--r--library/core/src/marker.rs3
-rw-r--r--library/core/src/mem/mod.rs3
-rw-r--r--library/core/src/num/nonzero.rs28
-rw-r--r--library/core/src/ptr/const_ptr.rs15
-rw-r--r--library/core/src/ptr/mod.rs5
-rw-r--r--library/core/src/ptr/mut_ptr.rs26
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--library/core/src/tuple.rs4
-rw-r--r--library/core/tests/clone.rs2
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/core/tests/mem.rs11
-rw-r--r--library/portable-simd/Cargo.toml2
-rw-r--r--library/std/Cargo.toml12
-rw-r--r--library/std/src/os/windows/io/handle.rs6
-rw-r--r--library/std/src/os/windows/io/socket.rs6
-rw-r--r--library/std/src/sys/wasi/fd.rs6
-rw-r--r--library/std/src/sys/wasi/fs.rs4
-rw-r--r--library/std/tests/common/mod.rs8
-rw-r--r--src/bootstrap/bootstrap.py21
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/compile.rs2
-rw-r--r--src/bootstrap/config.rs13
-rw-r--r--src/bootstrap/dist.rs3
-rw-r--r--src/bootstrap/download.rs5
-rw-r--r--src/bootstrap/flags.rs4
-rw-r--r--src/bootstrap/format.rs4
-rw-r--r--src/bootstrap/lib.rs19
-rw-r--r--src/bootstrap/metadata.rs3
-rw-r--r--src/bootstrap/render_tests.rs2
-rw-r--r--src/bootstrap/sanity.rs2
-rw-r--r--src/bootstrap/setup.rs4
-rw-r--r--src/bootstrap/test.rs25
-rw-r--r--src/bootstrap/tool.rs2
-rw-r--r--src/bootstrap/toolstate.rs8
-rw-r--r--src/bootstrap/util.rs25
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile2
-rw-r--r--src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml1
-rw-r--r--src/ci/stage-build.py2
-rw-r--r--src/doc/unstable-book/src/language-features/const-eval-limit.md7
-rw-r--r--src/etc/test-float-parse/Cargo.toml1
-rw-r--r--src/librustdoc/clean/mod.rs9
-rw-r--r--src/librustdoc/clean/types.rs44
-rw-r--r--src/librustdoc/html/format.rs39
-rw-r--r--src/librustdoc/html/markdown.rs15
-rw-r--r--src/librustdoc/html/render/mod.rs7
-rw-r--r--src/librustdoc/html/render/print_item.rs29
-rw-r--r--src/librustdoc/html/render/search_index.rs23
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css12
-rw-r--r--src/librustdoc/html/static/js/main.js148
-rw-r--r--src/librustdoc/json/conversions.rs5
-rw-r--r--src/librustdoc/visit_ast.rs57
-rw-r--r--src/stage0.json806
-rw-r--r--src/tools/build_helper/src/lib.rs1
-rw-r--r--src/tools/build_helper/src/util.rs41
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ref_to_mut.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs1
-rw-r--r--src/tools/clippy/tests/ui/cast_ref_to_mut.rs31
-rw-r--r--src/tools/clippy/tests/ui/cast_ref_to_mut.stderr22
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed2
-rw-r--r--src/tools/clippy/tests/ui/rename.rs2
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr106
-rw-r--r--src/tools/compiletest/src/runtest.rs47
-rw-r--r--src/tools/miri/tests/fail/modifying_constants.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs4
-rwxr-xr-xsrc/tools/rust-installer/combine-installers.sh4
-rwxr-xr-xsrc/tools/rust-installer/gen-installer.sh4
-rwxr-xr-xsrc/tools/rust-installer/make-tarballs.sh4
-rw-r--r--src/tools/rustdoc-gui-test/Cargo.toml1
-rw-r--r--src/tools/rustdoc-gui-test/src/main.rs28
-rw-r--r--src/tools/tidy/src/main.rs6
-rw-r--r--tests/assembly/asm/mips-types.rs12
-rw-r--r--tests/codegen/array-map.rs11
-rw-r--r--tests/codegen/autovectorize-f32x4.rs7
-rw-r--r--tests/codegen/const_scalar_pair.rs2
-rw-r--r--tests/codegen/intrinsics/transmute.rs75
-rw-r--r--tests/codegen/issues/issue-105386-ub-in-debuginfo.rs7
-rw-r--r--tests/incremental/hashes/match_expressions.rs3
-rw-r--r--tests/incremental/issue-101518.rs13
-rw-r--r--tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff96
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir104
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff96
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir104
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir10
-rw-r--r--tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir20
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir16
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir119
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir15
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir15
-rw-r--r--tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff78
-rw-r--r--tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff21
-rw-r--r--tests/rustdoc-gui/codeblock-tooltip.goml2
-rw-r--r--tests/rustdoc-gui/notable-trait.goml19
-rw-r--r--tests/rustdoc-gui/theme-in-history.goml6
-rw-r--r--tests/rustdoc/intra-doc/issue-108459.rs37
-rw-r--r--tests/rustdoc/intra-doc/prim-precedence.rs2
-rw-r--r--tests/rustdoc/reexport-doc-hidden-inside-private.rs16
-rw-r--r--tests/ui/chalkify/bugs/async.stderr13
-rw-r--r--tests/ui/const-generics/issues/issue-100313.rs1
-rw-r--r--tests/ui/const-generics/issues/issue-100313.stderr12
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.rs4
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.stderr23
-rw-r--r--tests/ui/consts/const-eval/issue-52475.rs3
-rw-r--r--tests/ui/consts/const-eval/issue-52475.stderr22
-rw-r--r--tests/ui/consts/const-eval/issue-70723.rs2
-rw-r--r--tests/ui/consts/const-eval/issue-70723.stderr14
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs2
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr19
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.rs5
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr27
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-recursion.rs3
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr24
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr19
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.rs12
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.stderr24
-rw-r--r--tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr62
-rw-r--r--tests/ui/consts/const_limit/const_eval_limit_not_reached.rs20
-rw-r--r--tests/ui/consts/const_limit/const_eval_limit_overflow.rs15
-rw-r--r--tests/ui/consts/const_limit/const_eval_limit_overflow.stderr10
-rw-r--r--tests/ui/consts/const_limit/const_eval_limit_reached.rs16
-rw-r--r--tests/ui/consts/const_limit/const_eval_limit_reached.stderr12
-rw-r--r--tests/ui/consts/const_limit/feature-gate-const_eval_limit.rs14
-rw-r--r--tests/ui/consts/const_limit/feature-gate-const_eval_limit.stderr12
-rw-r--r--tests/ui/dyn-star/param-env-infer.next.stderr35
-rw-r--r--tests/ui/impl-trait/auto-trait-leak.stderr70
-rw-r--r--tests/ui/impl-trait/multiple-defining-usages-in-body.rs2
-rw-r--r--tests/ui/impl-trait/multiple-defining-usages-in-body.stderr10
-rw-r--r--tests/ui/linkage-attr/incompatible-flavor.rs6
-rw-r--r--tests/ui/linkage-attr/incompatible-flavor.stderr6
-rw-r--r--tests/ui/linkage-attr/issue-10755.rs2
-rw-r--r--tests/ui/linkage-attr/unstable-flavor.bpf.stderr2
-rw-r--r--tests/ui/linkage-attr/unstable-flavor.ptx.stderr2
-rw-r--r--tests/ui/linkage-attr/unstable-flavor.rs10
-rw-r--r--tests/ui/lint/cast_ref_to_mut.rs50
-rw-r--r--tests/ui/lint/cast_ref_to_mut.stderr64
-rw-r--r--tests/ui/loops/dont-suggest-break-thru-item.rs55
-rw-r--r--tests/ui/loops/dont-suggest-break-thru-item.stderr55
-rw-r--r--tests/ui/match/issue-70972-dyn-trait.rs2
-rw-r--r--tests/ui/match/issue-70972-dyn-trait.stderr2
-rw-r--r--tests/ui/offset-of/offset-of-unsized.rs15
-rw-r--r--tests/ui/pattern/issue-72565.rs2
-rw-r--r--tests/ui/pattern/issue-72565.stderr2
-rw-r--r--tests/ui/suggestions/issue-88696.rs14
-rw-r--r--tests/ui/suggestions/issue-88696.stderr11
-rw-r--r--tests/ui/track-diagnostics/track6.stderr2
-rw-r--r--tests/ui/traits/new-solver/dont-remap-tait-substs.rs19
-rw-r--r--tests/ui/traits/new-solver/structural-resolve-field.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr11
244 files changed, 4230 insertions, 3765 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e49fbde363f..e7aa317ad75 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4289,6 +4289,7 @@ dependencies = [
 name = "rustdoc-gui-test"
 version = "0.1.0"
 dependencies = [
+ "build_helper",
  "compiletest",
  "getopts",
  "walkdir",
diff --git a/Cargo.toml b/Cargo.toml
index 8eb378afe42..6e84df5c693 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,4 +1,5 @@
 [workspace]
+resolver = "1"
 members = [
   "compiler/rustc",
   "library/std",
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 33f07c1d8fc..13e346b86bc 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -279,8 +279,18 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         // HACK This bubble is required for this tests to pass:
         // nested-return-type2-tait2.rs
         // nested-return-type2-tait3.rs
-        let infcx =
-            self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build();
+        // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
+        // and prepopulate this `InferCtxt` with known opaque values, rather than
+        // using the `Bind` anchor here. For now it's fine.
+        let infcx = self
+            .tcx
+            .infer_ctxt()
+            .with_opaque_type_inference(if self.tcx.trait_solver_next() {
+                DefiningAnchor::Bind(def_id)
+            } else {
+                DefiningAnchor::Bubble
+            })
+            .build();
         let ocx = ObligationCtxt::new(&infcx);
         // Require the hidden type to be well-formed with only the generics of the opaque type.
         // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 3b896f6540c..908ff3da5ca 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -188,9 +188,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
 
     // FIXME(-Ztrait-solver=next): A bit dubious that we're only registering
     // predefined opaques in the typeck root.
-    // FIXME(-Ztrait-solver=next): This is also totally wrong for TAITs, since
-    // the HIR typeck map defining usages back to their definition params,
-    // they won't actually match up with the usages in this body...
     if infcx.tcx.trait_solver_next() && !infcx.tcx.is_typeck_child(body.source.def_id()) {
         checker.register_predefined_opaques_in_new_solver();
     }
@@ -1042,10 +1039,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             .typeck(self.body.source.def_id().expect_local())
             .concrete_opaque_types
             .iter()
-            .map(|(&def_id, &hidden_ty)| {
-                let substs = ty::InternalSubsts::identity_for_item(self.infcx.tcx, def_id);
-                (ty::OpaqueTypeKey { def_id, substs }, hidden_ty)
-            })
+            .map(|(k, v)| (*k, *v))
             .collect();
 
         let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| {
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 869344ce92d..f9ea0f00456 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -758,7 +758,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         assert_eq!(place.llextra.is_some(), place.layout.is_unsized());
 
         if place.layout.is_zst() {
-            return OperandRef::new_zst(self, place.layout);
+            return OperandRef::zero_sized(place.layout);
         }
 
         fn scalar_load_metadata<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, load: RValue<'gcc>, scalar: &abi::Scalar) {
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index 5df8c1a209d..30a3fe67b85 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -159,8 +159,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
     fn is_gcc_immediate(&self) -> bool {
         match self.abi {
             Abi::Scalar(_) | Abi::Vector { .. } => true,
-            Abi::ScalarPair(..) => false,
-            Abi::Uninhabited | Abi::Aggregate { .. } => self.is_zst(),
+            Abi::ScalarPair(..) | Abi::Uninhabited | Abi::Aggregate { .. } => false,
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 4d0bcd53d15..5968e70b1cc 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -486,7 +486,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         assert_eq!(place.llextra.is_some(), place.layout.is_unsized());
 
         if place.layout.is_zst() {
-            return OperandRef::new_zst(self, place.layout);
+            return OperandRef::zero_sized(place.layout);
         }
 
         #[instrument(level = "trace", skip(bx))]
diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs
index e264ce78f0d..a493c9c0548 100644
--- a/compiler/rustc_codegen_llvm/src/type_of.rs
+++ b/compiler/rustc_codegen_llvm/src/type_of.rs
@@ -198,8 +198,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
     fn is_llvm_immediate(&self) -> bool {
         match self.abi {
             Abi::Scalar(_) | Abi::Vector { .. } => true,
-            Abi::ScalarPair(..) => false,
-            Abi::Uninhabited | Abi::Aggregate { .. } => self.is_zst(),
+            Abi::ScalarPair(..) | Abi::Uninhabited | Abi::Aggregate { .. } => false,
         }
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index bdbd10f8260..f8bb9bf2bb5 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -23,7 +23,7 @@ use rustc_session::utils::NativeLibKind;
 use rustc_session::{filesearch, Session};
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
-use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy};
+use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld, PanicStrategy};
 use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
 
 use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
@@ -1302,44 +1302,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
                 let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
                     sess.emit_fatal(errors::LinkerFileStem);
                 });
-
-                // Remove any version postfix.
-                let stem = stem
-                    .rsplit_once('-')
-                    .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs))
-                    .unwrap_or(stem);
-
-                // GCC/Clang can have an optional target prefix.
-                let flavor = if stem == "emcc" {
-                    LinkerFlavor::EmCc
-                } else if stem == "gcc"
-                    || stem.ends_with("-gcc")
-                    || stem == "g++"
-                    || stem.ends_with("-g++")
-                    || stem == "clang"
-                    || stem.ends_with("-clang")
-                    || stem == "clang++"
-                    || stem.ends_with("-clang++")
-                {
-                    LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target)
-                } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {
-                    LinkerFlavor::WasmLld(Cc::No)
-                } else if stem == "ld" || stem.ends_with("-ld") {
-                    LinkerFlavor::from_cli(LinkerFlavorCli::Ld, &sess.target)
-                } else if stem == "ld.lld" {
-                    LinkerFlavor::Gnu(Cc::No, Lld::Yes)
-                } else if stem == "link" {
-                    LinkerFlavor::Msvc(Lld::No)
-                } else if stem == "lld-link" {
-                    LinkerFlavor::Msvc(Lld::Yes)
-                } else if stem == "lld" || stem == "rust-lld" {
-                    let lld_flavor = sess.target.linker_flavor.lld_flavor();
-                    LinkerFlavor::from_cli(LinkerFlavorCli::Lld(lld_flavor), &sess.target)
-                } else {
-                    // fall back to the value in the target spec
-                    sess.target.linker_flavor
-                };
-
+                let flavor = sess.target.linker_flavor.with_linker_hints(stem);
                 Some((linker, flavor))
             }
             (None, None) => None,
@@ -1349,7 +1312,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
     // linker and linker flavor specified via command line have precedence over what the target
     // specification specifies
     let linker_flavor =
-        sess.opts.cg.linker_flavor.map(|flavor| LinkerFlavor::from_cli(flavor, &sess.target));
+        sess.opts.cg.linker_flavor.map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor));
     if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
         return ret;
     }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 15c7847155d..242d209b684 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -295,7 +295,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let (base, info) = match bx.load_operand(src).val {
                 OperandValue::Pair(base, info) => unsize_ptr(bx, base, src_ty, dst_ty, Some(info)),
                 OperandValue::Immediate(base) => unsize_ptr(bx, base, src_ty, dst_ty, None),
-                OperandValue::Ref(..) => bug!(),
+                OperandValue::Ref(..) | OperandValue::ZeroSized => bug!(),
             };
             OperandValue::Pair(base, info).store(bx, dst);
         }
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 3f0b64b1103..e0cb26d3ba8 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1,5 +1,5 @@
 use super::operand::OperandRef;
-use super::operand::OperandValue::{Immediate, Pair, Ref};
+use super::operand::OperandValue::{Immediate, Pair, Ref, ZeroSized};
 use super::place::PlaceRef;
 use super::{CachedLlbb, FunctionCx, LocalRef};
 
@@ -427,6 +427,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         assert_eq!(align, op.layout.align.abi, "return place is unaligned!");
                         llval
                     }
+                    ZeroSized => bug!("ZST return value shouldn't be in PassMode::Cast"),
                 };
                 let ty = bx.cast_backend_type(cast_ty);
                 let addr = bx.pointercast(llslot, bx.type_ptr_to(ty));
@@ -1386,6 +1387,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     (llval, align, true)
                 }
             }
+            ZeroSized => match arg.mode {
+                PassMode::Indirect { .. } => {
+                    // Though `extern "Rust"` doesn't pass ZSTs, some ABIs pass
+                    // a pointer for `repr(C)` structs even when empty, so get
+                    // one from an `alloca` (which can be left uninitialized).
+                    let scratch = PlaceRef::alloca(bx, arg.layout);
+                    (scratch.llval, scratch.align, true)
+                }
+                _ => bug!("ZST {op:?} wasn't ignored, but was passed with abi {arg:?}"),
+            },
         };
 
         if by_ref && !arg.is_indirect() {
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index bba2800fb05..4f79c6a3d82 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -352,6 +352,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         bx.set_var_name(a, &(name.clone() + ".0"));
                         bx.set_var_name(b, &(name.clone() + ".1"));
                     }
+                    OperandValue::ZeroSized => {
+                        // These never have a value to talk about
+                    }
                 },
                 LocalRef::PendingOperand => {}
             }
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 00414003202..2809ec2deb5 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -129,16 +129,13 @@ enum LocalRef<'tcx, V> {
     PendingOperand,
 }
 
-impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
-    fn new_operand<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
-        bx: &mut Bx,
-        layout: TyAndLayout<'tcx>,
-    ) -> LocalRef<'tcx, V> {
+impl<'tcx, V: CodegenObject> LocalRef<'tcx, V> {
+    fn new_operand(layout: TyAndLayout<'tcx>) -> LocalRef<'tcx, V> {
         if layout.is_zst() {
             // Zero-size temporaries aren't always initialized, which
             // doesn't matter because they don't contain data, but
             // we need something in the operand.
-            LocalRef::Operand(OperandRef::new_zst(bx, layout))
+            LocalRef::Operand(OperandRef::zero_sized(layout))
         } else {
             LocalRef::PendingOperand
         }
@@ -249,7 +246,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 }
             } else {
                 debug!("alloc: {:?} -> operand", local);
-                LocalRef::new_operand(&mut start_bx, layout)
+                LocalRef::new_operand(layout)
             }
         };
 
@@ -355,7 +352,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 let local = |op| LocalRef::Operand(op);
                 match arg.mode {
                     PassMode::Ignore => {
-                        return local(OperandRef::new_zst(bx, arg.layout));
+                        return local(OperandRef::zero_sized(arg.layout));
                     }
                     PassMode::Direct(_) => {
                         let llarg = bx.get_param(llarg_idx);
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 4000c9540ce..31c293d7c29 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -45,6 +45,14 @@ pub enum OperandValue<V> {
     /// as returned by [`LayoutTypeMethods::scalar_pair_element_backend_type`]
     /// with `immediate: true`.
     Pair(V, V),
+    /// A value taking no bytes, and which therefore needs no LLVM value at all.
+    ///
+    /// If you ever need a `V` to pass to something, get a fresh poison value
+    /// from [`ConstMethods::const_poison`].
+    ///
+    /// An `OperandValue` *must* be this variant for any type for which
+    /// `is_zst` on its `Layout` returns `true`.
+    ZeroSized,
 }
 
 /// An `OperandRef` is an "SSA" reference to a Rust value, along with
@@ -71,15 +79,9 @@ impl<V: CodegenObject> fmt::Debug for OperandRef<'_, V> {
 }
 
 impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
-    pub fn new_zst<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
-        bx: &mut Bx,
-        layout: TyAndLayout<'tcx>,
-    ) -> OperandRef<'tcx, V> {
+    pub fn zero_sized(layout: TyAndLayout<'tcx>) -> OperandRef<'tcx, V> {
         assert!(layout.is_zst());
-        OperandRef {
-            val: OperandValue::Immediate(bx.const_poison(bx.immediate_backend_type(layout))),
-            layout,
-        }
+        OperandRef { val: OperandValue::ZeroSized, layout }
     }
 
     pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
@@ -97,7 +99,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                 let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout));
                 OperandValue::Immediate(llval)
             }
-            ConstValue::ZeroSized => return OperandRef::new_zst(bx, layout),
+            ConstValue::ZeroSized => return OperandRef::zero_sized(layout),
             ConstValue::Slice { data, start, end } => {
                 let Abi::ScalarPair(a_scalar, _) = layout.abi else {
                     bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
@@ -178,7 +180,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                 );
                 OperandRef { val: OperandValue::Pair(a_val, b_val), layout }
             }
-            _ if layout.is_zst() => OperandRef::new_zst(bx, layout),
+            _ if layout.is_zst() => OperandRef::zero_sized(layout),
             _ => {
                 // Neither a scalar nor scalar pair. Load from a place
                 let init = bx.const_data_from_alloc(alloc);
@@ -216,6 +218,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             OperandValue::Immediate(llptr) => (llptr, None),
             OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)),
             OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self),
+            OperandValue::ZeroSized => bug!("Deref of ZST operand {:?}", self),
         };
         let layout = cx.layout_of(projected_ty);
         PlaceRef { llval: llptr, llextra, layout, align: layout.align.abi }
@@ -273,9 +276,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
 
         let mut val = match (self.val, self.layout.abi) {
             // If the field is ZST, it has no data.
-            _ if field.is_zst() => {
-                return OperandRef::new_zst(bx, field);
-            }
+            _ if field.is_zst() => OperandValue::ZeroSized,
 
             // Newtype of a scalar, scalar pair or vector.
             (OperandValue::Immediate(_) | OperandValue::Pair(..), _)
@@ -306,6 +307,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         };
 
         match (&mut val, field.abi) {
+            (OperandValue::ZeroSized, _) => {}
             (
                 OperandValue::Immediate(llval),
                 Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. },
@@ -359,8 +361,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
 impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
     /// Returns an `OperandValue` that's generally UB to use in any way.
     ///
-    /// Depending on the `layout`, returns an `Immediate` or `Pair` containing
-    /// poison value(s), or a `Ref` containing a poison pointer.
+    /// Depending on the `layout`, returns `ZeroSized` for ZSTs, an `Immediate` or
+    /// `Pair` containing poison value(s), or a `Ref` containing a poison pointer.
     ///
     /// Supports sized types only.
     pub fn poison<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
@@ -368,7 +370,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
         layout: TyAndLayout<'tcx>,
     ) -> OperandValue<V> {
         assert!(layout.is_sized());
-        if bx.cx().is_backend_immediate(layout) {
+        if layout.is_zst() {
+            OperandValue::ZeroSized
+        } else if bx.cx().is_backend_immediate(layout) {
             let ibty = bx.cx().immediate_backend_type(layout);
             OperandValue::Immediate(bx.const_poison(ibty))
         } else if bx.cx().is_backend_scalar_pair(layout) {
@@ -421,12 +425,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
         flags: MemFlags,
     ) {
         debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
-        // Avoid generating stores of zero-sized values, because the only way to have a zero-sized
-        // value is through `undef`, and store itself is useless.
-        if dest.layout.is_zst() {
-            return;
-        }
         match self {
+            OperandValue::ZeroSized => {
+                // Avoid generating stores of zero-sized values, because the only way to have a zero-sized
+                // value is through `undef`/`poison`, and the store itself is useless.
+            }
             OperandValue::Ref(r, None, source_align) => {
                 if flags.contains(MemFlags::NONTEMPORAL) {
                     // HACK(nox): This is inefficient but there is no nontemporal memcpy.
@@ -527,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             // checks in `codegen_consume` and `extract_field`.
                             let elem = o.layout.field(bx.cx(), 0);
                             if elem.is_zst() {
-                                o = OperandRef::new_zst(bx, elem);
+                                o = OperandRef::zero_sized(elem);
                             } else {
                                 return None;
                             }
@@ -561,7 +564,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // ZSTs don't require any actual memory access.
         if layout.is_zst() {
-            return OperandRef::new_zst(bx, layout);
+            return OperandRef::zero_sized(layout);
         }
 
         if let Some(o) = self.maybe_codegen_consume_direct(bx, place_ref) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 6e7065713b8..5241a5aee00 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -70,6 +70,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     OperandValue::Ref(_, Some(_), _) => {
                         bug!("unsized coercion on an unsized rvalue");
                     }
+                    OperandValue::ZeroSized => {
+                        bug!("unsized coercion on a ZST rvalue");
+                    }
                 }
             }
 
@@ -165,11 +168,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
 
         match src.val {
-            OperandValue::Ref(..) => {
+            OperandValue::Ref(..) | OperandValue::ZeroSized => {
                 span_bug!(
                     self.mir.span,
                     "Operand path should have handled transmute \
-                    from `Ref` {src:?} to place {dst:?}"
+                    from {src:?} to place {dst:?}"
                 );
             }
             OperandValue::Immediate(..) | OperandValue::Pair(..) => {
@@ -220,17 +223,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let fake_place = PlaceRef::new_sized_aligned(cast_ptr, cast, align);
                 Some(bx.load_operand(fake_place).val)
             }
+            OperandValue::ZeroSized => {
+                let OperandValueKind::ZeroSized = operand_kind else {
+                    bug!("Found {operand_kind:?} for operand {operand:?}");
+                };
+                if let OperandValueKind::ZeroSized = cast_kind {
+                    Some(OperandValue::ZeroSized)
+                } else {
+                    None
+                }
+            }
             OperandValue::Immediate(imm) => {
                 let OperandValueKind::Immediate(in_scalar) = operand_kind else {
                     bug!("Found {operand_kind:?} for operand {operand:?}");
                 };
-                if let OperandValueKind::Immediate(out_scalar) = cast_kind {
-                    match (in_scalar, out_scalar) {
-                        (ScalarOrZst::Zst, ScalarOrZst::Zst) => {
-                            Some(OperandRef::new_zst(bx, cast).val)
-                        }
-                        (ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar))
-                            if in_scalar.size(self.cx) == out_scalar.size(self.cx) =>
+                if let OperandValueKind::Immediate(out_scalar) = cast_kind
+                    && in_scalar.size(self.cx) == out_scalar.size(self.cx)
                         {
                             let operand_bty = bx.backend_type(operand.layout);
                             let cast_bty = bx.backend_type(cast);
@@ -242,9 +250,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                 out_scalar,
                                 cast_bty,
                             )))
-                        }
-                        _ => None,
-                    }
                 } else {
                     None
                 }
@@ -457,6 +462,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             OperandValue::Ref(..) => {
                                 bug!("by-ref operand {:?} in `codegen_rvalue_operand`", operand);
                             }
+                            OperandValue::ZeroSized => {
+                                bug!("zero-sized operand {:?} in `codegen_rvalue_operand`", operand);
+                            }
                         };
                         let (lldata, llextra) =
                             base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra);
@@ -490,6 +498,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             OperandValue::Ref(_, _, _) => todo!(),
                             OperandValue::Immediate(v) => (v, None),
                             OperandValue::Pair(v, l) => (v, Some(l)),
+                            OperandValue::ZeroSized => bug!("ZST -- which is not PointerLike -- in DynStar"),
                         };
                         let (lldata, llextra) =
                             base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);
@@ -668,11 +677,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
             mir::Rvalue::NullaryOp(ref null_op, ty) => {
                 let ty = self.monomorphize(ty);
-                assert!(bx.cx().type_is_sized(ty));
                 let layout = bx.cx().layout_of(ty);
                 let val = match null_op {
-                    mir::NullOp::SizeOf => layout.size.bytes(),
-                    mir::NullOp::AlignOf => layout.align.abi.bytes(),
+                    mir::NullOp::SizeOf => {
+                        assert!(bx.cx().type_is_sized(ty));
+                        layout.size.bytes()
+                    }
+                    mir::NullOp::AlignOf => {
+                        assert!(bx.cx().type_is_sized(ty));
+                        layout.align.abi.bytes()
+                    }
                     mir::NullOp::OffsetOf(fields) => {
                         layout.offset_of_subfield(bx.cx(), fields.iter().map(|f| f.index())).bytes()
                     }
@@ -713,7 +727,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 // According to `rvalue_creates_operand`, only ZST
                 // aggregate rvalues are allowed to be operands.
                 let ty = rvalue.ty(self.mir, self.cx.tcx());
-                OperandRef::new_zst(bx, self.cx.layout_of(self.monomorphize(ty)))
+                OperandRef::zero_sized(self.cx.layout_of(self.monomorphize(ty)))
             }
             mir::Rvalue::ShallowInitBox(ref operand, content_ty) => {
                 let operand = self.codegen_operand(bx, operand);
@@ -931,6 +945,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     // Can always load from a pointer as needed
                     (OperandValueKind::Ref, _) => true,
 
+                    // ZST-to-ZST is the easiest thing ever
+                    (OperandValueKind::ZeroSized, OperandValueKind::ZeroSized) => true,
+
+                    // But if only one of them is a ZST the sizes can't match
+                    (OperandValueKind::ZeroSized, _) | (_, OperandValueKind::ZeroSized) => false,
+
                     // Need to generate an `alloc` to get a pointer from an immediate
                     (OperandValueKind::Immediate(..) | OperandValueKind::Pair(..), OperandValueKind::Ref) => false,
 
@@ -974,12 +994,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
     /// Gets which variant of [`OperandValue`] is expected for a particular type.
     fn value_kind(&self, layout: TyAndLayout<'tcx>) -> OperandValueKind {
-        if self.cx.is_backend_immediate(layout) {
+        if layout.is_zst() {
+            OperandValueKind::ZeroSized
+        } else if self.cx.is_backend_immediate(layout) {
             debug_assert!(!self.cx.is_backend_scalar_pair(layout));
             OperandValueKind::Immediate(match layout.abi {
-                abi::Abi::Scalar(s) => ScalarOrZst::Scalar(s),
-                abi::Abi::Vector { element, .. } => ScalarOrZst::Scalar(element),
-                _ if layout.is_zst() => ScalarOrZst::Zst,
+                abi::Abi::Scalar(s) => s,
+                abi::Abi::Vector { element, .. } => element,
                 x => span_bug!(self.mir.span, "Couldn't translate {x:?} as backend immediate"),
             })
         } else if self.cx.is_backend_scalar_pair(layout) {
@@ -1002,21 +1023,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 #[derive(Debug, Copy, Clone)]
 enum OperandValueKind {
     Ref,
-    Immediate(ScalarOrZst),
+    Immediate(abi::Scalar),
     Pair(abi::Scalar, abi::Scalar),
-}
-
-#[derive(Debug, Copy, Clone)]
-enum ScalarOrZst {
-    Zst,
-    Scalar(abi::Scalar),
-}
-
-impl ScalarOrZst {
-    pub fn size(self, cx: &impl abi::HasDataLayout) -> abi::Size {
-        match self {
-            ScalarOrZst::Zst => abi::Size::ZERO,
-            ScalarOrZst::Scalar(s) => s.size(cx),
-        }
-    }
+    ZeroSized,
 }
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 7d56cf0aa07..917bd829572 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -10,6 +10,12 @@ const_eval_interior_mutable_data_refer =
         This would make multiple uses of a constant to be able to see different values and allow circumventing
         the `Send` and `Sync` requirements for shared mutable data, which is unsound.
 
+const_eval_long_running =
+    constant evaluation is taking a long time
+    .note = this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+        If your compilation actually takes a long time, you can safely allow the lint.
+    .label = the const evaluator is currently interpreting this expression
+    .help = the constant being evaluated
 const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
 
 const_eval_mut_deref =
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 046d2052968..e4d34b90018 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -103,7 +103,7 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
         tcx,
         root_span,
         param_env,
-        CompileTimeInterpreter::new(tcx.const_eval_limit(), can_access_statics, CheckAlignment::No),
+        CompileTimeInterpreter::new(can_access_statics, CheckAlignment::No),
     )
 }
 
@@ -306,7 +306,6 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
         // Statics (and promoteds inside statics) may access other statics, because unlike consts
         // they do not have to behave "as if" they were evaluated at runtime.
         CompileTimeInterpreter::new(
-            tcx.const_eval_limit(),
             /*can_access_statics:*/ is_static,
             if tcx.sess.opts.unstable_opts.extra_const_ub_checks {
                 CheckAlignment::Error
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 58b5755af07..a8b6b98c96c 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -16,11 +16,11 @@ use std::fmt;
 use rustc_ast::Mutability;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::AssertMessage;
-use rustc_session::Limit;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_target::abi::{Align, Size};
 use rustc_target::spec::abi::Abi as CallAbi;
 
+use crate::errors::{LongRunning, LongRunningWarn};
 use crate::interpret::{
     self, compile_time_machine, AllocId, ConstAllocation, FnVal, Frame, ImmTy, InterpCx,
     InterpResult, OpTy, PlaceTy, Pointer, Scalar,
@@ -28,13 +28,24 @@ use crate::interpret::{
 
 use super::error::*;
 
+/// When hitting this many interpreted terminators we emit a deny by default lint
+/// that notfies the user that their constant takes a long time to evaluate. If that's
+/// what they intended, they can just allow the lint.
+const LINT_TERMINATOR_LIMIT: usize = 2_000_000;
+/// The limit used by `-Z tiny-const-eval-limit`. This smaller limit is useful for internal
+/// tests not needing to run 30s or more to show some behaviour.
+const TINY_LINT_TERMINATOR_LIMIT: usize = 20;
+/// After this many interpreted terminators, we start emitting progress indicators at every
+/// power of two of interpreted terminators.
+const PROGRESS_INDICATOR_START: usize = 4_000_000;
+
 /// Extra machine state for CTFE, and the Machine instance
 pub struct CompileTimeInterpreter<'mir, 'tcx> {
-    /// For now, the number of terminators that can be evaluated before we throw a resource
-    /// exhaustion error.
+    /// The number of terminators that have been evaluated.
     ///
-    /// Setting this to `0` disables the limit and allows the interpreter to run forever.
-    pub(super) steps_remaining: usize,
+    /// This is used to produce lints informing the user that the compiler is not stuck.
+    /// Set to `usize::MAX` to never report anything.
+    pub(super) num_evaluated_steps: usize,
 
     /// The virtual call stack.
     pub(super) stack: Vec<Frame<'mir, 'tcx, AllocId, ()>>,
@@ -72,13 +83,9 @@ impl CheckAlignment {
 }
 
 impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
-    pub(crate) fn new(
-        const_eval_limit: Limit,
-        can_access_statics: bool,
-        check_alignment: CheckAlignment,
-    ) -> Self {
+    pub(crate) fn new(can_access_statics: bool, check_alignment: CheckAlignment) -> Self {
         CompileTimeInterpreter {
-            steps_remaining: const_eval_limit.0,
+            num_evaluated_steps: 0,
             stack: Vec::new(),
             can_access_statics,
             check_alignment,
@@ -569,13 +576,54 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
 
     fn increment_const_eval_counter(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
         // The step limit has already been hit in a previous call to `increment_const_eval_counter`.
-        if ecx.machine.steps_remaining == 0 {
-            return Ok(());
-        }
 
-        ecx.machine.steps_remaining -= 1;
-        if ecx.machine.steps_remaining == 0 {
-            throw_exhaust!(StepLimitReached)
+        if let Some(new_steps) = ecx.machine.num_evaluated_steps.checked_add(1) {
+            let (limit, start) = if ecx.tcx.sess.opts.unstable_opts.tiny_const_eval_limit {
+                (TINY_LINT_TERMINATOR_LIMIT, TINY_LINT_TERMINATOR_LIMIT)
+            } else {
+                (LINT_TERMINATOR_LIMIT, PROGRESS_INDICATOR_START)
+            };
+
+            ecx.machine.num_evaluated_steps = new_steps;
+            // By default, we have a *deny* lint kicking in after some time
+            // to ensure `loop {}` doesn't just go forever.
+            // In case that lint got reduced, in particular for `--cap-lint` situations, we also
+            // have a hard warning shown every now and then for really long executions.
+            if new_steps == limit {
+                // By default, we stop after a million steps, but the user can disable this lint
+                // to be able to run until the heat death of the universe or power loss, whichever
+                // comes first.
+                let hir_id = ecx.best_lint_scope();
+                let is_error = ecx
+                    .tcx
+                    .lint_level_at_node(
+                        rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
+                        hir_id,
+                    )
+                    .0
+                    .is_error();
+                let span = ecx.cur_span();
+                ecx.tcx.emit_spanned_lint(
+                    rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
+                    hir_id,
+                    span,
+                    LongRunning { item_span: ecx.tcx.span },
+                );
+                // If this was a hard error, don't bother continuing evaluation.
+                if is_error {
+                    let guard = ecx
+                        .tcx
+                        .sess
+                        .delay_span_bug(span, "The deny lint should have already errored");
+                    throw_inval!(AlreadyReported(guard.into()));
+                }
+            } else if new_steps > start && new_steps.is_power_of_two() {
+                // Only report after a certain number of terminators have been evaluated and the
+                // current number of evaluated terminators is a power of 2. The latter gives us a cheap
+                // way to implement exponential backoff.
+                let span = ecx.cur_span();
+                ecx.tcx.sess.emit_warning(LongRunningWarn { span, item_span: ecx.tcx.span });
+            }
         }
 
         Ok(())
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 05be45fef13..b59ca8e2070 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -2,10 +2,8 @@
 
 use crate::errors::MaxNumNodesInConstErr;
 use crate::interpret::{
-    intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta,
-    Scalar,
+    intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, Scalar,
 };
-use rustc_hir::Mutability;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId};
 use rustc_middle::ty::{self, TyCtxt};
@@ -131,38 +129,3 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
 
     Ok(mir::DestructuredConstant { variant, fields })
 }
-
-#[instrument(skip(tcx), level = "debug")]
-pub(crate) fn deref_mir_constant<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    val: mir::ConstantKind<'tcx>,
-) -> mir::ConstantKind<'tcx> {
-    let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
-    let op = ecx.eval_mir_constant(&val, None, None).unwrap();
-    let mplace = ecx.deref_operand(&op).unwrap();
-    if let Some(alloc_id) = mplace.ptr.provenance {
-        assert_eq!(
-            tcx.global_alloc(alloc_id).unwrap_memory().0.0.mutability,
-            Mutability::Not,
-            "deref_mir_constant cannot be used with mutable allocations as \
-            that could allow pattern matching to observe mutable statics",
-        );
-    }
-
-    let ty = match mplace.meta {
-        MemPlaceMeta::None => mplace.layout.ty,
-        // In case of unsized types, figure out the real type behind.
-        MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() {
-            ty::Str => bug!("there's no sized equivalent of a `str`"),
-            ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_target_usize(&tcx).unwrap()),
-            _ => bug!(
-                "type {} should not have metadata, but had {:?}",
-                mplace.layout.ty,
-                mplace.meta
-            ),
-        },
-    };
-
-    mir::ConstantKind::Val(op_to_const(&ecx, &mplace.into()), ty)
-}
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index f8b7cc6d7e1..ad2e68e752d 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -1,5 +1,5 @@
 use rustc_hir::ConstContext;
-use rustc_macros::Diagnostic;
+use rustc_macros::{Diagnostic, LintDiagnostic};
 use rustc_span::Span;
 
 #[derive(Diagnostic)]
@@ -194,3 +194,21 @@ pub(crate) struct InteriorMutabilityBorrow {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(const_eval_long_running)]
+#[note]
+pub struct LongRunning {
+    #[help]
+    pub item_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(const_eval_long_running)]
+pub struct LongRunningWarn {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[help]
+    pub item_span: Span,
+}
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 91ccdef7215..cd43a53b1b3 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -4,6 +4,7 @@ use std::mem;
 
 use either::{Either, Left, Right};
 
+use hir::CRATE_HIR_ID;
 use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
 use rustc_index::IndexVec;
 use rustc_middle::mir;
@@ -406,6 +407,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     }
 
     #[inline(always)]
+    /// Find the first stack frame that is within the current crate, if any, otherwise return the crate's HirId
+    pub fn best_lint_scope(&self) -> hir::HirId {
+        self.stack()
+            .iter()
+            .find_map(|frame| frame.body.source.def_id().as_local())
+            .map_or(CRATE_HIR_ID, |def_id| self.tcx.hir().local_def_id_to_hir_id(def_id))
+    }
+
+    #[inline(always)]
     pub(crate) fn stack(&self) -> &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>] {
         M::stack(self)
     }
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index c36282d5ed4..0c48d99915a 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -56,10 +56,6 @@ pub fn provide(providers: &mut Providers) {
     providers.valtree_to_const_val = |tcx, (ty, valtree)| {
         const_eval::valtree_to_const_value(tcx, ty::ParamEnv::empty().and(ty), valtree)
     };
-    providers.deref_mir_constant = |tcx, param_env_and_value| {
-        let (param_env, value) = param_env_and_value.into_parts();
-        const_eval::deref_mir_constant(tcx, param_env, value)
-    };
     providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| {
         util::check_validity_requirement(tcx, init_kind, param_env_and_ty)
     };
diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
index 23fcd22c52b..29063261ada 100644
--- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
+++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs
@@ -1,6 +1,5 @@
 use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement};
 use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
-use rustc_session::Limit;
 use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
 
 use crate::const_eval::{CheckAlignment, CompileTimeInterpreter};
@@ -45,11 +44,8 @@ fn might_permit_raw_init_strict<'tcx>(
     tcx: TyCtxt<'tcx>,
     kind: ValidityRequirement,
 ) -> Result<bool, LayoutError<'tcx>> {
-    let machine = CompileTimeInterpreter::new(
-        Limit::new(0),
-        /*can_access_statics:*/ false,
-        CheckAlignment::Error,
-    );
+    let machine =
+        CompileTimeInterpreter::new(/*can_access_statics:*/ false, CheckAlignment::Error);
 
     let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
 
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 6c3197d8ec2..25a08237346 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -139,9 +139,14 @@ cfg_if! {
 
         impl Atomic<bool> {
             pub fn fetch_or(&self, val: bool, _: Ordering) -> bool {
-                let result = self.0.get() | val;
-                self.0.set(val);
-                result
+                let old = self.0.get();
+                self.0.set(val | old);
+                old
+            }
+            pub fn fetch_and(&self, val: bool, _: Ordering) -> bool {
+                let old = self.0.get();
+                self.0.set(val & old);
+                old
             }
         }
 
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 5b2e4d15dfe..0170d52e82a 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -131,7 +131,7 @@ declare_features! (
     /// Allows `crate` in paths.
     (accepted, crate_in_paths, "1.30.0", Some(45477), None),
     /// Allows using `#[debugger_visualizer]` attribute.
-    (accepted, debugger_visualizer, "CURRENT_RUSTC_VERSION", Some(95939), None),
+    (accepted, debugger_visualizer, "1.71.0", Some(95939), None),
     /// Allows rustc to inject a default alloc_error_handler
     (accepted, default_alloc_error_handler, "1.68.0", Some(66741), None),
     /// Allows using assigning a default type to type parameters in algebraic data type definitions.
@@ -281,7 +281,7 @@ declare_features! (
     /// Allows use of the postfix `?` operator in expressions.
     (accepted, question_mark, "1.13.0", Some(31436), None),
     /// Allows the use of raw-dylibs (RFC 2627).
-    (accepted, raw_dylib, "CURRENT_RUSTC_VERSION", Some(58713), None),
+    (accepted, raw_dylib, "1.71.0", Some(58713), None),
     /// Allows keywords to be escaped for use as identifiers.
     (accepted, raw_identifiers, "1.30.0", Some(48589), None),
     /// Allows relaxing the coherence rules such that
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 57e55752027..4c53f9d8369 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -165,7 +165,7 @@ declare_features! (
     /// Allows the `multiple_supertrait_upcastable` lint.
     (active, multiple_supertrait_upcastable, "1.69.0", None, None),
     /// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
-    (incomplete, negative_bounds, "CURRENT_RUSTC_VERSION", None, None),
+    (incomplete, negative_bounds, "1.71.0", None, None),
     /// Allows using `#[omit_gdb_pretty_printer_section]`.
     (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
     /// Allows using `#[prelude_import]` on glob `use` items.
@@ -314,15 +314,15 @@ declare_features! (
     /// Allows async functions to be declared, implemented, and used in traits.
     (active, async_fn_in_trait, "1.66.0", Some(91611), None),
     /// Allows builtin # foo() syntax
-    (active, builtin_syntax, "CURRENT_RUSTC_VERSION", Some(110680), None),
+    (active, builtin_syntax, "1.71.0", Some(110680), None),
     /// Allows `c"foo"` literals.
-    (active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
+    (active, c_str_literals, "1.71.0", Some(105723), None),
     /// Treat `extern "C"` function as nounwind.
     (active, c_unwind, "1.52.0", Some(74990), None),
     /// Allows using C-variadics.
     (active, c_variadic, "1.34.0", Some(44930), None),
     /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
-    (active, cfg_overflow_checks, "CURRENT_RUSTC_VERSION", Some(111466), None),
+    (active, cfg_overflow_checks, "1.71.0", Some(111466), None),
     /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
     (active, cfg_sanitize, "1.41.0", Some(39699), None),
     /// Allows `cfg(target_abi = "...")`.
@@ -338,7 +338,7 @@ declare_features! (
     /// Allow conditional compilation depending on rust version
     (active, cfg_version, "1.45.0", Some(64796), None),
     /// Allows to use the `#[cfi_encoding = ""]` attribute.
-    (active, cfi_encoding, "CURRENT_RUSTC_VERSION", Some(89653), None),
+    (active, cfi_encoding, "1.71.0", Some(89653), None),
     /// Allows `for<...>` on closures and generators.
     (active, closure_lifetime_binder, "1.64.0", Some(97362), None),
     /// Allows `#[track_caller]` on closures and generators.
@@ -351,8 +351,6 @@ declare_features! (
     (active, const_async_blocks, "1.53.0", Some(85368), None),
     /// Allows `const || {}` closures in const contexts.
     (incomplete, const_closures, "1.68.0", Some(106003), None),
-    /// Allows limiting the evaluation steps of const expressions
-    (active, const_eval_limit, "1.43.0", Some(67217), None),
     /// Allows the definition of `const extern fn` and `const unsafe extern fn`.
     (active, const_extern_fn, "1.40.0", Some(64926), None),
     /// Allows basic arithmetic on floating point types in a `const fn`.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 06f4a0b5eef..9be28c338f6 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -356,10 +356,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
     ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
     gated!(
-        const_eval_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
-        const_eval_limit, experimental!(const_eval_limit)
-    ),
-    gated!(
         move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
         large_assignments, experimental!(move_size_limit)
     ),
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 8bca24b2bf0..ed5d76b861a 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -59,8 +59,10 @@ declare_features! (
     /// Allows comparing raw pointers during const eval.
     (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None,
      Some("cannot be allowed in const eval in any meaningful way")),
+    /// Allows limiting the evaluation steps of const expressions
+    (removed, const_eval_limit, "1.43.0", Some(67217), None, Some("removed the limit entirely")),
     /// Allows non-trivial generic constants which have to be manually propagated upwards.
-     (removed, const_evaluatable_checked, "1.48.0", Some(76560), None, Some("renamed to `generic_const_exprs`")),
+    (removed, const_evaluatable_checked, "1.48.0", Some(76560), None, Some("renamed to `generic_const_exprs`")),
     /// Allows the definition of `const` functions with some advanced features.
     (removed, const_fn, "1.54.0", Some(57563), None,
      Some("split into finer-grained feature gates")),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index f7c5b44678f..4d96a7ff4c3 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -1,3 +1,4 @@
+use rustc_errors::StashKey;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem};
@@ -59,7 +60,20 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
         }
     }
 
-    let Some(hidden) = locator.found else {
+    if let Some(hidden) = locator.found {
+        // Only check against typeck if we didn't already error
+        if !hidden.ty.references_error() {
+            for concrete_type in locator.typeck_types {
+                if concrete_type.ty != tcx.erase_regions(hidden.ty)
+                    && !(concrete_type, hidden).references_error()
+                {
+                    hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
+                }
+            }
+        }
+
+        hidden.ty
+    } else {
         let reported = tcx.sess.emit_err(UnconstrainedOpaqueType {
             span: tcx.def_span(def_id),
             name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
@@ -70,21 +84,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
                 _ => "item",
             },
         });
-        return tcx.ty_error(reported);
-    };
-
-    // Only check against typeck if we didn't already error
-    if !hidden.ty.references_error() {
-        for concrete_type in locator.typeck_types {
-            if concrete_type.ty != tcx.erase_regions(hidden.ty)
-                && !(concrete_type, hidden).references_error()
-            {
-                hidden.report_mismatch(&concrete_type, def_id, tcx).emit();
-            }
-        }
+        tcx.ty_error(reported)
     }
-
-    hidden.ty
 }
 
 struct TaitConstraintLocator<'tcx> {
@@ -130,13 +131,28 @@ impl TaitConstraintLocator<'_> {
             self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) });
             return;
         }
-        let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else {
+
+        let mut constrained = false;
+        for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
+            if opaque_type_key.def_id != self.def_id {
+                continue;
+            }
+            constrained = true;
+            let concrete_type =
+                self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params(
+                    opaque_type_key,
+                    self.tcx,
+                    true,
+                ));
+            if self.typeck_types.iter().all(|prev| prev.ty != concrete_type.ty) {
+                self.typeck_types.push(concrete_type);
+            }
+        }
+
+        if !constrained {
             debug!("no constraints in typeck results");
             return;
         };
-        if self.typeck_types.iter().all(|prev| prev.ty != typeck_hidden_ty.ty) {
-            self.typeck_types.push(typeck_hidden_ty);
-        }
 
         // Use borrowck to get the type with unerased regions.
         let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types;
@@ -190,17 +206,45 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
     }
 }
 
-pub(super) fn find_opaque_ty_constraints_for_rpit(
-    tcx: TyCtxt<'_>,
+pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
+    tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     owner_def_id: LocalDefId,
 ) -> Ty<'_> {
-    let concrete = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
+    let tables = tcx.typeck(owner_def_id);
+
+    // Check that all of the opaques we inferred during HIR are compatible.
+    // FIXME: We explicitly don't check that the types inferred during HIR
+    // typeck are compatible with the one that we infer during borrowck,
+    // because that one actually sometimes has consts evaluated eagerly so
+    // using strict type equality will fail.
+    let mut hir_opaque_ty: Option<ty::OpaqueHiddenType<'tcx>> = None;
+    if tables.tainted_by_errors.is_none() {
+        for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
+            if opaque_type_key.def_id != def_id {
+                continue;
+            }
+            let concrete_type = tcx.erase_regions(
+                hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true),
+            );
+            if let Some(prev) = &mut hir_opaque_ty {
+                if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
+                    prev.report_mismatch(&concrete_type, def_id, tcx).stash(
+                        tcx.def_span(opaque_type_key.def_id),
+                        StashKey::OpaqueHiddenTypeMismatch,
+                    );
+                }
+            } else {
+                hir_opaque_ty = Some(concrete_type);
+            }
+        }
+    }
 
-    if let Some(concrete) = concrete {
+    let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
+    if let Some(mir_opaque_ty) = mir_opaque_ty {
         let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
         debug!(?scope);
-        let mut locator = RpitConstraintChecker { def_id, tcx, found: concrete };
+        let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
 
         match tcx.hir().get(scope) {
             Node::Item(it) => intravisit::walk_item(&mut locator, it),
@@ -208,17 +252,18 @@ pub(super) fn find_opaque_ty_constraints_for_rpit(
             Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it),
             other => bug!("{:?} is not a valid scope for an opaque type item", other),
         }
-    }
 
-    concrete.map(|concrete| concrete.ty).unwrap_or_else(|| {
-        let table = tcx.typeck(owner_def_id);
-        if let Some(guar) = table.tainted_by_errors {
-            // Some error in the
-            // owner fn prevented us from populating
+        mir_opaque_ty.ty
+    } else {
+        if let Some(guar) = tables.tainted_by_errors {
+            // Some error in the owner fn prevented us from populating
             // the `concrete_opaque_types` table.
             tcx.ty_error(guar)
         } else {
-            table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| {
+            // Fall back to the RPIT we inferred during HIR typeck
+            if let Some(hir_opaque_ty) = hir_opaque_ty {
+                hir_opaque_ty.ty
+            } else {
                 // We failed to resolve the opaque type or it
                 // resolves to itself. We interpret this as the
                 // no values of the hidden type ever being constructed,
@@ -226,9 +271,9 @@ pub(super) fn find_opaque_ty_constraints_for_rpit(
                 // For backwards compatibility reasons, we fall back to
                 // `()` until we the diverging default is changed.
                 tcx.mk_diverging_default()
-            })
+            }
         }
-    })
+    }
 }
 
 struct RpitConstraintChecker<'tcx> {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index c4add4dbdfb..e19b0664461 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -874,7 +874,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let found = self.resolve_vars_with_obligations(found);
 
         let in_loop = self.is_loop(id)
-            || self.tcx.hir().parent_iter(id).any(|(parent_id, _)| self.is_loop(parent_id));
+            || self
+                .tcx
+                .hir()
+                .parent_iter(id)
+                .take_while(|(_, node)| {
+                    // look at parents until we find the first body owner
+                    node.body_id().is_none()
+                })
+                .any(|(parent_id, _)| self.is_loop(parent_id));
 
         let in_local_statement = self.is_local_statement(id)
             || self
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 0f21fc1e662..964acc4eb77 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -583,19 +583,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 continue;
             }
 
-            let hidden_type =
-                self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params(
-                    opaque_type_key,
-                    self.tcx(),
-                    true,
-                ));
-
+            // Here we only detect impl trait definition conflicts when they
+            // are equal modulo regions.
             if let Some(last_opaque_ty) = self
                 .typeck_results
                 .concrete_opaque_types
-                .insert(opaque_type_key.def_id, hidden_type)
+                .insert(opaque_type_key, hidden_type)
                 && last_opaque_ty.ty != hidden_type.ty
             {
+                assert!(!self.tcx().trait_solver_next());
                 hidden_type
                     .report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx())
                     .stash(
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index e707ac41a05..98fe3821947 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -155,6 +155,8 @@ lint_builtin_unused_doc_comment = unused doc comment
 lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
     .suggestion = use `loop`
 
+lint_cast_ref_to_mut = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+
 lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name}
 
 lint_check_name_unknown = unknown lint: `{$lint_name}`
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 358d412a4d8..213e8db66a0 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1317,10 +1317,14 @@ declare_lint! {
     ///
     /// ### Explanation
     ///
-    /// A bare `pub` visibility may be misleading if the item is not actually
-    /// publicly exported from the crate. The `pub(crate)` visibility is
-    /// recommended to be used instead, which more clearly expresses the intent
-    /// that the item is only visible within its own crate.
+    /// The `pub` keyword both expresses an intent for an item to be publicly available, and also
+    /// signals to the compiler to make the item publicly accessible. The intent can only be
+    /// satisfied, however, if all items which contain this item are *also* publicly accessible.
+    /// Thus, this lint serves to identify situations where the intent does not match the reality.
+    ///
+    /// If you wish the item to be accessible elsewhere within the crate, but not outside it, the
+    /// `pub(crate)` visibility is recommended to be used instead. This more clearly expresses the
+    /// intent that the item is only visible within its own crate.
     ///
     /// This lint is "allow" by default because it will trigger for a large
     /// amount existing Rust code, and has some false-positives. Eventually it
diff --git a/compiler/rustc_lint/src/cast_ref_to_mut.rs b/compiler/rustc_lint/src/cast_ref_to_mut.rs
new file mode 100644
index 00000000000..84308d48c10
--- /dev/null
+++ b/compiler/rustc_lint/src/cast_ref_to_mut.rs
@@ -0,0 +1,72 @@
+use rustc_ast::Mutability;
+use rustc_hir::{Expr, ExprKind, MutTy, TyKind, UnOp};
+use rustc_middle::ty;
+use rustc_span::sym;
+
+use crate::{lints::CastRefToMutDiag, LateContext, LateLintPass, LintContext};
+
+declare_lint! {
+    /// The `cast_ref_to_mut` lint checks for casts of `&T` to `&mut T`
+    /// without using interior mutability.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// fn x(r: &i32) {
+    ///     unsafe {
+    ///         *(r as *const i32 as *mut i32) += 1;
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Casting `&T` to `&mut T` without using interior mutability is undefined behavior,
+    /// as it's a violation of Rust reference aliasing requirements.
+    ///
+    /// `UnsafeCell` is the only way to obtain aliasable data that is considered
+    /// mutable.
+    CAST_REF_TO_MUT,
+    Deny,
+    "casts of `&T` to `&mut T` without interior mutability"
+}
+
+declare_lint_pass!(CastRefToMut => [CAST_REF_TO_MUT]);
+
+impl<'tcx> LateLintPass<'tcx> for CastRefToMut {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        let ExprKind::Unary(UnOp::Deref, e) = &expr.kind else { return; };
+
+        let e = e.peel_blocks();
+        let e = if let ExprKind::Cast(e, t) = e.kind
+            && let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind {
+            e
+        } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
+            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+            && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) {
+            expr
+        } else {
+            return;
+        };
+
+        let e = e.peel_blocks();
+        let e = if let ExprKind::Cast(e, t) = e.kind
+            && let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind {
+            e
+        } else if let ExprKind::Call(path, [arg]) = e.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && cx.tcx.is_diagnostic_item(sym::ptr_from_ref, def_id) {
+            arg
+        } else {
+            return;
+        };
+
+        let e = e.peel_blocks();
+        if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind() {
+            cx.emit_spanned_lint(CAST_REF_TO_MUT, expr.span, CastRefToMutDiag);
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index c62109b2986..5e3f057d428 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -50,6 +50,7 @@ extern crate tracing;
 
 mod array_into_iter;
 pub mod builtin;
+mod cast_ref_to_mut;
 mod context;
 mod deref_into_dyn_supertrait;
 mod drop_forget_useless;
@@ -97,6 +98,7 @@ use rustc_span::Span;
 
 use array_into_iter::ArrayIntoIter;
 use builtin::*;
+use cast_ref_to_mut::*;
 use deref_into_dyn_supertrait::*;
 use drop_forget_useless::*;
 use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
@@ -214,6 +216,7 @@ late_lint_methods!(
             BoxPointers: BoxPointers,
             PathStatements: PathStatements,
             LetUnderscore: LetUnderscore,
+            CastRefToMut: CastRefToMut,
             // Depends on referenced function signatures in expressions
             UnusedResults: UnusedResults,
             NonUpperCaseGlobals: NonUpperCaseGlobals,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 746abebeb37..fd15f795202 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -718,6 +718,11 @@ pub enum InvalidFromUtf8Diag {
     },
 }
 
+// cast_ref_to_mut.rs
+#[derive(LintDiagnostic)]
+#[diag(lint_cast_ref_to_mut)]
+pub struct CastRefToMutDiag;
+
 // hidden_unicode_codepoints.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_hidden_unicode_codepoints)]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 1507087bdd4..eb246c3f93e 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3357,6 +3357,7 @@ declare_lint_pass! {
         LARGE_ASSIGNMENTS,
         LATE_BOUND_LIFETIME_ARGUMENTS,
         LEGACY_DERIVE_HELPERS,
+        LONG_RUNNING_CONST_EVAL,
         LOSSY_PROVENANCE_CASTS,
         MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
         MACRO_USE_EXTERN_CRATE,
@@ -3427,6 +3428,43 @@ declare_lint_pass! {
 }
 
 declare_lint! {
+    /// The `long_running_const_eval` lint is emitted when const
+    /// eval is running for a long time to ensure rustc terminates
+    /// even if you accidentally wrote an infinite loop.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// const FOO: () = loop {};
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Loops allow const evaluation to compute arbitrary code, but may also
+    /// cause infinite loops or just very long running computations.
+    /// Users can enable long running computations by allowing the lint
+    /// on individual constants or for entire crates.
+    ///
+    /// ### Unconditional warnings
+    ///
+    /// Note that regardless of whether the lint is allowed or set to warn,
+    /// the compiler will issue warnings if constant evaluation runs significantly
+    /// longer than this lint's limit. These warnings are also shown to downstream
+    /// users from crates.io or similar registries. If you are above the lint's limit,
+    /// both you and downstream users might be exposed to these warnings.
+    /// They might also appear on compiler updates, as the compiler makes minor changes
+    /// about how complexity is measured: staying below the limit ensures that there
+    /// is enough room, and given that the lint is disabled for people who use your
+    /// dependency it means you will be the only one to get the warning and can put
+    /// out an update in your own time.
+    pub LONG_RUNNING_CONST_EVAL,
+    Deny,
+    "detects long const eval operations"
+}
+
+declare_lint! {
     /// The `unused_doc_comments` lint detects doc comments that aren't used
     /// by `rustdoc`.
     ///
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index aaf72ab94e7..b3976d756eb 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -365,6 +365,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         lib: Library,
         dep_kind: CrateDepKind,
         name: Symbol,
+        private_dep: Option<bool>,
     ) -> Result<CrateNum, CrateError> {
         let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
 
@@ -372,8 +373,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         let crate_root = metadata.get_root();
         let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
 
-        let private_dep =
-            self.sess.opts.externs.get(name.as_str()).is_some_and(|e| e.is_private_dep);
+        let private_dep = self
+            .sess
+            .opts
+            .externs
+            .get(name.as_str())
+            .map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
+            && private_dep.unwrap_or(true);
 
         // Claim this crate number and cache it
         let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
@@ -518,15 +524,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         if !name.as_str().is_ascii() {
             return Err(CrateError::NonAsciiName(name));
         }
-        let (root, hash, host_hash, extra_filename, path_kind) = match dep {
+        let (root, hash, host_hash, extra_filename, path_kind, private_dep) = match dep {
             Some((root, dep)) => (
                 Some(root),
                 Some(dep.hash),
                 dep.host_hash,
                 Some(&dep.extra_filename[..]),
                 PathKind::Dependency,
+                Some(dep.is_private),
             ),
-            None => (None, None, None, None, PathKind::Crate),
+            None => (None, None, None, None, PathKind::Crate, None),
         };
         let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
             (LoadResult::Previous(cnum), None)
@@ -562,10 +569,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
                     dep_kind = CrateDepKind::MacrosOnly;
                 }
                 data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind));
+                if let Some(private_dep) = private_dep {
+                    data.update_and_private_dep(private_dep);
+                }
                 Ok(cnum)
             }
             (LoadResult::Loaded(library), host_library) => {
-                self.register_crate(host_library, root, library, dep_kind, name)
+                self.register_crate(host_library, root, library, dep_kind, name, private_dep)
             }
             _ => panic!(),
         }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 09e24e012af..8f883bdcf12 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -9,7 +9,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::owned_slice::OwnedSlice;
 use rustc_data_structures::svh::Svh;
-use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
+use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceCell};
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
@@ -40,6 +40,7 @@ use proc_macro::bridge::client::ProcMacro;
 use std::iter::TrustedLen;
 use std::num::NonZeroUsize;
 use std::path::Path;
+use std::sync::atomic::Ordering;
 use std::{io, iter, mem};
 
 pub(super) use cstore_impl::provide;
@@ -112,9 +113,10 @@ pub(crate) struct CrateMetadata {
     dep_kind: Lock<CrateDepKind>,
     /// Filesystem location of this crate.
     source: Lrc<CrateSource>,
-    /// Whether or not this crate should be consider a private dependency
-    /// for purposes of the 'exported_private_dependencies' lint
-    private_dep: bool,
+    /// Whether or not this crate should be consider a private dependency.
+    /// Used by the 'exported_private_dependencies' lint, and for determining
+    /// whether to emit suggestions that reference this crate.
+    private_dep: AtomicBool,
     /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
     host_hash: Option<Svh>,
 
@@ -701,12 +703,13 @@ impl MetadataBlob {
         writeln!(out, "=External Dependencies=")?;
 
         for (i, dep) in root.crate_deps.decode(self).enumerate() {
-            let CrateDep { name, extra_filename, hash, host_hash, kind } = dep;
+            let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } = dep;
             let number = i + 1;
 
             writeln!(
                 out,
-                "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?}"
+                "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}",
+                privacy = if is_private { "private" } else { "public" }
             )?;
         }
         write!(out, "\n")?;
@@ -1624,7 +1627,7 @@ impl CrateMetadata {
             dependencies,
             dep_kind: Lock::new(dep_kind),
             source: Lrc::new(source),
-            private_dep,
+            private_dep: AtomicBool::new(private_dep),
             host_hash,
             extern_crate: Lock::new(None),
             hygiene_context: Default::default(),
@@ -1672,6 +1675,10 @@ impl CrateMetadata {
         self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
     }
 
+    pub(crate) fn update_and_private_dep(&self, private_dep: bool) {
+        self.private_dep.fetch_and(private_dep, Ordering::SeqCst);
+    }
+
     pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {
         self.root.required_panic_strategy
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 3d8991d99b5..a15307e4345 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -285,7 +285,13 @@ provide! { tcx, def_id, other, cdata,
     is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
 
     dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
-    is_private_dep => { cdata.private_dep }
+    is_private_dep => {
+        // Parallel compiler needs to synchronize type checking and linting (which use this flag)
+        // so that they happen strictly crate loading. Otherwise, the full list of available
+        // impls aren't loaded yet.
+        use std::sync::atomic::Ordering;
+        cdata.private_dep.load(Ordering::Acquire)
+    }
     is_panic_runtime => { cdata.root.panic_runtime }
     is_compiler_builtins => { cdata.root.compiler_builtins }
     has_global_allocator => { cdata.root.has_global_allocator }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index c673eb5afc7..6ceb61e793e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1883,6 +1883,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     host_hash: self.tcx.crate_host_hash(cnum),
                     kind: self.tcx.dep_kind(cnum),
                     extra_filename: self.tcx.extra_filename(cnum).clone(),
+                    is_private: self.tcx.is_private_dep(cnum),
                 };
                 (cnum, dep)
             })
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index ce2fe70a8b2..2da888f4468 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -322,6 +322,7 @@ pub(crate) struct CrateDep {
     pub host_hash: Option<Svh>,
     pub kind: CrateDepKind,
     pub extra_filename: String,
+    pub is_private: bool,
 }
 
 #[derive(MetadataEncodable, MetadataDecodable)]
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index dda30bce2c0..f002d7f97b9 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -439,7 +439,7 @@ where
     /// Given the metadata, extract out the value at a particular index (if any).
     #[inline(never)]
     pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
-        debug!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
+        trace!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
 
         let start = self.position.get();
         let bytes = &metadata.blob()[start..start + self.encoded_size];
diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs
index bd859d4d61b..d4f023958d6 100644
--- a/compiler/rustc_middle/src/middle/limits.rs
+++ b/compiler/rustc_middle/src/middle/limits.rs
@@ -1,8 +1,7 @@
 //! Registering limits:
 //! * recursion_limit,
-//! * move_size_limit,
-//! * type_length_limit, and
-//! * const_eval_limit
+//! * move_size_limit, and
+//! * type_length_limit
 //!
 //! There are various parts of the compiler that must impose arbitrary limits
 //! on how deeply they recurse to prevent stack overflow. Users can override
@@ -34,12 +33,6 @@ pub fn provide(providers: &mut Providers) {
             sym::type_length_limit,
             1048576,
         ),
-        const_eval_limit: get_limit(
-            tcx.hir().krate_attrs(),
-            tcx.sess,
-            sym::const_eval_limit,
-            2_000_000,
-        ),
     }
 }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 055d8e9a352..357bcca4419 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -465,10 +465,6 @@ impl fmt::Display for UnsupportedOpInfo {
 pub enum ResourceExhaustionInfo {
     /// The stack grew too big.
     StackFrameLimitReached,
-    /// The program ran for too long.
-    ///
-    /// The exact limit is set by the `const_eval_limit` attribute.
-    StepLimitReached,
     /// There is not enough memory (on the host) to perform an allocation.
     MemoryExhausted,
     /// The address space (of the target) is full.
@@ -482,9 +478,6 @@ impl fmt::Display for ResourceExhaustionInfo {
             StackFrameLimitReached => {
                 write!(f, "reached the configured maximum number of stack frames")
             }
-            StepLimitReached => {
-                write!(f, "exceeded interpreter step limit (see `#[const_eval_limit]`)")
-            }
             MemoryExhausted => {
                 write!(f, "tried to allocate more memory than available to compiler")
             }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 63cdba7f327..5c27bdec575 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -3,7 +3,7 @@
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
 
 use crate::mir::interpret::{
-    AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, LitToConstInput, Scalar,
+    AllocRange, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
 };
 use crate::mir::visit::MirVisitable;
 use crate::ty::codec::{TyDecoder, TyEncoder};
@@ -2461,51 +2461,6 @@ impl<'tcx> ConstantKind<'tcx> {
         Self::Val(val, ty)
     }
 
-    #[instrument(skip(tcx), level = "debug", ret)]
-    pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
-        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-        let body_id = match tcx.hir().get(hir_id) {
-            hir::Node::AnonConst(ac) => ac.body,
-            _ => span_bug!(
-                tcx.def_span(def_id.to_def_id()),
-                "from_inline_const can only process anonymous constants"
-            ),
-        };
-        let expr = &tcx.hir().body(body_id).value;
-        let ty = tcx.typeck(def_id).node_type(hir_id);
-
-        let lit_input = match expr.kind {
-            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
-            hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
-                hir::ExprKind::Lit(ref lit) => {
-                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
-                }
-                _ => None,
-            },
-            _ => None,
-        };
-        if let Some(lit_input) = lit_input {
-            // If an error occurred, ignore that it's a literal and leave reporting the error up to
-            // mir.
-            match tcx.at(expr.span).lit_to_mir_constant(lit_input) {
-                Ok(c) => return c,
-                Err(_) => {}
-            }
-        }
-
-        let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
-        let parent_substs =
-            tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
-        let substs =
-            ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
-                .substs;
-
-        let uneval = UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
-        debug_assert!(!uneval.has_free_regions());
-
-        Self::Unevaluated(uneval, ty)
-    }
-
     /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
     /// converted to a constant, everything else becomes `Unevaluated`.
     #[instrument(skip(tcx), level = "debug", ret)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 1528be42f6a..0b31c9bbf81 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1081,14 +1081,6 @@ rustc_queries! {
         desc { "destructuring MIR constant"}
     }
 
-    /// Dereference a constant reference or raw pointer and turn the result into a constant
-    /// again.
-    query deref_mir_constant(
-        key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>>
-    ) -> mir::ConstantKind<'tcx> {
-        desc { "dereferencing MIR constant" }
-    }
-
     query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
         desc { "getting a &core::panic::Location referring to a span" }
     }
@@ -1100,10 +1092,6 @@ rustc_queries! {
         desc { "converting literal to const" }
     }
 
-    query lit_to_mir_constant(key: LitToConstInput<'tcx>) -> Result<mir::ConstantKind<'tcx>, LitToConstError> {
-        desc { "converting literal to mir constant" }
-    }
-
     query check_match(key: LocalDefId) -> Result<(), rustc_errors::ErrorGuaranteed> {
         desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { true }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 77725f0b3b6..b05e791211d 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -82,8 +82,6 @@ use std::iter;
 use std::mem;
 use std::ops::{Bound, Deref};
 
-const TINY_CONST_EVAL_LIMIT: Limit = Limit(20);
-
 #[allow(rustc::usage_of_ty_tykind)]
 impl<'tcx> Interner for TyCtxt<'tcx> {
     type AdtDef = ty::AdtDef<'tcx>;
@@ -1178,14 +1176,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.limits(()).move_size_limit
     }
 
-    pub fn const_eval_limit(self) -> Limit {
-        if self.sess.opts.unstable_opts.tiny_const_eval_limit {
-            TINY_CONST_EVAL_LIMIT
-        } else {
-            self.limits(()).const_eval_limit
-        }
-    }
-
     pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
         iter::once(LOCAL_CRATE)
             .chain(self.crates(()).iter().copied())
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 3bbe6a23b66..8bcae3d9ab7 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -589,17 +589,6 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
     debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
     let tcx = relation.tcx();
 
-    // HACK(const_generics): We still need to eagerly evaluate consts when
-    // relating them because during `normalize_param_env_or_error`,
-    // we may relate an evaluated constant in a obligation against
-    // an unnormalized (i.e. unevaluated) const in the param-env.
-    // FIXME(generic_const_exprs): Once we always lazily unify unevaluated constants
-    // these `eval` calls can be removed.
-    if !tcx.features().generic_const_exprs {
-        a = a.eval(tcx, relation.param_env());
-        b = b.eval(tcx, relation.param_env());
-    }
-
     if tcx.features().generic_const_exprs {
         a = tcx.expand_abstract_consts(a);
         b = tcx.expand_abstract_consts(b);
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index e04dbbff9a7..8cbffa14850 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -155,11 +155,7 @@ pub struct TypeckResults<'tcx> {
     /// We also store the type here, so that the compiler can use it as a hint
     /// for figuring out hidden types, even if they are only set in dead code
     /// (which doesn't show up in MIR).
-    ///
-    /// These types are mapped back to the opaque's identity substitutions
-    /// (with erased regions), which is why we don't associated substs with any
-    /// of these usages.
-    pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
+    pub concrete_opaque_types: FxIndexMap<ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
     /// see `MinCaptureInformationMap` for more details.
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 311f63adc7f..dce2f5545f5 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_index::{Idx, IndexVec};
 use rustc_macros::HashStable;
@@ -857,6 +857,26 @@ impl<'tcx> TyCtxt<'tcx> {
             _ => def_kind.article(),
         }
     }
+
+    /// Return `true` if the supplied `CrateNum` is "user-visible," meaning either a [public]
+    /// dependency, or a [direct] private dependency. This is used to decide whether the crate can
+    /// be shown in `impl` suggestions.
+    ///
+    /// [public]: TyCtxt::is_private_dep
+    /// [direct]: rustc_session::cstore::ExternCrate::is_direct
+    pub fn is_user_visible_dep(self, key: CrateNum) -> bool {
+        // | Private | Direct | Visible |                    |
+        // |---------|--------|---------|--------------------|
+        // | Yes     | Yes    | Yes     | !true || true   |
+        // | No      | Yes    | Yes     | !false || true  |
+        // | Yes     | No     | No      | !true || false  |
+        // | No      | No     | Yes     | !false || false |
+        !self.is_private_dep(key)
+            // If `extern_crate` is `None`, then the crate was injected (e.g., by the allocator).
+            // Treat that kind of crate as "indirect", since it's an implementation detail of
+            // the language.
+            || self.extern_crate(key.as_def_id()).map_or(false, |e| e.is_direct())
+    }
 }
 
 struct OpaqueTypeExpander<'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 4d99ab4b0ec..73d5eb62750 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -106,7 +106,7 @@ pub fn as_constant_inner<'tcx>(
 }
 
 #[instrument(skip(tcx, lit_input))]
-pub(crate) fn lit_to_mir_constant<'tcx>(
+fn lit_to_mir_constant<'tcx>(
     tcx: TyCtxt<'tcx>,
     lit_input: LitToConstInput<'tcx>,
 ) -> Result<ConstantKind<'tcx>, LitToConstError> {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 4e3e98b56e7..8f6a069a7db 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -1,4 +1,3 @@
-pub(crate) use crate::build::expr::as_constant::lit_to_mir_constant;
 use crate::build::expr::as_place::PlaceBuilder;
 use crate::build::scope::DropKind;
 use rustc_apfloat::ieee::{Double, Single};
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index c964e62c9d0..0eaab9b5703 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -32,7 +32,6 @@ fluent_messages! { "../messages.ftl" }
 pub fn provide(providers: &mut Providers) {
     providers.check_match = thir::pattern::check_match;
     providers.lit_to_const = thir::constant::lit_to_const;
-    providers.lit_to_mir_constant = build::lit_to_mir_constant;
     providers.mir_built = build::mir_built;
     providers.thir_check_unsafety = check_unsafety::thir_check_unsafety;
     providers.thir_body = thir::cx::thir_body;
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index 57ae6a3652d..a7be8e3c903 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -3,6 +3,8 @@ use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
 use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt};
 use rustc_span::DUMMY_SP;
 
+use crate::build::parse_float_into_scalar;
+
 pub(crate) fn lit_to_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     lit_input: LitToConstInput<'tcx>,
@@ -46,12 +48,28 @@ pub(crate) fn lit_to_const<'tcx>(
         (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
             ty::ValTree::from_scalar_int((*n).into())
         }
+        (ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) =>
+        {
+            let bytes = data as &[u8];
+            ty::ValTree::from_raw_bytes(tcx, bytes)
+        }
         (ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
             let scalar_int =
                 trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?;
             ty::ValTree::from_scalar_int(scalar_int)
         }
         (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()),
+        (ast::LitKind::Float(n, _), ty::Float(fty)) => {
+            let bits = parse_float_into_scalar(*n, *fty, neg)
+                .ok_or_else(|| {
+                    LitToConstError::Reported(tcx.sess.delay_span_bug(
+                        DUMMY_SP,
+                        format!("couldn't parse float literal: {:?}", lit_input.lit),
+                    ))
+                })?
+                .assert_int();
+            ty::ValTree::from_scalar_int(bits)
+        }
         (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
         (ast::LitKind::Err, _) => {
             return Err(LitToConstError::Reported(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index b243f1dc8d0..7976b148f75 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -1,13 +1,14 @@
 use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
 use rustc_index::Idx;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::Obligation;
 use rustc_middle::mir;
 use rustc_middle::thir::{FieldPat, Pat, PatKind};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt, ValTree};
 use rustc_session::lint;
 use rustc_span::Span;
-use rustc_target::abi::FieldIdx;
+use rustc_target::abi::{FieldIdx, VariantIdx};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCause};
 
@@ -29,11 +30,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         cv: mir::ConstantKind<'tcx>,
         id: hir::HirId,
         span: Span,
-        mir_structural_match_violation: bool,
+        check_body_for_struct_match_violation: Option<DefId>,
     ) -> Box<Pat<'tcx>> {
         let infcx = self.tcx.infer_ctxt().build();
         let mut convert = ConstToPat::new(self, id, span, infcx);
-        convert.to_pat(cv, mir_structural_match_violation)
+        convert.to_pat(cv, check_body_for_struct_match_violation)
     }
 }
 
@@ -104,7 +105,7 @@ impl<'tcx> ConstToPat<'tcx> {
     fn to_pat(
         &mut self,
         cv: mir::ConstantKind<'tcx>,
-        mir_structural_match_violation: bool,
+        check_body_for_struct_match_violation: Option<DefId>,
     ) -> Box<Pat<'tcx>> {
         trace!(self.treat_byte_string_as_slice);
         // This method is just a wrapper handling a validity check; the heavy lifting is
@@ -114,14 +115,44 @@ impl<'tcx> ConstToPat<'tcx> {
         // once indirect_structural_match is a full fledged error, this
         // level of indirection can be eliminated
 
-        let inlined_const_as_pat =
-            self.recur(cv, mir_structural_match_violation).unwrap_or_else(|_| {
-                Box::new(Pat {
-                    span: self.span,
-                    ty: cv.ty(),
-                    kind: PatKind::Constant { value: cv },
-                })
-            });
+        let mir_structural_match_violation = check_body_for_struct_match_violation.map(|def_id| {
+            // `mir_const_qualif` must be called with the `DefId` of the item where the const is
+            // defined, not where it is declared. The difference is significant for associated
+            // constants.
+            self.tcx().mir_const_qualif(def_id).custom_eq
+        });
+        debug!(?check_body_for_struct_match_violation, ?mir_structural_match_violation);
+
+        let inlined_const_as_pat = match cv {
+            mir::ConstantKind::Ty(c) => match c.kind() {
+                ty::ConstKind::Param(_)
+                | ty::ConstKind::Infer(_)
+                | ty::ConstKind::Bound(_, _)
+                | ty::ConstKind::Placeholder(_)
+                | ty::ConstKind::Unevaluated(_)
+                | ty::ConstKind::Error(_)
+                | ty::ConstKind::Expr(_) => {
+                    span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind())
+                }
+                ty::ConstKind::Value(valtree) => self
+                    .recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
+                    .unwrap_or_else(|_| {
+                        Box::new(Pat {
+                            span: self.span,
+                            ty: cv.ty(),
+                            kind: PatKind::Constant { value: cv },
+                        })
+                    }),
+            },
+            mir::ConstantKind::Unevaluated(_, _) => {
+                span_bug!(self.span, "unevaluated const in `to_pat`: {cv:?}")
+            }
+            mir::ConstantKind::Val(_, _) => Box::new(Pat {
+                span: self.span,
+                ty: cv.ty(),
+                kind: PatKind::Constant { value: cv },
+            }),
+        };
 
         if !self.saw_const_match_error.get() {
             // If we were able to successfully convert the const to some pat,
@@ -141,29 +172,70 @@ impl<'tcx> ConstToPat<'tcx> {
             //
             // FIXME(#73448): Find a way to bring const qualification into parity with
             // `search_for_structural_match_violation`.
-            if structural.is_none() && mir_structural_match_violation {
+            if structural.is_none() && mir_structural_match_violation.unwrap_or(false) {
                 warn!("MIR const-checker found novel structural match violation. See #73448.");
                 return inlined_const_as_pat;
             }
 
             if let Some(non_sm_ty) = structural {
                 if !self.type_may_have_partial_eq_impl(cv.ty()) {
-                    // fatal avoids ICE from resolution of nonexistent method (rare case).
-                    self.tcx()
-                        .sess
-                        .emit_fatal(TypeNotStructural { span: self.span, non_sm_ty: non_sm_ty });
-                } else if mir_structural_match_violation && !self.saw_const_match_lint.get() {
-                    self.tcx().emit_spanned_lint(
-                        lint::builtin::INDIRECT_STRUCTURAL_MATCH,
-                        self.id,
-                        self.span,
-                        IndirectStructuralMatch { non_sm_ty },
-                    );
-                } else {
-                    debug!(
-                        "`search_for_structural_match_violation` found one, but `CustomEq` was \
-                          not in the qualifs for that `const`"
-                    );
+                    if let ty::Adt(def, ..) = non_sm_ty.kind() {
+                        if def.is_union() {
+                            let err = UnionPattern { span: self.span };
+                            self.tcx().sess.emit_err(err);
+                        } else {
+                            // fatal avoids ICE from resolution of nonexistent method (rare case).
+                            self.tcx()
+                                .sess
+                                .emit_fatal(TypeNotStructural { span: self.span, non_sm_ty });
+                        }
+                    } else {
+                        let err = InvalidPattern { span: self.span, non_sm_ty };
+                        self.tcx().sess.emit_err(err);
+                        return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
+                    }
+                } else if !self.saw_const_match_lint.get() {
+                    if let Some(mir_structural_match_violation) = mir_structural_match_violation {
+                        match non_sm_ty.kind() {
+                            ty::RawPtr(pointee)
+                                if pointee.ty.is_sized(self.tcx(), self.param_env) => {}
+                            ty::FnPtr(..) | ty::RawPtr(..) => {
+                                self.tcx().emit_spanned_lint(
+                                    lint::builtin::POINTER_STRUCTURAL_MATCH,
+                                    self.id,
+                                    self.span,
+                                    PointerPattern,
+                                );
+                            }
+                            ty::Adt(..) if mir_structural_match_violation => {
+                                self.tcx().emit_spanned_lint(
+                                    lint::builtin::INDIRECT_STRUCTURAL_MATCH,
+                                    self.id,
+                                    self.span,
+                                    IndirectStructuralMatch { non_sm_ty },
+                                );
+                            }
+                            _ => {
+                                debug!(
+                                    "`search_for_structural_match_violation` found one, but `CustomEq` was \
+                                  not in the qualifs for that `const`"
+                                );
+                            }
+                        }
+                    }
+                }
+            } else if !self.saw_const_match_lint.get() {
+                match cv.ty().kind() {
+                    ty::RawPtr(pointee) if pointee.ty.is_sized(self.tcx(), self.param_env) => {}
+                    ty::FnPtr(..) | ty::RawPtr(..) => {
+                        self.tcx().emit_spanned_lint(
+                            lint::builtin::POINTER_STRUCTURAL_MATCH,
+                            self.id,
+                            self.span,
+                            PointerPattern,
+                        );
+                    }
+                    _ => {}
                 }
             }
         }
@@ -171,6 +243,7 @@ impl<'tcx> ConstToPat<'tcx> {
         inlined_const_as_pat
     }
 
+    #[instrument(level = "trace", skip(self), ret)]
     fn type_may_have_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
         // double-check there even *is* a semantic `PartialEq` to dispatch to.
         //
@@ -187,29 +260,19 @@ impl<'tcx> ConstToPat<'tcx> {
         );
 
         // FIXME: should this call a `predicate_must_hold` variant instead?
-        let has_impl = self.infcx.predicate_may_hold(&partial_eq_obligation);
-
-        // Note: To fix rust-lang/rust#65466, we could just remove this type
-        // walk hack for function pointers, and unconditionally error
-        // if `PartialEq` is not implemented. However, that breaks stable
-        // code at the moment, because types like `for <'a> fn(&'a ())` do
-        // not *yet* implement `PartialEq`. So for now we leave this here.
-        has_impl
-            || ty.walk().any(|t| match t.unpack() {
-                ty::subst::GenericArgKind::Lifetime(_) => false,
-                ty::subst::GenericArgKind::Type(t) => t.is_fn_ptr(),
-                ty::subst::GenericArgKind::Const(_) => false,
-            })
+        self.infcx.predicate_may_hold(&partial_eq_obligation)
     }
 
     fn field_pats(
         &self,
-        vals: impl Iterator<Item = mir::ConstantKind<'tcx>>,
+        vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
     ) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
         vals.enumerate()
-            .map(|(idx, val)| {
+            .map(|(idx, (val, ty))| {
                 let field = FieldIdx::new(idx);
-                Ok(FieldPat { field, pattern: self.recur(val, false)? })
+                // Patterns can only use monomorphic types.
+                let ty = self.tcx().normalize_erasing_regions(self.param_env, ty);
+                Ok(FieldPat { field, pattern: self.recur(val, ty, false)? })
             })
             .collect()
     }
@@ -218,7 +281,8 @@ impl<'tcx> ConstToPat<'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn recur(
         &self,
-        cv: mir::ConstantKind<'tcx>,
+        cv: ValTree<'tcx>,
+        ty: Ty<'tcx>,
         mir_structural_match_violation: bool,
     ) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
         let id = self.id;
@@ -226,8 +290,9 @@ impl<'tcx> ConstToPat<'tcx> {
         let tcx = self.tcx();
         let param_env = self.param_env;
 
-        let kind = match cv.ty().kind() {
+        let kind = match ty.kind() {
             ty::Float(_) => {
+                self.saw_const_match_lint.set(true);
                 tcx.emit_spanned_lint(
                     lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
                     id,
@@ -236,27 +301,6 @@ impl<'tcx> ConstToPat<'tcx> {
                 );
                 return Err(FallbackToConstRef);
             }
-            ty::Adt(adt_def, _) if adt_def.is_union() => {
-                // Matching on union fields is unsafe, we can't hide it in constants
-                self.saw_const_match_error.set(true);
-                let err = UnionPattern { span };
-                tcx.sess.emit_err(err);
-                PatKind::Wild
-            }
-            ty::Adt(..)
-                if !self.type_may_have_partial_eq_impl(cv.ty())
-                    // FIXME(#73448): Find a way to bring const qualification into parity with
-                    // `search_for_structural_match_violation` and then remove this condition.
-
-                    // Obtain the actual type that isn't annotated. If we just looked at `cv.ty` we
-                    // could get `Option<NonStructEq>`, even though `Option` is annotated with derive.
-                    && let Some(non_sm_ty) = traits::search_for_structural_match_violation(span, tcx, cv.ty()) =>
-            {
-                self.saw_const_match_error.set(true);
-                let err = TypeNotStructural { span, non_sm_ty };
-                tcx.sess.emit_err(err);
-                PatKind::Wild
-            }
             // If the type is not structurally comparable, just emit the constant directly,
             // causing the pattern match code to treat it opaquely.
             // FIXME: This code doesn't emit errors itself, the caller emits the errors.
@@ -266,16 +310,14 @@ impl<'tcx> ConstToPat<'tcx> {
             // details.
             // Backwards compatibility hack because we can't cause hard errors on these
             // types, so we compare them via `PartialEq::eq` at runtime.
-            ty::Adt(..) if !self.type_marked_structural(cv.ty()) && self.behind_reference.get() => {
-                if !self.saw_const_match_error.get()
-                    && !self.saw_const_match_lint.get()
-                {
+            ty::Adt(..) if !self.type_marked_structural(ty) && self.behind_reference.get() => {
+                if !self.saw_const_match_error.get() && !self.saw_const_match_lint.get() {
                     self.saw_const_match_lint.set(true);
                     tcx.emit_spanned_lint(
                         lint::builtin::INDIRECT_STRUCTURAL_MATCH,
                         id,
                         span,
-                        IndirectStructuralMatch { non_sm_ty: cv.ty() },
+                        IndirectStructuralMatch { non_sm_ty: ty },
                     );
                 }
                 // Since we are behind a reference, we can just bubble the error up so we get a
@@ -283,77 +325,75 @@ impl<'tcx> ConstToPat<'tcx> {
                 // `PartialEq::eq` on it.
                 return Err(FallbackToConstRef);
             }
-            ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty()) => {
-                debug!(
-                    "adt_def {:?} has !type_marked_structural for cv.ty: {:?}",
-                    adt_def,
-                    cv.ty()
-                );
+            ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
+                debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
                 self.saw_const_match_error.set(true);
-                let err = TypeNotStructural { span, non_sm_ty: cv.ty() };
+                let err = TypeNotStructural { span, non_sm_ty: ty };
                 tcx.sess.emit_err(err);
                 PatKind::Wild
             }
             ty::Adt(adt_def, substs) if adt_def.is_enum() => {
-                let destructured = tcx.destructure_mir_constant(param_env, cv);
-
+                let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
+                let variant_index =
+                    VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap());
                 PatKind::Variant {
                     adt_def: *adt_def,
                     substs,
-                    variant_index: destructured
-                        .variant
-                        .expect("destructed const of adt without variant id"),
-                    subpatterns: self.field_pats(destructured.fields.iter().copied())?,
+                    variant_index,
+                    subpatterns: self.field_pats(
+                        fields.iter().copied().zip(
+                            adt_def.variants()[variant_index]
+                                .fields
+                                .iter()
+                                .map(|field| field.ty(self.tcx(), substs)),
+                        ),
+                    )?,
                 }
             }
-            ty::Tuple(_) | ty::Adt(_, _) => {
-                let destructured = tcx.destructure_mir_constant(param_env, cv);
-                PatKind::Leaf { subpatterns: self.field_pats(destructured.fields.iter().copied())? }
-            }
-            ty::Array(..) => PatKind::Array {
-                prefix: tcx
-                    .destructure_mir_constant(param_env, cv)
-                    .fields
+            ty::Tuple(fields) => PatKind::Leaf {
+                subpatterns: self
+                    .field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter()))?,
+            },
+            ty::Adt(def, substs) => PatKind::Leaf {
+                subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
+                    def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), substs)),
+                ))?,
+            },
+            ty::Array(elem_ty, _) => PatKind::Array {
+                prefix: cv
+                    .unwrap_branch()
                     .iter()
-                    .map(|val| self.recur(*val, false))
+                    .map(|val| self.recur(*val, *elem_ty, false))
                     .collect::<Result<_, _>>()?,
                 slice: None,
                 suffix: Box::new([]),
             },
             ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
-                // These are not allowed and will error elsewhere anyway.
-                ty::Dynamic(..) => {
-                    self.saw_const_match_error.set(true);
-                    let err = InvalidPattern { span, non_sm_ty: cv.ty() };
-                    tcx.sess.emit_err(err);
-                    PatKind::Wild
-                }
-                // `&str` is represented as `ConstValue::Slice`, let's keep using this
+                // `&str` is represented as a valtree, let's keep using this
                 // optimization for now.
-                ty::Str => PatKind::Constant { value: cv },
+                ty::Str => PatKind::Constant { value: mir::ConstantKind::Ty(tcx.mk_const(cv, ty)) },
                 // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
                 // matching against references, you can only use byte string literals.
                 // The typechecker has a special case for byte string literals, by treating them
                 // as slices. This means we turn `&[T; N]` constants into slice patterns, which
                 // has no negative effects on pattern matching, even if we're actually matching on
                 // arrays.
-                ty::Array(..) if !self.treat_byte_string_as_slice => {
+                ty::Array(elem_ty, _) if !self.treat_byte_string_as_slice => {
                     let old = self.behind_reference.replace(true);
-                    let array = tcx.deref_mir_constant(self.param_env.and(cv));
+                    // References have the same valtree representation as their pointee.
+                    let array = cv;
                     let val = PatKind::Deref {
                         subpattern: Box::new(Pat {
                             kind: PatKind::Array {
-                                prefix: tcx
-                                    .destructure_mir_constant(param_env, array)
-                                    .fields
+                                prefix: array.unwrap_branch()
                                     .iter()
-                                    .map(|val| self.recur(*val, false))
+                                    .map(|val| self.recur(*val, elem_ty, false))
                                     .collect::<Result<_, _>>()?,
                                 slice: None,
                                 suffix: Box::new([]),
                             },
                             span,
-                            ty: *pointee_ty,
+                            ty: tcx.mk_slice(elem_ty),
                         }),
                     };
                     self.behind_reference.set(old);
@@ -365,15 +405,14 @@ impl<'tcx> ConstToPat<'tcx> {
                 // pattern.
                 ty::Slice(elem_ty) => {
                     let old = self.behind_reference.replace(true);
-                    let array = tcx.deref_mir_constant(self.param_env.and(cv));
+                    // References have the same valtree representation as their pointee.
+                    let array = cv;
                     let val = PatKind::Deref {
                         subpattern: Box::new(Pat {
                             kind: PatKind::Slice {
-                                prefix: tcx
-                                    .destructure_mir_constant(param_env, array)
-                                    .fields
+                                prefix: array.unwrap_branch()
                                     .iter()
-                                    .map(|val| self.recur(*val, false))
+                                    .map(|val| self.recur(*val, elem_ty, false))
                                     .collect::<Result<_, _>>()?,
                                 slice: None,
                                 suffix: Box::new([]),
@@ -418,48 +457,28 @@ impl<'tcx> ConstToPat<'tcx> {
                 // deref pattern.
                 _ => {
                     if !pointee_ty.is_sized(tcx, param_env) {
-                        // `tcx.deref_mir_constant()` below will ICE with an unsized type
-                        // (except slices, which are handled in a separate arm above).
-
                         let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
                         tcx.sess.emit_err(err);
 
+                        // FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
                         PatKind::Wild
                     } else {
                         let old = self.behind_reference.replace(true);
-                        let subpattern = self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false)?;
+                        // References have the same valtree representation as their pointee.
+                        let subpattern = self.recur(cv, *pointee_ty, false)?;
                         self.behind_reference.set(old);
                         PatKind::Deref { subpattern }
                     }
                 }
             },
             ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
-                PatKind::Constant { value: cv }
-            }
-            ty::RawPtr(pointee) if pointee.ty.is_sized(tcx, param_env) => {
-                return Err(FallbackToConstRef);
-            }
-            // FIXME: these can have very surprising behaviour where optimization levels or other
-            // compilation choices change the runtime behaviour of the match.
-            // See https://github.com/rust-lang/rust/issues/70861 for examples.
-            ty::FnPtr(..) | ty::RawPtr(..) => {
-                if !self.saw_const_match_error.get()
-                    && !self.saw_const_match_lint.get()
-                {
-                    self.saw_const_match_lint.set(true);
-                    tcx.emit_spanned_lint(
-                        lint::builtin::POINTER_STRUCTURAL_MATCH,
-                        id,
-                        span,
-                        PointerPattern
-                    );
-                }
-                return Err(FallbackToConstRef);
+                PatKind::Constant { value: mir::ConstantKind::Ty(tcx.mk_const(cv, ty)) }
             }
+            ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
             _ => {
                 self.saw_const_match_error.set(true);
-                let err = InvalidPattern { span, non_sm_ty: cv.ty() };
-                    tcx.sess.emit_err(err);
+                let err = InvalidPattern { span, non_sm_ty: ty };
+                tcx.sess.emit_err(err);
                 PatKind::Wild
             }
         };
@@ -472,7 +491,7 @@ impl<'tcx> ConstToPat<'tcx> {
 
             // Obtain the actual type that isn't annotated. If we just looked at `cv.ty` we
             // could get `Option<NonStructEq>`, even though `Option` is annotated with derive.
-            && let Some(non_sm_ty) = traits::search_for_structural_match_violation(span, tcx, cv.ty())
+            && let Some(non_sm_ty) = traits::search_for_structural_match_violation(span, tcx, ty)
         {
             self.saw_const_match_lint.set(true);
             tcx.emit_spanned_lint(
@@ -483,6 +502,6 @@ impl<'tcx> ConstToPat<'tcx> {
             );
         }
 
-        Ok(Box::new(Pat { span, ty: cv.ty(), kind }))
+        Ok(Box::new(Pat { span, ty, kind }))
     }
 }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 6a77146138b..9df6d2f43ad 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -53,11 +53,11 @@ use smallvec::{smallvec, SmallVec};
 use rustc_data_structures::captures::Captures;
 use rustc_hir::{HirId, RangeEnd};
 use rustc_index::Idx;
+use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::mir;
 use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef};
-use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue};
 use rustc_session::lint;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT};
@@ -140,28 +140,17 @@ impl IntRange {
         value: mir::ConstantKind<'tcx>,
     ) -> Option<IntRange> {
         let ty = value.ty();
-        if let Some((target_size, bias)) = Self::integral_size_and_signed_bias(tcx, ty) {
-            let val = if let mir::ConstantKind::Val(ConstValue::Scalar(scalar), _) = value {
-                // For this specific pattern we can skip a lot of effort and go
-                // straight to the result, after doing a bit of checking. (We
-                // could remove this branch and just fall through, which
-                // is more general but much slower.)
-                scalar.to_bits_or_ptr_internal(target_size).unwrap().left()?
-            } else {
-                if let mir::ConstantKind::Ty(c) = value
-                    && let ty::ConstKind::Value(_) = c.kind()
-                {
-                    bug!("encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val");
-                }
+        let (target_size, bias) = Self::integral_size_and_signed_bias(tcx, ty)?;
+        let val = match value {
+            mir::ConstantKind::Ty(c) if let ty::ConstKind::Value(valtree) = c.kind() => {
+                valtree.unwrap_leaf().to_bits(target_size).ok()
+            },
+            // This is a more general form of the previous case.
+            _ => value.try_eval_bits(tcx, param_env, ty),
+        }?;
 
-                // This is a more general form of the previous case.
-                value.try_eval_bits(tcx, param_env, ty)?
-            };
-            let val = val ^ bias;
-            Some(IntRange { range: val..=val, bias })
-        } else {
-            None
-        }
+        let val = val ^ bias;
+        Some(IntRange { range: val..=val, bias })
     }
 
     #[inline]
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 1cf2f7ec0ff..1bbe7b45c1e 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -18,14 +18,15 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
 use rustc_hir::RangeEnd;
 use rustc_index::Idx;
 use rustc_middle::mir::interpret::{
-    ConstValue, ErrorHandled, LitToConstError, LitToConstInput, Scalar,
+    ConstValue, ErrorHandled, GlobalId, LitToConstError, LitToConstInput, Scalar,
 };
-use rustc_middle::mir::{self, UserTypeProjection};
+use rustc_middle::mir::{self, ConstantKind, UserTypeProjection};
 use rustc_middle::mir::{BorrowKind, Mutability};
 use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange};
 use rustc_middle::ty::subst::{GenericArg, SubstsRef};
 use rustc_middle::ty::CanonicalUserTypeAnnotation;
-use rustc_middle::ty::{self, AdtDef, ConstKind, Region, Ty, TyCtxt, UserType};
+use rustc_middle::ty::TypeVisitableExt;
+use rustc_middle::ty::{self, AdtDef, Region, Ty, TyCtxt, UserType};
 use rustc_span::{Span, Symbol};
 use rustc_target::abi::FieldIdx;
 
@@ -518,16 +519,24 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             }
         };
 
-        // `mir_const_qualif` must be called with the `DefId` of the item where the const is
-        // defined, not where it is declared. The difference is significant for associated
-        // constants.
-        let mir_structural_match_violation = self.tcx.mir_const_qualif(instance.def_id()).custom_eq;
-        debug!("mir_structural_match_violation({:?}) -> {}", qpath, mir_structural_match_violation);
-
-        match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) {
-            Ok(literal) => {
-                let const_ = mir::ConstantKind::Val(literal, ty);
-                let pattern = self.const_to_pat(const_, id, span, mir_structural_match_violation);
+        let cid = GlobalId { instance, promoted: None };
+        // Prefer valtrees over opaque constants.
+        let const_value = self
+            .tcx
+            .const_eval_global_id_for_typeck(param_env_reveal_all, cid, Some(span))
+            .map(|val| match val {
+                Some(valtree) => mir::ConstantKind::Ty(self.tcx.mk_const(valtree, ty)),
+                None => mir::ConstantKind::Val(
+                    self.tcx
+                        .const_eval_global_id(param_env_reveal_all, cid, Some(span))
+                        .expect("const_eval_global_id_for_typeck should have already failed"),
+                    ty,
+                ),
+            });
+
+        match const_value {
+            Ok(const_) => {
+                let pattern = self.const_to_pat(const_, id, span, Some(instance.def_id()));
 
                 if !is_associated_const {
                     return pattern;
@@ -577,27 +586,69 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         id: hir::HirId,
         span: Span,
     ) -> PatKind<'tcx> {
-        let value = mir::ConstantKind::from_inline_const(self.tcx, anon_const.def_id);
-
-        // Evaluate early like we do in `lower_path`.
-        let value = value.eval(self.tcx, self.param_env);
-
-        match value {
-            mir::ConstantKind::Ty(c) => match c.kind() {
-                ConstKind::Param(_) => {
-                    self.tcx.sess.emit_err(ConstParamInPattern { span });
-                    return PatKind::Wild;
-                }
-                ConstKind::Error(_) => {
-                    return PatKind::Wild;
+        let tcx = self.tcx;
+        let def_id = anon_const.def_id;
+        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+        let body_id = match tcx.hir().get(hir_id) {
+            hir::Node::AnonConst(ac) => ac.body,
+            _ => span_bug!(
+                tcx.def_span(def_id.to_def_id()),
+                "from_inline_const can only process anonymous constants"
+            ),
+        };
+        let expr = &tcx.hir().body(body_id).value;
+        let ty = tcx.typeck(def_id).node_type(hir_id);
+
+        // Special case inline consts that are just literals. This is solely
+        // a performance optimization, as we could also just go through the regular
+        // const eval path below.
+        // FIXME: investigate the performance impact of removing this.
+        let lit_input = match expr.kind {
+            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+            hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
+                hir::ExprKind::Lit(ref lit) => {
+                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
                 }
-                _ => bug!("Expected ConstKind::Param"),
+                _ => None,
             },
-            mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
-            mir::ConstantKind::Unevaluated(..) => {
-                // If we land here it means the const can't be evaluated because it's `TooGeneric`.
-                self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
-                return PatKind::Wild;
+            _ => None,
+        };
+        if let Some(lit_input) = lit_input {
+            match tcx.at(expr.span).lit_to_const(lit_input) {
+                Ok(c) => return self.const_to_pat(ConstantKind::Ty(c), id, span, None).kind,
+                // If an error occurred, ignore that it's a literal
+                // and leave reporting the error up to const eval of
+                // the unevaluated constant below.
+                Err(_) => {}
+            }
+        }
+
+        let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
+        let parent_substs =
+            tcx.erase_regions(ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
+        let substs =
+            ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
+                .substs;
+
+        let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
+        debug_assert!(!substs.has_free_regions());
+
+        let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), substs: substs };
+        // First try using a valtree in order to destructure the constant into a pattern.
+        if let Ok(Some(valtree)) =
+            self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span))
+        {
+            self.const_to_pat(ConstantKind::Ty(self.tcx.mk_const(valtree, ty)), id, span, None).kind
+        } else {
+            // If that fails, convert it to an opaque constant pattern.
+            match tcx.const_eval_resolve(self.param_env, uneval, None) {
+                Ok(val) => self.const_to_pat(mir::ConstantKind::Val(val, ty), id, span, None).kind,
+                Err(ErrorHandled::TooGeneric) => {
+                    // If we land here it means the const can't be evaluated because it's `TooGeneric`.
+                    self.tcx.sess.emit_err(ConstPatternDependsOnGenericParameter { span });
+                    PatKind::Wild
+                }
+                Err(ErrorHandled::Reported(_)) => PatKind::Wild,
             }
         }
     }
@@ -626,8 +677,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         let lit_input =
             LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
-        match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) {
-            Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
+        match self.tcx.at(expr.span).lit_to_const(lit_input) {
+            Ok(constant) => {
+                self.const_to_pat(ConstantKind::Ty(constant), expr.hir_id, lit.span, None).kind
+            }
             Err(LitToConstError::Reported(_)) => PatKind::Wild,
             Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
         }
@@ -806,6 +859,9 @@ pub(crate) fn compare_const_vals<'tcx>(
                 mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(a)), _a_ty),
                 mir::ConstantKind::Val(ConstValue::Scalar(Scalar::Int(b)), _b_ty),
             ) => return Some(a.cmp(&b)),
+            (mir::ConstantKind::Ty(a), mir::ConstantKind::Ty(b)) => {
+                return Some(a.kind().cmp(&b.kind()));
+            }
             _ => {}
         },
     }
diff --git a/compiler/rustc_mir_transform/src/const_goto.rs b/compiler/rustc_mir_transform/src/const_goto.rs
index da101ca7ad2..024bea62098 100644
--- a/compiler/rustc_mir_transform/src/const_goto.rs
+++ b/compiler/rustc_mir_transform/src/const_goto.rs
@@ -28,7 +28,7 @@ pub struct ConstGoto;
 
 impl<'tcx> MirPass<'tcx> for ConstGoto {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() >= 4
+        sess.mir_opt_level() >= 2
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index 1ba1951afde..f66a7a42ff8 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -103,7 +103,14 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
         // That would require a uniform one-def no-mutation analysis
         // and RPO (or recursing when needing the value of a local).
         let mut optimization_finder = ConstPropagator::new(body, dummy_body, tcx);
-        optimization_finder.visit_body(body);
+
+        // Traverse the body in reverse post-order, to ensure that `FullConstProp` locals are
+        // assigned before being read.
+        let postorder = body.basic_blocks.postorder().to_vec();
+        for bb in postorder.into_iter().rev() {
+            let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb];
+            optimization_finder.visit_basic_block_data(bb, data);
+        }
 
         trace!("ConstProp done for {:?}", def_id);
     }
@@ -789,12 +796,6 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
         self.tcx
     }
 
-    fn visit_body(&mut self, body: &mut Body<'tcx>) {
-        for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
-            self.visit_basic_block_data(bb, data);
-        }
-    }
-
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
         self.super_operand(operand, location);
 
@@ -885,14 +886,23 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
                 }
             }
             StatementKind::StorageLive(local) => {
-                let frame = self.ecx.frame_mut();
-                frame.locals[local].value =
-                    LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit));
-            }
-            StatementKind::StorageDead(local) => {
-                let frame = self.ecx.frame_mut();
-                frame.locals[local].value = LocalValue::Dead;
+                Self::remove_const(&mut self.ecx, local);
             }
+            // We do not need to mark dead locals as such. For `FullConstProp` locals,
+            // this allows to propagate the single assigned value in this case:
+            // ```
+            // let x = SOME_CONST;
+            // if a {
+            //   f(copy x);
+            //   StorageDead(x);
+            // } else {
+            //   g(copy x);
+            //   StorageDead(x);
+            // }
+            // ```
+            //
+            // This may propagate a constant where the local would be uninit or dead.
+            // In both cases, this does not matter, as those reads would be UB anyway.
             _ => {}
         }
     }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 54c138b6fbd..7d9f6c38e36 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -559,10 +559,13 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
             &multiple_return_terminators::MultipleReturnTerminators,
             &instsimplify::InstSimplify,
-            &separate_const_switch::SeparateConstSwitch,
             &simplify::SimplifyLocals::BeforeConstProp,
             &copy_prop::CopyProp,
             &ref_prop::ReferencePropagation,
+            // Perform `SeparateConstSwitch` after SSA-based analyses, as cloning blocks may
+            // destroy the SSA property. It should still happen before const-propagation, so the
+            // latter pass will leverage the created opportunities.
+            &separate_const_switch::SeparateConstSwitch,
             &const_prop::ConstProp,
             &dataflow_const_prop::DataflowConstProp,
             //
diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs
index 0ea8f2ba93f..243cb463560 100644
--- a/compiler/rustc_mir_transform/src/required_consts.rs
+++ b/compiler/rustc_mir_transform/src/required_consts.rs
@@ -17,8 +17,8 @@ impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
         let literal = constant.literal;
         match literal {
             ConstantKind::Ty(c) => match c.kind() {
-                ConstKind::Param(_) | ConstKind::Error(_) => {}
-                _ => bug!("only ConstKind::Param should be encountered here, got {:#?}", c),
+                ConstKind::Param(_) | ConstKind::Error(_) | ConstKind::Value(_) => {}
+                _ => bug!("only ConstKind::Param/Value should be encountered here, got {:#?}", c),
             },
             ConstantKind::Unevaluated(..) => self.required_consts.push(*constant),
             ConstantKind::Val(..) => {}
diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs
index 2479856b727..f35a5fb4276 100644
--- a/compiler/rustc_mir_transform/src/separate_const_switch.rs
+++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs
@@ -46,7 +46,7 @@ pub struct SeparateConstSwitch;
 
 impl<'tcx> MirPass<'tcx> for SeparateConstSwitch {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() >= 4
+        sess.mir_opt_level() >= 2
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 2d77291293d..e4b3b8b9262 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -6,23 +6,29 @@ use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields};
-use rustc_target::abi::FieldIdx;
+use rustc_target::abi::{FieldIdx, ReprFlags, FIRST_VARIANT};
 
 pub struct ScalarReplacementOfAggregates;
 
 impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() >= 3
+        sess.mir_opt_level() >= 2
     }
 
     #[instrument(level = "debug", skip(self, tcx, body))]
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!(def_id = ?body.source.def_id());
+
+        // Avoid query cycles (generators require optimized MIR for layout).
+        if tcx.type_of(body.source.def_id()).subst_identity().is_generator() {
+            return;
+        }
+
         let mut excluded = excluded_locals(body);
         let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
         loop {
             debug!(?excluded);
-            let escaping = escaping_locals(&excluded, body);
+            let escaping = escaping_locals(tcx, param_env, &excluded, body);
             debug!(?escaping);
             let replacements = compute_flattening(tcx, param_env, body, escaping);
             debug!(?replacements);
@@ -48,11 +54,45 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
 /// - the locals is a union or an enum;
 /// - the local's address is taken, and thus the relative addresses of the fields are observable to
 ///   client code.
-fn escaping_locals(excluded: &BitSet<Local>, body: &Body<'_>) -> BitSet<Local> {
+fn escaping_locals<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    excluded: &BitSet<Local>,
+    body: &Body<'tcx>,
+) -> BitSet<Local> {
+    let is_excluded_ty = |ty: Ty<'tcx>| {
+        if ty.is_union() || ty.is_enum() {
+            return true;
+        }
+        if let ty::Adt(def, _substs) = ty.kind() {
+            if def.repr().flags.contains(ReprFlags::IS_SIMD) {
+                // Exclude #[repr(simd)] types so that they are not de-optimized into an array
+                return true;
+            }
+            // We already excluded unions and enums, so this ADT must have one variant
+            let variant = def.variant(FIRST_VARIANT);
+            if variant.fields.len() > 1 {
+                // If this has more than one field, it cannot be a wrapper that only provides a
+                // niche, so we do not want to automatically exclude it.
+                return false;
+            }
+            let Ok(layout) = tcx.layout_of(param_env.and(ty)) else {
+                // We can't get the layout
+                return true;
+            };
+            if layout.layout.largest_niche().is_some() {
+                // This type has a niche
+                return true;
+            }
+        }
+        // Default for non-ADTs
+        false
+    };
+
     let mut set = BitSet::new_empty(body.local_decls.len());
     set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count));
     for (local, decl) in body.local_decls().iter_enumerated() {
-        if decl.ty.is_union() || decl.ty.is_enum() || excluded.contains(local) {
+        if excluded.contains(local) || is_excluded_ty(decl.ty) {
             set.insert(local);
         }
     }
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index cefa64d27ac..09025c1ee33 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -179,7 +179,6 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::lang_items::LangItem;
-use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::mir::interpret::{AllocId, ConstValue};
 use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
 use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
@@ -220,78 +219,29 @@ pub struct InliningMap<'tcx> {
     // The range selects elements within the `targets` vecs.
     index: FxHashMap<MonoItem<'tcx>, Range<usize>>,
     targets: Vec<MonoItem<'tcx>>,
-
-    // Contains one bit per mono item in the `targets` field. That bit
-    // is true if that mono item needs to be inlined into every CGU.
-    inlines: GrowableBitSet<usize>,
-}
-
-/// Struct to store mono items in each collecting and if they should
-/// be inlined. We call `instantiation_mode` to get their inlining
-/// status when inserting new elements, which avoids calling it in
-/// `inlining_map.lock_mut()`. See the `collect_items_rec` implementation
-/// below.
-struct MonoItems<'tcx> {
-    // If this is false, we do not need to compute whether items
-    // will need to be inlined.
-    compute_inlining: bool,
-
-    // The TyCtxt used to determine whether the a item should
-    // be inlined.
-    tcx: TyCtxt<'tcx>,
-
-    // The collected mono items. The bool field in each element
-    // indicates whether this element should be inlined.
-    items: Vec<(Spanned<MonoItem<'tcx>>, bool /*inlined*/)>,
 }
 
-impl<'tcx> MonoItems<'tcx> {
-    #[inline]
-    fn push(&mut self, item: Spanned<MonoItem<'tcx>>) {
-        self.extend([item]);
-    }
-
-    #[inline]
-    fn extend<T: IntoIterator<Item = Spanned<MonoItem<'tcx>>>>(&mut self, iter: T) {
-        self.items.extend(iter.into_iter().map(|mono_item| {
-            let inlined = if !self.compute_inlining {
-                false
-            } else {
-                mono_item.node.instantiation_mode(self.tcx) == InstantiationMode::LocalCopy
-            };
-            (mono_item, inlined)
-        }))
-    }
-}
+type MonoItems<'tcx> = Vec<Spanned<MonoItem<'tcx>>>;
 
 impl<'tcx> InliningMap<'tcx> {
     fn new() -> InliningMap<'tcx> {
-        InliningMap {
-            index: FxHashMap::default(),
-            targets: Vec::new(),
-            inlines: GrowableBitSet::with_capacity(1024),
-        }
+        InliningMap { index: FxHashMap::default(), targets: Vec::new() }
     }
 
     fn record_accesses<'a>(
         &mut self,
         source: MonoItem<'tcx>,
-        new_targets: &'a [(Spanned<MonoItem<'tcx>>, bool)],
+        new_targets: &'a [Spanned<MonoItem<'tcx>>],
     ) where
         'tcx: 'a,
     {
         let start_index = self.targets.len();
         let new_items_count = new_targets.len();
-        let new_items_count_total = new_items_count + self.targets.len();
 
         self.targets.reserve(new_items_count);
-        self.inlines.ensure(new_items_count_total);
 
-        for (i, (Spanned { node: mono_item, .. }, inlined)) in new_targets.into_iter().enumerate() {
+        for Spanned { node: mono_item, .. } in new_targets.into_iter() {
             self.targets.push(*mono_item);
-            if *inlined {
-                self.inlines.insert(i + start_index);
-            }
         }
 
         let end_index = self.targets.len();
@@ -300,13 +250,14 @@ impl<'tcx> InliningMap<'tcx> {
 
     /// Internally iterate over all items referenced by `source` which will be
     /// made available for inlining.
-    pub fn with_inlining_candidates<F>(&self, source: MonoItem<'tcx>, mut f: F)
+    pub fn with_inlining_candidates<F>(&self, tcx: TyCtxt<'tcx>, source: MonoItem<'tcx>, mut f: F)
     where
         F: FnMut(MonoItem<'tcx>),
     {
         if let Some(range) = self.index.get(&source) {
-            for (i, candidate) in self.targets[range.clone()].iter().enumerate() {
-                if self.inlines.contains(range.start + i) {
+            for candidate in self.targets[range.clone()].iter() {
+                let is_inlined = candidate.instantiation_mode(tcx) == InstantiationMode::LocalCopy;
+                if is_inlined {
                     f(*candidate);
                 }
             }
@@ -367,7 +318,7 @@ pub fn collect_crate_mono_items(
 #[instrument(skip(tcx, mode), level = "debug")]
 fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<'_>> {
     debug!("collecting roots");
-    let mut roots = MonoItems { compute_inlining: false, tcx, items: Vec::new() };
+    let mut roots = Vec::new();
 
     {
         let entry_fn = tcx.entry_fn(());
@@ -393,9 +344,8 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
     // whose predicates hold. Luckily, items that aren't instantiable
     // can't actually be used, so we can just skip codegenning them.
     roots
-        .items
         .into_iter()
-        .filter_map(|(Spanned { node: mono_item, .. }, _)| {
+        .filter_map(|Spanned { node: mono_item, .. }| {
             mono_item.is_instantiable(tcx).then_some(mono_item)
         })
         .collect()
@@ -417,7 +367,7 @@ fn collect_items_rec<'tcx>(
         return;
     }
 
-    let mut neighbors = MonoItems { compute_inlining: true, tcx, items: Vec::new() };
+    let mut neighbors = Vec::new();
     let recursion_depth_reset;
 
     //
@@ -542,9 +492,9 @@ fn collect_items_rec<'tcx>(
             formatted_item,
         });
     }
-    inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors.items);
+    inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors);
 
-    for (neighbour, _) in neighbors.items {
+    for neighbour in neighbors {
         collect_items_rec(tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map);
     }
 
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
new file mode 100644
index 00000000000..0bacb58383d
--- /dev/null
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -0,0 +1,1183 @@
+//! Partitioning Codegen Units for Incremental Compilation
+//! ======================================================
+//!
+//! The task of this module is to take the complete set of monomorphizations of
+//! a crate and produce a set of codegen units from it, where a codegen unit
+//! is a named set of (mono-item, linkage) pairs. That is, this module
+//! decides which monomorphization appears in which codegen units with which
+//! linkage. The following paragraphs describe some of the background on the
+//! partitioning scheme.
+//!
+//! The most important opportunity for saving on compilation time with
+//! incremental compilation is to avoid re-codegenning and re-optimizing code.
+//! Since the unit of codegen and optimization for LLVM is "modules" or, how
+//! we call them "codegen units", the particulars of how much time can be saved
+//! by incremental compilation are tightly linked to how the output program is
+//! partitioned into these codegen units prior to passing it to LLVM --
+//! especially because we have to treat codegen units as opaque entities once
+//! they are created: There is no way for us to incrementally update an existing
+//! LLVM module and so we have to build any such module from scratch if it was
+//! affected by some change in the source code.
+//!
+//! From that point of view it would make sense to maximize the number of
+//! codegen units by, for example, putting each function into its own module.
+//! That way only those modules would have to be re-compiled that were actually
+//! affected by some change, minimizing the number of functions that could have
+//! been re-used but just happened to be located in a module that is
+//! re-compiled.
+//!
+//! However, since LLVM optimization does not work across module boundaries,
+//! using such a highly granular partitioning would lead to very slow runtime
+//! code since it would effectively prohibit inlining and other inter-procedure
+//! optimizations. We want to avoid that as much as possible.
+//!
+//! Thus we end up with a trade-off: The bigger the codegen units, the better
+//! LLVM's optimizer can do its work, but also the smaller the compilation time
+//! reduction we get from incremental compilation.
+//!
+//! Ideally, we would create a partitioning such that there are few big codegen
+//! units with few interdependencies between them. For now though, we use the
+//! following heuristic to determine the partitioning:
+//!
+//! - There are two codegen units for every source-level module:
+//! - One for "stable", that is non-generic, code
+//! - One for more "volatile" code, i.e., monomorphized instances of functions
+//!   defined in that module
+//!
+//! In order to see why this heuristic makes sense, let's take a look at when a
+//! codegen unit can get invalidated:
+//!
+//! 1. The most straightforward case is when the BODY of a function or global
+//! changes. Then any codegen unit containing the code for that item has to be
+//! re-compiled. Note that this includes all codegen units where the function
+//! has been inlined.
+//!
+//! 2. The next case is when the SIGNATURE of a function or global changes. In
+//! this case, all codegen units containing a REFERENCE to that item have to be
+//! re-compiled. This is a superset of case 1.
+//!
+//! 3. The final and most subtle case is when a REFERENCE to a generic function
+//! is added or removed somewhere. Even though the definition of the function
+//! might be unchanged, a new REFERENCE might introduce a new monomorphized
+//! instance of this function which has to be placed and compiled somewhere.
+//! Conversely, when removing a REFERENCE, it might have been the last one with
+//! that particular set of generic arguments and thus we have to remove it.
+//!
+//! From the above we see that just using one codegen unit per source-level
+//! module is not such a good idea, since just adding a REFERENCE to some
+//! generic item somewhere else would invalidate everything within the module
+//! containing the generic item. The heuristic above reduces this detrimental
+//! side-effect of references a little by at least not touching the non-generic
+//! code of the module.
+//!
+//! A Note on Inlining
+//! ------------------
+//! As briefly mentioned above, in order for LLVM to be able to inline a
+//! function call, the body of the function has to be available in the LLVM
+//! module where the call is made. This has a few consequences for partitioning:
+//!
+//! - The partitioning algorithm has to take care of placing functions into all
+//!   codegen units where they should be available for inlining. It also has to
+//!   decide on the correct linkage for these functions.
+//!
+//! - The partitioning algorithm has to know which functions are likely to get
+//!   inlined, so it can distribute function instantiations accordingly. Since
+//!   there is no way of knowing for sure which functions LLVM will decide to
+//!   inline in the end, we apply a heuristic here: Only functions marked with
+//!   `#[inline]` are considered for inlining by the partitioner. The current
+//!   implementation will not try to determine if a function is likely to be
+//!   inlined by looking at the functions definition.
+//!
+//! Note though that as a side-effect of creating a codegen units per
+//! source-level module, functions from the same module will be available for
+//! inlining, even when they are not marked `#[inline]`.
+
+use std::cmp;
+use std::collections::hash_map::Entry;
+use std::fs::{self, File};
+use std::io::{BufWriter, Write};
+use std::path::{Path, PathBuf};
+
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::sync;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
+use rustc_hir::definitions::DefPathDataName;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
+use rustc_middle::mir;
+use rustc_middle::mir::mono::{
+    CodegenUnit, CodegenUnitNameBuilder, InstantiationMode, Linkage, MonoItem, Visibility,
+};
+use rustc_middle::query::Providers;
+use rustc_middle::ty::print::{characteristic_def_id_of_type, with_no_trimmed_paths};
+use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt};
+use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
+use rustc_span::symbol::Symbol;
+
+use crate::collector::InliningMap;
+use crate::collector::{self, MonoItemCollectionMode};
+use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode};
+
+struct PartitioningCx<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    target_cgu_count: usize,
+    inlining_map: &'a InliningMap<'tcx>,
+}
+
+struct PlacedRootMonoItems<'tcx> {
+    codegen_units: Vec<CodegenUnit<'tcx>>,
+    roots: FxHashSet<MonoItem<'tcx>>,
+    internalization_candidates: FxHashSet<MonoItem<'tcx>>,
+}
+
+fn partition<'tcx, I>(
+    tcx: TyCtxt<'tcx>,
+    mono_items: &mut I,
+    max_cgu_count: usize,
+    inlining_map: &InliningMap<'tcx>,
+) -> Vec<CodegenUnit<'tcx>>
+where
+    I: Iterator<Item = MonoItem<'tcx>>,
+{
+    let _prof_timer = tcx.prof.generic_activity("cgu_partitioning");
+
+    let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map };
+    // In the first step, we place all regular monomorphizations into their
+    // respective 'home' codegen unit. Regular monomorphizations are all
+    // functions and statics defined in the local crate.
+    let PlacedRootMonoItems { mut codegen_units, roots, internalization_candidates } = {
+        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
+        place_root_mono_items(cx, mono_items)
+    };
+
+    for cgu in &mut codegen_units {
+        cgu.create_size_estimate(tcx);
+    }
+
+    debug_dump(tcx, "INITIAL PARTITIONING", &codegen_units);
+
+    // Merge until we have at most `max_cgu_count` codegen units.
+    // `merge_codegen_units` is responsible for updating the CGU size
+    // estimates.
+    {
+        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
+        merge_codegen_units(cx, &mut codegen_units);
+        debug_dump(tcx, "POST MERGING", &codegen_units);
+    }
+
+    // In the next step, we use the inlining map to determine which additional
+    // monomorphizations have to go into each codegen unit. These additional
+    // monomorphizations can be drop-glue, functions from external crates, and
+    // local functions the definition of which is marked with `#[inline]`.
+    let mono_item_placements = {
+        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
+        place_inlined_mono_items(cx, &mut codegen_units, roots)
+    };
+
+    for cgu in &mut codegen_units {
+        cgu.create_size_estimate(tcx);
+    }
+
+    debug_dump(tcx, "POST INLINING", &codegen_units);
+
+    // Next we try to make as many symbols "internal" as possible, so LLVM has
+    // more freedom to optimize.
+    if !tcx.sess.link_dead_code() {
+        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
+        internalize_symbols(
+            cx,
+            &mut codegen_units,
+            mono_item_placements,
+            internalization_candidates,
+        );
+    }
+
+    let instrument_dead_code =
+        tcx.sess.instrument_coverage() && !tcx.sess.instrument_coverage_except_unused_functions();
+
+    if instrument_dead_code {
+        assert!(
+            codegen_units.len() > 0,
+            "There must be at least one CGU that code coverage data can be generated in."
+        );
+
+        // Find the smallest CGU that has exported symbols and put the dead
+        // function stubs in that CGU. We look for exported symbols to increase
+        // the likelihood the linker won't throw away the dead functions.
+        // FIXME(#92165): In order to truly resolve this, we need to make sure
+        // the object file (CGU) containing the dead function stubs is included
+        // in the final binary. This will probably require forcing these
+        // function symbols to be included via `-u` or `/include` linker args.
+        let mut cgus: Vec<_> = codegen_units.iter_mut().collect();
+        cgus.sort_by_key(|cgu| cgu.size_estimate());
+
+        let dead_code_cgu =
+            if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
+                cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
+            }) {
+                cgu
+            } else {
+                // If there are no CGUs that have externally linked items,
+                // then we just pick the first CGU as a fallback.
+                &mut codegen_units[0]
+            };
+        dead_code_cgu.make_code_coverage_dead_code_cgu();
+    }
+
+    // Finally, sort by codegen unit name, so that we get deterministic results.
+    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
+
+    debug_dump(tcx, "FINAL", &codegen_units);
+
+    codegen_units
+}
+
+fn place_root_mono_items<'tcx, I>(
+    cx: &PartitioningCx<'_, 'tcx>,
+    mono_items: &mut I,
+) -> PlacedRootMonoItems<'tcx>
+where
+    I: Iterator<Item = MonoItem<'tcx>>,
+{
+    let mut roots = FxHashSet::default();
+    let mut codegen_units = FxHashMap::default();
+    let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
+    let mut internalization_candidates = FxHashSet::default();
+
+    // Determine if monomorphizations instantiated in this crate will be made
+    // available to downstream crates. This depends on whether we are in
+    // share-generics mode and whether the current crate can even have
+    // downstream crates.
+    let export_generics =
+        cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics();
+
+    let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
+    let cgu_name_cache = &mut FxHashMap::default();
+
+    for mono_item in mono_items {
+        match mono_item.instantiation_mode(cx.tcx) {
+            InstantiationMode::GloballyShared { .. } => {}
+            InstantiationMode::LocalCopy => continue,
+        }
+
+        let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
+        let is_volatile = is_incremental_build && mono_item.is_generic_fn();
+
+        let codegen_unit_name = match characteristic_def_id {
+            Some(def_id) => compute_codegen_unit_name(
+                cx.tcx,
+                cgu_name_builder,
+                def_id,
+                is_volatile,
+                cgu_name_cache,
+            ),
+            None => fallback_cgu_name(cgu_name_builder),
+        };
+
+        let codegen_unit = codegen_units
+            .entry(codegen_unit_name)
+            .or_insert_with(|| CodegenUnit::new(codegen_unit_name));
+
+        let mut can_be_internalized = true;
+        let (linkage, visibility) = mono_item_linkage_and_visibility(
+            cx.tcx,
+            &mono_item,
+            &mut can_be_internalized,
+            export_generics,
+        );
+        if visibility == Visibility::Hidden && can_be_internalized {
+            internalization_candidates.insert(mono_item);
+        }
+
+        codegen_unit.items_mut().insert(mono_item, (linkage, visibility));
+        roots.insert(mono_item);
+    }
+
+    // Always ensure we have at least one CGU; otherwise, if we have a
+    // crate with just types (for example), we could wind up with no CGU.
+    if codegen_units.is_empty() {
+        let codegen_unit_name = fallback_cgu_name(cgu_name_builder);
+        codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
+    }
+
+    let codegen_units = codegen_units.into_values().collect();
+    PlacedRootMonoItems { codegen_units, roots, internalization_candidates }
+}
+
+fn merge_codegen_units<'tcx>(
+    cx: &PartitioningCx<'_, 'tcx>,
+    codegen_units: &mut Vec<CodegenUnit<'tcx>>,
+) {
+    assert!(cx.target_cgu_count >= 1);
+
+    // Note that at this point in time the `codegen_units` here may not be
+    // in a deterministic order (but we know they're deterministically the
+    // same set). We want this merging to produce a deterministic ordering
+    // of codegen units from the input.
+    //
+    // Due to basically how we've implemented the merging below (merge the
+    // two smallest into each other) we're sure to start off with a
+    // deterministic order (sorted by name). This'll mean that if two cgus
+    // have the same size the stable sort below will keep everything nice
+    // and deterministic.
+    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
+
+    // This map keeps track of what got merged into what.
+    let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
+        codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
+
+    // Merge the two smallest codegen units until the target size is
+    // reached.
+    while codegen_units.len() > cx.target_cgu_count {
+        // Sort small cgus to the back
+        codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
+        let mut smallest = codegen_units.pop().unwrap();
+        let second_smallest = codegen_units.last_mut().unwrap();
+
+        // Move the mono-items from `smallest` to `second_smallest`
+        second_smallest.modify_size_estimate(smallest.size_estimate());
+        for (k, v) in smallest.items_mut().drain() {
+            second_smallest.items_mut().insert(k, v);
+        }
+
+        // Record that `second_smallest` now contains all the stuff that was
+        // in `smallest` before.
+        let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
+        cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names);
+
+        debug!(
+            "CodegenUnit {} merged into CodegenUnit {}",
+            smallest.name(),
+            second_smallest.name()
+        );
+    }
+
+    let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
+
+    if cx.tcx.sess.opts.incremental.is_some() {
+        // If we are doing incremental compilation, we want CGU names to
+        // reflect the path of the source level module they correspond to.
+        // For CGUs that contain the code of multiple modules because of the
+        // merging done above, we use a concatenation of the names of all
+        // contained CGUs.
+        let new_cgu_names: FxHashMap<Symbol, String> = cgu_contents
+            .into_iter()
+            // This `filter` makes sure we only update the name of CGUs that
+            // were actually modified by merging.
+            .filter(|(_, cgu_contents)| cgu_contents.len() > 1)
+            .map(|(current_cgu_name, cgu_contents)| {
+                let mut cgu_contents: Vec<&str> = cgu_contents.iter().map(|s| s.as_str()).collect();
+
+                // Sort the names, so things are deterministic and easy to
+                // predict. We are sorting primitive `&str`s here so we can
+                // use unstable sort.
+                cgu_contents.sort_unstable();
+
+                (current_cgu_name, cgu_contents.join("--"))
+            })
+            .collect();
+
+        for cgu in codegen_units.iter_mut() {
+            if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
+                if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
+                    cgu.set_name(Symbol::intern(&new_cgu_name));
+                } else {
+                    // If we don't require CGU names to be human-readable,
+                    // we use a fixed length hash of the composite CGU name
+                    // instead.
+                    let new_cgu_name = CodegenUnit::mangle_name(&new_cgu_name);
+                    cgu.set_name(Symbol::intern(&new_cgu_name));
+                }
+            }
+        }
+    } else {
+        // If we are compiling non-incrementally we just generate simple CGU
+        // names containing an index.
+        for (index, cgu) in codegen_units.iter_mut().enumerate() {
+            let numbered_codegen_unit_name =
+                cgu_name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index));
+            cgu.set_name(numbered_codegen_unit_name);
+        }
+    }
+}
+
+/// For symbol internalization, we need to know whether a symbol/mono-item is
+/// accessed from outside the codegen unit it is defined in. This type is used
+/// to keep track of that.
+#[derive(Clone, PartialEq, Eq, Debug)]
+enum MonoItemPlacement {
+    SingleCgu { cgu_name: Symbol },
+    MultipleCgus,
+}
+
+fn place_inlined_mono_items<'tcx>(
+    cx: &PartitioningCx<'_, 'tcx>,
+    codegen_units: &mut [CodegenUnit<'tcx>],
+    roots: FxHashSet<MonoItem<'tcx>>,
+) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
+    let mut mono_item_placements = FxHashMap::default();
+
+    let single_codegen_unit = codegen_units.len() == 1;
+
+    for old_codegen_unit in codegen_units.iter_mut() {
+        // Collect all items that need to be available in this codegen unit.
+        let mut reachable = FxHashSet::default();
+        for root in old_codegen_unit.items().keys() {
+            follow_inlining(cx.tcx, *root, cx.inlining_map, &mut reachable);
+        }
+
+        let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
+
+        // Add all monomorphizations that are not already there.
+        for mono_item in reachable {
+            if let Some(linkage) = old_codegen_unit.items().get(&mono_item) {
+                // This is a root, just copy it over.
+                new_codegen_unit.items_mut().insert(mono_item, *linkage);
+            } else {
+                if roots.contains(&mono_item) {
+                    bug!(
+                        "GloballyShared mono-item inlined into other CGU: \
+                          {:?}",
+                        mono_item
+                    );
+                }
+
+                // This is a CGU-private copy.
+                new_codegen_unit
+                    .items_mut()
+                    .insert(mono_item, (Linkage::Internal, Visibility::Default));
+            }
+
+            if !single_codegen_unit {
+                // If there is more than one codegen unit, we need to keep track
+                // in which codegen units each monomorphization is placed.
+                match mono_item_placements.entry(mono_item) {
+                    Entry::Occupied(e) => {
+                        let placement = e.into_mut();
+                        debug_assert!(match *placement {
+                            MonoItemPlacement::SingleCgu { cgu_name } => {
+                                cgu_name != new_codegen_unit.name()
+                            }
+                            MonoItemPlacement::MultipleCgus => true,
+                        });
+                        *placement = MonoItemPlacement::MultipleCgus;
+                    }
+                    Entry::Vacant(e) => {
+                        e.insert(MonoItemPlacement::SingleCgu {
+                            cgu_name: new_codegen_unit.name(),
+                        });
+                    }
+                }
+            }
+        }
+
+        *old_codegen_unit = new_codegen_unit;
+    }
+
+    return mono_item_placements;
+
+    fn follow_inlining<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        mono_item: MonoItem<'tcx>,
+        inlining_map: &InliningMap<'tcx>,
+        visited: &mut FxHashSet<MonoItem<'tcx>>,
+    ) {
+        if !visited.insert(mono_item) {
+            return;
+        }
+
+        inlining_map.with_inlining_candidates(tcx, mono_item, |target| {
+            follow_inlining(tcx, target, inlining_map, visited);
+        });
+    }
+}
+
+fn internalize_symbols<'tcx>(
+    cx: &PartitioningCx<'_, 'tcx>,
+    codegen_units: &mut [CodegenUnit<'tcx>],
+    mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
+    internalization_candidates: FxHashSet<MonoItem<'tcx>>,
+) {
+    if codegen_units.len() == 1 {
+        // Fast path for when there is only one codegen unit. In this case we
+        // can internalize all candidates, since there is nowhere else they
+        // could be accessed from.
+        for cgu in codegen_units {
+            for candidate in &internalization_candidates {
+                cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default));
+            }
+        }
+
+        return;
+    }
+
+    // Build a map from every monomorphization to all the monomorphizations that
+    // reference it.
+    let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
+    cx.inlining_map.iter_accesses(|accessor, accessees| {
+        for accessee in accessees {
+            accessor_map.entry(*accessee).or_default().push(accessor);
+        }
+    });
+
+    // For each internalization candidates in each codegen unit, check if it is
+    // accessed from outside its defining codegen unit.
+    for cgu in codegen_units {
+        let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
+
+        for (accessee, linkage_and_visibility) in cgu.items_mut() {
+            if !internalization_candidates.contains(accessee) {
+                // This item is no candidate for internalizing, so skip it.
+                continue;
+            }
+            debug_assert_eq!(mono_item_placements[accessee], home_cgu);
+
+            if let Some(accessors) = accessor_map.get(accessee) {
+                if accessors
+                    .iter()
+                    .filter_map(|accessor| {
+                        // Some accessors might not have been
+                        // instantiated. We can safely ignore those.
+                        mono_item_placements.get(accessor)
+                    })
+                    .any(|placement| *placement != home_cgu)
+                {
+                    // Found an accessor from another CGU, so skip to the next
+                    // item without marking this one as internal.
+                    continue;
+                }
+            }
+
+            // If we got here, we did not find any accesses from other CGUs,
+            // so it's fine to make this monomorphization internal.
+            *linkage_and_visibility = (Linkage::Internal, Visibility::Default);
+        }
+    }
+}
+
+fn characteristic_def_id_of_mono_item<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mono_item: MonoItem<'tcx>,
+) -> Option<DefId> {
+    match mono_item {
+        MonoItem::Fn(instance) => {
+            let def_id = match instance.def {
+                ty::InstanceDef::Item(def) => def,
+                ty::InstanceDef::VTableShim(..)
+                | ty::InstanceDef::ReifyShim(..)
+                | ty::InstanceDef::FnPtrShim(..)
+                | ty::InstanceDef::ClosureOnceShim { .. }
+                | ty::InstanceDef::Intrinsic(..)
+                | ty::InstanceDef::DropGlue(..)
+                | ty::InstanceDef::Virtual(..)
+                | ty::InstanceDef::CloneShim(..)
+                | ty::InstanceDef::ThreadLocalShim(..)
+                | ty::InstanceDef::FnPtrAddrShim(..) => return None,
+            };
+
+            // If this is a method, we want to put it into the same module as
+            // its self-type. If the self-type does not provide a characteristic
+            // DefId, we use the location of the impl after all.
+
+            if tcx.trait_of_item(def_id).is_some() {
+                let self_ty = instance.substs.type_at(0);
+                // This is a default implementation of a trait method.
+                return characteristic_def_id_of_type(self_ty).or(Some(def_id));
+            }
+
+            if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
+                if tcx.sess.opts.incremental.is_some()
+                    && tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait()
+                {
+                    // Put `Drop::drop` into the same cgu as `drop_in_place`
+                    // since `drop_in_place` is the only thing that can
+                    // call it.
+                    return None;
+                }
+
+                // When polymorphization is enabled, methods which do not depend on their generic
+                // parameters, but the self-type of their impl block do will fail to normalize.
+                if !tcx.sess.opts.unstable_opts.polymorphize || !instance.has_param() {
+                    // This is a method within an impl, find out what the self-type is:
+                    let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
+                        instance.substs,
+                        ty::ParamEnv::reveal_all(),
+                        tcx.type_of(impl_def_id),
+                    );
+                    if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
+                        return Some(def_id);
+                    }
+                }
+            }
+
+            Some(def_id)
+        }
+        MonoItem::Static(def_id) => Some(def_id),
+        MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.to_def_id()),
+    }
+}
+
+fn compute_codegen_unit_name(
+    tcx: TyCtxt<'_>,
+    name_builder: &mut CodegenUnitNameBuilder<'_>,
+    def_id: DefId,
+    volatile: bool,
+    cache: &mut CguNameCache,
+) -> Symbol {
+    // Find the innermost module that is not nested within a function.
+    let mut current_def_id = def_id;
+    let mut cgu_def_id = None;
+    // Walk backwards from the item we want to find the module for.
+    loop {
+        if current_def_id.is_crate_root() {
+            if cgu_def_id.is_none() {
+                // If we have not found a module yet, take the crate root.
+                cgu_def_id = Some(def_id.krate.as_def_id());
+            }
+            break;
+        } else if tcx.def_kind(current_def_id) == DefKind::Mod {
+            if cgu_def_id.is_none() {
+                cgu_def_id = Some(current_def_id);
+            }
+        } else {
+            // If we encounter something that is not a module, throw away
+            // any module that we've found so far because we now know that
+            // it is nested within something else.
+            cgu_def_id = None;
+        }
+
+        current_def_id = tcx.parent(current_def_id);
+    }
+
+    let cgu_def_id = cgu_def_id.unwrap();
+
+    *cache.entry((cgu_def_id, volatile)).or_insert_with(|| {
+        let def_path = tcx.def_path(cgu_def_id);
+
+        let components = def_path.data.iter().map(|part| match part.data.name() {
+            DefPathDataName::Named(name) => name,
+            DefPathDataName::Anon { .. } => unreachable!(),
+        });
+
+        let volatile_suffix = volatile.then_some("volatile");
+
+        name_builder.build_cgu_name(def_path.krate, components, volatile_suffix)
+    })
+}
+
+// Anything we can't find a proper codegen unit for goes into this.
+fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol {
+    name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu"))
+}
+
+fn mono_item_linkage_and_visibility<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mono_item: &MonoItem<'tcx>,
+    can_be_internalized: &mut bool,
+    export_generics: bool,
+) -> (Linkage, Visibility) {
+    if let Some(explicit_linkage) = mono_item.explicit_linkage(tcx) {
+        return (explicit_linkage, Visibility::Default);
+    }
+    let vis = mono_item_visibility(tcx, mono_item, can_be_internalized, export_generics);
+    (Linkage::External, vis)
+}
+
+type CguNameCache = FxHashMap<(DefId, bool), Symbol>;
+
+fn static_visibility<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    can_be_internalized: &mut bool,
+    def_id: DefId,
+) -> Visibility {
+    if tcx.is_reachable_non_generic(def_id) {
+        *can_be_internalized = false;
+        default_visibility(tcx, def_id, false)
+    } else {
+        Visibility::Hidden
+    }
+}
+
+fn mono_item_visibility<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    mono_item: &MonoItem<'tcx>,
+    can_be_internalized: &mut bool,
+    export_generics: bool,
+) -> Visibility {
+    let instance = match mono_item {
+        // This is pretty complicated; see below.
+        MonoItem::Fn(instance) => instance,
+
+        // Misc handling for generics and such, but otherwise:
+        MonoItem::Static(def_id) => return static_visibility(tcx, can_be_internalized, *def_id),
+        MonoItem::GlobalAsm(item_id) => {
+            return static_visibility(tcx, can_be_internalized, item_id.owner_id.to_def_id());
+        }
+    };
+
+    let def_id = match instance.def {
+        InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id,
+
+        // We match the visibility of statics here
+        InstanceDef::ThreadLocalShim(def_id) => {
+            return static_visibility(tcx, can_be_internalized, def_id);
+        }
+
+        // These are all compiler glue and such, never exported, always hidden.
+        InstanceDef::VTableShim(..)
+        | InstanceDef::ReifyShim(..)
+        | InstanceDef::FnPtrShim(..)
+        | InstanceDef::Virtual(..)
+        | InstanceDef::Intrinsic(..)
+        | InstanceDef::ClosureOnceShim { .. }
+        | InstanceDef::DropGlue(..)
+        | InstanceDef::CloneShim(..)
+        | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden,
+    };
+
+    // The `start_fn` lang item is actually a monomorphized instance of a
+    // function in the standard library, used for the `main` function. We don't
+    // want to export it so we tag it with `Hidden` visibility but this symbol
+    // is only referenced from the actual `main` symbol which we unfortunately
+    // don't know anything about during partitioning/collection. As a result we
+    // forcibly keep this symbol out of the `internalization_candidates` set.
+    //
+    // FIXME: eventually we don't want to always force this symbol to have
+    //        hidden visibility, it should indeed be a candidate for
+    //        internalization, but we have to understand that it's referenced
+    //        from the `main` symbol we'll generate later.
+    //
+    //        This may be fixable with a new `InstanceDef` perhaps? Unsure!
+    if tcx.lang_items().start_fn() == Some(def_id) {
+        *can_be_internalized = false;
+        return Visibility::Hidden;
+    }
+
+    let is_generic = instance.substs.non_erasable_generics().next().is_some();
+
+    // Upstream `DefId` instances get different handling than local ones.
+    let Some(def_id) = def_id.as_local() else {
+        return if export_generics && is_generic {
+            // If it is an upstream monomorphization and we export generics, we must make
+            // it available to downstream crates.
+            *can_be_internalized = false;
+            default_visibility(tcx, def_id, true)
+        } else {
+            Visibility::Hidden
+        };
+    };
+
+    if is_generic {
+        if export_generics {
+            if tcx.is_unreachable_local_definition(def_id) {
+                // This instance cannot be used from another crate.
+                Visibility::Hidden
+            } else {
+                // This instance might be useful in a downstream crate.
+                *can_be_internalized = false;
+                default_visibility(tcx, def_id.to_def_id(), true)
+            }
+        } else {
+            // We are not exporting generics or the definition is not reachable
+            // for downstream crates, we can internalize its instantiations.
+            Visibility::Hidden
+        }
+    } else {
+        // If this isn't a generic function then we mark this a `Default` if
+        // this is a reachable item, meaning that it's a symbol other crates may
+        // access when they link to us.
+        if tcx.is_reachable_non_generic(def_id.to_def_id()) {
+            *can_be_internalized = false;
+            debug_assert!(!is_generic);
+            return default_visibility(tcx, def_id.to_def_id(), false);
+        }
+
+        // If this isn't reachable then we're gonna tag this with `Hidden`
+        // visibility. In some situations though we'll want to prevent this
+        // symbol from being internalized.
+        //
+        // There's two categories of items here:
+        //
+        // * First is weak lang items. These are basically mechanisms for
+        //   libcore to forward-reference symbols defined later in crates like
+        //   the standard library or `#[panic_handler]` definitions. The
+        //   definition of these weak lang items needs to be referencable by
+        //   libcore, so we're no longer a candidate for internalization.
+        //   Removal of these functions can't be done by LLVM but rather must be
+        //   done by the linker as it's a non-local decision.
+        //
+        // * Second is "std internal symbols". Currently this is primarily used
+        //   for allocator symbols. Allocators are a little weird in their
+        //   implementation, but the idea is that the compiler, at the last
+        //   minute, defines an allocator with an injected object file. The
+        //   `alloc` crate references these symbols (`__rust_alloc`) and the
+        //   definition doesn't get hooked up until a linked crate artifact is
+        //   generated.
+        //
+        //   The symbols synthesized by the compiler (`__rust_alloc`) are thin
+        //   veneers around the actual implementation, some other symbol which
+        //   implements the same ABI. These symbols (things like `__rg_alloc`,
+        //   `__rdl_alloc`, `__rde_alloc`, etc), are all tagged with "std
+        //   internal symbols".
+        //
+        //   The std-internal symbols here **should not show up in a dll as an
+        //   exported interface**, so they return `false` from
+        //   `is_reachable_non_generic` above and we'll give them `Hidden`
+        //   visibility below. Like the weak lang items, though, we can't let
+        //   LLVM internalize them as this decision is left up to the linker to
+        //   omit them, so prevent them from being internalized.
+        let attrs = tcx.codegen_fn_attrs(def_id);
+        if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
+            *can_be_internalized = false;
+        }
+
+        Visibility::Hidden
+    }
+}
+
+fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
+    if !tcx.sess.target.default_hidden_visibility {
+        return Visibility::Default;
+    }
+
+    // Generic functions never have export-level C.
+    if is_generic {
+        return Visibility::Hidden;
+    }
+
+    // Things with export level C don't get instantiated in
+    // downstream crates.
+    if !id.is_local() {
+        return Visibility::Hidden;
+    }
+
+    // C-export level items remain at `Default`, all other internal
+    // items become `Hidden`.
+    match tcx.reachable_non_generics(id.krate).get(&id) {
+        Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => Visibility::Default,
+        _ => Visibility::Hidden,
+    }
+}
+fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<'tcx>]) {
+    let dump = move || {
+        use std::fmt::Write;
+
+        let num_cgus = cgus.len();
+        let max = cgus.iter().map(|cgu| cgu.size_estimate()).max().unwrap();
+        let min = cgus.iter().map(|cgu| cgu.size_estimate()).min().unwrap();
+        let ratio = max as f64 / min as f64;
+
+        let s = &mut String::new();
+        let _ = writeln!(
+            s,
+            "{label} ({num_cgus} CodegenUnits, max={max}, min={min}, max/min={ratio:.1}):"
+        );
+        for cgu in cgus {
+            let _ =
+                writeln!(s, "CodegenUnit {} estimated size {}:", cgu.name(), cgu.size_estimate());
+
+            for (mono_item, linkage) in cgu.items() {
+                let symbol_name = mono_item.symbol_name(tcx).name;
+                let symbol_hash_start = symbol_name.rfind('h');
+                let symbol_hash = symbol_hash_start.map_or("<no hash>", |i| &symbol_name[i..]);
+
+                let _ = with_no_trimmed_paths!(writeln!(
+                    s,
+                    " - {} [{:?}] [{}] estimated size {}",
+                    mono_item,
+                    linkage,
+                    symbol_hash,
+                    mono_item.size_estimate(tcx)
+                ));
+            }
+
+            let _ = writeln!(s);
+        }
+
+        std::mem::take(s)
+    };
+
+    debug!("{}", dump());
+}
+
+#[inline(never)] // give this a place in the profiler
+fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I)
+where
+    I: Iterator<Item = &'a MonoItem<'tcx>>,
+    'tcx: 'a,
+{
+    let _prof_timer = tcx.prof.generic_activity("assert_symbols_are_distinct");
+
+    let mut symbols: Vec<_> =
+        mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect();
+
+    symbols.sort_by_key(|sym| sym.1);
+
+    for &[(mono_item1, ref sym1), (mono_item2, ref sym2)] in symbols.array_windows() {
+        if sym1 == sym2 {
+            let span1 = mono_item1.local_span(tcx);
+            let span2 = mono_item2.local_span(tcx);
+
+            // Deterministically select one of the spans for error reporting
+            let span = match (span1, span2) {
+                (Some(span1), Some(span2)) => {
+                    Some(if span1.lo().0 > span2.lo().0 { span1 } else { span2 })
+                }
+                (span1, span2) => span1.or(span2),
+            };
+
+            tcx.sess.emit_fatal(SymbolAlreadyDefined { span, symbol: sym1.to_string() });
+        }
+    }
+}
+
+fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[CodegenUnit<'_>]) {
+    let collection_mode = match tcx.sess.opts.unstable_opts.print_mono_items {
+        Some(ref s) => {
+            let mode = s.to_lowercase();
+            let mode = mode.trim();
+            if mode == "eager" {
+                MonoItemCollectionMode::Eager
+            } else {
+                if mode != "lazy" {
+                    tcx.sess.emit_warning(UnknownCguCollectionMode { mode });
+                }
+
+                MonoItemCollectionMode::Lazy
+            }
+        }
+        None => {
+            if tcx.sess.link_dead_code() {
+                MonoItemCollectionMode::Eager
+            } else {
+                MonoItemCollectionMode::Lazy
+            }
+        }
+    };
+
+    let (items, inlining_map) = collector::collect_crate_mono_items(tcx, collection_mode);
+
+    tcx.sess.abort_if_errors();
+
+    let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {
+        sync::join(
+            || {
+                let mut codegen_units = partition(
+                    tcx,
+                    &mut items.iter().copied(),
+                    tcx.sess.codegen_units(),
+                    &inlining_map,
+                );
+                codegen_units[0].make_primary();
+                &*tcx.arena.alloc_from_iter(codegen_units)
+            },
+            || assert_symbols_are_distinct(tcx, items.iter()),
+        )
+    });
+
+    if tcx.prof.enabled() {
+        // Record CGU size estimates for self-profiling.
+        for cgu in codegen_units {
+            tcx.prof.artifact_size(
+                "codegen_unit_size_estimate",
+                cgu.name().as_str(),
+                cgu.size_estimate() as u64,
+            );
+        }
+    }
+
+    let mono_items: DefIdSet = items
+        .iter()
+        .filter_map(|mono_item| match *mono_item {
+            MonoItem::Fn(ref instance) => Some(instance.def_id()),
+            MonoItem::Static(def_id) => Some(def_id),
+            _ => None,
+        })
+        .collect();
+
+    // Output monomorphization stats per def_id
+    if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats {
+        if let Err(err) =
+            dump_mono_items_stats(tcx, &codegen_units, path, tcx.crate_name(LOCAL_CRATE))
+        {
+            tcx.sess.emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
+        }
+    }
+
+    if tcx.sess.opts.unstable_opts.print_mono_items.is_some() {
+        let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
+
+        for cgu in codegen_units {
+            for (&mono_item, &linkage) in cgu.items() {
+                item_to_cgus.entry(mono_item).or_default().push((cgu.name(), linkage));
+            }
+        }
+
+        let mut item_keys: Vec<_> = items
+            .iter()
+            .map(|i| {
+                let mut output = with_no_trimmed_paths!(i.to_string());
+                output.push_str(" @@");
+                let mut empty = Vec::new();
+                let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
+                cgus.sort_by_key(|(name, _)| *name);
+                cgus.dedup();
+                for &(ref cgu_name, (linkage, _)) in cgus.iter() {
+                    output.push(' ');
+                    output.push_str(cgu_name.as_str());
+
+                    let linkage_abbrev = match linkage {
+                        Linkage::External => "External",
+                        Linkage::AvailableExternally => "Available",
+                        Linkage::LinkOnceAny => "OnceAny",
+                        Linkage::LinkOnceODR => "OnceODR",
+                        Linkage::WeakAny => "WeakAny",
+                        Linkage::WeakODR => "WeakODR",
+                        Linkage::Appending => "Appending",
+                        Linkage::Internal => "Internal",
+                        Linkage::Private => "Private",
+                        Linkage::ExternalWeak => "ExternalWeak",
+                        Linkage::Common => "Common",
+                    };
+
+                    output.push('[');
+                    output.push_str(linkage_abbrev);
+                    output.push(']');
+                }
+                output
+            })
+            .collect();
+
+        item_keys.sort();
+
+        for item in item_keys {
+            println!("MONO_ITEM {item}");
+        }
+    }
+
+    (tcx.arena.alloc(mono_items), codegen_units)
+}
+
+/// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s
+/// def, to a file in the given output directory.
+fn dump_mono_items_stats<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    codegen_units: &[CodegenUnit<'tcx>],
+    output_directory: &Option<PathBuf>,
+    crate_name: Symbol,
+) -> Result<(), Box<dyn std::error::Error>> {
+    let output_directory = if let Some(ref directory) = output_directory {
+        fs::create_dir_all(directory)?;
+        directory
+    } else {
+        Path::new(".")
+    };
+
+    let format = tcx.sess.opts.unstable_opts.dump_mono_stats_format;
+    let ext = format.extension();
+    let filename = format!("{crate_name}.mono_items.{ext}");
+    let output_path = output_directory.join(&filename);
+    let file = File::create(&output_path)?;
+    let mut file = BufWriter::new(file);
+
+    // Gather instantiated mono items grouped by def_id
+    let mut items_per_def_id: FxHashMap<_, Vec<_>> = Default::default();
+    for cgu in codegen_units {
+        for (&mono_item, _) in cgu.items() {
+            // Avoid variable-sized compiler-generated shims
+            if mono_item.is_user_defined() {
+                items_per_def_id.entry(mono_item.def_id()).or_default().push(mono_item);
+            }
+        }
+    }
+
+    #[derive(serde::Serialize)]
+    struct MonoItem {
+        name: String,
+        instantiation_count: usize,
+        size_estimate: usize,
+        total_estimate: usize,
+    }
+
+    // Output stats sorted by total instantiated size, from heaviest to lightest
+    let mut stats: Vec<_> = items_per_def_id
+        .into_iter()
+        .map(|(def_id, items)| {
+            let name = with_no_trimmed_paths!(tcx.def_path_str(def_id));
+            let instantiation_count = items.len();
+            let size_estimate = items[0].size_estimate(tcx);
+            let total_estimate = instantiation_count * size_estimate;
+            MonoItem { name, instantiation_count, size_estimate, total_estimate }
+        })
+        .collect();
+    stats.sort_unstable_by_key(|item| cmp::Reverse(item.total_estimate));
+
+    if !stats.is_empty() {
+        match format {
+            DumpMonoStatsFormat::Json => serde_json::to_writer(file, &stats)?,
+            DumpMonoStatsFormat::Markdown => {
+                writeln!(
+                    file,
+                    "| Item | Instantiation count | Estimated Cost Per Instantiation | Total Estimated Cost |"
+                )?;
+                writeln!(file, "| --- | ---: | ---: | ---: |")?;
+
+                for MonoItem { name, instantiation_count, size_estimate, total_estimate } in stats {
+                    writeln!(
+                        file,
+                        "| `{name}` | {instantiation_count} | {size_estimate} | {total_estimate} |"
+                    )?;
+                }
+            }
+        }
+    }
+
+    Ok(())
+}
+
+fn codegened_and_inlined_items(tcx: TyCtxt<'_>, (): ()) -> &DefIdSet {
+    let (items, cgus) = tcx.collect_and_partition_mono_items(());
+    let mut visited = DefIdSet::default();
+    let mut result = items.clone();
+
+    for cgu in cgus {
+        for (item, _) in cgu.items() {
+            if let MonoItem::Fn(ref instance) = item {
+                let did = instance.def_id();
+                if !visited.insert(did) {
+                    continue;
+                }
+                let body = tcx.instance_mir(instance.def);
+                for block in body.basic_blocks.iter() {
+                    for statement in &block.statements {
+                        let mir::StatementKind::Coverage(_) = statement.kind else { continue };
+                        let scope = statement.source_info.scope;
+                        if let Some(inlined) = scope.inlined_instance(&body.source_scopes) {
+                            result.insert(inlined.def_id());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    tcx.arena.alloc(result)
+}
+
+pub fn provide(providers: &mut Providers) {
+    providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
+    providers.codegened_and_inlined_items = codegened_and_inlined_items;
+
+    providers.is_codegened_item = |tcx, def_id| {
+        let (all_mono_items, _) = tcx.collect_and_partition_mono_items(());
+        all_mono_items.contains(&def_id)
+    };
+
+    providers.codegen_unit = |tcx, name| {
+        let (_, all) = tcx.collect_and_partition_mono_items(());
+        all.iter()
+            .find(|cgu| cgu.name() == name)
+            .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}"))
+    };
+}
diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs
deleted file mode 100644
index 603b3ddc106..00000000000
--- a/compiler/rustc_monomorphize/src/partitioning/default.rs
+++ /dev/null
@@ -1,644 +0,0 @@
-use std::cmp;
-use std::collections::hash_map::Entry;
-
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LOCAL_CRATE};
-use rustc_hir::definitions::DefPathDataName;
-use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
-use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility};
-use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
-use rustc_middle::ty::print::characteristic_def_id_of_type;
-use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt};
-use rustc_span::symbol::Symbol;
-
-use super::PartitioningCx;
-use crate::collector::InliningMap;
-use crate::partitioning::{MonoItemPlacement, Partition, PlacedRootMonoItems};
-
-pub struct DefaultPartitioning;
-
-impl<'tcx> Partition<'tcx> for DefaultPartitioning {
-    fn place_root_mono_items<I>(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        mono_items: &mut I,
-    ) -> PlacedRootMonoItems<'tcx>
-    where
-        I: Iterator<Item = MonoItem<'tcx>>,
-    {
-        let mut roots = FxHashSet::default();
-        let mut codegen_units = FxHashMap::default();
-        let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
-        let mut internalization_candidates = FxHashSet::default();
-
-        // Determine if monomorphizations instantiated in this crate will be made
-        // available to downstream crates. This depends on whether we are in
-        // share-generics mode and whether the current crate can even have
-        // downstream crates.
-        let export_generics =
-            cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics();
-
-        let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
-        let cgu_name_cache = &mut FxHashMap::default();
-
-        for mono_item in mono_items {
-            match mono_item.instantiation_mode(cx.tcx) {
-                InstantiationMode::GloballyShared { .. } => {}
-                InstantiationMode::LocalCopy => continue,
-            }
-
-            let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
-            let is_volatile = is_incremental_build && mono_item.is_generic_fn();
-
-            let codegen_unit_name = match characteristic_def_id {
-                Some(def_id) => compute_codegen_unit_name(
-                    cx.tcx,
-                    cgu_name_builder,
-                    def_id,
-                    is_volatile,
-                    cgu_name_cache,
-                ),
-                None => fallback_cgu_name(cgu_name_builder),
-            };
-
-            let codegen_unit = codegen_units
-                .entry(codegen_unit_name)
-                .or_insert_with(|| CodegenUnit::new(codegen_unit_name));
-
-            let mut can_be_internalized = true;
-            let (linkage, visibility) = mono_item_linkage_and_visibility(
-                cx.tcx,
-                &mono_item,
-                &mut can_be_internalized,
-                export_generics,
-            );
-            if visibility == Visibility::Hidden && can_be_internalized {
-                internalization_candidates.insert(mono_item);
-            }
-
-            codegen_unit.items_mut().insert(mono_item, (linkage, visibility));
-            roots.insert(mono_item);
-        }
-
-        // Always ensure we have at least one CGU; otherwise, if we have a
-        // crate with just types (for example), we could wind up with no CGU.
-        if codegen_units.is_empty() {
-            let codegen_unit_name = fallback_cgu_name(cgu_name_builder);
-            codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name));
-        }
-
-        let codegen_units = codegen_units.into_values().collect();
-        PlacedRootMonoItems { codegen_units, roots, internalization_candidates }
-    }
-
-    fn merge_codegen_units(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut Vec<CodegenUnit<'tcx>>,
-    ) {
-        assert!(cx.target_cgu_count >= 1);
-
-        // Note that at this point in time the `codegen_units` here may not be
-        // in a deterministic order (but we know they're deterministically the
-        // same set). We want this merging to produce a deterministic ordering
-        // of codegen units from the input.
-        //
-        // Due to basically how we've implemented the merging below (merge the
-        // two smallest into each other) we're sure to start off with a
-        // deterministic order (sorted by name). This'll mean that if two cgus
-        // have the same size the stable sort below will keep everything nice
-        // and deterministic.
-        codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
-
-        // This map keeps track of what got merged into what.
-        let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
-            codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
-
-        // Merge the two smallest codegen units until the target size is
-        // reached.
-        while codegen_units.len() > cx.target_cgu_count {
-            // Sort small cgus to the back
-            codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
-            let mut smallest = codegen_units.pop().unwrap();
-            let second_smallest = codegen_units.last_mut().unwrap();
-
-            // Move the mono-items from `smallest` to `second_smallest`
-            second_smallest.modify_size_estimate(smallest.size_estimate());
-            for (k, v) in smallest.items_mut().drain() {
-                second_smallest.items_mut().insert(k, v);
-            }
-
-            // Record that `second_smallest` now contains all the stuff that was
-            // in `smallest` before.
-            let mut consumed_cgu_names = cgu_contents.remove(&smallest.name()).unwrap();
-            cgu_contents.get_mut(&second_smallest.name()).unwrap().append(&mut consumed_cgu_names);
-
-            debug!(
-                "CodegenUnit {} merged into CodegenUnit {}",
-                smallest.name(),
-                second_smallest.name()
-            );
-        }
-
-        let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
-
-        if cx.tcx.sess.opts.incremental.is_some() {
-            // If we are doing incremental compilation, we want CGU names to
-            // reflect the path of the source level module they correspond to.
-            // For CGUs that contain the code of multiple modules because of the
-            // merging done above, we use a concatenation of the names of all
-            // contained CGUs.
-            let new_cgu_names: FxHashMap<Symbol, String> = cgu_contents
-                .into_iter()
-                // This `filter` makes sure we only update the name of CGUs that
-                // were actually modified by merging.
-                .filter(|(_, cgu_contents)| cgu_contents.len() > 1)
-                .map(|(current_cgu_name, cgu_contents)| {
-                    let mut cgu_contents: Vec<&str> =
-                        cgu_contents.iter().map(|s| s.as_str()).collect();
-
-                    // Sort the names, so things are deterministic and easy to
-                    // predict. We are sorting primitive `&str`s here so we can
-                    // use unstable sort.
-                    cgu_contents.sort_unstable();
-
-                    (current_cgu_name, cgu_contents.join("--"))
-                })
-                .collect();
-
-            for cgu in codegen_units.iter_mut() {
-                if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
-                    if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names {
-                        cgu.set_name(Symbol::intern(&new_cgu_name));
-                    } else {
-                        // If we don't require CGU names to be human-readable,
-                        // we use a fixed length hash of the composite CGU name
-                        // instead.
-                        let new_cgu_name = CodegenUnit::mangle_name(&new_cgu_name);
-                        cgu.set_name(Symbol::intern(&new_cgu_name));
-                    }
-                }
-            }
-        } else {
-            // If we are compiling non-incrementally we just generate simple CGU
-            // names containing an index.
-            for (index, cgu) in codegen_units.iter_mut().enumerate() {
-                let numbered_codegen_unit_name =
-                    cgu_name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index));
-                cgu.set_name(numbered_codegen_unit_name);
-            }
-        }
-    }
-
-    fn place_inlined_mono_items(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut [CodegenUnit<'tcx>],
-        roots: FxHashSet<MonoItem<'tcx>>,
-    ) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
-        let mut mono_item_placements = FxHashMap::default();
-
-        let single_codegen_unit = codegen_units.len() == 1;
-
-        for old_codegen_unit in codegen_units.iter_mut() {
-            // Collect all items that need to be available in this codegen unit.
-            let mut reachable = FxHashSet::default();
-            for root in old_codegen_unit.items().keys() {
-                follow_inlining(*root, cx.inlining_map, &mut reachable);
-            }
-
-            let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
-
-            // Add all monomorphizations that are not already there.
-            for mono_item in reachable {
-                if let Some(linkage) = old_codegen_unit.items().get(&mono_item) {
-                    // This is a root, just copy it over.
-                    new_codegen_unit.items_mut().insert(mono_item, *linkage);
-                } else {
-                    if roots.contains(&mono_item) {
-                        bug!(
-                            "GloballyShared mono-item inlined into other CGU: \
-                              {:?}",
-                            mono_item
-                        );
-                    }
-
-                    // This is a CGU-private copy.
-                    new_codegen_unit
-                        .items_mut()
-                        .insert(mono_item, (Linkage::Internal, Visibility::Default));
-                }
-
-                if !single_codegen_unit {
-                    // If there is more than one codegen unit, we need to keep track
-                    // in which codegen units each monomorphization is placed.
-                    match mono_item_placements.entry(mono_item) {
-                        Entry::Occupied(e) => {
-                            let placement = e.into_mut();
-                            debug_assert!(match *placement {
-                                MonoItemPlacement::SingleCgu { cgu_name } => {
-                                    cgu_name != new_codegen_unit.name()
-                                }
-                                MonoItemPlacement::MultipleCgus => true,
-                            });
-                            *placement = MonoItemPlacement::MultipleCgus;
-                        }
-                        Entry::Vacant(e) => {
-                            e.insert(MonoItemPlacement::SingleCgu {
-                                cgu_name: new_codegen_unit.name(),
-                            });
-                        }
-                    }
-                }
-            }
-
-            *old_codegen_unit = new_codegen_unit;
-        }
-
-        return mono_item_placements;
-
-        fn follow_inlining<'tcx>(
-            mono_item: MonoItem<'tcx>,
-            inlining_map: &InliningMap<'tcx>,
-            visited: &mut FxHashSet<MonoItem<'tcx>>,
-        ) {
-            if !visited.insert(mono_item) {
-                return;
-            }
-
-            inlining_map.with_inlining_candidates(mono_item, |target| {
-                follow_inlining(target, inlining_map, visited);
-            });
-        }
-    }
-
-    fn internalize_symbols(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut [CodegenUnit<'tcx>],
-        mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
-        internalization_candidates: FxHashSet<MonoItem<'tcx>>,
-    ) {
-        if codegen_units.len() == 1 {
-            // Fast path for when there is only one codegen unit. In this case we
-            // can internalize all candidates, since there is nowhere else they
-            // could be accessed from.
-            for cgu in codegen_units {
-                for candidate in &internalization_candidates {
-                    cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default));
-                }
-            }
-
-            return;
-        }
-
-        // Build a map from every monomorphization to all the monomorphizations that
-        // reference it.
-        let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
-        cx.inlining_map.iter_accesses(|accessor, accessees| {
-            for accessee in accessees {
-                accessor_map.entry(*accessee).or_default().push(accessor);
-            }
-        });
-
-        // For each internalization candidates in each codegen unit, check if it is
-        // accessed from outside its defining codegen unit.
-        for cgu in codegen_units {
-            let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() };
-
-            for (accessee, linkage_and_visibility) in cgu.items_mut() {
-                if !internalization_candidates.contains(accessee) {
-                    // This item is no candidate for internalizing, so skip it.
-                    continue;
-                }
-                debug_assert_eq!(mono_item_placements[accessee], home_cgu);
-
-                if let Some(accessors) = accessor_map.get(accessee) {
-                    if accessors
-                        .iter()
-                        .filter_map(|accessor| {
-                            // Some accessors might not have been
-                            // instantiated. We can safely ignore those.
-                            mono_item_placements.get(accessor)
-                        })
-                        .any(|placement| *placement != home_cgu)
-                    {
-                        // Found an accessor from another CGU, so skip to the next
-                        // item without marking this one as internal.
-                        continue;
-                    }
-                }
-
-                // If we got here, we did not find any accesses from other CGUs,
-                // so it's fine to make this monomorphization internal.
-                *linkage_and_visibility = (Linkage::Internal, Visibility::Default);
-            }
-        }
-    }
-}
-
-fn characteristic_def_id_of_mono_item<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mono_item: MonoItem<'tcx>,
-) -> Option<DefId> {
-    match mono_item {
-        MonoItem::Fn(instance) => {
-            let def_id = match instance.def {
-                ty::InstanceDef::Item(def) => def,
-                ty::InstanceDef::VTableShim(..)
-                | ty::InstanceDef::ReifyShim(..)
-                | ty::InstanceDef::FnPtrShim(..)
-                | ty::InstanceDef::ClosureOnceShim { .. }
-                | ty::InstanceDef::Intrinsic(..)
-                | ty::InstanceDef::DropGlue(..)
-                | ty::InstanceDef::Virtual(..)
-                | ty::InstanceDef::CloneShim(..)
-                | ty::InstanceDef::ThreadLocalShim(..)
-                | ty::InstanceDef::FnPtrAddrShim(..) => return None,
-            };
-
-            // If this is a method, we want to put it into the same module as
-            // its self-type. If the self-type does not provide a characteristic
-            // DefId, we use the location of the impl after all.
-
-            if tcx.trait_of_item(def_id).is_some() {
-                let self_ty = instance.substs.type_at(0);
-                // This is a default implementation of a trait method.
-                return characteristic_def_id_of_type(self_ty).or(Some(def_id));
-            }
-
-            if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
-                if tcx.sess.opts.incremental.is_some()
-                    && tcx.trait_id_of_impl(impl_def_id) == tcx.lang_items().drop_trait()
-                {
-                    // Put `Drop::drop` into the same cgu as `drop_in_place`
-                    // since `drop_in_place` is the only thing that can
-                    // call it.
-                    return None;
-                }
-
-                // When polymorphization is enabled, methods which do not depend on their generic
-                // parameters, but the self-type of their impl block do will fail to normalize.
-                if !tcx.sess.opts.unstable_opts.polymorphize || !instance.has_param() {
-                    // This is a method within an impl, find out what the self-type is:
-                    let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
-                        instance.substs,
-                        ty::ParamEnv::reveal_all(),
-                        tcx.type_of(impl_def_id),
-                    );
-                    if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
-                        return Some(def_id);
-                    }
-                }
-            }
-
-            Some(def_id)
-        }
-        MonoItem::Static(def_id) => Some(def_id),
-        MonoItem::GlobalAsm(item_id) => Some(item_id.owner_id.to_def_id()),
-    }
-}
-
-fn compute_codegen_unit_name(
-    tcx: TyCtxt<'_>,
-    name_builder: &mut CodegenUnitNameBuilder<'_>,
-    def_id: DefId,
-    volatile: bool,
-    cache: &mut CguNameCache,
-) -> Symbol {
-    // Find the innermost module that is not nested within a function.
-    let mut current_def_id = def_id;
-    let mut cgu_def_id = None;
-    // Walk backwards from the item we want to find the module for.
-    loop {
-        if current_def_id.is_crate_root() {
-            if cgu_def_id.is_none() {
-                // If we have not found a module yet, take the crate root.
-                cgu_def_id = Some(def_id.krate.as_def_id());
-            }
-            break;
-        } else if tcx.def_kind(current_def_id) == DefKind::Mod {
-            if cgu_def_id.is_none() {
-                cgu_def_id = Some(current_def_id);
-            }
-        } else {
-            // If we encounter something that is not a module, throw away
-            // any module that we've found so far because we now know that
-            // it is nested within something else.
-            cgu_def_id = None;
-        }
-
-        current_def_id = tcx.parent(current_def_id);
-    }
-
-    let cgu_def_id = cgu_def_id.unwrap();
-
-    *cache.entry((cgu_def_id, volatile)).or_insert_with(|| {
-        let def_path = tcx.def_path(cgu_def_id);
-
-        let components = def_path.data.iter().map(|part| match part.data.name() {
-            DefPathDataName::Named(name) => name,
-            DefPathDataName::Anon { .. } => unreachable!(),
-        });
-
-        let volatile_suffix = volatile.then_some("volatile");
-
-        name_builder.build_cgu_name(def_path.krate, components, volatile_suffix)
-    })
-}
-
-// Anything we can't find a proper codegen unit for goes into this.
-fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol {
-    name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu"))
-}
-
-fn mono_item_linkage_and_visibility<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mono_item: &MonoItem<'tcx>,
-    can_be_internalized: &mut bool,
-    export_generics: bool,
-) -> (Linkage, Visibility) {
-    if let Some(explicit_linkage) = mono_item.explicit_linkage(tcx) {
-        return (explicit_linkage, Visibility::Default);
-    }
-    let vis = mono_item_visibility(tcx, mono_item, can_be_internalized, export_generics);
-    (Linkage::External, vis)
-}
-
-type CguNameCache = FxHashMap<(DefId, bool), Symbol>;
-
-fn static_visibility<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    can_be_internalized: &mut bool,
-    def_id: DefId,
-) -> Visibility {
-    if tcx.is_reachable_non_generic(def_id) {
-        *can_be_internalized = false;
-        default_visibility(tcx, def_id, false)
-    } else {
-        Visibility::Hidden
-    }
-}
-
-fn mono_item_visibility<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mono_item: &MonoItem<'tcx>,
-    can_be_internalized: &mut bool,
-    export_generics: bool,
-) -> Visibility {
-    let instance = match mono_item {
-        // This is pretty complicated; see below.
-        MonoItem::Fn(instance) => instance,
-
-        // Misc handling for generics and such, but otherwise:
-        MonoItem::Static(def_id) => return static_visibility(tcx, can_be_internalized, *def_id),
-        MonoItem::GlobalAsm(item_id) => {
-            return static_visibility(tcx, can_be_internalized, item_id.owner_id.to_def_id());
-        }
-    };
-
-    let def_id = match instance.def {
-        InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id,
-
-        // We match the visibility of statics here
-        InstanceDef::ThreadLocalShim(def_id) => {
-            return static_visibility(tcx, can_be_internalized, def_id);
-        }
-
-        // These are all compiler glue and such, never exported, always hidden.
-        InstanceDef::VTableShim(..)
-        | InstanceDef::ReifyShim(..)
-        | InstanceDef::FnPtrShim(..)
-        | InstanceDef::Virtual(..)
-        | InstanceDef::Intrinsic(..)
-        | InstanceDef::ClosureOnceShim { .. }
-        | InstanceDef::DropGlue(..)
-        | InstanceDef::CloneShim(..)
-        | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden,
-    };
-
-    // The `start_fn` lang item is actually a monomorphized instance of a
-    // function in the standard library, used for the `main` function. We don't
-    // want to export it so we tag it with `Hidden` visibility but this symbol
-    // is only referenced from the actual `main` symbol which we unfortunately
-    // don't know anything about during partitioning/collection. As a result we
-    // forcibly keep this symbol out of the `internalization_candidates` set.
-    //
-    // FIXME: eventually we don't want to always force this symbol to have
-    //        hidden visibility, it should indeed be a candidate for
-    //        internalization, but we have to understand that it's referenced
-    //        from the `main` symbol we'll generate later.
-    //
-    //        This may be fixable with a new `InstanceDef` perhaps? Unsure!
-    if tcx.lang_items().start_fn() == Some(def_id) {
-        *can_be_internalized = false;
-        return Visibility::Hidden;
-    }
-
-    let is_generic = instance.substs.non_erasable_generics().next().is_some();
-
-    // Upstream `DefId` instances get different handling than local ones.
-    let Some(def_id) = def_id.as_local() else {
-        return if export_generics && is_generic {
-            // If it is an upstream monomorphization and we export generics, we must make
-            // it available to downstream crates.
-            *can_be_internalized = false;
-            default_visibility(tcx, def_id, true)
-        } else {
-            Visibility::Hidden
-        };
-    };
-
-    if is_generic {
-        if export_generics {
-            if tcx.is_unreachable_local_definition(def_id) {
-                // This instance cannot be used from another crate.
-                Visibility::Hidden
-            } else {
-                // This instance might be useful in a downstream crate.
-                *can_be_internalized = false;
-                default_visibility(tcx, def_id.to_def_id(), true)
-            }
-        } else {
-            // We are not exporting generics or the definition is not reachable
-            // for downstream crates, we can internalize its instantiations.
-            Visibility::Hidden
-        }
-    } else {
-        // If this isn't a generic function then we mark this a `Default` if
-        // this is a reachable item, meaning that it's a symbol other crates may
-        // access when they link to us.
-        if tcx.is_reachable_non_generic(def_id.to_def_id()) {
-            *can_be_internalized = false;
-            debug_assert!(!is_generic);
-            return default_visibility(tcx, def_id.to_def_id(), false);
-        }
-
-        // If this isn't reachable then we're gonna tag this with `Hidden`
-        // visibility. In some situations though we'll want to prevent this
-        // symbol from being internalized.
-        //
-        // There's two categories of items here:
-        //
-        // * First is weak lang items. These are basically mechanisms for
-        //   libcore to forward-reference symbols defined later in crates like
-        //   the standard library or `#[panic_handler]` definitions. The
-        //   definition of these weak lang items needs to be referencable by
-        //   libcore, so we're no longer a candidate for internalization.
-        //   Removal of these functions can't be done by LLVM but rather must be
-        //   done by the linker as it's a non-local decision.
-        //
-        // * Second is "std internal symbols". Currently this is primarily used
-        //   for allocator symbols. Allocators are a little weird in their
-        //   implementation, but the idea is that the compiler, at the last
-        //   minute, defines an allocator with an injected object file. The
-        //   `alloc` crate references these symbols (`__rust_alloc`) and the
-        //   definition doesn't get hooked up until a linked crate artifact is
-        //   generated.
-        //
-        //   The symbols synthesized by the compiler (`__rust_alloc`) are thin
-        //   veneers around the actual implementation, some other symbol which
-        //   implements the same ABI. These symbols (things like `__rg_alloc`,
-        //   `__rdl_alloc`, `__rde_alloc`, etc), are all tagged with "std
-        //   internal symbols".
-        //
-        //   The std-internal symbols here **should not show up in a dll as an
-        //   exported interface**, so they return `false` from
-        //   `is_reachable_non_generic` above and we'll give them `Hidden`
-        //   visibility below. Like the weak lang items, though, we can't let
-        //   LLVM internalize them as this decision is left up to the linker to
-        //   omit them, so prevent them from being internalized.
-        let attrs = tcx.codegen_fn_attrs(def_id);
-        if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
-            *can_be_internalized = false;
-        }
-
-        Visibility::Hidden
-    }
-}
-
-fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
-    if !tcx.sess.target.default_hidden_visibility {
-        return Visibility::Default;
-    }
-
-    // Generic functions never have export-level C.
-    if is_generic {
-        return Visibility::Hidden;
-    }
-
-    // Things with export level C don't get instantiated in
-    // downstream crates.
-    if !id.is_local() {
-        return Visibility::Hidden;
-    }
-
-    // C-export level items remain at `Default`, all other internal
-    // items become `Hidden`.
-    match tcx.reachable_non_generics(id.krate).get(&id) {
-        Some(SymbolExportInfo { level: SymbolExportLevel::C, .. }) => Visibility::Default,
-        _ => Visibility::Hidden,
-    }
-}
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
deleted file mode 100644
index d0b23ca9ea4..00000000000
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ /dev/null
@@ -1,673 +0,0 @@
-//! Partitioning Codegen Units for Incremental Compilation
-//! ======================================================
-//!
-//! The task of this module is to take the complete set of monomorphizations of
-//! a crate and produce a set of codegen units from it, where a codegen unit
-//! is a named set of (mono-item, linkage) pairs. That is, this module
-//! decides which monomorphization appears in which codegen units with which
-//! linkage. The following paragraphs describe some of the background on the
-//! partitioning scheme.
-//!
-//! The most important opportunity for saving on compilation time with
-//! incremental compilation is to avoid re-codegenning and re-optimizing code.
-//! Since the unit of codegen and optimization for LLVM is "modules" or, how
-//! we call them "codegen units", the particulars of how much time can be saved
-//! by incremental compilation are tightly linked to how the output program is
-//! partitioned into these codegen units prior to passing it to LLVM --
-//! especially because we have to treat codegen units as opaque entities once
-//! they are created: There is no way for us to incrementally update an existing
-//! LLVM module and so we have to build any such module from scratch if it was
-//! affected by some change in the source code.
-//!
-//! From that point of view it would make sense to maximize the number of
-//! codegen units by, for example, putting each function into its own module.
-//! That way only those modules would have to be re-compiled that were actually
-//! affected by some change, minimizing the number of functions that could have
-//! been re-used but just happened to be located in a module that is
-//! re-compiled.
-//!
-//! However, since LLVM optimization does not work across module boundaries,
-//! using such a highly granular partitioning would lead to very slow runtime
-//! code since it would effectively prohibit inlining and other inter-procedure
-//! optimizations. We want to avoid that as much as possible.
-//!
-//! Thus we end up with a trade-off: The bigger the codegen units, the better
-//! LLVM's optimizer can do its work, but also the smaller the compilation time
-//! reduction we get from incremental compilation.
-//!
-//! Ideally, we would create a partitioning such that there are few big codegen
-//! units with few interdependencies between them. For now though, we use the
-//! following heuristic to determine the partitioning:
-//!
-//! - There are two codegen units for every source-level module:
-//! - One for "stable", that is non-generic, code
-//! - One for more "volatile" code, i.e., monomorphized instances of functions
-//!   defined in that module
-//!
-//! In order to see why this heuristic makes sense, let's take a look at when a
-//! codegen unit can get invalidated:
-//!
-//! 1. The most straightforward case is when the BODY of a function or global
-//! changes. Then any codegen unit containing the code for that item has to be
-//! re-compiled. Note that this includes all codegen units where the function
-//! has been inlined.
-//!
-//! 2. The next case is when the SIGNATURE of a function or global changes. In
-//! this case, all codegen units containing a REFERENCE to that item have to be
-//! re-compiled. This is a superset of case 1.
-//!
-//! 3. The final and most subtle case is when a REFERENCE to a generic function
-//! is added or removed somewhere. Even though the definition of the function
-//! might be unchanged, a new REFERENCE might introduce a new monomorphized
-//! instance of this function which has to be placed and compiled somewhere.
-//! Conversely, when removing a REFERENCE, it might have been the last one with
-//! that particular set of generic arguments and thus we have to remove it.
-//!
-//! From the above we see that just using one codegen unit per source-level
-//! module is not such a good idea, since just adding a REFERENCE to some
-//! generic item somewhere else would invalidate everything within the module
-//! containing the generic item. The heuristic above reduces this detrimental
-//! side-effect of references a little by at least not touching the non-generic
-//! code of the module.
-//!
-//! A Note on Inlining
-//! ------------------
-//! As briefly mentioned above, in order for LLVM to be able to inline a
-//! function call, the body of the function has to be available in the LLVM
-//! module where the call is made. This has a few consequences for partitioning:
-//!
-//! - The partitioning algorithm has to take care of placing functions into all
-//!   codegen units where they should be available for inlining. It also has to
-//!   decide on the correct linkage for these functions.
-//!
-//! - The partitioning algorithm has to know which functions are likely to get
-//!   inlined, so it can distribute function instantiations accordingly. Since
-//!   there is no way of knowing for sure which functions LLVM will decide to
-//!   inline in the end, we apply a heuristic here: Only functions marked with
-//!   `#[inline]` are considered for inlining by the partitioner. The current
-//!   implementation will not try to determine if a function is likely to be
-//!   inlined by looking at the functions definition.
-//!
-//! Note though that as a side-effect of creating a codegen units per
-//! source-level module, functions from the same module will be available for
-//! inlining, even when they are not marked `#[inline]`.
-
-mod default;
-
-use std::cmp;
-use std::fs::{self, File};
-use std::io::{BufWriter, Write};
-use std::path::{Path, PathBuf};
-
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::sync;
-use rustc_hir::def_id::{DefIdSet, LOCAL_CRATE};
-use rustc_middle::mir;
-use rustc_middle::mir::mono::MonoItem;
-use rustc_middle::mir::mono::{CodegenUnit, Linkage};
-use rustc_middle::query::Providers;
-use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::TyCtxt;
-use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
-use rustc_span::symbol::Symbol;
-
-use crate::collector::InliningMap;
-use crate::collector::{self, MonoItemCollectionMode};
-use crate::errors::{
-    CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode, UnknownPartitionStrategy,
-};
-
-enum Partitioner {
-    Default(default::DefaultPartitioning),
-    // Other partitioning strategies can go here.
-    Unknown,
-}
-
-impl<'tcx> Partition<'tcx> for Partitioner {
-    fn place_root_mono_items<I>(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        mono_items: &mut I,
-    ) -> PlacedRootMonoItems<'tcx>
-    where
-        I: Iterator<Item = MonoItem<'tcx>>,
-    {
-        match self {
-            Partitioner::Default(partitioner) => partitioner.place_root_mono_items(cx, mono_items),
-            Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
-        }
-    }
-
-    fn merge_codegen_units(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut Vec<CodegenUnit<'tcx>>,
-    ) {
-        match self {
-            Partitioner::Default(partitioner) => partitioner.merge_codegen_units(cx, codegen_units),
-            Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
-        }
-    }
-
-    fn place_inlined_mono_items(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut [CodegenUnit<'tcx>],
-        roots: FxHashSet<MonoItem<'tcx>>,
-    ) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement> {
-        match self {
-            Partitioner::Default(partitioner) => {
-                partitioner.place_inlined_mono_items(cx, codegen_units, roots)
-            }
-            Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
-        }
-    }
-
-    fn internalize_symbols(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut [CodegenUnit<'tcx>],
-        mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
-        internalization_candidates: FxHashSet<MonoItem<'tcx>>,
-    ) {
-        match self {
-            Partitioner::Default(partitioner) => partitioner.internalize_symbols(
-                cx,
-                codegen_units,
-                mono_item_placements,
-                internalization_candidates,
-            ),
-            Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy),
-        }
-    }
-}
-
-struct PartitioningCx<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    target_cgu_count: usize,
-    inlining_map: &'a InliningMap<'tcx>,
-}
-
-pub struct PlacedRootMonoItems<'tcx> {
-    codegen_units: Vec<CodegenUnit<'tcx>>,
-    roots: FxHashSet<MonoItem<'tcx>>,
-    internalization_candidates: FxHashSet<MonoItem<'tcx>>,
-}
-
-trait Partition<'tcx> {
-    fn place_root_mono_items<I>(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        mono_items: &mut I,
-    ) -> PlacedRootMonoItems<'tcx>
-    where
-        I: Iterator<Item = MonoItem<'tcx>>;
-
-    fn merge_codegen_units(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut Vec<CodegenUnit<'tcx>>,
-    );
-
-    fn place_inlined_mono_items(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut [CodegenUnit<'tcx>],
-        roots: FxHashSet<MonoItem<'tcx>>,
-    ) -> FxHashMap<MonoItem<'tcx>, MonoItemPlacement>;
-
-    fn internalize_symbols(
-        &mut self,
-        cx: &PartitioningCx<'_, 'tcx>,
-        codegen_units: &mut [CodegenUnit<'tcx>],
-        mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
-        internalization_candidates: FxHashSet<MonoItem<'tcx>>,
-    );
-}
-
-fn get_partitioner(tcx: TyCtxt<'_>) -> Partitioner {
-    let strategy = match &tcx.sess.opts.unstable_opts.cgu_partitioning_strategy {
-        None => "default",
-        Some(s) => &s[..],
-    };
-
-    match strategy {
-        "default" => Partitioner::Default(default::DefaultPartitioning),
-        _ => Partitioner::Unknown,
-    }
-}
-
-fn partition<'tcx, I>(
-    tcx: TyCtxt<'tcx>,
-    mono_items: &mut I,
-    max_cgu_count: usize,
-    inlining_map: &InliningMap<'tcx>,
-) -> Vec<CodegenUnit<'tcx>>
-where
-    I: Iterator<Item = MonoItem<'tcx>>,
-{
-    let _prof_timer = tcx.prof.generic_activity("cgu_partitioning");
-
-    let mut partitioner = get_partitioner(tcx);
-    let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map };
-    // In the first step, we place all regular monomorphizations into their
-    // respective 'home' codegen unit. Regular monomorphizations are all
-    // functions and statics defined in the local crate.
-    let PlacedRootMonoItems { mut codegen_units, roots, internalization_candidates } = {
-        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
-        partitioner.place_root_mono_items(cx, mono_items)
-    };
-
-    for cgu in &mut codegen_units {
-        cgu.create_size_estimate(tcx);
-    }
-
-    debug_dump(tcx, "INITIAL PARTITIONING", &codegen_units);
-
-    // Merge until we have at most `max_cgu_count` codegen units.
-    // `merge_codegen_units` is responsible for updating the CGU size
-    // estimates.
-    {
-        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
-        partitioner.merge_codegen_units(cx, &mut codegen_units);
-        debug_dump(tcx, "POST MERGING", &codegen_units);
-    }
-
-    // In the next step, we use the inlining map to determine which additional
-    // monomorphizations have to go into each codegen unit. These additional
-    // monomorphizations can be drop-glue, functions from external crates, and
-    // local functions the definition of which is marked with `#[inline]`.
-    let mono_item_placements = {
-        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
-        partitioner.place_inlined_mono_items(cx, &mut codegen_units, roots)
-    };
-
-    for cgu in &mut codegen_units {
-        cgu.create_size_estimate(tcx);
-    }
-
-    debug_dump(tcx, "POST INLINING", &codegen_units);
-
-    // Next we try to make as many symbols "internal" as possible, so LLVM has
-    // more freedom to optimize.
-    if !tcx.sess.link_dead_code() {
-        let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
-        partitioner.internalize_symbols(
-            cx,
-            &mut codegen_units,
-            mono_item_placements,
-            internalization_candidates,
-        );
-    }
-
-    let instrument_dead_code =
-        tcx.sess.instrument_coverage() && !tcx.sess.instrument_coverage_except_unused_functions();
-
-    if instrument_dead_code {
-        assert!(
-            codegen_units.len() > 0,
-            "There must be at least one CGU that code coverage data can be generated in."
-        );
-
-        // Find the smallest CGU that has exported symbols and put the dead
-        // function stubs in that CGU. We look for exported symbols to increase
-        // the likelihood the linker won't throw away the dead functions.
-        // FIXME(#92165): In order to truly resolve this, we need to make sure
-        // the object file (CGU) containing the dead function stubs is included
-        // in the final binary. This will probably require forcing these
-        // function symbols to be included via `-u` or `/include` linker args.
-        let mut cgus: Vec<_> = codegen_units.iter_mut().collect();
-        cgus.sort_by_key(|cgu| cgu.size_estimate());
-
-        let dead_code_cgu =
-            if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
-                cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
-            }) {
-                cgu
-            } else {
-                // If there are no CGUs that have externally linked items,
-                // then we just pick the first CGU as a fallback.
-                &mut codegen_units[0]
-            };
-        dead_code_cgu.make_code_coverage_dead_code_cgu();
-    }
-
-    // Finally, sort by codegen unit name, so that we get deterministic results.
-    codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
-
-    debug_dump(tcx, "FINAL", &codegen_units);
-
-    codegen_units
-}
-
-/// For symbol internalization, we need to know whether a symbol/mono-item is
-/// accessed from outside the codegen unit it is defined in. This type is used
-/// to keep track of that.
-#[derive(Clone, PartialEq, Eq, Debug)]
-enum MonoItemPlacement {
-    SingleCgu { cgu_name: Symbol },
-    MultipleCgus,
-}
-
-fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<'tcx>]) {
-    let dump = move || {
-        use std::fmt::Write;
-
-        let num_cgus = cgus.len();
-        let max = cgus.iter().map(|cgu| cgu.size_estimate()).max().unwrap();
-        let min = cgus.iter().map(|cgu| cgu.size_estimate()).min().unwrap();
-        let ratio = max as f64 / min as f64;
-
-        let s = &mut String::new();
-        let _ = writeln!(
-            s,
-            "{label} ({num_cgus} CodegenUnits, max={max}, min={min}, max/min={ratio:.1}):"
-        );
-        for cgu in cgus {
-            let _ =
-                writeln!(s, "CodegenUnit {} estimated size {}:", cgu.name(), cgu.size_estimate());
-
-            for (mono_item, linkage) in cgu.items() {
-                let symbol_name = mono_item.symbol_name(tcx).name;
-                let symbol_hash_start = symbol_name.rfind('h');
-                let symbol_hash = symbol_hash_start.map_or("<no hash>", |i| &symbol_name[i..]);
-
-                let _ = with_no_trimmed_paths!(writeln!(
-                    s,
-                    " - {} [{:?}] [{}] estimated size {}",
-                    mono_item,
-                    linkage,
-                    symbol_hash,
-                    mono_item.size_estimate(tcx)
-                ));
-            }
-
-            let _ = writeln!(s);
-        }
-
-        std::mem::take(s)
-    };
-
-    debug!("{}", dump());
-}
-
-#[inline(never)] // give this a place in the profiler
-fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I)
-where
-    I: Iterator<Item = &'a MonoItem<'tcx>>,
-    'tcx: 'a,
-{
-    let _prof_timer = tcx.prof.generic_activity("assert_symbols_are_distinct");
-
-    let mut symbols: Vec<_> =
-        mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect();
-
-    symbols.sort_by_key(|sym| sym.1);
-
-    for &[(mono_item1, ref sym1), (mono_item2, ref sym2)] in symbols.array_windows() {
-        if sym1 == sym2 {
-            let span1 = mono_item1.local_span(tcx);
-            let span2 = mono_item2.local_span(tcx);
-
-            // Deterministically select one of the spans for error reporting
-            let span = match (span1, span2) {
-                (Some(span1), Some(span2)) => {
-                    Some(if span1.lo().0 > span2.lo().0 { span1 } else { span2 })
-                }
-                (span1, span2) => span1.or(span2),
-            };
-
-            tcx.sess.emit_fatal(SymbolAlreadyDefined { span, symbol: sym1.to_string() });
-        }
-    }
-}
-
-fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[CodegenUnit<'_>]) {
-    let collection_mode = match tcx.sess.opts.unstable_opts.print_mono_items {
-        Some(ref s) => {
-            let mode = s.to_lowercase();
-            let mode = mode.trim();
-            if mode == "eager" {
-                MonoItemCollectionMode::Eager
-            } else {
-                if mode != "lazy" {
-                    tcx.sess.emit_warning(UnknownCguCollectionMode { mode });
-                }
-
-                MonoItemCollectionMode::Lazy
-            }
-        }
-        None => {
-            if tcx.sess.link_dead_code() {
-                MonoItemCollectionMode::Eager
-            } else {
-                MonoItemCollectionMode::Lazy
-            }
-        }
-    };
-
-    let (items, inlining_map) = collector::collect_crate_mono_items(tcx, collection_mode);
-
-    tcx.sess.abort_if_errors();
-
-    let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {
-        sync::join(
-            || {
-                let mut codegen_units = partition(
-                    tcx,
-                    &mut items.iter().copied(),
-                    tcx.sess.codegen_units(),
-                    &inlining_map,
-                );
-                codegen_units[0].make_primary();
-                &*tcx.arena.alloc_from_iter(codegen_units)
-            },
-            || assert_symbols_are_distinct(tcx, items.iter()),
-        )
-    });
-
-    if tcx.prof.enabled() {
-        // Record CGU size estimates for self-profiling.
-        for cgu in codegen_units {
-            tcx.prof.artifact_size(
-                "codegen_unit_size_estimate",
-                cgu.name().as_str(),
-                cgu.size_estimate() as u64,
-            );
-        }
-    }
-
-    let mono_items: DefIdSet = items
-        .iter()
-        .filter_map(|mono_item| match *mono_item {
-            MonoItem::Fn(ref instance) => Some(instance.def_id()),
-            MonoItem::Static(def_id) => Some(def_id),
-            _ => None,
-        })
-        .collect();
-
-    // Output monomorphization stats per def_id
-    if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats {
-        if let Err(err) =
-            dump_mono_items_stats(tcx, &codegen_units, path, tcx.crate_name(LOCAL_CRATE))
-        {
-            tcx.sess.emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
-        }
-    }
-
-    if tcx.sess.opts.unstable_opts.print_mono_items.is_some() {
-        let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
-
-        for cgu in codegen_units {
-            for (&mono_item, &linkage) in cgu.items() {
-                item_to_cgus.entry(mono_item).or_default().push((cgu.name(), linkage));
-            }
-        }
-
-        let mut item_keys: Vec<_> = items
-            .iter()
-            .map(|i| {
-                let mut output = with_no_trimmed_paths!(i.to_string());
-                output.push_str(" @@");
-                let mut empty = Vec::new();
-                let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
-                cgus.sort_by_key(|(name, _)| *name);
-                cgus.dedup();
-                for &(ref cgu_name, (linkage, _)) in cgus.iter() {
-                    output.push(' ');
-                    output.push_str(cgu_name.as_str());
-
-                    let linkage_abbrev = match linkage {
-                        Linkage::External => "External",
-                        Linkage::AvailableExternally => "Available",
-                        Linkage::LinkOnceAny => "OnceAny",
-                        Linkage::LinkOnceODR => "OnceODR",
-                        Linkage::WeakAny => "WeakAny",
-                        Linkage::WeakODR => "WeakODR",
-                        Linkage::Appending => "Appending",
-                        Linkage::Internal => "Internal",
-                        Linkage::Private => "Private",
-                        Linkage::ExternalWeak => "ExternalWeak",
-                        Linkage::Common => "Common",
-                    };
-
-                    output.push('[');
-                    output.push_str(linkage_abbrev);
-                    output.push(']');
-                }
-                output
-            })
-            .collect();
-
-        item_keys.sort();
-
-        for item in item_keys {
-            println!("MONO_ITEM {item}");
-        }
-    }
-
-    (tcx.arena.alloc(mono_items), codegen_units)
-}
-
-/// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s
-/// def, to a file in the given output directory.
-fn dump_mono_items_stats<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    codegen_units: &[CodegenUnit<'tcx>],
-    output_directory: &Option<PathBuf>,
-    crate_name: Symbol,
-) -> Result<(), Box<dyn std::error::Error>> {
-    let output_directory = if let Some(ref directory) = output_directory {
-        fs::create_dir_all(directory)?;
-        directory
-    } else {
-        Path::new(".")
-    };
-
-    let format = tcx.sess.opts.unstable_opts.dump_mono_stats_format;
-    let ext = format.extension();
-    let filename = format!("{crate_name}.mono_items.{ext}");
-    let output_path = output_directory.join(&filename);
-    let file = File::create(&output_path)?;
-    let mut file = BufWriter::new(file);
-
-    // Gather instantiated mono items grouped by def_id
-    let mut items_per_def_id: FxHashMap<_, Vec<_>> = Default::default();
-    for cgu in codegen_units {
-        for (&mono_item, _) in cgu.items() {
-            // Avoid variable-sized compiler-generated shims
-            if mono_item.is_user_defined() {
-                items_per_def_id.entry(mono_item.def_id()).or_default().push(mono_item);
-            }
-        }
-    }
-
-    #[derive(serde::Serialize)]
-    struct MonoItem {
-        name: String,
-        instantiation_count: usize,
-        size_estimate: usize,
-        total_estimate: usize,
-    }
-
-    // Output stats sorted by total instantiated size, from heaviest to lightest
-    let mut stats: Vec<_> = items_per_def_id
-        .into_iter()
-        .map(|(def_id, items)| {
-            let name = with_no_trimmed_paths!(tcx.def_path_str(def_id));
-            let instantiation_count = items.len();
-            let size_estimate = items[0].size_estimate(tcx);
-            let total_estimate = instantiation_count * size_estimate;
-            MonoItem { name, instantiation_count, size_estimate, total_estimate }
-        })
-        .collect();
-    stats.sort_unstable_by_key(|item| cmp::Reverse(item.total_estimate));
-
-    if !stats.is_empty() {
-        match format {
-            DumpMonoStatsFormat::Json => serde_json::to_writer(file, &stats)?,
-            DumpMonoStatsFormat::Markdown => {
-                writeln!(
-                    file,
-                    "| Item | Instantiation count | Estimated Cost Per Instantiation | Total Estimated Cost |"
-                )?;
-                writeln!(file, "| --- | ---: | ---: | ---: |")?;
-
-                for MonoItem { name, instantiation_count, size_estimate, total_estimate } in stats {
-                    writeln!(
-                        file,
-                        "| `{name}` | {instantiation_count} | {size_estimate} | {total_estimate} |"
-                    )?;
-                }
-            }
-        }
-    }
-
-    Ok(())
-}
-
-fn codegened_and_inlined_items(tcx: TyCtxt<'_>, (): ()) -> &DefIdSet {
-    let (items, cgus) = tcx.collect_and_partition_mono_items(());
-    let mut visited = DefIdSet::default();
-    let mut result = items.clone();
-
-    for cgu in cgus {
-        for (item, _) in cgu.items() {
-            if let MonoItem::Fn(ref instance) = item {
-                let did = instance.def_id();
-                if !visited.insert(did) {
-                    continue;
-                }
-                let body = tcx.instance_mir(instance.def);
-                for block in body.basic_blocks.iter() {
-                    for statement in &block.statements {
-                        let mir::StatementKind::Coverage(_) = statement.kind else { continue };
-                        let scope = statement.source_info.scope;
-                        if let Some(inlined) = scope.inlined_instance(&body.source_scopes) {
-                            result.insert(inlined.def_id());
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    tcx.arena.alloc(result)
-}
-
-pub fn provide(providers: &mut Providers) {
-    providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
-    providers.codegened_and_inlined_items = codegened_and_inlined_items;
-
-    providers.is_codegened_item = |tcx, def_id| {
-        let (all_mono_items, _) = tcx.collect_and_partition_mono_items(());
-        all_mono_items.contains(&def_id)
-    };
-
-    providers.codegen_unit = |tcx, name| {
-        let (_, all) = tcx.collect_and_partition_mono_items(());
-        all.iter()
-            .find(|cgu| cgu.name() == name)
-            .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}"))
-    };
-}
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 5a0b8f9f73c..4897bd8d5da 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -27,6 +27,10 @@ session_feature_gate_error = {$explain}
 session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
 
 session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
+
+session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target
+    .note = compatible flavors are: {$compatible_list}
+
 session_incorrect_cgu_reuse_type =
     CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
     [one] {"at least "}
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 6c8c8e484f9..0ce83e79097 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -12,7 +12,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 
 use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
 use rustc_target::abi::Align;
-use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo};
+use rustc_target::spec::{LinkerFlavorCli, PanicStrategy, SanitizerSet, SplitDebuginfo};
 use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
 
 use crate::parse::{CrateCheckConfig, CrateConfig};
@@ -2525,6 +2525,19 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         }
     }
 
+    if let Some(flavor) = cg.linker_flavor {
+        if matches!(flavor, LinkerFlavorCli::BpfLinker | LinkerFlavorCli::PtxLinker)
+            && !nightly_options::is_unstable_enabled(matches)
+        {
+            let msg = format!(
+                "linker flavor `{}` is unstable, `-Z unstable-options` \
+                 flag must also be passed to explicitly use it",
+                flavor.desc()
+            );
+            early_error(error_format, msg);
+        }
+    }
+
     let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format);
 
     let cg = cg;
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 546c0fa8e03..4a3e668da11 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -422,3 +422,11 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
 pub struct OptimisationFuelExhausted {
     pub msg: String,
 }
+
+#[derive(Diagnostic)]
+#[diag(session_incompatible_linker_flavor)]
+#[note]
+pub struct IncompatibleLinkerFlavor {
+    pub flavor: &'static str,
+    pub compatible_list: String,
+}
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 007e720823b..7cc2b2c880c 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1372,8 +1372,6 @@ options! {
         "set options for branch target identification and pointer authentication on AArch64"),
     cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],
         "instrument control-flow architecture protection"),
-    cgu_partitioning_strategy: Option<String> = (None, parse_opt_string, [TRACKED],
-        "the codegen unit partitioning strategy to use"),
     codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
         "the backend to use"),
     combine_cgu: bool = (false, parse_bool, [TRACKED],
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index d1e4042e8d8..a433e2371c9 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -84,6 +84,7 @@ impl SymbolGallery {
 
 /// Construct a diagnostic for a language feature error due to the given `span`.
 /// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
+#[track_caller]
 pub fn feature_err(
     sess: &ParseSess,
     feature: Symbol,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index bbe52dbced0..2ebd83540ee 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -128,8 +128,6 @@ pub struct Limits {
     pub move_size_limit: Limit,
     /// The maximum length of types during monomorphization.
     pub type_length_limit: Limit,
-    /// The maximum blocks a const expression can evaluate.
-    pub const_eval_limit: Limit,
 }
 
 pub struct CompilerIO {
@@ -1675,6 +1673,13 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
         sess.emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
     }
+
+    if let Some(flavor) = sess.opts.cg.linker_flavor {
+        if let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor) {
+            let flavor = flavor.desc();
+            sess.emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
+        }
+    }
 }
 
 /// Holds data on the current incremental compilation session, if there is one.
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index b219fde4da9..0c7e36b3bef 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1288,7 +1288,7 @@ pub fn decode_expn_id(
     decode_data: impl FnOnce(ExpnId) -> (ExpnData, ExpnHash),
 ) -> ExpnId {
     if index == 0 {
-        debug!("decode_expn_id: deserialized root");
+        trace!("decode_expn_id: deserialized root");
         return ExpnId::root();
     }
 
@@ -1321,7 +1321,7 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
 ) -> SyntaxContext {
     let raw_id: u32 = Decodable::decode(d);
     if raw_id == 0 {
-        debug!("decode_syntax_context: deserialized root");
+        trace!("decode_syntax_context: deserialized root");
         // The root is special
         return SyntaxContext::root();
     }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 1185563ea80..2f002e42427 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1146,6 +1146,8 @@ symbols! {
         profiler_builtins,
         profiler_runtime,
         ptr,
+        ptr_cast_mut,
+        ptr_from_ref,
         ptr_guaranteed_cmp,
         ptr_mask,
         ptr_null,
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index dc2cc23ffb1..a7b54766bc6 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -11,6 +11,7 @@
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
 #![feature(exhaustive_patterns)]
+#![feature(iter_intersperse)]
 #![feature(min_specialization)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
index fc5dbd114e4..b9df0046b12 100644
--- a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
@@ -12,7 +12,7 @@ pub fn target() -> Target {
             endian: Endian::Big,
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".into(),
-            features: "+mips64r2".into(),
+            features: "+mips64r2,+xgot".into(),
             max_atomic_width: Some(64),
             mcount: "_mcount".into(),
 
diff --git a/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
index e0d5f6f57f1..57ad8c47399 100644
--- a/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
             abi: "abi64".into(),
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".into(),
-            features: "+mips64r2".into(),
+            features: "+mips64r2,+xgot".into(),
             max_atomic_width: Some(64),
             mcount: "_mcount".into(),
 
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 62f94209cf0..05cb7e87a93 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -205,15 +205,11 @@ impl ToJson for LldFlavor {
 }
 
 impl LinkerFlavor {
-    pub fn from_cli(cli: LinkerFlavorCli, target: &TargetOptions) -> LinkerFlavor {
-        Self::from_cli_impl(cli, target.linker_flavor.lld_flavor(), target.linker_flavor.is_gnu())
-    }
-
-    /// The passed CLI flavor is preferred over other args coming from the default target spec,
-    /// so this function can produce a flavor that is incompatible with the current target.
-    /// FIXME: Produce errors when `-Clinker-flavor` is set to something incompatible
-    /// with the current target.
-    fn from_cli_impl(cli: LinkerFlavorCli, lld_flavor: LldFlavor, is_gnu: bool) -> LinkerFlavor {
+    /// At this point the target's reference linker flavor doesn't yet exist and we need to infer
+    /// it. The inference always succeds and gives some result, and we don't report any flavor
+    /// incompatibility errors for json target specs. The CLI flavor is used as the main source
+    /// of truth, other flags are used in case of ambiguities.
+    fn from_cli_json(cli: LinkerFlavorCli, lld_flavor: LldFlavor, is_gnu: bool) -> LinkerFlavor {
         match cli {
             LinkerFlavorCli::Gcc => match lld_flavor {
                 LldFlavor::Ld if is_gnu => LinkerFlavor::Gnu(Cc::Yes, Lld::No),
@@ -257,6 +253,85 @@ impl LinkerFlavor {
         }
     }
 
+    fn infer_cli_hints(cli: LinkerFlavorCli) -> (Option<Cc>, Option<Lld>) {
+        match cli {
+            LinkerFlavorCli::Gcc | LinkerFlavorCli::Em => (Some(Cc::Yes), None),
+            LinkerFlavorCli::Lld(_) => (Some(Cc::No), Some(Lld::Yes)),
+            LinkerFlavorCli::Ld | LinkerFlavorCli::Msvc => (Some(Cc::No), Some(Lld::No)),
+            LinkerFlavorCli::BpfLinker | LinkerFlavorCli::PtxLinker => (None, None),
+        }
+    }
+
+    fn infer_linker_hints(linker_stem: &str) -> (Option<Cc>, Option<Lld>) {
+        // Remove any version postfix.
+        let stem = linker_stem
+            .rsplit_once('-')
+            .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs))
+            .unwrap_or(linker_stem);
+
+        // GCC/Clang can have an optional target prefix.
+        if stem == "emcc"
+            || stem == "gcc"
+            || stem.ends_with("-gcc")
+            || stem == "g++"
+            || stem.ends_with("-g++")
+            || stem == "clang"
+            || stem.ends_with("-clang")
+            || stem == "clang++"
+            || stem.ends_with("-clang++")
+        {
+            (Some(Cc::Yes), None)
+        } else if stem == "wasm-ld"
+            || stem.ends_with("-wasm-ld")
+            || stem == "ld.lld"
+            || stem == "lld"
+            || stem == "rust-lld"
+            || stem == "lld-link"
+        {
+            (Some(Cc::No), Some(Lld::Yes))
+        } else if stem == "ld" || stem.ends_with("-ld") || stem == "link" {
+            (Some(Cc::No), Some(Lld::No))
+        } else {
+            (None, None)
+        }
+    }
+
+    fn with_hints(self, (cc_hint, lld_hint): (Option<Cc>, Option<Lld>)) -> LinkerFlavor {
+        match self {
+            LinkerFlavor::Gnu(cc, lld) => {
+                LinkerFlavor::Gnu(cc_hint.unwrap_or(cc), lld_hint.unwrap_or(lld))
+            }
+            LinkerFlavor::Darwin(cc, lld) => {
+                LinkerFlavor::Darwin(cc_hint.unwrap_or(cc), lld_hint.unwrap_or(lld))
+            }
+            LinkerFlavor::WasmLld(cc) => LinkerFlavor::WasmLld(cc_hint.unwrap_or(cc)),
+            LinkerFlavor::Unix(cc) => LinkerFlavor::Unix(cc_hint.unwrap_or(cc)),
+            LinkerFlavor::Msvc(lld) => LinkerFlavor::Msvc(lld_hint.unwrap_or(lld)),
+            LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => self,
+        }
+    }
+
+    pub fn with_cli_hints(self, cli: LinkerFlavorCli) -> LinkerFlavor {
+        self.with_hints(LinkerFlavor::infer_cli_hints(cli))
+    }
+
+    pub fn with_linker_hints(self, linker_stem: &str) -> LinkerFlavor {
+        self.with_hints(LinkerFlavor::infer_linker_hints(linker_stem))
+    }
+
+    pub fn check_compatibility(self, cli: LinkerFlavorCli) -> Option<String> {
+        // The CLI flavor should be compatible with the target if it survives this roundtrip.
+        let compatible = |cli| cli == self.with_cli_hints(cli).to_cli();
+        (!compatible(cli)).then(|| {
+            LinkerFlavorCli::all()
+                .iter()
+                .filter(|cli| compatible(**cli))
+                .map(|cli| cli.desc())
+                .intersperse(", ")
+                .collect()
+        })
+    }
+
     pub fn lld_flavor(self) -> LldFlavor {
         match self {
             LinkerFlavor::Gnu(..)
@@ -278,6 +353,10 @@ impl LinkerFlavor {
 macro_rules! linker_flavor_cli_impls {
     ($(($($flavor:tt)*) $string:literal)*) => (
         impl LinkerFlavorCli {
+            const fn all() -> &'static [LinkerFlavorCli] {
+                &[$($($flavor)*,)*]
+            }
+
             pub const fn one_of() -> &'static str {
                 concat!("one of: ", $($string, " ",)*)
             }
@@ -289,8 +368,8 @@ macro_rules! linker_flavor_cli_impls {
                 })
             }
 
-            pub fn desc(&self) -> &str {
-                match *self {
+            pub fn desc(self) -> &'static str {
+                match self {
                     $($($flavor)* => $string,)*
                 }
             }
@@ -1801,7 +1880,7 @@ impl TargetOptions {
     }
 
     fn update_from_cli(&mut self) {
-        self.linker_flavor = LinkerFlavor::from_cli_impl(
+        self.linker_flavor = LinkerFlavor::from_cli_json(
             self.linker_flavor_json,
             self.lld_flavor_json,
             self.linker_is_gnu_json,
@@ -1815,12 +1894,7 @@ impl TargetOptions {
         ] {
             args.clear();
             for (flavor, args_json) in args_json {
-                // Cannot use `from_cli` due to borrow checker.
-                let linker_flavor = LinkerFlavor::from_cli_impl(
-                    *flavor,
-                    self.lld_flavor_json,
-                    self.linker_is_gnu_json,
-                );
+                let linker_flavor = self.linker_flavor.with_cli_hints(*flavor);
                 // Normalize to no lld to avoid asserts.
                 let linker_flavor = match linker_flavor {
                     LinkerFlavor::Gnu(cc, _) => LinkerFlavor::Gnu(cc, Lld::No),
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 9012bda4043..1470dc452a1 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1776,6 +1776,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     || !trait_pred
                         .skip_binder()
                         .is_constness_satisfied_by(self.tcx.constness(def_id))
+                    || !self.tcx.is_user_visible_dep(def_id.krate)
                 {
                     return None;
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 4b38687eebe..f7389bda159 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -32,7 +32,7 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
-use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeSuperVisitable};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFolder, TypeSuperVisitable};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
 use rustc_span::def_id::DefId;
 use rustc_span::Span;
@@ -272,8 +272,62 @@ pub fn normalize_param_env_or_error<'tcx>(
     // parameter environments once for every fn as it goes,
     // and errors will get reported then; so outside of type inference we
     // can be sure that no errors should occur.
-    let mut predicates: Vec<_> =
-        util::elaborate(tcx, unnormalized_env.caller_bounds().into_iter()).collect();
+    let mut predicates: Vec<_> = util::elaborate(
+        tcx,
+        unnormalized_env.caller_bounds().into_iter().map(|predicate| {
+            if tcx.features().generic_const_exprs {
+                return predicate;
+            }
+
+            struct ConstNormalizer<'tcx>(TyCtxt<'tcx>);
+
+            impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ConstNormalizer<'tcx> {
+                fn interner(&self) -> TyCtxt<'tcx> {
+                    self.0
+                }
+
+                fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
+                    // While it is pretty sus to be evaluating things with an empty param env, it
+                    // should actually be okay since without `feature(generic_const_exprs)` the only
+                    // const arguments that have a non-empty param env are array repeat counts. These
+                    // do not appear in the type system though.
+                    c.eval(self.0, ty::ParamEnv::empty())
+                }
+            }
+
+            // This whole normalization step is a hack to work around the fact that
+            // `normalize_param_env_or_error` is fundamentally broken from using an
+            // unnormalized param env with a trait solver that expects the param env
+            // to be normalized.
+            //
+            // When normalizing the param env we can end up evaluating obligations
+            // that have been normalized but can only be proven via a where clause
+            // which is still in its unnormalized form. example:
+            //
+            // Attempting to prove `T: Trait<<u8 as Identity>::Assoc>` in a param env
+            // with a `T: Trait<<u8 as Identity>::Assoc>` where clause will fail because
+            // we first normalize obligations before proving them so we end up proving
+            // `T: Trait<u8>`. Since lazy normalization is not implemented equating `u8`
+            // with `<u8 as Identity>::Assoc` fails outright so we incorrectly believe that
+            // we cannot prove `T: Trait<u8>`.
+            //
+            // The same thing is true for const generics- attempting to prove
+            // `T: Trait<ConstKind::Unevaluated(...)>` with the same thing as a where clauses
+            // will fail. After normalization we may be attempting to prove `T: Trait<4>` with
+            // the unnormalized where clause `T: Trait<ConstKind::Unevaluated(...)>`. In order
+            // for the obligation to hold `4` must be equal to `ConstKind::Unevaluated(...)`
+            // but as we do not have lazy norm implemented, equating the two consts fails outright.
+            //
+            // Ideally we would not normalize consts here at all but it is required for backwards
+            // compatibility. Eventually when lazy norm is implemented this can just be removed.
+            // We do not normalize types here as there is no backwards compatibility requirement
+            // for us to do so.
+            //
+            // FIXME(-Ztrait-solver=next): remove this hack since we have deferred projection equality
+            predicate.fold_with(&mut ConstNormalizer(tcx))
+        }),
+    )
+    .collect();
 
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 01d1fdc9b2a..8c4f6a73d7f 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -38,7 +38,6 @@ extern "Rust" {
     #[rustc_nounwind]
     fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
 
-    #[cfg(not(bootstrap))]
     static __rust_no_alloc_shim_is_unstable: u8;
 }
 
@@ -96,7 +95,6 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
     unsafe {
         // Make sure we don't accidentally allow omitting the allocator shim in
         // stable code until it is actually stabilized.
-        #[cfg(not(bootstrap))]
         core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable);
 
         __rust_alloc(layout.size(), layout.align())
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index c524d4c0367..59e3f887b52 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -2624,7 +2624,7 @@ impl ToString for String {
 }
 
 #[cfg(not(no_global_oom_handling))]
-#[stable(feature = "fmt_arguments_to_string_specialization", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "fmt_arguments_to_string_specialization", since = "1.71.0")]
 impl ToString for fmt::Arguments<'_> {
     #[inline]
     fn to_string(&self) -> String {
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index fec92320a4b..76b3589b9e4 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -538,29 +538,6 @@ impl<T, const N: usize> [T; N] {
         drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f)))
     }
 
-    /// 'Zips up' two arrays into a single array of pairs.
-    ///
-    /// `zip()` returns a new array where every element is a tuple where the
-    /// first element comes from the first array, and the second element comes
-    /// from the second array. In other words, it zips two arrays together,
-    /// into a single one.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(array_zip)]
-    /// let x = [1, 2, 3];
-    /// let y = [4, 5, 6];
-    /// let z = x.zip(y);
-    /// assert_eq!(z, [(1, 4), (2, 5), (3, 6)]);
-    /// ```
-    #[unstable(feature = "array_zip", issue = "80094")]
-    pub fn zip<U>(self, rhs: [U; N]) -> [(T, U); N] {
-        drain_array_with(self, |lhs| {
-            drain_array_with(rhs, |rhs| from_trusted_iterator(crate::iter::zip(lhs, rhs)))
-        })
-    }
-
     /// Returns a slice containing the entire array. Equivalent to `&s[..]`.
     #[stable(feature = "array_as_slice", since = "1.57.0")]
     #[rustc_const_stable(feature = "array_as_slice", since = "1.57.0")]
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 38a6d1ccdb5..799085e9a83 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -495,8 +495,7 @@ pub trait Into<T>: Sized {
 /// By converting underlying error types to our own custom error type that encapsulates the
 /// underlying error type, we can return a single error type without losing information on the
 /// underlying cause. The '?' operator automatically converts the underlying error type to our
-/// custom error type by calling `Into<CliError>::into` which is automatically provided when
-/// implementing `From`. The compiler then infers which implementation of `Into` should be used.
+/// custom error type with `From::from`.
 ///
 /// ```
 /// use std::fs;
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 201bacb28c7..50c7516b7fe 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -81,7 +81,7 @@ use crate::str;
 #[derive(Hash)]
 #[stable(feature = "core_c_str", since = "1.64.0")]
 #[rustc_has_incoherent_inherent_impls]
-#[cfg_attr(not(bootstrap), lang = "CStr")]
+#[lang = "CStr"]
 // FIXME:
 // `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
 // on `CStr` being layout-compatible with `[u8]`.
@@ -531,8 +531,8 @@ impl CStr {
     /// # }
     /// ```
     #[inline]
-    #[stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "cstr_is_empty", since = "1.71.0")]
+    #[rustc_const_stable(feature = "cstr_is_empty", since = "1.71.0")]
     pub const fn is_empty(&self) -> bool {
         // SAFETY: We know there is at least one byte; for empty strings it
         // is the NUL terminator.
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index b73abbbaca7..86ea154a886 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -202,7 +202,7 @@ mod c_long_definition {
 //     would be uninhabited and at least dereferencing such pointers would
 //     be UB.
 #[doc = include_str!("c_void.md")]
-#[cfg_attr(not(bootstrap), lang = "c_void")]
+#[lang = "c_void"]
 #[cfg_attr(not(doc), repr(u8))] // work around https://github.com/rust-lang/rust/issues/90435
 #[stable(feature = "core_c_void", since = "1.30.0")]
 pub enum c_void {
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index ca7c0772de8..794a57f0922 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -695,7 +695,7 @@ pub trait BuildHasher {
     ///     bh.hash_one(&OrderAmbivalentPair(2, 10))
     /// );
     /// ```
-    #[stable(feature = "build_hasher_simple_hash_one", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "build_hasher_simple_hash_one", since = "1.71.0")]
     fn hash_one<T: Hash>(&self, x: T) -> u64
     where
         Self: Sized,
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 23ded42fa66..6dca1fe1e69 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1385,7 +1385,6 @@ extern "rust-intrinsic" {
     ///
     /// This is not expected to ever be exposed directly to users, rather it
     /// may eventually be exposed through some more-constrained API.
-    #[cfg(not(bootstrap))]
     #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
     #[rustc_nounwind]
     pub fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
@@ -1425,19 +1424,11 @@ extern "rust-intrinsic" {
     /// returned value will result in undefined behavior.
     ///
     /// The stabilized version of this intrinsic is [`pointer::offset`].
-    #[cfg(not(bootstrap))]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
     #[rustc_nounwind]
     pub fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
 
-    /// The bootstrap version of this is more restricted.
-    #[cfg(bootstrap)]
-    #[must_use = "returns a new pointer rather than modifying its argument"]
-    #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
-    #[rustc_nounwind]
-    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
-
     /// Calculates the offset from a pointer, potentially wrapping.
     ///
     /// This is implemented as an intrinsic to avoid converting to and from an
@@ -2260,7 +2251,7 @@ extern "rust-intrinsic" {
     /// This intrinsic can *only* be called where the pointer is a local without
     /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
     /// trivially obeys runtime-MIR rules about derefs in operands.
-    #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
     #[rustc_nounwind]
     pub fn read_via_copy<T>(ptr: *const T) -> T;
 
@@ -2270,7 +2261,6 @@ extern "rust-intrinsic" {
     /// This intrinsic can *only* be called where the pointer is a local without
     /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
     /// that it trivially obeys runtime-MIR rules about derefs in operands.
-    #[cfg(not(bootstrap))]
     #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
     #[rustc_nounwind]
     pub fn write_via_move<T>(ptr: *mut T, value: T);
@@ -2832,24 +2822,3 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
         write_bytes(dst, val, count)
     }
 }
-
-/// Polyfill for bootstrap
-#[cfg(bootstrap)]
-pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst {
-    use crate::mem::*;
-    // SAFETY: It's a transmute -- the caller promised it's fine.
-    unsafe { transmute_copy(&ManuallyDrop::new(src)) }
-}
-
-/// Polyfill for bootstrap
-#[cfg(bootstrap)]
-pub const unsafe fn write_via_move<T>(ptr: *mut T, value: T) {
-    use crate::mem::*;
-    // SAFETY: the caller must guarantee that `dst` is valid for writes.
-    // `dst` cannot overlap `src` because the caller has mutable access
-    // to `dst` while `src` is owned by this function.
-    unsafe {
-        copy_nonoverlapping::<T>(&value, ptr, 1);
-        forget(value);
-    }
-}
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 8dab8d1a692..2d2d5d49175 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -971,7 +971,7 @@ pub trait Tuple {}
 pub trait PointerLike {}
 
 /// A marker for types which can be used as types of `const` generic parameters.
-#[cfg_attr(not(bootstrap), lang = "const_param_ty")]
+#[lang = "const_param_ty"]
 #[unstable(feature = "adt_const_params", issue = "95174")]
 #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
 pub trait ConstParamTy: StructuralEq {}
@@ -979,7 +979,6 @@ pub trait ConstParamTy: StructuralEq {}
 /// Derive macro generating an impl of the trait `ConstParamTy`.
 #[rustc_builtin_macro]
 #[unstable(feature = "adt_const_params", issue = "95174")]
-#[cfg(not(bootstrap))]
 pub macro ConstParamTy($item:item) {
     /* compiler built-in */
 }
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index afbfd6d362d..39c9a04eea9 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -968,7 +968,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
 /// Integers and other types implementing [`Copy`] are unaffected by `drop`.
 ///
 /// ```
-/// # #![cfg_attr(not(bootstrap), allow(dropping_copy_types))]
+/// # #![allow(dropping_copy_types)]
 /// #[derive(Copy, Clone)]
 /// struct Foo(u8);
 ///
@@ -1316,7 +1316,6 @@ impl<T> SizedTypeProperties for T {}
 ///
 /// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
 /// ```
-#[cfg(not(bootstrap))]
 #[unstable(feature = "offset_of", issue = "106655")]
 #[allow_internal_unstable(builtin_syntax)]
 pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 38a1c42d9e8..7f06e170ad0 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -769,8 +769,8 @@ macro_rules! nonzero_signed_operations {
                 /// ```
                 #[must_use]
                 #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
                 pub const fn is_positive(self) -> bool {
                     self.get().is_positive()
                 }
@@ -794,8 +794,8 @@ macro_rules! nonzero_signed_operations {
                 /// ```
                 #[must_use]
                 #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
                 pub const fn is_negative(self) -> bool {
                     self.get().is_negative()
                 }
@@ -819,8 +819,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
                 pub const fn checked_neg(self) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_neg() {
                         // SAFETY: negation of nonzero cannot yield zero values.
@@ -851,8 +851,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
                 pub const fn overflowing_neg(self) -> ($Ty, bool) {
                     let (result, overflow) = self.get().overflowing_neg();
                     // SAFETY: negation of nonzero cannot yield zero values.
@@ -884,8 +884,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
                 pub const fn saturating_neg(self) -> $Ty {
                     if let Some(result) = self.checked_neg() {
                         return result;
@@ -916,8 +916,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "CURRENT_RUSTC_VERSION")]
+                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
                 pub const fn wrapping_neg(self) -> $Ty {
                     let result = self.get().wrapping_neg();
                     // SAFETY: negation of nonzero cannot yield zero values.
@@ -925,7 +925,7 @@ macro_rules! nonzero_signed_operations {
                 }
             }
 
-            #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")]
+            #[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
             impl Neg for $Ty {
                 type Output = $Ty;
 
@@ -937,7 +937,7 @@ macro_rules! nonzero_signed_operations {
             }
 
             forward_ref_unop! { impl Neg, neg for $Ty,
-                #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] }
+                #[stable(feature = "signed_nonzero_neg", since = "1.71.0")] }
         )+
     }
 }
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 5ee1b5e4afc..926189a17b2 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -104,6 +104,7 @@ impl<T: ?Sized> *const T {
     /// refactored.
     #[stable(feature = "ptr_const_cast", since = "1.65.0")]
     #[rustc_const_stable(feature = "ptr_const_cast", since = "1.65.0")]
+    #[rustc_diagnostic_item = "ptr_cast_mut"]
     #[inline(always)]
     pub const fn cast_mut(self) -> *mut T {
         self as _
@@ -916,16 +917,8 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        #[cfg(bootstrap)]
         // SAFETY: the caller must uphold the safety contract for `offset`.
-        unsafe {
-            self.offset(count as isize)
-        }
-        #[cfg(not(bootstrap))]
-        // SAFETY: the caller must uphold the safety contract for `offset`.
-        unsafe {
-            intrinsics::offset(self, count)
-        }
+        unsafe { intrinsics::offset(self, count) }
     }
 
     /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -1195,7 +1188,7 @@ impl<T: ?Sized> *const T {
     ///
     /// [`ptr::read`]: crate::ptr::read()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn read(self) -> T
@@ -1236,7 +1229,7 @@ impl<T: ?Sized> *const T {
     ///
     /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn read_unaligned(self) -> T
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index ff9fa48f311..acc9ca29d41 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -698,6 +698,7 @@ where
 #[inline(always)]
 #[must_use]
 #[unstable(feature = "ptr_from_ref", issue = "106116")]
+#[rustc_diagnostic_item = "ptr_from_ref"]
 pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
     r
 }
@@ -1139,7 +1140,7 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
 /// [valid]: self#safety
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
 #[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub const unsafe fn read<T>(src: *const T) -> T {
@@ -1256,7 +1257,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 /// ```
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
-#[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
 #[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 5edd291fb76..c6f43857887 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -473,20 +473,10 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        #[cfg(bootstrap)]
         // SAFETY: the caller must uphold the safety contract for `offset`.
         // The obtained pointer is valid for writes since the caller must
         // guarantee that it points to the same allocated object as `self`.
-        unsafe {
-            intrinsics::offset(self, count) as *mut T
-        }
-        #[cfg(not(bootstrap))]
-        // SAFETY: the caller must uphold the safety contract for `offset`.
-        // The obtained pointer is valid for writes since the caller must
-        // guarantee that it points to the same allocated object as `self`.
-        unsafe {
-            intrinsics::offset(self, count)
-        }
+        unsafe { intrinsics::offset(self, count) }
     }
 
     /// Calculates the offset from a pointer in bytes.
@@ -1026,16 +1016,8 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        #[cfg(bootstrap)]
-        // SAFETY: the caller must uphold the safety contract for `offset`.
-        unsafe {
-            self.offset(count as isize)
-        }
-        #[cfg(not(bootstrap))]
         // SAFETY: the caller must uphold the safety contract for `offset`.
-        unsafe {
-            intrinsics::offset(self, count)
-        }
+        unsafe { intrinsics::offset(self, count) }
     }
 
     /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -1305,7 +1287,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::read`]: crate::ptr::read()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn read(self) -> T
@@ -1346,7 +1328,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_stable(feature = "const_ptr_read", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn read_unaligned(self) -> T
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 62003ddf515..c87af35fbc4 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1854,7 +1854,7 @@ impl<T> [T] {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")]
     #[rustc_allow_const_fn_unstable(slice_split_at_unchecked)]
     #[inline]
     #[track_caller]
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 172e5fccb61..a1388dfeee6 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -100,7 +100,7 @@ macro_rules! tuple_impls {
             }
         }
 
-        #[stable(feature = "array_tuple_conv", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
         impl<T> From<[T; ${count(T)}]> for ($(${ignore(T)} T,)+) {
             #[inline]
             #[allow(non_snake_case)]
@@ -110,7 +110,7 @@ macro_rules! tuple_impls {
             }
         }
 
-        #[stable(feature = "array_tuple_conv", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
         impl<T> From<($(${ignore(T)} T,)+)> for [T; ${count(T)}] {
             #[inline]
             #[allow(non_snake_case)]
diff --git a/library/core/tests/clone.rs b/library/core/tests/clone.rs
index aafe5ced2e9..64193e11558 100644
--- a/library/core/tests/clone.rs
+++ b/library/core/tests/clone.rs
@@ -1,5 +1,5 @@
 #[test]
-#[cfg_attr(not(bootstrap), allow(suspicious_double_ref_op))]
+#[allow(suspicious_double_ref_op)]
 fn test_borrowed_clone() {
     let x = 5;
     let y: &i32 = &x;
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 3933e328951..3e6d31fcd2f 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -109,7 +109,7 @@
 #![feature(utf8_chunks)]
 #![feature(is_ascii_octdigit)]
 #![feature(get_many_mut)]
-#![cfg_attr(not(bootstrap), feature(offset_of))]
+#![feature(offset_of)]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(fuzzy_provenance_casts)]
 
diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs
index aee9c89b595..5c2e18745ea 100644
--- a/library/core/tests/mem.rs
+++ b/library/core/tests/mem.rs
@@ -366,7 +366,6 @@ fn const_maybe_uninit() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of() {
     #[repr(C)]
     struct Foo {
@@ -391,7 +390,7 @@ fn offset_of() {
     struct Generic<T> {
         x: u8,
         y: u32,
-        z: T
+        z: T,
     }
 
     trait Trait {}
@@ -409,7 +408,6 @@ fn offset_of() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_union() {
     #[repr(C)]
     union Foo {
@@ -429,7 +427,6 @@ fn offset_of_union() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_dst() {
     #[repr(C)]
     struct Alpha {
@@ -469,7 +466,6 @@ fn offset_of_dst() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_packed() {
     #[repr(C, packed)]
     struct Foo {
@@ -482,7 +478,6 @@ fn offset_of_packed() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_projection() {
     #[repr(C)]
     struct Foo {
@@ -503,7 +498,6 @@ fn offset_of_projection() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_alias() {
     #[repr(C)]
     struct Foo {
@@ -518,7 +512,6 @@ fn offset_of_alias() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn const_offset_of() {
     #[repr(C)]
     struct Foo {
@@ -534,7 +527,6 @@ fn const_offset_of() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_without_const_promotion() {
     #[repr(C)]
     struct Foo<SuppressConstPromotion> {
@@ -555,7 +547,6 @@ fn offset_of_without_const_promotion() {
 }
 
 #[test]
-#[cfg(not(bootstrap))]
 fn offset_of_addr() {
     #[repr(C)]
     struct Foo {
diff --git a/library/portable-simd/Cargo.toml b/library/portable-simd/Cargo.toml
index 9802386e456..d1732aaec2f 100644
--- a/library/portable-simd/Cargo.toml
+++ b/library/portable-simd/Cargo.toml
@@ -1,5 +1,5 @@
 [workspace]
-
+resolver = "1"
 members = [
     "crates/core_simd",
     "crates/std_float",
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 824abc72a22..72d910bf957 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -1,3 +1,5 @@
+cargo-features = ["public-dependency"]
+
 [package]
 name = "std"
 version = "0.0.0"
@@ -10,12 +12,12 @@ edition = "2021"
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-alloc = { path = "../alloc" }
+alloc = { path = "../alloc", public = true }
 cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
-core = { path = "../core" }
-libc = { version = "0.2.143", default-features = false, features = ['rustc-dep-of-std'] }
+core = { path = "../core", public = true }
+libc = { version = "0.2.143", default-features = false, features = ['rustc-dep-of-std'], public = true }
 compiler_builtins = { version = "0.1.92" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
@@ -25,7 +27,7 @@ std_detect = { path = "../stdarch/crates/std_detect", default-features = false,
 # Dependencies of the `backtrace` crate
 addr2line = { version = "0.19.0", optional = true, default-features = false }
 rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] }
-miniz_oxide = { version = "0.6.0", optional = true, default-features = false }
+miniz_oxide = { version = "0.6.0", optional = true, default-features = false, public = false }
 [dependencies.object]
 version = "0.30.0"
 optional = true
@@ -40,7 +42,7 @@ rand_xorshift = "0.3.0"
 dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
 
 [target.x86_64-fortanix-unknown-sgx.dependencies]
-fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
+fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true }
 
 [target.'cfg(target_os = "hermit")'.dependencies]
 hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] }
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index cbf8209a5ad..274af08a388 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -437,7 +437,7 @@ impl<T: AsHandle> AsHandle for &mut T {
     }
 }
 
-#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 /// This impl allows implementing traits that require `AsHandle` on Arc.
 /// ```
 /// # #[cfg(windows)] mod group_cfg {
@@ -457,7 +457,7 @@ impl<T: AsHandle> AsHandle for crate::sync::Arc<T> {
     }
 }
 
-#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 impl<T: AsHandle> AsHandle for crate::rc::Rc<T> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
@@ -465,7 +465,7 @@ impl<T: AsHandle> AsHandle for crate::rc::Rc<T> {
     }
 }
 
-#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 impl<T: AsHandle> AsHandle for Box<T> {
     #[inline]
     fn as_handle(&self) -> BorrowedHandle<'_> {
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index 0c90d55c024..6359835cad5 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -254,7 +254,7 @@ impl<T: AsSocket> AsSocket for &mut T {
     }
 }
 
-#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 /// This impl allows implementing traits that require `AsSocket` on Arc.
 /// ```
 /// # #[cfg(windows)] mod group_cfg {
@@ -274,7 +274,7 @@ impl<T: AsSocket> AsSocket for crate::sync::Arc<T> {
     }
 }
 
-#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
@@ -282,7 +282,7 @@ impl<T: AsSocket> AsSocket for crate::rc::Rc<T> {
     }
 }
 
-#[stable(feature = "as_windows_ptrs", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "as_windows_ptrs", since = "1.71.0")]
 impl<T: AsSocket> AsSocket for Box<T> {
     #[inline]
     fn as_socket(&self) -> BorrowedSocket<'_> {
diff --git a/library/std/src/sys/wasi/fd.rs b/library/std/src/sys/wasi/fd.rs
index 9a8b2a0be5b..1b50c2ea6dd 100644
--- a/library/std/src/sys/wasi/fd.rs
+++ b/library/std/src/sys/wasi/fd.rs
@@ -96,7 +96,7 @@ impl WasiFd {
         unsafe { wasi::fd_sync(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
     }
 
-    pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
+    pub(crate) fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
         unsafe {
             wasi::fd_advise(self.as_raw_fd() as wasi::Fd, offset, len, advice).map_err(err2io)
         }
@@ -179,7 +179,7 @@ impl WasiFd {
         }
     }
 
-    pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
+    pub(crate) fn filestat_get(&self) -> io::Result<wasi::Filestat> {
         unsafe { wasi::fd_filestat_get(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
     }
 
@@ -199,7 +199,7 @@ impl WasiFd {
         unsafe { wasi::fd_filestat_set_size(self.as_raw_fd() as wasi::Fd, size).map_err(err2io) }
     }
 
-    pub fn path_filestat_get(
+    pub(crate) fn path_filestat_get(
         &self,
         flags: wasi::Lookupflags,
         path: &str,
diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs
index 8d1dbf59155..437aae3ae7f 100644
--- a/library/std/src/sys/wasi/fs.rs
+++ b/library/std/src/sys/wasi/fs.rs
@@ -104,7 +104,7 @@ impl FileAttr {
         Ok(SystemTime::from_wasi_timestamp(self.meta.ctim))
     }
 
-    pub fn as_wasi(&self) -> &wasi::Filestat {
+    pub(crate) fn as_wasi(&self) -> &wasi::Filestat {
         &self.meta
     }
 }
@@ -142,7 +142,7 @@ impl FileType {
         self.bits == wasi::FILETYPE_SYMBOLIC_LINK
     }
 
-    pub fn bits(&self) -> wasi::Filetype {
+    pub(crate) fn bits(&self) -> wasi::Filetype {
         self.bits
     }
 }
diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs
index fce220223a0..358c2c3f9b2 100644
--- a/library/std/tests/common/mod.rs
+++ b/library/std/tests/common/mod.rs
@@ -20,15 +20,15 @@ pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
 }
 
 // Copied from std::sys_common::io
-pub struct TempDir(PathBuf);
+pub(crate) struct TempDir(PathBuf);
 
 impl TempDir {
-    pub fn join(&self, path: &str) -> PathBuf {
+    pub(crate) fn join(&self, path: &str) -> PathBuf {
         let TempDir(ref p) = *self;
         p.join(path)
     }
 
-    pub fn path(&self) -> &Path {
+    pub(crate) fn path(&self) -> &Path {
         let TempDir(ref p) = *self;
         p
     }
@@ -49,7 +49,7 @@ impl Drop for TempDir {
 }
 
 #[track_caller] // for `test_rng`
-pub fn tmpdir() -> TempDir {
+pub(crate) fn tmpdir() -> TempDir {
     let p = env::temp_dir();
     let mut r = test_rng();
     let ret = p.join(&format!("rust-{}", r.next_u32()));
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 58d1926ad96..473fdbe1edc 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -835,7 +835,7 @@ class RustBuild(object):
         """
         return os.path.join(self.build_dir, "bootstrap", "debug", "bootstrap")
 
-    def build_bootstrap(self, color, verbose_count):
+    def build_bootstrap(self, color, warnings, verbose_count):
         """Build bootstrap"""
         env = os.environ.copy()
         if "GITHUB_ACTIONS" in env:
@@ -877,6 +877,12 @@ class RustBuild(object):
 
         # preserve existing RUSTFLAGS
         env.setdefault("RUSTFLAGS", "")
+        # we need to explicitly add +xgot here so that we can successfully bootstrap
+        # a usable stage1 compiler
+        # FIXME: remove this if condition on the next bootstrap bump
+        # cfg(bootstrap)
+        if self.build_triple().startswith('mips'):
+            env["RUSTFLAGS"] += " -Ctarget-feature=+xgot"
         target_features = []
         if self.get_toml("crt-static", build_section) == "true":
             target_features += ["+crt-static"]
@@ -888,7 +894,11 @@ class RustBuild(object):
         if target_linker is not None:
             env["RUSTFLAGS"] += " -C linker=" + target_linker
         env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes"
-        if self.get_toml("deny-warnings", "rust") != "false":
+        if warnings == "default":
+            deny_warnings = self.get_toml("deny-warnings", "rust") != "false"
+        else:
+            deny_warnings = warnings == "deny"
+        if deny_warnings:
             env["RUSTFLAGS"] += " -Dwarnings"
 
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
@@ -912,6 +922,10 @@ class RustBuild(object):
             args.append("--color=always")
         elif color == "never":
             args.append("--color=never")
+        try:
+            args += env["CARGOFLAGS"].split()
+        except KeyError:
+            pass
 
         # Run this from the source directory so cargo finds .cargo/config
         run(args, env=env, verbose=self.verbose, cwd=self.rust_root)
@@ -977,6 +991,7 @@ def parse_args():
     parser.add_argument('--color', choices=['always', 'never', 'auto'])
     parser.add_argument('--clean', action='store_true')
     parser.add_argument('--json-output', action='store_true')
+    parser.add_argument('--warnings', choices=['deny', 'warn', 'default'], default='default')
     parser.add_argument('-v', '--verbose', action='count', default=0)
 
     return parser.parse_known_args(sys.argv)[0]
@@ -1042,7 +1057,7 @@ def bootstrap(args):
     # Fetch/build the bootstrap
     build.download_toolchain()
     sys.stdout.flush()
-    build.build_bootstrap(args.color, verbose_count)
+    build.build_bootstrap(args.color, args.warnings, verbose_count)
     sys.stdout.flush()
 
     # Run the bootstrap
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 30359e47e73..43c859b0063 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -381,7 +381,7 @@ impl StepDescription {
             eprintln!(
                 "note: if you are adding a new Step to bootstrap itself, make sure you register it with `describe!`"
             );
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
     }
 }
@@ -1355,7 +1355,7 @@ impl<'a> Builder<'a> {
                         "error: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component"
                     );
                     eprintln!("help: try `rustup component add clippy`");
-                    crate::detail_exit(1);
+                    crate::detail_exit_macro!(1);
                 });
                 if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") {
                     rustflags.arg("--cfg=bootstrap");
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index a7ebd018a87..1c66c00eda7 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1686,7 +1686,7 @@ pub fn run_cargo(
     });
 
     if !ok {
-        crate::detail_exit(1);
+        crate::detail_exit_macro!(1);
     }
 
     // Ok now we need to actually find all the files listed in `toplevel`. We've
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 41aca0210f6..45ad1547eb7 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -23,6 +23,7 @@ use crate::channel::{self, GitInfo};
 pub use crate::flags::Subcommand;
 use crate::flags::{Color, Flags, Warnings};
 use crate::util::{exe, output, t};
+use build_helper::detail_exit_macro;
 use once_cell::sync::OnceCell;
 use serde::{Deserialize, Deserializer};
 use serde_derive::Deserialize;
@@ -579,7 +580,7 @@ macro_rules! define_config {
                                         panic!("overriding existing option")
                                     } else {
                                         eprintln!("overriding existing option: `{}`", stringify!($field));
-                                        crate::detail_exit(2);
+                                        detail_exit_macro!(2);
                                     }
                                 } else {
                                     self.$field = other.$field;
@@ -678,7 +679,7 @@ impl<T> Merge for Option<T> {
                             panic!("overriding existing option")
                         } else {
                             eprintln!("overriding existing option");
-                            crate::detail_exit(2);
+                            detail_exit_macro!(2);
                         }
                     } else {
                         *self = other;
@@ -944,7 +945,7 @@ impl Config {
                 .and_then(|table: toml::Value| TomlConfig::deserialize(table))
                 .unwrap_or_else(|err| {
                     eprintln!("failed to parse TOML configuration '{}': {err}", file.display());
-                    crate::detail_exit(2);
+                    detail_exit_macro!(2);
                 })
         }
         Self::parse_inner(args, get_toml)
@@ -978,7 +979,7 @@ impl Config {
             eprintln!(
                 "Cannot use both `llvm_bolt_profile_generate` and `llvm_bolt_profile_use` at the same time"
             );
-            crate::detail_exit(1);
+            detail_exit_macro!(1);
         }
 
         // Infer the rest of the configuration.
@@ -1094,7 +1095,7 @@ impl Config {
                 }
             }
             eprintln!("failed to parse override `{option}`: `{err}");
-            crate::detail_exit(2)
+            detail_exit_macro!(2)
         }
         toml.merge(override_toml, ReplaceOpt::Override);
 
@@ -1810,7 +1811,7 @@ impl Config {
             println!("help: maybe your repository history is too shallow?");
             println!("help: consider disabling `download-rustc`");
             println!("help: or fetch enough history to include one upstream commit");
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
 
         // Warn if there were changes to the compiler or standard library since the ancestor commit.
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 46fc5b80e99..6a2409a0fbf 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1009,6 +1009,9 @@ impl Step for PlainSourceTarball {
                 .arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml"))
                 .arg("--sync")
                 .arg(builder.src.join("./src/bootstrap/Cargo.toml"))
+                // Will read the libstd Cargo.toml
+                // which uses the unstable `public-dependency` feature.
+                .env("RUSTC_BOOTSTRAP", "1")
                 .current_dir(&plain_dst_src);
 
             let config = if !builder.config.dry_run() {
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
index c7969d2a2c7..12780df2175 100644
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -7,6 +7,7 @@ use std::{
     process::{Command, Stdio},
 };
 
+use build_helper::util::try_run;
 use once_cell::sync::OnceCell;
 use xz2::bufread::XzDecoder;
 
@@ -14,7 +15,7 @@ use crate::{
     config::RustfmtMetadata,
     llvm::detect_llvm_sha,
     t,
-    util::{check_run, exe, program_out_of_date, try_run},
+    util::{check_run, exe, program_out_of_date},
     Config,
 };
 
@@ -245,7 +246,7 @@ impl Config {
             if !help_on_error.is_empty() {
                 eprintln!("{}", help_on_error);
             }
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
     }
 
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 80e71577798..dc05f47ee9c 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -193,7 +193,7 @@ impl Flags {
             } else {
                 panic!("No paths available for subcommand `{}`", subcommand.as_str());
             }
-            crate::detail_exit(0);
+            crate::detail_exit_macro!(0);
         }
 
         Flags::parse_from(it)
@@ -538,7 +538,7 @@ pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Opt
     } else {
         std::fs::read_to_string(path).unwrap_or_else(|_| {
             eprintln!("couldn't read {}", path.display());
-            crate::detail_exit(1)
+            crate::detail_exit_macro!(1)
         })
     };
     let mut buf = Vec::new();
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index d8d3f300a35..ebf068b2cb1 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -40,7 +40,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F
                         code, run `./x.py fmt` instead.",
                 cmd_debug,
             );
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
         true
     }
@@ -196,7 +196,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
 
     let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
         eprintln!("./x.py fmt is not supported on this channel");
-        crate::detail_exit(1);
+        crate::detail_exit_macro!(1);
     });
     assert!(rustfmt_path.exists(), "{}", rustfmt_path.display());
     let src = build.src.clone();
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f7d30de67eb..a1aaee68c62 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -27,6 +27,7 @@ use std::process::{Command, Stdio};
 use std::str;
 
 use build_helper::ci::{gha, CiEnv};
+use build_helper::detail_exit_macro;
 use channel::GitInfo;
 use config::{DryRun, Target};
 use filetime::FileTime;
@@ -699,7 +700,7 @@ impl Build {
             for failure in failures.iter() {
                 eprintln!("  - {}\n", failure);
             }
-            detail_exit(1);
+            detail_exit_macro!(1);
         }
 
         #[cfg(feature = "build-metrics")]
@@ -1482,7 +1483,7 @@ impl Build {
                 "Error: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?",
                 stamp.display()
             );
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
 
         let mut paths = Vec::new();
@@ -1674,7 +1675,7 @@ Alternatively, set `download-ci-llvm = true` in that `[llvm]` section
 to download LLVM rather than building it.
 "
                 );
-                detail_exit(1);
+                detail_exit_macro!(1);
             }
         }
 
@@ -1739,18 +1740,6 @@ fn chmod(path: &Path, perms: u32) {
 #[cfg(windows)]
 fn chmod(_path: &Path, _perms: u32) {}
 
-/// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.)
-/// If the test is running and code is an error code, it will cause a panic.
-fn detail_exit(code: i32) -> ! {
-    // if in test and code is an error code, panic with status code provided
-    if cfg!(test) {
-        panic!("status code: {}", code);
-    } else {
-        // otherwise,exit with provided status code
-        std::process::exit(code);
-    }
-}
-
 impl Compiler {
     pub fn with_stage(mut self, stage: u32) -> Compiler {
         self.stage = stage;
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
index 8f2c3faca3a..3b20ceac875 100644
--- a/src/bootstrap/metadata.rs
+++ b/src/bootstrap/metadata.rs
@@ -74,6 +74,9 @@ fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
     let collect_metadata = |manifest_path| {
         let mut cargo = Command::new(&build.initial_cargo);
         cargo
+            // Will read the libstd Cargo.toml
+            // which uses the unstable `public-dependency` feature.
+            .env("RUSTC_BOOTSTRAP", "1")
             .arg("metadata")
             .arg("--format-version")
             .arg("1")
diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs
index fa0a4806618..872b75f6c15 100644
--- a/src/bootstrap/render_tests.rs
+++ b/src/bootstrap/render_tests.rs
@@ -30,7 +30,7 @@ pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
 
     if !run_tests(builder, cmd) {
         if builder.fail_fast {
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         } else {
             let mut failures = builder.delayed_failures.borrow_mut();
             failures.push(format!("{cmd:?}"));
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 140259b0213..8f5ba42736b 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -104,7 +104,7 @@ You should install cmake, or set `download-ci-llvm = true` in the
 than building it.
 "
             );
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
     }
 
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index 09f26862b4a..40038df8332 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -194,7 +194,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
             "note: this will use the configuration in {}",
             profile.include_path(&config.src).display()
         );
-        crate::detail_exit(1);
+        crate::detail_exit_macro!(1);
     }
 
     let settings = format!(
@@ -380,7 +380,7 @@ pub fn interactive_path() -> io::Result<Profile> {
         io::stdin().read_line(&mut input)?;
         if input.is_empty() {
             eprintln!("EOF on stdin, when expecting answer to question.  Giving up.");
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
         break match parse_with_abbrev(&input) {
             Ok(profile) => profile,
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 960abb31b20..eec8c4ad69f 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -773,7 +773,7 @@ impl Step for Clippy {
         }
 
         if !builder.config.cmd.bless() {
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
 
         let mut cargo = builder.cargo(compiler, Mode::ToolRustc, SourceType::InTree, host, "run");
@@ -1085,7 +1085,7 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy`
                     PATH = inferred_rustfmt_dir.display(),
                     CHAN = builder.config.channel,
                 );
-                crate::detail_exit(1);
+                crate::detail_exit_macro!(1);
             }
             crate::format::format(&builder, !builder.config.cmd.bless(), &[]);
         }
@@ -1108,7 +1108,7 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy`
                 eprintln!(
                     "x.py completions were changed; run `x.py run generate-completions` to update them"
                 );
-                crate::detail_exit(1);
+                crate::detail_exit_macro!(1);
             }
         }
     }
@@ -1329,7 +1329,7 @@ help: to test the compiler, use `--stage 1` instead
 help: to test the standard library, use `--stage 0 library/std` instead
 note: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `COMPILETEST_FORCE_STAGE0=1`."
             );
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
 
         let mut compiler = self.compiler;
@@ -1704,10 +1704,6 @@ note: if you're sure you want to do this, please open an issue as to why. In the
             cmd.arg("--git-hash");
         }
 
-        if let Some(commit) = builder.config.download_rustc_commit() {
-            cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}"));
-        }
-
         builder.ci_env.force_coloring_in_ci(&mut cmd);
 
         #[cfg(feature = "build-metrics")]
@@ -1776,6 +1772,14 @@ impl Step for BookTest {
     ///
     /// This uses the `rustdoc` that sits next to `compiler`.
     fn run(self, builder: &Builder<'_>) {
+        let host = self.compiler.host;
+        let _guard = builder.msg(
+            Kind::Test,
+            self.compiler.stage,
+            &format!("book {}", self.name),
+            host,
+            host,
+        );
         // External docs are different from local because:
         // - Some books need pre-processing by mdbook before being tested.
         // - They need to save their state to toolstate.
@@ -1967,7 +1971,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
         }
     }
 
-    builder.info(&format!("doc tests for: {}", markdown.display()));
+    builder.verbose(&format!("doc tests for: {}", markdown.display()));
     let mut cmd = builder.rustdoc_cmd(compiler);
     builder.add_rust_test_threads(&mut cmd);
     // allow for unstable options such as new editions
@@ -2503,6 +2507,9 @@ impl Step for Distcheck {
         let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml");
         builder.run(
             Command::new(&builder.initial_cargo)
+                // Will read the libstd Cargo.toml
+                // which uses the unstable `public-dependency` feature.
+                .env("RUSTC_BOOTSTRAP", "1")
                 .arg("generate-lockfile")
                 .arg("--manifest-path")
                 .arg(&toml)
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index b3791efaf58..0f0a3bb8775 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -116,7 +116,7 @@ impl Step for ToolBuild {
 
         if !is_expected {
             if !is_optional_tool {
-                crate::detail_exit(1);
+                crate::detail_exit_macro!(1);
             } else {
                 None
             }
diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index 7aab88a1a73..9c4d0ea265d 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -91,7 +91,7 @@ fn print_error(tool: &str, submodule: &str) {
     eprintln!("If you do NOT intend to update '{}', please ensure you did not accidentally", tool);
     eprintln!("change the submodule at '{}'. You may ask your reviewer for the", submodule);
     eprintln!("proper steps.");
-    crate::detail_exit(3);
+    crate::detail_exit_macro!(3);
 }
 
 fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) {
@@ -106,7 +106,7 @@ fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) {
         Ok(o) => o,
         Err(e) => {
             eprintln!("Failed to get changed files: {:?}", e);
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
     };
 
@@ -177,7 +177,7 @@ impl Step for ToolStateCheck {
         }
 
         if did_error {
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
 
         check_changed_files(&toolstates);
@@ -223,7 +223,7 @@ impl Step for ToolStateCheck {
         }
 
         if did_error {
-            crate::detail_exit(1);
+            crate::detail_exit_macro!(1);
         }
 
         if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() {
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 9bfdc77e6b6..e4bbccdb067 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -3,6 +3,7 @@
 //! Simple things like testing the various filesystem operations here and there,
 //! not a lot of interesting happenings here unfortunately.
 
+use build_helper::util::{fail, try_run};
 use std::env;
 use std::fs;
 use std::io;
@@ -230,25 +231,10 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef<Path>>(
 
 pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) {
     if !try_run(cmd, print_cmd_on_fail) {
-        crate::detail_exit(1);
+        crate::detail_exit_macro!(1);
     }
 }
 
-pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
-    let status = match cmd.status() {
-        Ok(status) => status,
-        Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)),
-    };
-    if !status.success() && print_cmd_on_fail {
-        println!(
-            "\n\ncommand did not execute successfully: {:?}\n\
-             expected success, got: {}\n\n",
-            cmd, status
-        );
-    }
-    status.success()
-}
-
 pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
     let status = match cmd.status() {
         Ok(status) => status,
@@ -269,7 +255,7 @@ pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
 
 pub fn run_suppressed(cmd: &mut Command) {
     if !try_run_suppressed(cmd) {
-        crate::detail_exit(1);
+        crate::detail_exit_macro!(1);
     }
 }
 
@@ -374,11 +360,6 @@ fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool {
     })
 }
 
-fn fail(s: &str) -> ! {
-    eprintln!("\n\n{}\n\n", s);
-    crate::detail_exit(1);
-}
-
 /// Copied from `std::path::absolute` until it stabilizes.
 ///
 /// FIXME: this shouldn't exist.
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 04fdb15f5ac..c2fd2e3a91a 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -55,7 +55,7 @@ RUN ./build-clang.sh
 ENV CC=clang CXX=clang++
 
 # rustc-perf version from 2023-03-15
-ENV PERF_COMMIT 9dfaa35193154b690922347ee1141a06ec87a199
+ENV PERF_COMMIT 8b2ac3042e1ff2c0074455a0a3618adef97156b1
 RUN curl -LS -o perf.zip https://github.com/rust-lang/rustc-perf/archive/$PERF_COMMIT.zip && \
     unzip perf.zip && \
     mv rustc-perf-$PERF_COMMIT rustc-perf && \
diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml
index fa8e5b3d080..2d17cf7d47a 100644
--- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml
+++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml
@@ -4,6 +4,7 @@ version = "0.0.0"
 edition = "2021"
 
 [workspace]
+resolver = "1"
 
 [dependencies]
 r-efi = "4.1.0"
diff --git a/src/ci/stage-build.py b/src/ci/stage-build.py
index 8d03d3759bf..066d3a198f2 100644
--- a/src/ci/stage-build.py
+++ b/src/ci/stage-build.py
@@ -175,7 +175,7 @@ class WindowsPipeline(Pipeline):
 
     def build_rustc_perf(self):
         # rustc-perf version from 2023-03-15
-        perf_commit = "9dfaa35193154b690922347ee1141a06ec87a199"
+        perf_commit = "8b2ac3042e1ff2c0074455a0a3618adef97156b1"
         rustc_perf_zip_path = self.opt_artifacts() / "perf.zip"
 
         def download_rustc_perf():
diff --git a/src/doc/unstable-book/src/language-features/const-eval-limit.md b/src/doc/unstable-book/src/language-features/const-eval-limit.md
deleted file mode 100644
index df68e83bcac..00000000000
--- a/src/doc/unstable-book/src/language-features/const-eval-limit.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# `const_eval_limit`
-
-The tracking issue for this feature is: [#67217]
-
-[#67217]: https://github.com/rust-lang/rust/issues/67217
-
-The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
diff --git a/src/etc/test-float-parse/Cargo.toml b/src/etc/test-float-parse/Cargo.toml
index 7ee19a0b6d9..6d7b227d0ad 100644
--- a/src/etc/test-float-parse/Cargo.toml
+++ b/src/etc/test-float-parse/Cargo.toml
@@ -5,6 +5,7 @@ edition = "2021"
 publish = false
 
 [workspace]
+resolver = "1"
 
 [dependencies]
 rand = "0.4"
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 03adc19e359..5fd867189fd 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1111,8 +1111,8 @@ fn clean_fn_decl_with_args<'tcx>(
     args: Arguments,
 ) -> FnDecl {
     let output = match decl.output {
-        hir::FnRetTy::Return(typ) => Return(clean_ty(typ, cx)),
-        hir::FnRetTy::DefaultReturn(..) => DefaultReturn,
+        hir::FnRetTy::Return(typ) => clean_ty(typ, cx),
+        hir::FnRetTy::DefaultReturn(..) => Type::Tuple(Vec::new()),
     };
     FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
 }
@@ -1126,10 +1126,7 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
 
     // We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
     // but shouldn't change any code meaning.
-    let output = match clean_middle_ty(sig.output(), cx, None) {
-        Type::Tuple(inner) if inner.is_empty() => DefaultReturn,
-        ty => Return(ty),
-    };
+    let output = clean_middle_ty(sig.output(), cx, None);
 
     FnDecl {
         output,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index e9ccea2cf27..1999a6b671d 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -42,7 +42,6 @@ use crate::formats::item_type::ItemType;
 use crate::html::render::Context;
 use crate::passes::collect_intra_doc_links::UrlFragment;
 
-pub(crate) use self::FnRetTy::*;
 pub(crate) use self::ItemKind::*;
 pub(crate) use self::SelfTy::*;
 pub(crate) use self::Type::{
@@ -1353,7 +1352,7 @@ pub(crate) struct Function {
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub(crate) struct FnDecl {
     pub(crate) inputs: Arguments,
-    pub(crate) output: FnRetTy,
+    pub(crate) output: Type,
     pub(crate) c_variadic: bool,
 }
 
@@ -1371,18 +1370,16 @@ impl FnDecl {
     ///
     /// This function will panic if the return type does not match the expected sugaring for async
     /// functions.
-    pub(crate) fn sugared_async_return_type(&self) -> FnRetTy {
-        match &self.output {
-            FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
-                GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
-                    let bindings = trait_.bindings().unwrap();
-                    let ret_ty = bindings[0].term();
-                    let ty = ret_ty.ty().expect("Unexpected constant return term");
-                    FnRetTy::Return(ty.clone())
-                }
-                _ => panic!("unexpected desugaring of async function"),
-            },
-            _ => panic!("unexpected desugaring of async function"),
+    pub(crate) fn sugared_async_return_type(&self) -> Type {
+        if let Type::ImplTrait(v) = &self.output &&
+            let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..]
+        {
+            let bindings = trait_.bindings().unwrap();
+            let ret_ty = bindings[0].term();
+            let ty = ret_ty.ty().expect("Unexpected constant return term");
+            ty.clone()
+        } else {
+            panic!("unexpected desugaring of async function")
         }
     }
 }
@@ -1425,21 +1422,6 @@ impl Argument {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub(crate) enum FnRetTy {
-    Return(Type),
-    DefaultReturn,
-}
-
-impl FnRetTy {
-    pub(crate) fn as_return(&self) -> Option<&Type> {
-        match self {
-            Return(ret) => Some(ret),
-            DefaultReturn => None,
-        }
-    }
-}
-
 #[derive(Clone, Debug)]
 pub(crate) struct Trait {
     pub(crate) def_id: DefId,
@@ -1641,6 +1623,10 @@ impl Type {
         matches!(self, Type::ImplTrait(_))
     }
 
+    pub(crate) fn is_unit(&self) -> bool {
+        matches!(self, Type::Tuple(v) if v.is_empty())
+    }
+
     pub(crate) fn projection(&self) -> Option<(&Type, DefId, PathSegment)> {
         if let QPath(box QPathData { self_type, trait_, assoc, .. }) = self {
             Some((self_type, trait_.as_ref()?.def_id(), assoc.clone()))
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d963d6092c4..f26d74629dd 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1257,9 +1257,9 @@ impl clean::Impl {
                 };
                 primitive_link_fragment(f, PrimitiveType::Tuple, &format!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?;
                 // Write output.
-                if let clean::FnRetTy::Return(ty) = &bare_fn.decl.output {
+                if !bare_fn.decl.output.is_unit() {
                     write!(f, " -> ")?;
-                    fmt_type(ty, f, use_absolute, cx)?;
+                    fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
                 }
             } else if let Some(ty) = self.kind.as_blanket_ty() {
                 fmt_type(ty, f, use_absolute, cx)?;
@@ -1296,22 +1296,6 @@ impl clean::Arguments {
     }
 }
 
-impl clean::FnRetTy {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl fmt::Display + 'a + Captures<'tcx> {
-        display_fn(move |f| match self {
-            clean::Return(clean::Tuple(tys)) if tys.is_empty() => Ok(()),
-            clean::Return(ty) if f.alternate() => {
-                write!(f, " -> {:#}", ty.print(cx))
-            }
-            clean::Return(ty) => write!(f, " -&gt; {}", ty.print(cx)),
-            clean::DefaultReturn => Ok(()),
-        })
-    }
-}
-
 impl clean::BareFunctionDecl {
     fn print_hrtb_with_space<'a, 'tcx: 'a>(
         &'a self,
@@ -1366,7 +1350,7 @@ impl clean::FnDecl {
                     "({args:#}{ellipsis}){arrow:#}",
                     args = self.inputs.print(cx),
                     ellipsis = ellipsis,
-                    arrow = self.output.print(cx)
+                    arrow = self.print_output(cx)
                 )
             } else {
                 write!(
@@ -1374,7 +1358,7 @@ impl clean::FnDecl {
                     "({args}{ellipsis}){arrow}",
                     args = self.inputs.print(cx),
                     ellipsis = ellipsis,
-                    arrow = self.output.print(cx)
+                    arrow = self.print_output(cx)
                 )
             }
         })
@@ -1464,9 +1448,22 @@ impl clean::FnDecl {
             Some(n) => write!(f, "\n{})", Indent(n))?,
         };
 
-        fmt::Display::fmt(&self.output.print(cx), f)?;
+        fmt::Display::fmt(&self.print_output(cx), f)?;
         Ok(())
     }
+
+    pub(crate) fn print_output<'a, 'tcx: 'a>(
+        &'a self,
+        cx: &'a Context<'tcx>,
+    ) -> impl fmt::Display + 'a + Captures<'tcx> {
+        display_fn(move |f| match &self.output {
+            clean::Tuple(tys) if tys.is_empty() => Ok(()),
+            ty if f.alternate() => {
+                write!(f, " -> {:#}", ty.print(cx))
+            }
+            ty => write!(f, " -&gt; {}", ty.print(cx)),
+        })
+    }
 }
 
 pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index b26a5c32ec6..1c27320024a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -381,7 +381,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
             Some(Event::Code(text)) => {
                 trace!("saw code {}", text);
                 if let Some(link) = self.shortcut_link {
-                    trace!("original text was {}", link.original_text);
                     // NOTE: this only replaces if the code block is the *entire* text.
                     // If only part of the link has code highlighting, the disambiguator will not be removed.
                     // e.g. [fn@`f`]
@@ -390,8 +389,11 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
                     // So we could never be sure we weren't replacing too much:
                     // [fn@my_`f`unc] is treated the same as [my_func()] in that pass.
                     //
-                    // NOTE: &[1..len() - 1] is to strip the backticks
-                    if **text == link.original_text[1..link.original_text.len() - 1] {
+                    // NOTE: .get(1..len() - 1) is to strip the backticks
+                    if let Some(link) = self.links.iter().find(|l| {
+                        l.href == link.href
+                            && Some(&**text) == l.original_text.get(1..l.original_text.len() - 1)
+                    }) {
                         debug!("replacing {} with {}", text, link.new_text);
                         *text = CowStr::Borrowed(&link.new_text);
                     }
@@ -402,9 +404,12 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
             Some(Event::Text(text)) => {
                 trace!("saw text {}", text);
                 if let Some(link) = self.shortcut_link {
-                    trace!("original text was {}", link.original_text);
                     // NOTE: same limitations as `Event::Code`
-                    if **text == *link.original_text {
+                    if let Some(link) = self
+                        .links
+                        .iter()
+                        .find(|l| l.href == link.href && **text == *l.original_text)
+                    {
                         debug!("replacing {} with {}", text, link.new_text);
                         *text = CowStr::Borrowed(&link.new_text);
                     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 42e27d35a94..a5223bd6309 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -844,7 +844,7 @@ fn assoc_method(
         + name.as_str().len()
         + generics_len;
 
-    let notable_traits = d.output.as_return().and_then(|output| notable_traits_button(output, cx));
+    let notable_traits = notable_traits_button(&d.output, cx);
 
     let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
         header_len += 4;
@@ -1282,6 +1282,11 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
 pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> Option<String> {
     let mut has_notable_trait = false;
 
+    if ty.is_unit() {
+        // Very common fast path.
+        return None;
+    }
+
     let did = ty.def_id(cx.cache())?;
 
     // Box has pass-through impls for Read, Write, Iterator, and Future when the
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index d2dc47af7ac..21f61acb2c5 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -587,8 +587,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
         + name.as_str().len()
         + generics_len;
 
-    let notable_traits =
-        f.decl.output.as_return().and_then(|output| notable_traits_button(output, cx));
+    let notable_traits = notable_traits_button(&f.decl.output, cx);
 
     wrap_item(w, |w| {
         w.reserve(header_len);
@@ -1420,30 +1419,36 @@ fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
     write!(w, "{}", document(cx, it, None, HeadingOffset::H2))
 }
 
-fn item_proc_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
-    wrap_item(w, |w| {
+fn item_proc_macro(
+    w: &mut impl fmt::Write,
+    cx: &mut Context<'_>,
+    it: &clean::Item,
+    m: &clean::ProcMacro,
+) {
+    let mut buffer = Buffer::new();
+    wrap_item(&mut buffer, |buffer| {
         let name = it.name.expect("proc-macros always have names");
         match m.kind {
             MacroKind::Bang => {
-                write!(w, "{}!() {{ /* proc-macro */ }}", name);
+                write!(buffer, "{}!() {{ /* proc-macro */ }}", name);
             }
             MacroKind::Attr => {
-                write!(w, "#[{}]", name);
+                write!(buffer, "#[{}]", name);
             }
             MacroKind::Derive => {
-                write!(w, "#[derive({})]", name);
+                write!(buffer, "#[derive({})]", name);
                 if !m.helpers.is_empty() {
-                    w.push_str("\n{\n");
-                    w.push_str("    // Attributes available to this derive:\n");
+                    buffer.push_str("\n{\n");
+                    buffer.push_str("    // Attributes available to this derive:\n");
                     for attr in &m.helpers {
-                        writeln!(w, "    #[{}]", attr);
+                        writeln!(buffer, "    #[{}]", attr);
                     }
-                    w.push_str("}\n");
+                    buffer.push_str("}\n");
                 }
             }
         }
     });
-    write!(w, "{}", document(cx, it, None, HeadingOffset::H2))
+    write!(w, "{}{}", buffer.into_inner(), document(cx, it, None, HeadingOffset::H2)).unwrap();
 }
 
 fn item_primitive(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 846299f02e3..f34be120d29 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -7,7 +7,7 @@ use rustc_span::symbol::Symbol;
 use serde::ser::{Serialize, SerializeStruct, Serializer};
 
 use crate::clean;
-use crate::clean::types::{FnRetTy, Function, Generics, ItemId, Type, WherePredicate};
+use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
 use crate::formats::cache::{Cache, OrphanImplItem};
 use crate::formats::item_type::ItemType;
 use crate::html::format::join_with_double_colon;
@@ -656,22 +656,9 @@ fn get_fn_inputs_and_outputs<'tcx>(
     }
 
     let mut ret_types = Vec::new();
-    match decl.output {
-        FnRetTy::Return(ref return_type) => {
-            add_generics_and_bounds_as_types(
-                self_,
-                generics,
-                return_type,
-                tcx,
-                0,
-                &mut ret_types,
-                cache,
-            );
-            if ret_types.is_empty() {
-                ret_types.push(get_index_type(return_type, vec![]));
-            }
-        }
-        _ => {}
-    };
+    add_generics_and_bounds_as_types(self_, generics, &decl.output, tcx, 0, &mut ret_types, cache);
+    if ret_types.is_empty() {
+        ret_types.push(get_index_type(&decl.output, vec![]));
+    }
     (all_types, ret_types)
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index a7d5f497756..054cfe7597e 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1179,6 +1179,10 @@ a.test-arrow:hover {
 	position: relative;
 }
 
+.code-header a.tooltip:hover {
+	color: var(--link-color);
+}
+
 /* placeholder thunk so that the mouse can easily travel from "(i)" to popover
 	the resulting "hover tunnel" is a stepped triangle, approximating
 	https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown */
@@ -1191,6 +1195,14 @@ a.tooltip:hover::after {
 	content: "\00a0";
 }
 
+/* This animation is layered onto the mistake-proofing delay for dismissing
+	a hovered tooltip, to ensure it feels responsive even with the delay.
+	*/
+.fade-out {
+	opacity: 0;
+	transition: opacity 0.45s cubic-bezier(0, 0, 0.1, 1.0);
+}
+
 .popover.tooltip .content {
 	margin: 0.25em 0.5em;
 }
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index bccf675c14b..6da51ea0a55 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -4,6 +4,13 @@
 
 "use strict";
 
+// The amount of time that the cursor must remain still over a hover target before
+// revealing a tooltip.
+//
+// https://www.nngroup.com/articles/timing-exposing-content/
+window.RUSTDOC_TOOLTIP_HOVER_MS = 300;
+window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS = 450;
+
 // Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL
 // for a resource under the root-path, with the resource-suffix.
 function resourcePath(basename, extension) {
@@ -772,6 +779,13 @@ function preLoadCss(cssUrl) {
         });
     });
 
+    /**
+     * Show a tooltip immediately.
+     *
+     * @param {DOMElement} e - The tooltip's anchor point. The DOM is consulted to figure
+     *                         out what the tooltip should contain, and where it should be
+     *                         positioned.
+     */
     function showTooltip(e) {
         const notable_ty = e.getAttribute("data-notable-ty");
         if (!window.NOTABLE_TRAITS && notable_ty) {
@@ -782,8 +796,10 @@ function preLoadCss(cssUrl) {
                 throw new Error("showTooltip() called with notable without any notable traits!");
             }
         }
+        // Make this function idempotent. If the tooltip is already shown, avoid doing extra work
+        // and leave it alone.
         if (window.CURRENT_TOOLTIP_ELEMENT && window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE === e) {
-            // Make this function idempotent.
+            clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
             return;
         }
         window.hideAllModals(false);
@@ -791,11 +807,18 @@ function preLoadCss(cssUrl) {
         if (notable_ty) {
             wrapper.innerHTML = "<div class=\"content\">" +
                 window.NOTABLE_TRAITS[notable_ty] + "</div>";
-        } else if (e.getAttribute("title") !== undefined) {
-            const titleContent = document.createElement("div");
-            titleContent.className = "content";
-            titleContent.appendChild(document.createTextNode(e.getAttribute("title")));
-            wrapper.appendChild(titleContent);
+        } else {
+            // Replace any `title` attribute with `data-title` to avoid double tooltips.
+            if (e.getAttribute("title") !== null) {
+                e.setAttribute("data-title", e.getAttribute("title"));
+                e.removeAttribute("title");
+            }
+            if (e.getAttribute("data-title") !== null) {
+                const titleContent = document.createElement("div");
+                titleContent.className = "content";
+                titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));
+                wrapper.appendChild(titleContent);
+            }
         }
         wrapper.className = "tooltip popover";
         const focusCatcher = document.createElement("div");
@@ -824,17 +847,77 @@ function preLoadCss(cssUrl) {
         wrapper.style.visibility = "";
         window.CURRENT_TOOLTIP_ELEMENT = wrapper;
         window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE = e;
+        clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
+        wrapper.onpointerenter = function(ev) {
+            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+            if (ev.pointerType !== "mouse") {
+                return;
+            }
+            clearTooltipHoverTimeout(e);
+        };
         wrapper.onpointerleave = function(ev) {
             // If this is a synthetic touch event, ignore it. A click event will be along shortly.
             if (ev.pointerType !== "mouse") {
                 return;
             }
-            if (!e.TOOLTIP_FORCE_VISIBLE && !elemIsInParent(event.relatedTarget, e)) {
-                hideTooltip(true);
+            if (!e.TOOLTIP_FORCE_VISIBLE && !elemIsInParent(ev.relatedTarget, e)) {
+                // See "Tooltip pointer leave gesture" below.
+                setTooltipHoverTimeout(e, false);
+                addClass(wrapper, "fade-out");
             }
         };
     }
 
+    /**
+     * Show or hide the tooltip after a timeout. If a timeout was already set before this function
+     * was called, that timeout gets cleared. If the tooltip is already in the requested state,
+     * this function will still clear any pending timeout, but otherwise do nothing.
+     *
+     * @param {DOMElement} element - The tooltip's anchor point. The DOM is consulted to figure
+     *                               out what the tooltip should contain, and where it should be
+     *                               positioned.
+     * @param {boolean}    show    - If true, the tooltip will be made visible. If false, it will
+     *                               be hidden.
+     */
+    function setTooltipHoverTimeout(element, show) {
+        clearTooltipHoverTimeout(element);
+        if (!show && !window.CURRENT_TOOLTIP_ELEMENT) {
+            // To "hide" an already hidden element, just cancel its timeout.
+            return;
+        }
+        if (show && window.CURRENT_TOOLTIP_ELEMENT) {
+            // To "show" an already visible element, just cancel its timeout.
+            return;
+        }
+        if (window.CURRENT_TOOLTIP_ELEMENT &&
+            window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE !== element) {
+            // Don't do anything if another tooltip is already visible.
+            return;
+        }
+        element.TOOLTIP_HOVER_TIMEOUT = setTimeout(() => {
+            if (show) {
+                showTooltip(element);
+            } else if (!element.TOOLTIP_FORCE_VISIBLE) {
+                hideTooltip(false);
+            }
+        }, show ? window.RUSTDOC_TOOLTIP_HOVER_MS : window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS);
+    }
+
+    /**
+     * If a show/hide timeout was set by `setTooltipHoverTimeout`, cancel it. If none exists,
+     * do nothing.
+     *
+     * @param {DOMElement} element - The tooltip's anchor point,
+     *                               as passed to `setTooltipHoverTimeout`.
+     */
+    function clearTooltipHoverTimeout(element) {
+        if (element.TOOLTIP_HOVER_TIMEOUT !== undefined) {
+            removeClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out");
+            clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);
+            delete element.TOOLTIP_HOVER_TIMEOUT;
+        }
+    }
+
     function tooltipBlurHandler(event) {
         if (window.CURRENT_TOOLTIP_ELEMENT &&
             !elemIsInParent(document.activeElement, window.CURRENT_TOOLTIP_ELEMENT) &&
@@ -854,6 +937,12 @@ function preLoadCss(cssUrl) {
         }
     }
 
+    /**
+     * Hide the current tooltip immediately.
+     *
+     * @param {boolean} focus - If set to `true`, move keyboard focus to the tooltip anchor point.
+     *                          If set to `false`, leave keyboard focus alone.
+     */
     function hideTooltip(focus) {
         if (window.CURRENT_TOOLTIP_ELEMENT) {
             if (window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE) {
@@ -864,6 +953,7 @@ function preLoadCss(cssUrl) {
             }
             const body = document.getElementsByTagName("body")[0];
             body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);
+            clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);
             window.CURRENT_TOOLTIP_ELEMENT = null;
         }
     }
@@ -886,7 +976,14 @@ function preLoadCss(cssUrl) {
             if (ev.pointerType !== "mouse") {
                 return;
             }
-            showTooltip(this);
+            setTooltipHoverTimeout(this, true);
+        };
+        e.onpointermove = function(ev) {
+            // If this is a synthetic touch event, ignore it. A click event will be along shortly.
+            if (ev.pointerType !== "mouse") {
+                return;
+            }
+            setTooltipHoverTimeout(this, true);
         };
         e.onpointerleave = function(ev) {
             // If this is a synthetic touch event, ignore it. A click event will be along shortly.
@@ -895,7 +992,38 @@ function preLoadCss(cssUrl) {
             }
             if (!this.TOOLTIP_FORCE_VISIBLE &&
                 !elemIsInParent(ev.relatedTarget, window.CURRENT_TOOLTIP_ELEMENT)) {
-                hideTooltip(true);
+                // Tooltip pointer leave gesture:
+                //
+                // Designing a good hover microinteraction is a matter of guessing user
+                // intent from what are, literally, vague gestures. In this case, guessing if
+                // hovering in or out of the tooltip base is intentional or not.
+                //
+                // To figure this out, a few different techniques are used:
+                //
+                // * When the mouse pointer enters a tooltip anchor point, its hitbox is grown
+                //   on the bottom, where the popover is/will appear. Search "hover tunnel" in
+                //   rustdoc.css for the implementation.
+                // * There's a delay when the mouse pointer enters the popover base anchor, in
+                //   case the mouse pointer was just passing through and the user didn't want
+                //   to open it.
+                // * Similarly, a delay is added when exiting the anchor, or the popover
+                //   itself, before hiding it.
+                // * A fade-out animation is layered onto the pointer exit delay to immediately
+                //   inform the user that they successfully dismissed the popover, while still
+                //   providing a way for them to cancel it if it was a mistake and they still
+                //   wanted to interact with it.
+                // * No animation is used for revealing it, because we don't want people to try
+                //   to interact with an element while it's in the middle of fading in: either
+                //   they're allowed to interact with it while it's fading in, meaning it can't
+                //   serve as mistake-proofing for the popover, or they can't, but
+                //   they might try and be frustrated.
+                //
+                // See also:
+                // * https://www.nngroup.com/articles/timing-exposing-content/
+                // * https://www.nngroup.com/articles/tooltip-guidelines/
+                // * https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown
+                setTooltipHoverTimeout(e, false);
+                addClass(window.CURRENT_TOOLTIP_ELEMENT, "fade-out");
             }
         };
     });
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 935bb721f18..91cd55b1113 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -624,10 +624,7 @@ impl FromWithTcx<clean::FnDecl> for FnDecl {
                 .into_iter()
                 .map(|arg| (arg.name.to_string(), arg.type_.into_tcx(tcx)))
                 .collect(),
-            output: match output {
-                clean::FnRetTy::Return(t) => Some(t.into_tcx(tcx)),
-                clean::FnRetTy::DefaultReturn => None,
-            },
+            output: if output.is_unit() { None } else { Some(output.into_tcx(tcx)) },
             c_variadic,
         }
     }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 6b7ad4cf21a..abb9229fbd5 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -267,6 +267,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline)
             || use_attrs.lists(sym::doc).has_word(sym::hidden);
 
+        if is_no_inline {
+            return false;
+        }
+
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation -- a previously unreachable item can be
         // made reachable by cross-crate inlining which we're checking here.
@@ -281,31 +285,38 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         };
 
         let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did);
-        let is_hidden = inherits_doc_hidden(tcx, res_did, None);
+        let is_hidden = tcx.is_doc_hidden(ori_res_did);
+        let item = tcx.hir().get_by_def_id(res_did);
 
-        // Only inline if requested or if the item would otherwise be stripped.
-        if (!please_inline && !is_private && !is_hidden) || is_no_inline {
-            return false;
-        }
-
-        if !please_inline &&
-            let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
+        if !please_inline {
+            let inherits_hidden = inherits_doc_hidden(tcx, res_did, None);
+            // Only inline if requested or if the item would otherwise be stripped.
+            //
+            // If it's a doc hidden module, we need to keep it in case some of its inner items
+            // are re-exported.
+            if (!is_private && !inherits_hidden) || (
+                is_hidden &&
+                !matches!(item, Node::Item(&hir::Item { kind: hir::ItemKind::Mod(_), .. }))
+            ) {
+                return false;
+            } else if let Some(item_def_id) = reexport_chain(tcx, def_id, res_did).iter()
                 .flat_map(|reexport| reexport.id()).map(|id| id.expect_local())
                 .chain(iter::once(res_did)).nth(1) &&
-            item_def_id != def_id &&
-            self
-                .cx
-                .cache
-                .effective_visibilities
-                .is_directly_public(tcx, item_def_id.to_def_id()) &&
-            !inherits_doc_hidden(tcx, item_def_id, None)
-        {
-            // The imported item is public and not `doc(hidden)` so no need to inline it.
-            return false;
+                item_def_id != def_id &&
+                self
+                    .cx
+                    .cache
+                    .effective_visibilities
+                    .is_directly_public(tcx, item_def_id.to_def_id()) &&
+                !inherits_doc_hidden(tcx, item_def_id, None)
+            {
+                // The imported item is public and not `doc(hidden)` so no need to inline it.
+                return false;
+            }
         }
 
         let is_bang_macro = matches!(
-            tcx.hir().get_by_def_id(res_did),
+            item,
             Node::Item(&hir::Item { kind: hir::ItemKind::Macro(_, MacroKind::Bang), .. })
         );
 
@@ -317,12 +328,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             // Bang macros are handled a bit on their because of how they are handled by the
             // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have
             // `#[doc(inline)]`, then we don't inline it.
-            Node::Item(_)
-                if is_bang_macro
-                    && !please_inline
-                    && renamed.is_some()
-                    && self.cx.tcx.is_doc_hidden(ori_res_did) =>
-            {
+            Node::Item(_) if is_bang_macro && !please_inline && renamed.is_some() && is_hidden => {
                 return false;
             }
             Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
@@ -455,6 +461,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                             is_glob,
                             please_inline,
                         ) {
+                            debug!("Inlining {:?}", item.owner_id.def_id);
                             continue;
                         }
                     }
diff --git a/src/stage0.json b/src/stage0.json
index 7a8bf0a80ab..89ad4e0a649 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -17,409 +17,419 @@
     "tool is executed."
   ],
   "compiler": {
-    "date": "2023-04-20",
+    "date": "2023-05-30",
     "version": "beta"
   },
   "rustfmt": {
-    "date": "2023-04-21",
+    "date": "2023-05-30",
     "version": "nightly"
   },
   "checksums_sha256": {
-    "dist/2023-04-20/cargo-beta-aarch64-apple-darwin.tar.gz": "4d98b7d2ed4ff9a73c3d26a45acd113406c122a0d4ced1c1945cbbcefc857828",
-    "dist/2023-04-20/cargo-beta-aarch64-apple-darwin.tar.xz": "3319213011ff4898373894d1ff5c7d9b2dee44cc39c6b0bc69e9736ae5a971e7",
-    "dist/2023-04-20/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "84307f386d3c331ebb43da3b4b7fce61672a32a88ceabfecbd452f0d510eed0a",
-    "dist/2023-04-20/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "7903dd5957bfb2f45127f66ad6bec16bef461a1620ccc39ff44e0566786c97d0",
-    "dist/2023-04-20/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "f383343e236a896ebfa382a5f1ce5087239582ac2d8772625441ea91d08b9f1e",
-    "dist/2023-04-20/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "ece2088b56c5ae2fd41027f6986d16e812b13eda2b0ff3672fbb103d265be1e5",
-    "dist/2023-04-20/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "1766ef8efeed5f606d3ffe6f5a041defb8b07982f83cbc54d134dc278216a506",
-    "dist/2023-04-20/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "492a07d0164f28ba0cd25e2f32d94c800ef106c8f9a39b8253fca05cc33e243e",
-    "dist/2023-04-20/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "44c2d142fd8f1d868e349413e9c072cc518cdf98ab76b29c30eb54feedf39a9c",
-    "dist/2023-04-20/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "3c8819f0ca9e0988c6ca6b8261d1e2c1f37c57af2a6fc49d8b75cffaba835551",
-    "dist/2023-04-20/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "c59ad33dc775892a7465d3e49ff304b7ee105f554f9ba8c7f4bdc9b057b696f8",
-    "dist/2023-04-20/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "8b17731fef0970ee38d1ebd9868ffda44c6ab57a51bac497a36587e49a96f857",
-    "dist/2023-04-20/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "b1e93383e4de4901c1cfa4e85e07d3d5f7e224628df32efd47824dd391c84bf5",
-    "dist/2023-04-20/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "12a4606fc358ad00934cf7dc4b3779c70653acc304d8f4c3ebfd29322a401fbb",
-    "dist/2023-04-20/cargo-beta-i686-pc-windows-gnu.tar.gz": "4a69cda4b23f8482e73f060cb13e71ae16968b9e7a78514ca5c588f285bf8148",
-    "dist/2023-04-20/cargo-beta-i686-pc-windows-gnu.tar.xz": "415929203b23223cb590b37b68b05f27ad84d92b0ee203c26db02da5633b0edd",
-    "dist/2023-04-20/cargo-beta-i686-pc-windows-msvc.tar.gz": "5897a03a62444d6fcc2928afb702b7087b3d6d3ee79dd283b08456857a461fad",
-    "dist/2023-04-20/cargo-beta-i686-pc-windows-msvc.tar.xz": "2c739f9481782515cc4e911686dd5afc5fe839a88fade616bad2c97ac3f5ce81",
-    "dist/2023-04-20/cargo-beta-i686-unknown-linux-gnu.tar.gz": "e9fe240dff59be45f5e9b798e8c05c1548d983ba9356e4f700c50a85fe215f3d",
-    "dist/2023-04-20/cargo-beta-i686-unknown-linux-gnu.tar.xz": "375e787c939c71c15c7286997d2845a3cdf38b614bac9b872886a6b3e92ee64a",
-    "dist/2023-04-20/cargo-beta-mips-unknown-linux-gnu.tar.gz": "c5808c561f5519ff33666dd9457185b3617641e17ade91e6b88b577e2c95f004",
-    "dist/2023-04-20/cargo-beta-mips-unknown-linux-gnu.tar.xz": "24dffb76be37cdd51f69ae8509a7d0acfefce7de46bd1536fe45e7807567dd90",
-    "dist/2023-04-20/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "b5fc64052bcd93154a1da5908a65922ed106b443a8633d8b888b7c5c20bf1469",
-    "dist/2023-04-20/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "813ba9323a1fb70bc04260eb74fece4efb7de88755a1c77dbc9cfda0c9f81f86",
-    "dist/2023-04-20/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "fc67b687248225694f07e4e18716231899cbfdaa2cd74a58460129eb55b47e22",
-    "dist/2023-04-20/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "7f1375c416058e8ac3261d205f2f979986b11cfd020cd5df9ea42c67013a890a",
-    "dist/2023-04-20/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "6296f405cdcef28e877d878ba0e1b9a8555d4a067148b7fc5d8409e39b59b41c",
-    "dist/2023-04-20/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "c22cb99cc2afac88cba85cab7a177361eb98119c3d7748d511112f4ae464c98b",
-    "dist/2023-04-20/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "e30746ab117d9c59a5e36486794394c9279ac4078cd63441efe1bc4843b2e44b",
-    "dist/2023-04-20/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "267f3889a4bfb5caf22132fc6e04ca143240a44a1e8549782e02b287940bab9e",
-    "dist/2023-04-20/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "c6114d5a546c5462fbbfebb092b2b532f3e94a36b1edaa038246f08bc4c05693",
-    "dist/2023-04-20/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "18ef9c3cdbce1e8fbfd50fc41b4b3e45419dfa5bd4f888e64036ca3639c184f8",
-    "dist/2023-04-20/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "c7a511ad37e6bad90b9ecc51cdd74f8c63fca89f0d7c7d639b8770de86cebef7",
-    "dist/2023-04-20/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "45a7b42f9444f3c03b9743d19dfdd3faac55574fd7100372fb9237e2702cb19f",
-    "dist/2023-04-20/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "3e792e4198ea979f3cd572a5d86079594d45e66a40e76a40498a90d3507a4cd0",
-    "dist/2023-04-20/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "6417f9dee2f0f8a96eaac09420eb8906d6d94678404e47f4c5881fc69c43fa00",
-    "dist/2023-04-20/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "95b3116b14643dd7d400a5719865c6b272c84d992e1ab59e292460d82d0466a6",
-    "dist/2023-04-20/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "5d7507e287dfc78b6c526b02a8b2dda940c6953a01dfe0a19c18ce3d1caa0a73",
-    "dist/2023-04-20/cargo-beta-x86_64-apple-darwin.tar.gz": "8b2075a2021b3779b373bb7c0f4243a4830e0d177c486849791aacf96c7c3046",
-    "dist/2023-04-20/cargo-beta-x86_64-apple-darwin.tar.xz": "84da8de65979a9a292bbae1e46478be56fb65b7f85e7e6a7da1a1392494b3f83",
-    "dist/2023-04-20/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "2d8d7c4d7265e1a0b7d845b0d03d73391be2a7bc4ccb00d618a19b86bd7d3d86",
-    "dist/2023-04-20/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "eceeecbaab98ad656d4bd81d770a930d62bcfa800ea8b2272026422433a5791d",
-    "dist/2023-04-20/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "1e00d745fc4c45bc1859527636073b064f66d8050b2d4e740ea3fc0c0ebbd366",
-    "dist/2023-04-20/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "07ae876661f9d58c333ad8bf0d6c93a76a3386c38fa864550afed9fe60f904b2",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-freebsd.tar.gz": "cad8be555d550b9295b7440ab3cc088c7ad41bc7fe01845bf9daf8362c59861b",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-freebsd.tar.xz": "b8cf24eeef7d19a26f525bd9fdfc9425524e916aea96f009dc5a885c13789cd8",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-illumos.tar.gz": "7f58eaaca7b157c82c3631ea15c8cc06bcf273b36acdaf5fcb9099bb88f3050a",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-illumos.tar.xz": "ba28a88433b3f1a5ad306191960fa1f9a886fb13382b9aaa631c3738958573cd",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "1a86221d09e8ef97b3f78c6742159184e5a08420b46729cbaed037ffa999c4be",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "9e4e0a0839a87303fca33e245fd4962f4c7ac76e91fafcfc6e918f29f230f277",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "e6030829304e60f198647403d00d72402302fd09742dbe75e666d2e3ea4475ed",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "f3a8860dd293fbfffe317964df25421b5de2b43db9c69c831084d6d25a4432a5",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-netbsd.tar.gz": "5bc329ca4bbcd1dff623999177d6bc68043eb9320358da59e935ea6c4bd5eb44",
-    "dist/2023-04-20/cargo-beta-x86_64-unknown-netbsd.tar.xz": "8666cff4e8c4c1b54ad93e202421c008caa33bbc72ef3f9d8e8c4c9d11a495ec",
-    "dist/2023-04-20/rust-std-beta-aarch64-apple-darwin.tar.gz": "d033c430d3af35801bf2ba9ad67e302b71108d5b4a4e5a5f8e55e929451ea65b",
-    "dist/2023-04-20/rust-std-beta-aarch64-apple-darwin.tar.xz": "72d78202353bcaec8ea63c3c41da85a787630d42f1ee1f60df859d08cffe58a1",
-    "dist/2023-04-20/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "338045ac14fb4bd3315075552a0d3ce1ebded292a7601e115ac6b329a36181a9",
-    "dist/2023-04-20/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "59ce7292af43c8af70a4264a76e4429ca07c276a59863902d13c47265defc796",
-    "dist/2023-04-20/rust-std-beta-aarch64-apple-ios.tar.gz": "9cf19d3ce1d48fd59e060c1fdc483ef98d03b34ff81cbe95abb89e6a89db281e",
-    "dist/2023-04-20/rust-std-beta-aarch64-apple-ios.tar.xz": "de6e3ec39eef54f87853609fb747634c3d5e7916274d8f08610d1da318ecbc37",
-    "dist/2023-04-20/rust-std-beta-aarch64-linux-android.tar.gz": "e5385590450562a6057004f36d8b5b2b3e2fa7a04006de54dfbf8247adf12b7e",
-    "dist/2023-04-20/rust-std-beta-aarch64-linux-android.tar.xz": "0e5f65414953dcb7be3dbf556a8da44e0915d33a93c5d62c6f1c8d7e0c32f6bb",
-    "dist/2023-04-20/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "63431ed5bd5037df838f7d7f46118cefebef16393fea2adac7f697775845d4b5",
-    "dist/2023-04-20/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "481bfcb150bee2638336f281cdedcf023a7e65a6f4b8c39255237636afb7d51a",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "16180718b23f1301b45a799e7c7c9e1a0ff83b8a63142d32eb3c07798038ec2e",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "3b0dcc2ea10e8482f49afb0188887b5f17f4404d4f182f8b9e2f852aad220d70",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "ed6117f7d0e7bcf9e7ef7a67b2a552ef616cb16843ff44d6d4cb9de2b0145a78",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "449daea8f5466e760ddb5b45526486b6386ddd6a546b5d2d589a38d96b2373fe",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "2719afaa0560f3974a56eebe24b783b45a0b6022c1830336d96ce9979d58995e",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "6eadf7df3987c9a56023303d950779ca24648a7b3408ddd8e492d74210c95914",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "a2428f7ceae916c49f54891f85a8db5f7d48748afd9cc121f1bcd58041afc0b6",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "72b84200dec649a417317c78f05162ebb8a3325b9c3a582085b0a2bc0de34741",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-none.tar.gz": "de5a37cd7aa2b97f693364b3202eb1ef3af57efe510626df536a8e21589ed2f0",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-none.tar.xz": "e95b5428f7347ce021d509d64c414705f82800d979dc9e0937f3f7318da1e8f1",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-uefi.tar.gz": "869534cf8258feffab97417db638f8e18fc8980fc7f5f47f347fddb1190e3575",
-    "dist/2023-04-20/rust-std-beta-aarch64-unknown-uefi.tar.xz": "9697f68c98a764c7105fefadb35a911e9aeca6cb094134033abcae429fe1acff",
-    "dist/2023-04-20/rust-std-beta-arm-linux-androideabi.tar.gz": "bcaf8f9e3099e77a3389b32f016af7d9faaeb661976707df02d5fc43ba9c1809",
-    "dist/2023-04-20/rust-std-beta-arm-linux-androideabi.tar.xz": "a9553688137f7b345f13fb3fb3a7b57370a6856b513be52752336a8b33da4329",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "55bb0e601d0b60f3c6ce434ad527a2fa4eae1c1749c63958ebee60a3b75a78ab",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "0e54d080e47693d6de6ad9b3a25a3667754346e3c699017adee94095f31130a9",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "6724ca816dbbcb6020ae413de2ff7b6dea7d976eb36e92916700a4e3c9284dbe",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "b39ea928a753ee8a66bed531900b2f5526c30c6a959b17aab72580e22027c5e7",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "3165943ddcdd9a308e2bb5437b09aacd4e164a345495439d0edab26b497ddf2c",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "3e6f52a2e03d4fe56ba0fd7fa4db7ee95c115c678ebd71baeeddb0ad6e08ec36",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "8228dbc77321a471bb4760e245d4658459bc89590ec49e459b158d99bc3a043a",
-    "dist/2023-04-20/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "a1699ee7bb2d84a2dfb25b66b8fb926874839c7c5b171dffa5acbdcb611c4cd7",
-    "dist/2023-04-20/rust-std-beta-armebv7r-none-eabi.tar.gz": "a9217cb08456e3bc8806ee7be3ec02c3de9ded69562c65762e574d54322ef9a2",
-    "dist/2023-04-20/rust-std-beta-armebv7r-none-eabi.tar.xz": "08b8ac8409b38da84a56b3f8eb662c805e279d8526b6e5b38205f9e6cd0b93bd",
-    "dist/2023-04-20/rust-std-beta-armebv7r-none-eabihf.tar.gz": "673f4d0984a8f18c921bbad319afc6ec3b8e25e3bdb0c38480cbfcccc1e6c130",
-    "dist/2023-04-20/rust-std-beta-armebv7r-none-eabihf.tar.xz": "0f47b88fa6ac741ce7175357f8e92c7e9b5a1d4a41d364c7ad6c4a0bca18f8c2",
-    "dist/2023-04-20/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "b6574d3da501f73de2837997621772522b175c7bae99d2e8e23353a889889db5",
-    "dist/2023-04-20/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "95e2ce2cfdfaa802acd84dbf8a5bc897fa632b18138c3826357ff84fd3f11f51",
-    "dist/2023-04-20/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "dd61c1c8e55f54d92307444d5db0e092de545046b66cc7205ec93c4e6852700b",
-    "dist/2023-04-20/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "0728bec4717ff37f52736cee33fff9196654b0c496b27078e74eeba2634045bd",
-    "dist/2023-04-20/rust-std-beta-armv7-linux-androideabi.tar.gz": "588af191bbff71616dc2d7fddf3415321114f44d0a8e3fe8a6c522a334010b34",
-    "dist/2023-04-20/rust-std-beta-armv7-linux-androideabi.tar.xz": "29f75c5799f79d7a8d589c069c9897817861388d74e3e4cc02cde8c458b59c70",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "252e0e1fb1f91449224ac4fa73eb5b13aa204c1cdf9b275abb05105b289936f4",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "e0211b866c7136823b5ab2ab0514411e50666cfa898afa2fc4927c870382bd33",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "7c68de890cc95eec9a42a4669972f214a5fa2f6cba552c584015ad1f7b89d5e8",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "3875fd0963af34cc7deb643e7b82a854de819aa58b521eb151ae8036967af74b",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "be5937a48d7dcacb0c25e733bb83bfe93cdf7acb10fd22f679580a0519f426df",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "2c34b67a2dc81af1ccbc582d57aa29eb3372f637093a2c782f82ed89ef52010b",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "98cc474e0fb49435fe1650f410b39484e02daf10a82fcbe947112496c30ccdbb",
-    "dist/2023-04-20/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "cf1231ff373492437353ff3e465174524661776ec0bc39c5e7bf6ccafed3cba0",
-    "dist/2023-04-20/rust-std-beta-armv7a-none-eabi.tar.gz": "4ab6cc13a0a902dcc95e590edbff7b6839ae7f115683766a8e1b7f0b20120b0b",
-    "dist/2023-04-20/rust-std-beta-armv7a-none-eabi.tar.xz": "bf39cb32d900a6d5856094ee1f972b560256beb80ba7e5a9b6ca8a0e3c34b319",
-    "dist/2023-04-20/rust-std-beta-armv7r-none-eabi.tar.gz": "ad57ceb9ecd6ea1d0691fda8637a4d756576b6695f4c3c07fde74800bca7e857",
-    "dist/2023-04-20/rust-std-beta-armv7r-none-eabi.tar.xz": "163967e6d9361208efc60931db53a7db5ae10a0ddaf6b27e7d3144d9d0d1b4bf",
-    "dist/2023-04-20/rust-std-beta-armv7r-none-eabihf.tar.gz": "d54a199ff6e803adb28dceb196ff90fb6018f817eb6bda2dc69ad0d14dd6e271",
-    "dist/2023-04-20/rust-std-beta-armv7r-none-eabihf.tar.xz": "252ab39a5c07ea74a4c517318b4ca70f946fd3aff6c379d1f9eae801829d1500",
-    "dist/2023-04-20/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "5d55a83f821547e691f4796761faa19b5d4a20b13de6328f461de92169ade335",
-    "dist/2023-04-20/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "1862d1b76a2ae8684994fe8b9718c96aac9936ea11d9c41f520e24d3e01b718d",
-    "dist/2023-04-20/rust-std-beta-i586-pc-windows-msvc.tar.gz": "545d56bbc00df1a535dd6274bb3e0a1bec1bae5c19632fb685d43dd7f877e014",
-    "dist/2023-04-20/rust-std-beta-i586-pc-windows-msvc.tar.xz": "f239658a666a99838b9dc85732fc94b6ae641df07566c0790ba2876495106b54",
-    "dist/2023-04-20/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "3b439a90c15f0382939c350fc0358e71d68ae49a1c56569d0a2954b6148d6044",
-    "dist/2023-04-20/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "c9bb0f39e3d6178b675ae1b73dc366e7a15bc625384453e796fc1b2fc62d58fe",
-    "dist/2023-04-20/rust-std-beta-i586-unknown-linux-musl.tar.gz": "6016b8ea6bb6b056fb01cef60ce26aaa9155c121dde32815ce5cb6bb3314c9ba",
-    "dist/2023-04-20/rust-std-beta-i586-unknown-linux-musl.tar.xz": "b2cd62404bde5d4c745d31d89c6ac3ddc88aac420bb7625dba4ad6cd91ff6551",
-    "dist/2023-04-20/rust-std-beta-i686-linux-android.tar.gz": "8e078415c424d7462814e338b426d77d3351efa702c74d28444f4cfe27c012ee",
-    "dist/2023-04-20/rust-std-beta-i686-linux-android.tar.xz": "c6844efceabff4f5753648a578aed0feffc946819b1c06c2b9119d208876cabe",
-    "dist/2023-04-20/rust-std-beta-i686-pc-windows-gnu.tar.gz": "ebc118086fd129cda6f7fd830547d6bf6d25c7099130c0a9d97ddd60b7fb4d2e",
-    "dist/2023-04-20/rust-std-beta-i686-pc-windows-gnu.tar.xz": "87571ee1fbeae08b184ae8b3ab7c5c9c3a1678479b878bb007810d2755d67a29",
-    "dist/2023-04-20/rust-std-beta-i686-pc-windows-msvc.tar.gz": "0ab9eb41374b2907a1d7912b427861ce47c977ac9c7a9246d0d2025e907ae055",
-    "dist/2023-04-20/rust-std-beta-i686-pc-windows-msvc.tar.xz": "086b03ce92cfa352855fb73ee19ec6ba2f87508fb48a83a87ba8b4e1c1ac685f",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-freebsd.tar.gz": "562a6b5ac2d177628ff6e6440954bcb9306ece91dd0e18fd9802a60c5a49c9a5",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-freebsd.tar.xz": "d258389bdc1300da58edc6c40904b6e63bef3c0ae0d2b86b115c97d66573cdcd",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "35df2bb07444d663b42950316d0257098c7afc2f3ed38586a49b977acfc11002",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "10b50981e0a1cd66c45da4c565336d89ff9221c0389edbea8fcf09bbae0ec2af",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-linux-musl.tar.gz": "8ab88821e6431c42e5a2c185ee645f4eeb6bc68c5ed0e6ab958bf08e72c1f400",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-linux-musl.tar.xz": "1bb1b2eb46f93792dabc08a5494de4cb30bcee598ef6e20dd93140e2c23e67fb",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-uefi.tar.gz": "01de016073f34946b0250b99e69c800eb7618c3062e3ce7cf2020725598b42ff",
-    "dist/2023-04-20/rust-std-beta-i686-unknown-uefi.tar.xz": "ab8981777cf708f9ca36123a827eccec73791ac55ec9b66ee1ff760c13794090",
-    "dist/2023-04-20/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "81e08c858cc7ff3d16030673b274ae469e04e225898249dae9f77c9013ad0f89",
-    "dist/2023-04-20/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "e5d1867128653a60659844dc8730e34dc110a0f6d69847a8ea6e2d919567bbbe",
-    "dist/2023-04-20/rust-std-beta-mips-unknown-linux-musl.tar.gz": "b8a3b04ffb88b374d1d4ba4a2314b288c5668794b4901bc7086c7fde30f2f901",
-    "dist/2023-04-20/rust-std-beta-mips-unknown-linux-musl.tar.xz": "fab6780f39862274350244a1abc7f1966c3da3c8fa0690a05db31406ad4cc30d",
-    "dist/2023-04-20/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "970f3eae77c78d27f7ba14c31a594151a95e88cad72af5e0cf9d94d350ba3118",
-    "dist/2023-04-20/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "bedcd164f715442282d353ea083dcd34ce7c872475c6cd134bb572a69886ac9e",
-    "dist/2023-04-20/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "67ca11faca21ddd40e4d3734c8b1cbd53eb614c1904662e45ded35e204f14bde",
-    "dist/2023-04-20/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "e338d2024f636dbaf1b6d9eed1e35f2ae63fdaee0e0e6c6cc8c4bf1f90d0f322",
-    "dist/2023-04-20/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "265c2c2575147d0afa844cd480224e2f2ebeb12290b2895ac996aa5fc849731b",
-    "dist/2023-04-20/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "6a08c02546b350c0b38cc8190cc29abf520990178017ff2cfabf502be9af30ea",
-    "dist/2023-04-20/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "a39233f78f76691f102a88a76608015c9223cabcac455763239d572dc4a7004b",
-    "dist/2023-04-20/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "cdaf45841f2465b7827bb86e493d8e471199f431b1b7ab8afdadabf9ccbabbb9",
-    "dist/2023-04-20/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "2f126f585de6ebd896ff9eee00441a79398ef194a6ff676be6d0f8050510932d",
-    "dist/2023-04-20/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "8b42ae4a31f68f864938365055e110c7665e47efd0c98a60f50e77b7e27e156d",
-    "dist/2023-04-20/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "03332ca367b11151fa3dd17df697134bac23f46b79cdf43c86ad17cef0df06dd",
-    "dist/2023-04-20/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "54e0094bd9000029e9349ce7797921703452ea3d110470ee9a493e4e0127708d",
-    "dist/2023-04-20/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "c51a75587b5c864cf2c6b07f41924ad7bf984e00734c9f94cea978ca21ca1c3c",
-    "dist/2023-04-20/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "13074f9149b35e9f88e869f6ae85f27a65c66ec144755f786bfcccb802fa497a",
-    "dist/2023-04-20/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "078fb778f57d80bd115fb765bc36206776d5d2f121d10e4b62ef0cfed787cb6d",
-    "dist/2023-04-20/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "d1e29ab981fa5d18607bc9bb65661676f296133593d133fb175feeaa4f5374a4",
-    "dist/2023-04-20/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "138f93d88c5cf8fe4e67383c0a4b8c3cd1d51e76a30a668439691ec61943f2dd",
-    "dist/2023-04-20/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "7fef6c1d757716aa08213ab034ef77b7d3ea2b749b37608342c4809c972057bc",
-    "dist/2023-04-20/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "a1c9ebd4322d9215e0391d5c30d3e634e05d23c6689980e7576c591342da0e03",
-    "dist/2023-04-20/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "9d21462bbbd99fd57f236ca82b14656a1429301fc81ee152f9e4029b9749245d",
-    "dist/2023-04-20/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "a332218306e37bd6140f8725b1c377af43f39693c7b1443b247107fcfa4a1a21",
-    "dist/2023-04-20/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "79b4eef0907b0ec275e5b287a97f1fd27407c1906243913963171ae584fec222",
-    "dist/2023-04-20/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "5ea2e0d35c18a7c95c9c070286edfe064d73e5a7ef7c17aa1b08d098518d10bc",
-    "dist/2023-04-20/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "12c91e2f5c04ef34a9da4a1ed25c5e4cc4f324f95a27efe832b2e29255b3bc1a",
-    "dist/2023-04-20/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "8cdd8a51216adca6122e684eeb8bd98aefb70315295eccf2f1e5ec2ea3bf7630",
-    "dist/2023-04-20/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "83fda212d6c189cd2ad9a21e442e1d48656d30165c6de941d4f46b6fef9db187",
-    "dist/2023-04-20/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "4e01f5d02fe6a23c0440e2d59fc16a590ed9e514e933622cb836858b3faa9a5d",
-    "dist/2023-04-20/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "a89a4c5ae01ad7d26df5153fc2919815709a63a17e7fd771a3678912e15865d9",
-    "dist/2023-04-20/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "339f71343320dde6a38a270ad26439f66cbc4da4afc3a72c3133c533dd47f75d",
-    "dist/2023-04-20/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "24d2a176029a4894c1474a099fefd27d1e86af70c2cb35ecee29e6e1c0482d87",
-    "dist/2023-04-20/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "7eb3384ed0a63f2b1566e5f7e87100ba790de784ef5237d3272f9c94db88212c",
-    "dist/2023-04-20/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "6524d41fcc8ebf0e2e7ad4c4c0add45b39467aac153448786b1458f2c56d18a8",
-    "dist/2023-04-20/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "a9cd65f1796163a681c1946782627a1c1f4ecf28df7fbcee56cbbcf6d5b28f15",
-    "dist/2023-04-20/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "d03ccbfc381e6ec9458b6e5a2a6d7638b01b2164e43e50403b89ee9f7d10bab1",
-    "dist/2023-04-20/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "ccf9e75be80ab8a64b13d57483c58eb09c16001a6a44ffa275a0e00c830d8707",
-    "dist/2023-04-20/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "9cfb6b4604433f52dd8f0d1a08e86a000795fed9095148c51b1f81287ffb12db",
-    "dist/2023-04-20/rust-std-beta-sparcv9-sun-solaris.tar.gz": "18cf1837ba56256716f79fd5d53b45a50ecc0c2caa368ab162589904a51e7e31",
-    "dist/2023-04-20/rust-std-beta-sparcv9-sun-solaris.tar.xz": "188b3a51ca73a38e9aeba7adf88b9bd7954e8b479c570d4f6844c43e1aac6a57",
-    "dist/2023-04-20/rust-std-beta-thumbv6m-none-eabi.tar.gz": "826e0eea9d14a3f5b9b1b831e1644f5dd8129480683e1dd934772c860394f691",
-    "dist/2023-04-20/rust-std-beta-thumbv6m-none-eabi.tar.xz": "0fd19cc21dc6efce2caa2244fa39f5562fdfebef5f423b4e58d790c1f66de44d",
-    "dist/2023-04-20/rust-std-beta-thumbv7em-none-eabi.tar.gz": "8498c8ace2c28dd06d0c3528759549f3075cb8b6f2e846db479eb96b43a21b32",
-    "dist/2023-04-20/rust-std-beta-thumbv7em-none-eabi.tar.xz": "259b5f0cf679561cf81ef801815ae89c2848232336d6bc5bc8ea06f9ea8d13e2",
-    "dist/2023-04-20/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "6521e7eb5dd003862685dcd19bd6b8aac3ebca54e945846bb061916cb5a8c100",
-    "dist/2023-04-20/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "c2c7102b9135cf63e988401740dd9f0e47d0f6bafa866475ad65d8c2e3a5a6e4",
-    "dist/2023-04-20/rust-std-beta-thumbv7m-none-eabi.tar.gz": "c0cf188a9830d7992796f5b5f5d15d6baa0b94da8575f9992464e8d8811e7d4e",
-    "dist/2023-04-20/rust-std-beta-thumbv7m-none-eabi.tar.xz": "ee37f54d02e22c238d21454ee678b5d349b6b86160a97ab4ba9e348822878b8d",
-    "dist/2023-04-20/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "88d087e15f8a9aff522fa30a7b461bfdcc8a14a1ad22d874727823e8f1dbcc1d",
-    "dist/2023-04-20/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "90f370a2d93866c4a465ad4f7363c46b71f0e7eceb538be0761548447e46b143",
-    "dist/2023-04-20/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "032fe22201db120cb3f95e4f4ff96fdc09fe72b3c023dad19161c94b1bf49b4e",
-    "dist/2023-04-20/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "a2f661de0a9287bd5fbd8a9bbc2fe971d6d0f3e0e33d367339231e788779edd5",
-    "dist/2023-04-20/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "fc8fe009d76071b5a567a5dd6a2efd3daace2acc3cf358242e24c30aeba8e8b2",
-    "dist/2023-04-20/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "6220037537a32841f3ff5ac551b28d85eed3ec2d4a8e9e6d833dca6493b33fbe",
-    "dist/2023-04-20/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "e0f3ae6ea1bf62a5c875ed3d7d0146ae5d7d56826ac1e447a19ec90e564827a5",
-    "dist/2023-04-20/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "796f4b094c1c8df7189584a92158ca8ffc05e4a1a0d3a4d0f8a216bb99bc1665",
-    "dist/2023-04-20/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "65a74d18cc2597e012fbc7800f2b75e16082afb197c680e89f1007257fd114fc",
-    "dist/2023-04-20/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "c6480f3d6cdd2d2ef43d27e103cb894843239f9c2570f9b73afa0d75536dc4af",
-    "dist/2023-04-20/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "bedd0f7d8bd141dc9239484f9fbc2898863097802683652bcb7c59ff812fde9c",
-    "dist/2023-04-20/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "af3121db2d2d98da862e923ccd315af5e4c72f5fcb42b7ece712db8ead615be5",
-    "dist/2023-04-20/rust-std-beta-wasm32-unknown-unknown.tar.gz": "fb9b55a54528fc8894a915578a6e5c3f17e5253355154af48543488da16ac407",
-    "dist/2023-04-20/rust-std-beta-wasm32-unknown-unknown.tar.xz": "0b28eceb3dc40e9de08a9ee6ba781a052b0785ac42b3e6583a6a084332d8993f",
-    "dist/2023-04-20/rust-std-beta-wasm32-wasi.tar.gz": "b801aff4b972011b14b08952f2ea9cb2e12262f50c7c916dbf0a20744b7d3f19",
-    "dist/2023-04-20/rust-std-beta-wasm32-wasi.tar.xz": "26f49c2b5f77404881b9ac6514b9c0a9a49b35515a841c203387cd5e007fda2a",
-    "dist/2023-04-20/rust-std-beta-x86_64-apple-darwin.tar.gz": "23788d725fbeb6055ae38389b7c8c81461fab9f11ac64b39383d2c358ecb83a5",
-    "dist/2023-04-20/rust-std-beta-x86_64-apple-darwin.tar.xz": "d6299ca57f4e2fdef065724507a22ba63bee76fd4fd1c475bf66be2efe396912",
-    "dist/2023-04-20/rust-std-beta-x86_64-apple-ios.tar.gz": "3e1d7c5e728c306d7697564d512577d7f2b0868c3bf4cddca206948b9ef676ee",
-    "dist/2023-04-20/rust-std-beta-x86_64-apple-ios.tar.xz": "a34a5a4a8fc36501a3511a34721c68659098d985e7516e1fb30e2ae9ebb13697",
-    "dist/2023-04-20/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "fe046c71f7a09a0a4eb4b023756c6b751afea7092e7f4b53b6321c593dbf6e34",
-    "dist/2023-04-20/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "b4f482c9cf11bb1ae253cee16ec90748d2327733b6b9a0b32d68a16cea99974e",
-    "dist/2023-04-20/rust-std-beta-x86_64-linux-android.tar.gz": "ca160d9645ebcaed94e742bc4d2a70c026c5cc505c00ed0feae406ab5eb2ea68",
-    "dist/2023-04-20/rust-std-beta-x86_64-linux-android.tar.xz": "764c2cc73a77c754c84752cc3ff9f6369c7ff2af0bc8c3840aab20bbabae7d79",
-    "dist/2023-04-20/rust-std-beta-x86_64-pc-solaris.tar.gz": "bc3159503789a508943b5e5a1fd4199fec023b448da52ddba517a9c748d9fdb8",
-    "dist/2023-04-20/rust-std-beta-x86_64-pc-solaris.tar.xz": "2d43fcb2748fbec913001f880e1b279a3d854b6203694acf513bde0a3c172fc1",
-    "dist/2023-04-20/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "1385f3a1468a4d30a7b4d58d4bd683656bc1191ba7371ea4172a868a15af9343",
-    "dist/2023-04-20/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "d7e4dded34cd043c411dc6d78463442ee02545610fb34b050afd4b453f8d3328",
-    "dist/2023-04-20/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "eb9181a4bc3d7e02aa4fb959446894ba8a3efe4e71dfbc3e7b1ede6cb52ae87c",
-    "dist/2023-04-20/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "1b23632345f55cccb9fbc47efdb8f8c9fd4bd0172fa21dc813832a9bcf58f75c",
-    "dist/2023-04-20/rust-std-beta-x86_64-sun-solaris.tar.gz": "8edcf15812bb2726d5a0efce4e8e49d442c91c26fc35a26a76993aedb7a514dc",
-    "dist/2023-04-20/rust-std-beta-x86_64-sun-solaris.tar.xz": "8050ae692ee600cd5beedcabb2088e7c1f7f222c85abda5af289861a550c1a21",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "7f820b5362c8ab6d52a3d54689383cad76db2bad351fdbc703c0ac25f2fb2f41",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "d22641d071a0d07206300cbdd0024ca49b4fa95635c6b5477114119421cacef6",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "f27dd55f65b30f5528d1ecd53209435501747a6dc95940dcd193b0887befb635",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "5298fcba18a6a74f39ea5ef356e2b7af6a605c1bc988bf3808f188ac331231f5",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-illumos.tar.gz": "74e6f11ae802eacd6ceec24c349167919fdcdc12645b0884acd3a97f8dda29bd",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-illumos.tar.xz": "28aadd9024dd2caad14bcbe18a917d72bc5c6336e3498c2622c361086ae4f357",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "050e31339de130c68c1f20403a95140aa438f1254c56aae5f3525ce6b610fbcd",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "f68ffe728f8317f19ea1431542803c2800272174c003b6a8c2f3d2f12494c20d",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "1355d05d311e6380bc1d40b23c3f4d8cdfe5b41f900ca1025b7bfce309cee2f0",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "f6441f808026691def0f4909dd1df9ead77d2698ec44fa2627110aab271ba44c",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "c11b544ad540c7d0ef1fc4b09bfa7219d738b214baad0de961ddda011ea88a6d",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "9fdaf1c1f1fc26bede80b9dbd3c86bb5e9d528a9b94ae9185bad6bb9b56bc7ab",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "809a1a05f2367286e5bc22c2b963cb0c6216af552f7f16ff460776fc87b64147",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "ead16d54ad9b75957396b9294c11289d2580c48e3a270ab45bd7ed4462065767",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-none.tar.gz": "b5791dd97106c645c4d36255fecfcf917c80ecb59d12c06e74f89cd7cdd81ae8",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-none.tar.xz": "15eb3115d973d298a2994bc9ea2c9c34dcc8c220152adc85618a4ef8892db427",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-redox.tar.gz": "afb13c0ed02115605d4f5ffc303365604463ff1a6e63c4f1a8b7c5d7975db2b0",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-redox.tar.xz": "f8b8d606122dbaded0219c332b2c8f440356af559738bfe98072f5cc6460d057",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-uefi.tar.gz": "591a861e52f362b5ccda9cf4bb658cf9731bf03e992de3a7a176ac0d282bcfd5",
-    "dist/2023-04-20/rust-std-beta-x86_64-unknown-uefi.tar.xz": "8017eb935b1fa3fc84bd0f02b30076f4c8317d5a0249461f095336139457a03e",
-    "dist/2023-04-20/rustc-beta-aarch64-apple-darwin.tar.gz": "df30a906559e5fe0ffe481e6c53048e11cded36299dd5e208cf43ca10ccb0c89",
-    "dist/2023-04-20/rustc-beta-aarch64-apple-darwin.tar.xz": "2d5310cff690739cb0ca63b1f8ee91f7cac09a3f3459bc877660b1f29821d4c2",
-    "dist/2023-04-20/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "12cfd51bf114a9d1fda6a4b9853bb77412c55a75b98212758bee39dad0426ea0",
-    "dist/2023-04-20/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "bb638a2efd4a2069d692986a4d5664f9aff3e1b446691b4b119517d339d98145",
-    "dist/2023-04-20/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "b3f9a0f6ddff10cf023b7ef8cab23663199e0714b9315e339f73a3de7f3064a3",
-    "dist/2023-04-20/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "f6daeb04ca076a552a7b985f87cf82a85d41c1e293d05d3991987df1924f748a",
-    "dist/2023-04-20/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "4415af9650a37c4f88430679f8647b94bfa731b71355a8bf1144a15c5b0b0944",
-    "dist/2023-04-20/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "2022d75946b1799bd62b17dfe216aca86eaa28528ddc226fcb4e88d82d443ec4",
-    "dist/2023-04-20/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "7a94b768ecc665c3d9c4d093ed3b8d7912e38246646540ea57b9ef7b013fad92",
-    "dist/2023-04-20/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "e5ca6d324efc9b1eedb307d3e425c4811d62d46102ea8ddd72c39bf2f3c789ab",
-    "dist/2023-04-20/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "94d1602c630a92ffee62e7ab6acc3a3bd9475e90482658e97bbc6e1072f60a87",
-    "dist/2023-04-20/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "50c3bd42c30c5d3eb7a79ec0c977736391803a2ca3f00bacf9593899b1dca9fd",
-    "dist/2023-04-20/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "c60a9bcdaabb7c7420740a1e4480c4927277498bed34ffa5578c85bd5158eaab",
-    "dist/2023-04-20/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "a837407a2338986e23479caa752056746f5b6cca4c90f08c0f31eb8aaf8a4c45",
-    "dist/2023-04-20/rustc-beta-i686-pc-windows-gnu.tar.gz": "46eb4e2a617ba1cdb7964a1b5678d977d486883deb13801c7114359c5c73c8db",
-    "dist/2023-04-20/rustc-beta-i686-pc-windows-gnu.tar.xz": "c6f2e7912736e467c99c0a96041c77db1bcbd22b370861dfc599c37a04606456",
-    "dist/2023-04-20/rustc-beta-i686-pc-windows-msvc.tar.gz": "58487cd26b0bd63ff5a55aeafa5263dc9973267a9a1bec0d3d75da5dab83e34d",
-    "dist/2023-04-20/rustc-beta-i686-pc-windows-msvc.tar.xz": "700dacd476ad96ff0d4e3d95700d309eec8d4d6f25fcaa75c096d31890a86f4c",
-    "dist/2023-04-20/rustc-beta-i686-unknown-linux-gnu.tar.gz": "5b1c00b59e65da0d1ef324d8cb7ac2b4d2467d48747aa20013ea32385ae7b110",
-    "dist/2023-04-20/rustc-beta-i686-unknown-linux-gnu.tar.xz": "b9f08288717c10a199847fa8a8881db6150f4bd041b6fe5fc3522bfcce66994b",
-    "dist/2023-04-20/rustc-beta-mips-unknown-linux-gnu.tar.gz": "77c6117d251e2ae8ce7490c2883ce70f93bc82422c727c0440e0a95e1567d1b2",
-    "dist/2023-04-20/rustc-beta-mips-unknown-linux-gnu.tar.xz": "b6e6e946e1e0c23c40f36fb290be44417e6d20cef97b5b52093a127ed4bfdfd9",
-    "dist/2023-04-20/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "808f0678511d2b0028e563d13370978538fa5017886f7f7a6f4aab3cf980cce3",
-    "dist/2023-04-20/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "f57673de409033817dd28ad563ae55af7605ffd6764e08b8ad7edc3ae2a4371a",
-    "dist/2023-04-20/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "9466f0b8816eb4579186f4bf0dc16c97171767df42779ce227df115ce6dc9555",
-    "dist/2023-04-20/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "06b768bf4c0c359a10ee937943587a5a37c32335fee3d4276114c4e3f6828ecc",
-    "dist/2023-04-20/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "f4ff7fc2dadaa65b8777e147e46d176f1b8e1612f060ae5c9547f3ccb3515391",
-    "dist/2023-04-20/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "21f6553daee7f77d50d70a8b5950de0a4c7c06152637db5eaf42217260f2d79b",
-    "dist/2023-04-20/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "e8e5a6f5c9ec807f2f4e4c0944244c81896793180614cfd6bb1181d50a70fb3e",
-    "dist/2023-04-20/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "5de90f98ee29edd5d1d7a2de216571c23ada154d913dd03f218caf8bb23682f9",
-    "dist/2023-04-20/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "e91270ea9b83946e7f4d267f8bcff0a3670d070bc87abb1e27c161db832f1965",
-    "dist/2023-04-20/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "0ebf2ce2ec6c892be3b010d3d09a46fc0d7a23a77485aa8ab468444fcfc7bb08",
-    "dist/2023-04-20/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "7a40bba3c68766a184507c9a378a1e4ace9745f065d0409519e9fbad57dd48ee",
-    "dist/2023-04-20/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "8b1187e4a089b66e9487b791b4a60850eb57c6c452b8a0c745d24715ac44956e",
-    "dist/2023-04-20/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "550fbced66a230358f8d55b9b204e737bb3bed4bb8ddff844adf598a6b2bc54b",
-    "dist/2023-04-20/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "ba68303e8f056b800884b50f477544ba15374defa88d174174f1a8a8a14a589a",
-    "dist/2023-04-20/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "d734fb85d633662a554bd2c72b7adb36d904951fa9bb48194a092b35b5d36ef7",
-    "dist/2023-04-20/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "ab189b6ac12fde284b4c0357b864dc4846c805a39c9d5a4049799d08323a6820",
-    "dist/2023-04-20/rustc-beta-x86_64-apple-darwin.tar.gz": "b3f56d905276e934772709e270ebbb13faa8301cc92207e061adff917310a370",
-    "dist/2023-04-20/rustc-beta-x86_64-apple-darwin.tar.xz": "190e0e338dd39326ff7835dfd13bf2b53355c5a71f0b63df0e2e822997f7ef6d",
-    "dist/2023-04-20/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "68e286df51faf067bba9c4c10dc6ccd4e6b81d7c2bb1487960f57d9ff18c1e73",
-    "dist/2023-04-20/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "28fd89783bd2023bd4ef052d7ac541772ed39b51f87838806b80ec493f35da10",
-    "dist/2023-04-20/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "0072d99adc95ccb1922137a6060b1aae74142e0a8343fdd459a772502e0a34a7",
-    "dist/2023-04-20/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "32839a7cc46f066681bfa5c8609ddfb473813e7771b363f194d061d8d886c5ba",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-freebsd.tar.gz": "b3b10e6eb7c7ed578418f42058e1d5b287477a1a95a3d1263976c8512ed93ab0",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-freebsd.tar.xz": "6f65d34f49d87a59c82464d6c045f346a6797e2795fb9e31223b09fe64f60c9c",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-illumos.tar.gz": "83a97feaab58ec2997a96f902ac45cb8a0d8d307bc8e3c7a7d2e7a6cbe0df1cb",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-illumos.tar.xz": "18b0611345a6ff33a36d1f19f175dc9b7a8e2fafd9e84ef95fd9978b74e14bb7",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "c64fc2556a68c3a775d844478e8ab7f46ada112474d965ebb917ed033cffe48b",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "cd24c2150f618aeff6287d99cd8623f55f766db0d7b929b9263666c86a71d2bc",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "208dec1e29ceea4bd35d54476f9c57228598eaf98bfec823e19386ae476f231d",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "a205bd7ac479b549c23dc6d50e49c603c93289d8987c2c87fa46a430b7392dd4",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-netbsd.tar.gz": "b55315862eea659a2c4b1c1a832bee5e56ab789ac62618e746a2ba3ddeb13023",
-    "dist/2023-04-20/rustc-beta-x86_64-unknown-netbsd.tar.xz": "f67e17d9d9b98ed126a6b4b3c2dc86048fc96187fd26cb9f1fc5fb5269bdea05",
-    "dist/2023-04-21/rustc-nightly-aarch64-apple-darwin.tar.gz": "b14dc1f1473ea109907787a1886b4c0f89359957dbca6accb3ab6ee1cf1aa64c",
-    "dist/2023-04-21/rustc-nightly-aarch64-apple-darwin.tar.xz": "cd8a5b832c0a54d23f82dcc556bdcb387ea0f761deb2502e7b952923bc0f05fe",
-    "dist/2023-04-21/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "8b1ac2260179d455896659e04bd282a57db1e43638ea7d305ebdca8007b9a89e",
-    "dist/2023-04-21/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "748af05581d719e3aab0f0a75391979c9f15f7c0ee37bd8244051b5d00632d32",
-    "dist/2023-04-21/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "c60938505082ca3d0d581b2749aa53792b63e9061ae80be0addbdc2367ee07e9",
-    "dist/2023-04-21/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "9f0f3f4d332b5d106b4fb45060fe71f9cec973cfed8169d6279644ab5d37cdb7",
-    "dist/2023-04-21/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "f211b27640ab0b9a2aa6275d3dc4f11749beee4f48ada3df723c27214d0048a0",
-    "dist/2023-04-21/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "2a4355f91f3a5ee31e41905740541504149ec4045a7b806017d869cf00453d0c",
-    "dist/2023-04-21/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "adc2537aeb691226d10d1b306805fe6e9b96461df33854917f33018569968af1",
-    "dist/2023-04-21/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "1bac0bfdaf8f538099b7551225ab18754a5457cd89d1805368b3bbb583cbd9f2",
-    "dist/2023-04-21/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "e98227f4396417d72889d1ef9d073cd81668539e24691b2803f877227341a7ee",
-    "dist/2023-04-21/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "e9d6b6e35164da9b2c7adf474178e5263e79acd65a9f020cc3be16d55f5eb511",
-    "dist/2023-04-21/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "4a5917e4bd3eb6210903edbd5551426911141768b6979d59eef53b36c125ad3a",
-    "dist/2023-04-21/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "dcc87e08210dfaa4629bef68f71464b8b81bbf9e7180d9d385a2c15b06b7f18d",
-    "dist/2023-04-21/rustc-nightly-i686-pc-windows-gnu.tar.gz": "4252bf99e0738dac18e51f0c7f4c3628ead5909222d18b3b7b780b90062aea7b",
-    "dist/2023-04-21/rustc-nightly-i686-pc-windows-gnu.tar.xz": "150824f08e818b6b1485823217056a2d568c803e63c9c753fb11cf93b4de6cf1",
-    "dist/2023-04-21/rustc-nightly-i686-pc-windows-msvc.tar.gz": "73de440b9916a3ce442501dd15239184a11f47e17fb2d7e3943af2c0ccbf9f1f",
-    "dist/2023-04-21/rustc-nightly-i686-pc-windows-msvc.tar.xz": "8fea649215bfffa876143c91ff4fcddfd6c5305bb05d4f8656766fc63c1a19bb",
-    "dist/2023-04-21/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "07484b9e5c9bd6fedf24999fa3350f3efa3e04da99a4bb7d6e51e27b296a1833",
-    "dist/2023-04-21/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "2440021d923189b5bfa789d0714e974707750deedc9dac79da7c41896ceb210c",
-    "dist/2023-04-21/rustc-nightly-mips-unknown-linux-gnu.tar.gz": "2d0b23098bc0cfa680234fb3440908f88a075d91da8a489b8da043dcfdb8d361",
-    "dist/2023-04-21/rustc-nightly-mips-unknown-linux-gnu.tar.xz": "39b47607fc849cbbf80ca89881e7440e00ec2b0af83ec6274dd0d4723f960dad",
-    "dist/2023-04-21/rustc-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "bf7a8a1f9a712604072baea92f8637fc44b8b33796d187a9ef9477d142f0c2a6",
-    "dist/2023-04-21/rustc-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "df760912c668f6b3b23607e97f6dfbeab9d29357293d31becd41d842debe866a",
-    "dist/2023-04-21/rustc-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "4438e9f19f8dccda2be4911e20a99cc4fcd3555282ea40f363d75ac96133b9cf",
-    "dist/2023-04-21/rustc-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "e9085975facdc36f0a133d6e9a6726a4322848b833a72a5bcf54e438685d0a50",
-    "dist/2023-04-21/rustc-nightly-mipsel-unknown-linux-gnu.tar.gz": "8e4ae9bf1ee6743b8783c5412843b587bab9b9bd67d02b2f919e6dcab770e221",
-    "dist/2023-04-21/rustc-nightly-mipsel-unknown-linux-gnu.tar.xz": "af6a21afd7ef9d9735c58bf797a3bd2c6eae41741c37395a81b9238a1f37c1d9",
-    "dist/2023-04-21/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "e9ceb40b6d389526b72ca08dbdc035603e307b18b41e070564ee20ae15105cab",
-    "dist/2023-04-21/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "7f30002cbd5c81ccebad47cd8129df88391c12a19f44626a0776f8093f420a24",
-    "dist/2023-04-21/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "e710bde14522bd4a24e90e6d274d7293fcf47e29d432910f206bbf024652d073",
-    "dist/2023-04-21/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "47730b4838b7c6e28436174bc5835d966af0a3a9f4f1180e160ca030cd8009d4",
-    "dist/2023-04-21/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "b6c969e1b6393a0749de17b930313df76f64024a5ff68e4a5d7ab182a2c39fd5",
-    "dist/2023-04-21/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "1530809f81bf2805415980148678a12f680909d439ac440157c6ba5df64e0d7c",
-    "dist/2023-04-21/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "690a283c9a3db2b3234aa5fc7828df2ce2901fdd72db10b35e8234c3df8520f8",
-    "dist/2023-04-21/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "531f4ba41edd1de2b27ee8798a5e8f5e3b5fc1488d743e5020d29834cccae273",
-    "dist/2023-04-21/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "ad454aa9437687fae9617f84d921489ce2ea8e61e5c2e50b3ec13ca026c0d515",
-    "dist/2023-04-21/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "9cc9a96848519c8c80cd44d14760e49b0b92cfaa851db55c5b1c7f7bf9fd95d5",
-    "dist/2023-04-21/rustc-nightly-x86_64-apple-darwin.tar.gz": "1c4ed2e08ee181cd9d28fbd0cc4b5c0c73d8e6a377c5ab6b4849e0ad8182a729",
-    "dist/2023-04-21/rustc-nightly-x86_64-apple-darwin.tar.xz": "25efab0032ce61d70abeb9f3053a089f827ba693c0502df2225939e8f77184a2",
-    "dist/2023-04-21/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "bec16f18e79a32f304c17811baf64ac1a8149a15504c7bb5f3d198cfe09db6bc",
-    "dist/2023-04-21/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "709fce3891b9688a05d7e7dfbb9cfef15ad6461ce54923e06b2dbbcf87ab9b57",
-    "dist/2023-04-21/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "15704e62bad40fcec9a14bda6f6d11419970f1d050aedbf4157f1f26cbec45cc",
-    "dist/2023-04-21/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "7f5f8fd10c2068a7d1bff3ee9bef92dbe9a11638b7546ebb8864058b7d1efdaa",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "1302219d277d6625b0bde7768e78f2dd285d47a8de928eb2c767b4b9e20f11ed",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "51311fc67fd86ca7baa0601ac2f1d53a4dc4671132c190dd305f96d6bec47a40",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-illumos.tar.gz": "2409082de839f235c9dc1b8366b1060356f708be2476e72aa3a911abd9b46542",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-illumos.tar.xz": "98c6da8aa7783d3b078240133d0446b99277a5721ef8ec94bb56735fc444eba1",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "7703bfcbaa7dbd99175101fc5a9c99556fdd556b77f107c3c0e89aa5c78e2479",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "30704ed5b752bf574e3b149056f033ff2bf96f6841810c2adebc5c5e52593002",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "d46394234d911737ff913dddc4697d352e291dd8f9b9e39a1ff92e0a6292a0cc",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "d6a8a6bbdd8fc0e97f455bd7df71c1bc5ea0230b7894af5beff2e76880fef1bb",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "701fd848e1529d39bd2d0b0aab40b20d2259e9f57dc40f4bf77c1d45bd894d25",
-    "dist/2023-04-21/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "ec6bea58a1b0788391ea57107d3c78734328c47f5b91edb92996d64a8b5f8bc8",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "66dd75310abe0112d3ef75345a0f3054ff936ea7098a040d20cb8968b7d1b2dc",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "705d9dc8548dc84ba9c69bf5935860658ae501cf577584610974b4448ba7588f",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "b4d2541fbc41a5b9fbfb6bbe8a869eb8794d658ad100fe402c4c3ceea12cc824",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "d16338308c83de20b9f86e56c83f9601fb3ce3b7f9be26d9210f401319786ee2",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "b8300c62cbf2136b86fab4ba1357ede3b4be997262844bae7cf1694b250a75f5",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "6979a86d568e58fa1295fefe71007d374a2975ab10773af7a2f2876ad2f2773b",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "74ef4daacace0d036148f5dad87e759441925b1882da2bd6fa2f8628a290edc3",
-    "dist/2023-04-21/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "6a35624795fc157d7587bf4606698c471ce82c2f12269741cf5d414e91ee4b6e",
-    "dist/2023-04-21/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "7d4914fffa7ceb97c8e16969c9f2072decadaedea658bd51d6590a6caf2b53c2",
-    "dist/2023-04-21/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "5df0c332bd3760c4da08d4cd330e3f2fc865f9f0b11b54fd7c7c41fc56f582ce",
-    "dist/2023-04-21/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "2ab4f71ff23e68923e24ce906f387bc1b6c00f07e1ed13492516c14b652936f2",
-    "dist/2023-04-21/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "bef7cb9b4dd0bdfbba20afe603d60aa37df77ba6aa8e179a27a0a46ce9febe9c",
-    "dist/2023-04-21/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "adbf12810a829d35e85811d5fb715012434d99d42f88340ae61a9141bec9ba95",
-    "dist/2023-04-21/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "242205fe65d10548b69a7520b33ab6584248817454f19c3da1328044c43c2260",
-    "dist/2023-04-21/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "2e720a30089b192f4bad517600544c9085a5b8ff0a3afcf7d1b1a8149eba5af1",
-    "dist/2023-04-21/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "7a2c5a01cb6a47d86ef02d3bbbc2b7d5b1f2eef68cd4aee00f3566accfc429e2",
-    "dist/2023-04-21/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "f7e1d6cbf83508a0e3c06090fe80ab314299d2ac24be0f8e3e5658177e270a0d",
-    "dist/2023-04-21/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "630bbe6d526774effd0602ec17eac0d4b5d00e67402fb189f282416dc614a3a2",
-    "dist/2023-04-21/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "47e2b997cd75a8e1efd67bed1f0a3e3255cedffb542bc8eb3da695cc819d5684",
-    "dist/2023-04-21/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "71c07ca9546a8e404da5e2024374876e3f282aac54f04076c26dd4f3f53d79e8",
-    "dist/2023-04-21/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "2131b14553e7f3cc276410a6e3e3fe309a12a65ce8dc287b2bc543d1c1769122",
-    "dist/2023-04-21/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "8ad25a066126b1b0485cbae336f0350c6b46e4463fbc9593916c495875b5f3e9",
-    "dist/2023-04-21/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "a5231553b80b57703988099f4c466a60e4b8d13cae9e8e25a3acfb5c59e3d493",
-    "dist/2023-04-21/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "7da93b04275989b6917e5538d0f2591ecce0c87bf78c4fa79ec24b262fcede12",
-    "dist/2023-04-21/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "ff173fb7a5b2884963890c4a5728c3766d89d6d68e823d9d0f026e4b47c04adb",
-    "dist/2023-04-21/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "23f0af9943a0d5f97e61258e5f75b6a0542a9c6ccc9919f083e3d331c154b55e",
-    "dist/2023-04-21/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "b6610919e1f96cd101d1170541b9ffec0a5e617760cd1ff221e1aa163bbe96d3",
-    "dist/2023-04-21/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "6f17563141a1153b5b2e489925336ef2d52fb3db66a081f818e475ce03a8fbce",
-    "dist/2023-04-21/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "9596395db964723ad81b790b6ab8cde64584dc6fc672bea5a0f77388457d385c",
-    "dist/2023-04-21/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "eb0175964c23b792a20e4d7e086d97a857842982a41f9500462851203c9ce54e",
-    "dist/2023-04-21/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "5681022c372dd95afe8751b0eb1a4085d2b47163c4858744f80381d47ee113fb",
-    "dist/2023-04-21/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "cd3b6d0d9510eb99e7cbaeb8e947ead7f1a8456dae4e7b727c08b3b4510bda4c",
-    "dist/2023-04-21/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "8e6329116e796f8f26921ced59ff28040f23773b0b9db8b2ac8519c779703c23",
-    "dist/2023-04-21/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "7850600a2ef836e47b0a3fdc33e8d6f804a522db01dc5c40d5c1f59198065d07",
-    "dist/2023-04-21/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "f8b54967642fbb715160497e7ea7dd5ecdb0d4f8583011ddb590e39ea96ef0df",
-    "dist/2023-04-21/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "f47b04ad9fc80f29100b56906754a17f1d6afa97942cdfb764269ea68e437592",
-    "dist/2023-04-21/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "5233106943cfc8f6665f800cf947415a429154ac8a3f5833cacb83b052cc9888",
-    "dist/2023-04-21/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "bc3a67a351897778a97eaa513b4dea9644ddee0bf76925c95fd9bbc3f3da368b",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "b8ddbb26d9422d65bdd5e81dae4b2fda27c3f47b12d6bf87e37bc2a5fd3d35e0",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "ded34445ffe8efb8255b61bca618a8a09db5ed95e54e02267796e41b221914bc",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "7c37ca08a4cf3495d0850acaaa69c79064501fe5e626c909cdb0cb936bc5f84f",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "fe2cbdf088b2738bacf75ccaaf9761b85f633c8fe56823bd05fd0e53570a58e9",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "cc1a68fb4322cd1336349abb5d1528dcf5c8e0113895f5fa6467d8f9c040c58f",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "e21f7c6f3bf939e066b8c2bae6eb8a26cfe124422e895b54d051e3013d8a1b89",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "638cd63bbec1312df98ce8e5b375b0ff1cf3256b8ef085e169639706f75f7f72",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "b615bcb14ba429fbb38cbe09f62bdad058dfb783055f067ceee58dd0799252aa",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "1797efad43a1a4bd63885e8b3a3e713ab7f971d8146f80a9b5ee72314e2c7fee",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "873cc18bb54a7db47763b88b91715360febf419302fd29fca2294073b09ae29f",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "3087b49def00930fcc4abea6391d4ded3e6fac8e66ac5275d58a3717bcbccc29",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "4a71c0720700ac94e1e7ec40ed0eb27cba60bab6f13b7b28bfdd15935c0bf639",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "eef5d412db6fd9535a109ad9575bb6d1428cf4bb56130d6c97332d5a56f9b504",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "453a0dcaf90ffb33af0e7994d317932e897980307897794d1143078c208dd42b",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "383a6196c67352f5fd6efad5dcd41cc325cef547baa2bf1376138cd628e1f16f",
-    "dist/2023-04-21/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "1c33e794c88b4740ddb5c7a1354f19471fe719b21402e67ca205cfbad6aa9f6f"
+    "dist/2023-05-30/cargo-beta-aarch64-apple-darwin.tar.gz": "ec0ef9ab4514f493675cf7c6c8539d29d4d9035813f3c2fe11df9f41cacb254f",
+    "dist/2023-05-30/cargo-beta-aarch64-apple-darwin.tar.xz": "1a9aa0848d79f7e8d13ed96e9df068a95c98056eaf569e1f5baa8ed02b1bd610",
+    "dist/2023-05-30/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "4617ed30df22b2fc97b02d70bffd2f08e6bffacffee5f6f7bf73799372320802",
+    "dist/2023-05-30/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "a7ea7ded3eceae4a3ffd21ab3b2af0e7e63e686e1d696508f05b764af5d071b0",
+    "dist/2023-05-30/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "05cd8f23b86bf8bf755d9300a344bcc6332398c81ec490a1afea8a3cfa489138",
+    "dist/2023-05-30/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "fc260df9c4fc721cf55edb2d10626b51232a566ccdf0fff76859542937aa8e3a",
+    "dist/2023-05-30/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "be257b324db5f97e58d56c51c1da184689aeb53052731992454101abba5e69ba",
+    "dist/2023-05-30/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "d12a3399e8a59121cd70620c735a2c3b33ca12d88db8b20f7f150f640ca2c3d6",
+    "dist/2023-05-30/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "f917a6722192bdac52994306033db82afa7aed3f7f0659bd3edfa125aad26286",
+    "dist/2023-05-30/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "d19e74b6dcca36100f667f752a3e61c0f4c0376f065d925dac1a04f35a2e2df7",
+    "dist/2023-05-30/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "4ee94ac076f491a725cfb0bd1fd562e76ba0c877f1ab3964289a93cf4d50e907",
+    "dist/2023-05-30/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "c054bece6c071b1c2633e59f7193e25ed3e29ab1b6cad5e62d9ec71304f92cc3",
+    "dist/2023-05-30/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "15ed708ecbf86769a5d3e64e2263f0c534db30f793ede9f4ea6e04fa6b462d5f",
+    "dist/2023-05-30/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "b11e35f7ccf65d9ee224d4695e0f769f52ed1e87f32221ab62a79d1e818dab88",
+    "dist/2023-05-30/cargo-beta-i686-pc-windows-gnu.tar.gz": "62509f8a6c096ea442ddfbc46c16942e905cfb5017b1cf85dc94f812da243bd2",
+    "dist/2023-05-30/cargo-beta-i686-pc-windows-gnu.tar.xz": "cfb63865159c01bfa1b4db6368219f255aacc9bbd94c2d04633cd705d53c6fbe",
+    "dist/2023-05-30/cargo-beta-i686-pc-windows-msvc.tar.gz": "81c5f9e12449ce7c7dca6a32ba18fa232df19085acf5650bfbed65e228c06b57",
+    "dist/2023-05-30/cargo-beta-i686-pc-windows-msvc.tar.xz": "acbac0d53c7ab771f3ae91c8461304ba811f8a067575c148e207311f425d694f",
+    "dist/2023-05-30/cargo-beta-i686-unknown-linux-gnu.tar.gz": "0bb73bb2d3abf4065cb559e022332c6ce9d6b2223c074b974fbc39450e46e345",
+    "dist/2023-05-30/cargo-beta-i686-unknown-linux-gnu.tar.xz": "11622821b4b11a02c9262daf4aa35aa2b71407362079557be604c72962175bf7",
+    "dist/2023-05-30/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "1f7c1a3d0879d6a04396cc31ca2e41dde5f9ca8cef360c9c44b32b909f4e8d4c",
+    "dist/2023-05-30/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "8952d2e179a80ee8257d89cfd417a6df50edc07c22c0d6e3ae55a7838cf51ba9",
+    "dist/2023-05-30/cargo-beta-mips-unknown-linux-gnu.tar.gz": "931a2f303b97bd21498e51370392e9ebc66d6cdbfaf537035245988781173b45",
+    "dist/2023-05-30/cargo-beta-mips-unknown-linux-gnu.tar.xz": "ce71db299106759857ba00ab57bc275bdb4817576a51333b8bfd6a9f1d7b8010",
+    "dist/2023-05-30/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "3f32c9a97da50ee98a2b60e8e3f5140941d12d3374a9926f169081d3b6ab6a51",
+    "dist/2023-05-30/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "568732ec25848560ed886d0742fcc5c84f6aef8dba16d530853aaddc3196553c",
+    "dist/2023-05-30/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "b9dafe965f6ee947b57b70ceb7317d9996ed35c11c761be45194e0415d41fd05",
+    "dist/2023-05-30/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "32226b19d7d6d46a99c7ca1b4d20e4228071ea9062bea564083633a2723c495e",
+    "dist/2023-05-30/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "69f8b8dccd7bce10f5c753b0e41f46ba6f29b32499a7b1e16ddcdfd9a592b5fa",
+    "dist/2023-05-30/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "95e7e39eef157e060dda4ed8613a78d1eba5065a1a8189d887a81a12ab432d27",
+    "dist/2023-05-30/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "613a81e9fec3814e4e5467dbcff0bb83e29b450733c4b36d8442fd2e8c5dc24a",
+    "dist/2023-05-30/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "2983b7fb28441408b53a49aeb3a7089c555460c31bb91b0a11d17f448c677de8",
+    "dist/2023-05-30/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "e63195ba700e4ab778e772ca935c4d3e42ce18474f3180226d254b0874cb65f9",
+    "dist/2023-05-30/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "eaaba4a4c35cdf30ba6225f652415312cf8d8a1d7edd2e4216f2379099b6d8c8",
+    "dist/2023-05-30/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "22c14003af58c489f07e52419edd2cfd50d8e2ed147a25f648855629d9f56478",
+    "dist/2023-05-30/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "2e513a599b7779dc37367e8ee28943b1568c296ba2b2e697f22b6cfabbb062c8",
+    "dist/2023-05-30/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "eb75f2008324c4956cc14989692904c20f412a30311a82f2a085516706f9e2a3",
+    "dist/2023-05-30/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "5cfe6a533005c70aaf14f86cdba51245272b0cb2c04a74a03da69744b18d40b8",
+    "dist/2023-05-30/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "b37acb2fca2ec79e72f9ed5b87eba157a629ca1e3fa044d0caf6fd665451d09b",
+    "dist/2023-05-30/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "cd590ac88ea46e6f347c1d433a3ffd661c4766504eae7197d06de69f3303ff07",
+    "dist/2023-05-30/cargo-beta-x86_64-apple-darwin.tar.gz": "a8db5d95e0d8ab4cfe323165abd423d17e1545d1b99bb2e8bf4b197ca2471e84",
+    "dist/2023-05-30/cargo-beta-x86_64-apple-darwin.tar.xz": "95ceb8066879807752f9f7a70aeb2e9d08991659f49d64249b04c2b1ea545ac6",
+    "dist/2023-05-30/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "2971558e43ee1e6a8c6ce5277b902a537d7f6d31ce714702e89efc468cf8dfde",
+    "dist/2023-05-30/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "6ad42cca05e6c752424c3725516e24e9b1051e201b3ef0c2e1d8ec2e44973717",
+    "dist/2023-05-30/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "c5f0cf8ebd206dfc39c0c889ae8670a6b6b2fb55cdbfeee3ba8b2ec72daf6135",
+    "dist/2023-05-30/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "90d13c515e737193858f48901d8f150c5528a09e2a1c8a08987140f2ad8fbc03",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-freebsd.tar.gz": "a183226ff05ac8d16baf03c81a9281f42e1de5a0b270b1592ba785397e4d32da",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-freebsd.tar.xz": "96984a716ac37b2888181b00939c975a544cdf21a0dc1db5bcd5b4468e28eeab",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-illumos.tar.gz": "997cc3167983b80bbd8d323a61d718022ff0fd9827299379166e7240b0fbb2ff",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-illumos.tar.xz": "6f1c276cfc53f17cae1e1fdf372275a39c60a3d4c543dbed553222557707c6e9",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "a5075bdb4ca1b4a5b5cc734a131277967a5a34c9915afa52e3275da60e87993b",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "417b88bae9f028c94ee0563baf421abf8a18ceffe35d731ad9736f71d6a1b34b",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "495b66a5e9dd3987c02f004eb8e3515b84dc132b274e726df36359cc9974f4a9",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "faeb090c8e1d15b20c256eb7b326de2375812ffc7984e8c11e28a0add3fddec5",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-netbsd.tar.gz": "adc9720e065861ff8aeeec8ffdc231161755e603301521982f6ef405d2d12c95",
+    "dist/2023-05-30/cargo-beta-x86_64-unknown-netbsd.tar.xz": "2def53546856b6cce7ddfce00329fe05be0f649f0b8421168fbab85d9c23715d",
+    "dist/2023-05-30/rust-std-beta-aarch64-apple-darwin.tar.gz": "ebd92098d173efea06a3e2d2edec299483fc77925427417e182800567ff6d642",
+    "dist/2023-05-30/rust-std-beta-aarch64-apple-darwin.tar.xz": "028c6269d40f8adf897b5e6b61387ce49cb1c2c82244965d48efa68ca71d74e1",
+    "dist/2023-05-30/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "ea5654c6a23488e56c0b1c8c8c655c449bcadc9c3676db9ff37ef3fe742c4f9e",
+    "dist/2023-05-30/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "9b0542cd5aa8ab4df51e41800e99563a8a3d6a202d32008a9166ba29d40c7ce5",
+    "dist/2023-05-30/rust-std-beta-aarch64-apple-ios.tar.gz": "ff1bd99fa25176ccb5fe5ef9dca6bf902094c6b6f2ba1985481c1a0fb58cbc7d",
+    "dist/2023-05-30/rust-std-beta-aarch64-apple-ios.tar.xz": "3009eb898a50aebf7fda060b5abf1098271061431f732542e2d1e2bd98e17f60",
+    "dist/2023-05-30/rust-std-beta-aarch64-linux-android.tar.gz": "15ee7baf5a04c9651abc176b3d6679104a395c128724256aadaaf1174d76dbab",
+    "dist/2023-05-30/rust-std-beta-aarch64-linux-android.tar.xz": "93ffc5e6252ba061966338ebae85c1addea410cb1c6cc34936c86376a4ae264b",
+    "dist/2023-05-30/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "c13e9ef9c5c2088f7b7d111861bc1c6e11b2e2e26e5e43f44fcdb1629f1a5183",
+    "dist/2023-05-30/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "e19e125a06f6c1cfe719cc2c1e1925609c315c368e95fd32d75ace3f1dfdad32",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "2d8e20471633b28d5fac2f443ddfce59f84c49e87065f6538924c4484054aa85",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "bec968d53659373451860525922b6833204e0e61efa192739d59fe64fc8fd8e1",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "4092203bfab27e32bd3fe2254cb91cd70d332a613a1d2286fbe985036c6f96ea",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "a288efac80a2692858669537daa6b2657470dc4124541654a22d9ff415ad0389",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "d4e1d2ccec8e8ff63f77ea678864d2ec569da5c8a7ae625b820827fd5b4bc193",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "a14a29b6d213a1e744d7e9273c674cc97de9266764ecdb62ec1b9ab7dc2c81be",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "cc8facb1c53ee1cf734933fb997c3eee57a6a0ac2fec8af571e01ad01c09e023",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "d84cac6b97e396bcb64f2c794f0b2ebe73217a07a46e2a85a8b6ce73ebf279ce",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-none.tar.gz": "e119575ce29c103ca82134e216ae3a77b01252ca7348212bab36ccb5d785e6b0",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-none.tar.xz": "21472aa2b47a16e479f8759bbd206090169586fb29ab0f976b47fc7bc62c81b8",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-uefi.tar.gz": "699727b60d15a4386659c8679aa612455b4a57fbd0901172d7daa7fc5ca253a7",
+    "dist/2023-05-30/rust-std-beta-aarch64-unknown-uefi.tar.xz": "95949ba372aa947c1bac030805af76644a99d6098442054bada9278b5c8f0722",
+    "dist/2023-05-30/rust-std-beta-arm-linux-androideabi.tar.gz": "765a7f836bff1ed7b10816a0ace2cdeb0b9aa383fbaa90fd0fba203093b4255c",
+    "dist/2023-05-30/rust-std-beta-arm-linux-androideabi.tar.xz": "66b909b5a4e6a19f4b45ca5396353437da76a350c994696d25e5b617b54e7df6",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "43f2e2230c405809115bac27ff1b344ec7da7e410728c88092e021688819aa61",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "8eb6821edf96ad1ead828a95513e8ed8deafe1f1697cc965e6e9830175ce41a3",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "7fcc7ccc6d705636bbd37096707358eaeb192179409983a6c3681a2664446ef9",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "506f392a315b45d458111b30bc3d13b266a43ed1890418e8c85e02e9eb0cd284",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "6b42b38873821320ec597ec44767ec03d87068389a61360aa566347506ad2a8e",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "33324c183092e505b77a76a0ea6d0e169838dd76e96a8ad94b142843449ec9e3",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "414e4834f232862cc6b371716f014a7384e23fa4d4997b25ca77ba03ce4acda3",
+    "dist/2023-05-30/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "bf60815516d3dd2d4452de0985dd95a615b905789669dcfe225eb2fa6b26c3d8",
+    "dist/2023-05-30/rust-std-beta-armebv7r-none-eabi.tar.gz": "132fa87ff6c7d9a94871edbc2a9634f96bf16ea46b04978680ea25855530b9ab",
+    "dist/2023-05-30/rust-std-beta-armebv7r-none-eabi.tar.xz": "1c2d6404ac467cff3ffb2f440a807b35532d03469730131b53b4ddd9e7f43f57",
+    "dist/2023-05-30/rust-std-beta-armebv7r-none-eabihf.tar.gz": "92c3b59c2cd7324d27edb928292017f27a9e88d12a5e5cc66a851be35481a29a",
+    "dist/2023-05-30/rust-std-beta-armebv7r-none-eabihf.tar.xz": "b545ba9763df61d95faa14e59124fab46d09ae95707e9686f325459140abb950",
+    "dist/2023-05-30/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "2accb0f63c0ffb0aa0db99c05e5eedee369348d2a571df1b87689225cdb61d44",
+    "dist/2023-05-30/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "fae4c7f7549789f51c1ee7037fa6142ec8ace96d8438ed964bf15f9241948fab",
+    "dist/2023-05-30/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "414978972ee622cfaf64dfd4fbe3cb5ec5e2d8436f129a75283d98fadf17f595",
+    "dist/2023-05-30/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "abc1719b2b29ad091a11d9515e633dadb98a665fb209a47e291a490d4e79f6c9",
+    "dist/2023-05-30/rust-std-beta-armv7-linux-androideabi.tar.gz": "c1159cab2a4bbb24e2ab7135d449583dd0e2f1fb329b7420aea69b005c9556a9",
+    "dist/2023-05-30/rust-std-beta-armv7-linux-androideabi.tar.xz": "b37e60b73d802535e2832351a344c3180bfe931cd14a03df5ea8bee8bd2f3f3e",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "65b9809fcda771576c1586c239d5dfaf960c2968e4ba09473f4d304b2684eeb1",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "331788bfc44fdeb49d85ef84591c400b95f7939661a722aaf36728617b86ce6d",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "b932fd571a95f97e9a5dac39c99cfe488f2d29f9e86e9e2821b16df33cabc6a3",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "7427c8103ecb0d0cf3f211f8700f0cf2bf6969e982ff599c20de87027224a814",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "1206cf83b0bdf96bb1fb2c074c4078f99242d6eb273321e8090ed2cedb760c14",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "5f1ac81a4508e6f2fb9b931cb556cb2d45ebe88e90eeeb7c25690a0f9448a0e1",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "a833ab5f38416ee1d94565db936dd0f351ff4313456f6faecf581e07508080e5",
+    "dist/2023-05-30/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "ba7c2dc66a19a960bf4e914cc30f8c40cde435d4da11e4dc44208cb950c67892",
+    "dist/2023-05-30/rust-std-beta-armv7a-none-eabi.tar.gz": "34ca46fc29871e03490d17df73e55f250699204cfb1ea0d72427434212c4f7e6",
+    "dist/2023-05-30/rust-std-beta-armv7a-none-eabi.tar.xz": "d6b58d542f3219e5075794588c2183a7849530b6ea174dd8cdcf1cc289c4c13e",
+    "dist/2023-05-30/rust-std-beta-armv7r-none-eabi.tar.gz": "ff262f5ac8cb94feaccfac8715f6a97a1edbf59e8778add720ec356203e2f9b7",
+    "dist/2023-05-30/rust-std-beta-armv7r-none-eabi.tar.xz": "ae386368da77e529eeb40c1d123bca34b07d65cc359d790949f257a541abdf91",
+    "dist/2023-05-30/rust-std-beta-armv7r-none-eabihf.tar.gz": "26e123410afb4c0aa7c110c12d31ad00b99f6ffc042745de2bca34b86e04c685",
+    "dist/2023-05-30/rust-std-beta-armv7r-none-eabihf.tar.xz": "ce3400eba477600cc4675b7d91366ca80e82ce656b62f83cea532b60248ad7d8",
+    "dist/2023-05-30/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "6874686cdc7e9d1842cf59c1d55570379cd0f3933da55683435b7b36178ca106",
+    "dist/2023-05-30/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "1a8cf6d6d86101c84e456667d9bb9866039b81e833e6b7bdbc227e6af540fccf",
+    "dist/2023-05-30/rust-std-beta-i586-pc-windows-msvc.tar.gz": "7f121cf6edf07b54e731e863d5c3ec92da88e39e88057e96b07f31a1cc16cb8b",
+    "dist/2023-05-30/rust-std-beta-i586-pc-windows-msvc.tar.xz": "a3c8dd03a35b272045fffd57d773064556637241ecd83218c78d9f20c5200b12",
+    "dist/2023-05-30/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "5a3475ae3f6974ff33e7372867e1cfd6c944dab4af52e4daabdd471d270effd0",
+    "dist/2023-05-30/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "4f2c386aa8f2689f88069ac96a88eb72bd56c6f3d3f002e7dd095fba3d0cd8ca",
+    "dist/2023-05-30/rust-std-beta-i586-unknown-linux-musl.tar.gz": "2659f824119c5abff708e1e282915a291989a98eb7710676a24adfe52c851f93",
+    "dist/2023-05-30/rust-std-beta-i586-unknown-linux-musl.tar.xz": "07960cf2f28f52eaf8351573da0e3964481f0cfa5502ab5b5e3ea4ad535dcd6e",
+    "dist/2023-05-30/rust-std-beta-i686-linux-android.tar.gz": "ef4eea9c214eea6a4d1425fcee382f0553a66d6d17ce33c3949d7df24e76d1d8",
+    "dist/2023-05-30/rust-std-beta-i686-linux-android.tar.xz": "3e54d56aab895defcab4c31d7fa0ed731387fae0a5df4ed56511173a20f4ab9b",
+    "dist/2023-05-30/rust-std-beta-i686-pc-windows-gnu.tar.gz": "92b09c74bc552e01f68d0090316287026340c92bd8804cffd5d2bbbe44124822",
+    "dist/2023-05-30/rust-std-beta-i686-pc-windows-gnu.tar.xz": "2f96ceb5fed911b830553e354bcc47cc6f1983e22a4b1227e61983308e184457",
+    "dist/2023-05-30/rust-std-beta-i686-pc-windows-msvc.tar.gz": "2251b6cdd4d9d7cd2990efa1641e93ca8fb51e7228eb95305a468e61c4a53d3e",
+    "dist/2023-05-30/rust-std-beta-i686-pc-windows-msvc.tar.xz": "e4c00779bea04c7e5a2f859900325355d64e9ef6cfbc452a3a8e5fd20b440518",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-freebsd.tar.gz": "b731321a1a2beddb2d64009e77b883d97e679bcca8ae454e9e5b33a72461c220",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-freebsd.tar.xz": "2d99b9633fb37ad1f017539f65dbea5644b6d85a44e657a48f71766b306cc172",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "1782c79086dff3dc53d15894a6c3bec8dd87f457fab73c472c302eded6258d10",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "8eb6afcc2fe17a383212f24e09db66ce37e0662925039f87a47bb50f44d4b671",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-linux-musl.tar.gz": "4890d5adbee68aaac44e23b84487a4db6a602438d14b046bca23193273130485",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-linux-musl.tar.xz": "9b00cdfc7890ca8a169556b2af8b690f59a17b49f44669a64fb0a27e42ba45a2",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-uefi.tar.gz": "f672aa10394ec1f4998a29fd4e871d5da4057de5a67ef1e88e99fbf044485572",
+    "dist/2023-05-30/rust-std-beta-i686-unknown-uefi.tar.xz": "5da375bff19cbd2b6c550514b5452005cb1cb19c29f41e3efbe1652b367ee9ee",
+    "dist/2023-05-30/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "e52febf6ff0bead6c72efdf5afbda8951a8a52ec87980fe42179d624b21b51fc",
+    "dist/2023-05-30/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "a1b218f627223d60c231441752ae1696612471e90a3367a471ffe367309ec4e3",
+    "dist/2023-05-30/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "1cade6c46209e8cf605794d18c6c8a2d0cdfd81b154802f0e916f5b59688f77e",
+    "dist/2023-05-30/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "98cbb0c41f140acea077cae5145a28153f0d5f06e6009cad73064365d3bc373b",
+    "dist/2023-05-30/rust-std-beta-mips-unknown-linux-musl.tar.gz": "cfaedf4168ab803720bccf508ff04fef073d5b73ab6d9a27aaa5473edfe85b2a",
+    "dist/2023-05-30/rust-std-beta-mips-unknown-linux-musl.tar.xz": "7a9b2ab5dd58f61c1656081d0606ab60fade1e3f7c2d91d40b6dbb8255359df1",
+    "dist/2023-05-30/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "670990fab0d668344d8b0b67a7613415c1fe596f73b2bc800e2f8acefed5a447",
+    "dist/2023-05-30/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "3fd409a760598d6b830f4469c474a2d50e0332886f5e90bd6d80960cb593f948",
+    "dist/2023-05-30/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "2d583489021ea04e11a1c19743c29f77622cb95102122d16cbc77d24d6e6de8c",
+    "dist/2023-05-30/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "4a340a6d2292256b2f370931b74490afc07570c58f95a5a97be6840c6a426e3e",
+    "dist/2023-05-30/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "7a19789581b82f31c90a83d604a2894e82ce309b26598b0acb028f8ba749aa39",
+    "dist/2023-05-30/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "2507a916346c53dd44dc590334630eacd5b4c5a57a240a936203a73b4e96d507",
+    "dist/2023-05-30/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "4b676b406389acc80c61fe89dbf4f8439436c8ef5f2e4a7f36202a9a48ddd487",
+    "dist/2023-05-30/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "83ad872a06bd1cace948d542e1a69210f550abe536d74b0dbf036cc02d7c05a1",
+    "dist/2023-05-30/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "31bc6097eec7ac51e5e923199aec47fb129f34dc472b3ba3d2398c4481aaf12b",
+    "dist/2023-05-30/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "68bffca2afe433a435e8712174efbd61b628e5dacdbf151713f7b43c67804e57",
+    "dist/2023-05-30/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "34520ba878f3ab24d86f965d7470292df65deed971d1a3f1b078c3e4b353ead3",
+    "dist/2023-05-30/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "8ef5dffe7ed584ea59a8d1114f15d1eeb2bd598239fb3d2bc3efbbbe3da36c44",
+    "dist/2023-05-30/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "2297e2cb62b5d1085318d19334f55277e547b0d7bed86a29f60859f5e029d259",
+    "dist/2023-05-30/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "3f012c0cc6c7adad8e08f40c697c0248938103e5a1949c07d1139ef3d5a8cf9d",
+    "dist/2023-05-30/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "8438185ba380e24cdae232aad740e9cc580e2bc4eb4b4aacc006a66e3b846ea0",
+    "dist/2023-05-30/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "c751381d33ada7720f3aa10a242a26055806e56cfbc2348c2f21fb2b767f46df",
+    "dist/2023-05-30/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "1923978ae0a1130fea64fa35ef3aa9c5808b8d8a4af89cd78e0a3edf448404b9",
+    "dist/2023-05-30/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "36481e7b876977c357c1171d2bf4641f55ca7df70288c5aae0e94bd37380928d",
+    "dist/2023-05-30/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "965b9ee397d3ae5fe783c89e9b587dfbef1d3a572ad1503dfa997cb0016444ec",
+    "dist/2023-05-30/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "5963b85d5e8e41d86fd6447ad99ba0a3b36d07657c935fbd810c259d1bb6ccc1",
+    "dist/2023-05-30/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "c38b5bce61132789809aaed43151739ccde285186d42882f411610170ab3bded",
+    "dist/2023-05-30/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "973389204e68468825084d29934c6d89ef3215563402cad62d0630764e0f7adf",
+    "dist/2023-05-30/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "39153c0171d86611ebfe77f0cd2d26ae9a432910778b86163fcd29ef633ce8a3",
+    "dist/2023-05-30/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "1f90107007322dd3167c0a11bf50ab3c939f52fee06ac8cf737891cef7be030e",
+    "dist/2023-05-30/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "ea75cc8c20192334d3f22719fcd67343d64c04a64cb1750f2182548b34643368",
+    "dist/2023-05-30/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "2c48229fa6c41d68535590f8993c0dc45325d890fadad0c6ebcc7a0afa1c77a4",
+    "dist/2023-05-30/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "041dd4a64a699968a487c22893c11ef0944b6e920cdd23f2c904e3cfd847700b",
+    "dist/2023-05-30/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "6a5558581221b88a4e99ba3231bb0c35445537b1e0f1f0b6e02345297df9f1ee",
+    "dist/2023-05-30/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "08830dfee466dd7e295489c2ab2b954e4d88001f851a5c96ed19de158c594490",
+    "dist/2023-05-30/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "2a0bd37a0250ecaebe522df54201dd0b70fadcac9df01dfd70f681fa27385627",
+    "dist/2023-05-30/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "b7c82cdf881d8d5052e365cbeb1966bc4c59627692619642617d4cf9fc8dd02d",
+    "dist/2023-05-30/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "da29b033566bb1f97a98851fba1b41818d4a3a41d65713e4f1644e0ff43e0ef0",
+    "dist/2023-05-30/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "731fdf689c118040eb79917fe194a7691f82b5c68246d99496f21fc8d095c6f2",
+    "dist/2023-05-30/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "a7dfdbc15fcf1311b813b0ca8fe07270b28d1b0e7a87bb64663aa3999367430b",
+    "dist/2023-05-30/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "445d91c3240b79d86d48e47f3553a14375932c9751fe4c917357e34890b86830",
+    "dist/2023-05-30/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "6fbcf8e4e09a93216053781c20d2879660cac129d078ed610cb1e6db72d9d59c",
+    "dist/2023-05-30/rust-std-beta-sparcv9-sun-solaris.tar.gz": "e45cece10a961fc046adf7721f920e592bc7c0c5c276bb55bfc6b6c8fb95486e",
+    "dist/2023-05-30/rust-std-beta-sparcv9-sun-solaris.tar.xz": "b3778ff0a994f38133e49a448c091e51fbfe90a3fcf4ddcf209a3b49bd9c1c8f",
+    "dist/2023-05-30/rust-std-beta-thumbv6m-none-eabi.tar.gz": "5625a51ff41dd444d32d653c329139c906edf26e20782765feaf0168b4fce643",
+    "dist/2023-05-30/rust-std-beta-thumbv6m-none-eabi.tar.xz": "4a2ca2f8f99f297fa2b17c423b8c850476fb80a2bd19e6fd914f2efa813e13c1",
+    "dist/2023-05-30/rust-std-beta-thumbv7em-none-eabi.tar.gz": "26189595572717cf9721394f4f604a7c81cc9066813bda81e0eb8508075d4510",
+    "dist/2023-05-30/rust-std-beta-thumbv7em-none-eabi.tar.xz": "f4f88f6a85761207a3c1496ce3cbd87608de99febc74e01ac0851577c33ec248",
+    "dist/2023-05-30/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "246b7f137c982e32d3f80e34c8e26a4ff64072b8f01d012fede280a1c356ec0b",
+    "dist/2023-05-30/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "14904ce77090bacee8727529a2cbefc14ec2ba21a94e90e15b04841e562c7100",
+    "dist/2023-05-30/rust-std-beta-thumbv7m-none-eabi.tar.gz": "d02b075118d4aa29e7a842c95b7f5fb7f438f8d11c8c6ef3059a812993862811",
+    "dist/2023-05-30/rust-std-beta-thumbv7m-none-eabi.tar.xz": "564352083d92236466aaa6742b0df362f6dca5ea30696ab0b7c68da7b2c1ea05",
+    "dist/2023-05-30/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "6f339f2a9491ac5cfee317fbb6539a14b0f1d6cf6cc8ccf1091f3493bd5d3e06",
+    "dist/2023-05-30/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "475593fcb658f7e01610c2aa9cbf76f3db7b1306c6697ea40626ae51dfab3b28",
+    "dist/2023-05-30/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "fdb20a3f739747105e72718b2a2e79a23b2dc603153ad8feca51a4f6791edb22",
+    "dist/2023-05-30/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "ed9fae43e824c70ecf1efde92a45a3c85781b2913597ed0d60e75c7410145968",
+    "dist/2023-05-30/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "68f91796bdc580170716ec00be393c939359657b6f5aeba7c3e88ca0d068f8b9",
+    "dist/2023-05-30/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "2c014f52137862b2e7355812aee142ace2b4770c25dadac8f8e99239d82d7ca3",
+    "dist/2023-05-30/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "d2b691c5a6b11b5489898673e3d69aaaeccd2b97b0856421b1aa5c91fd48c5af",
+    "dist/2023-05-30/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "ff61566f1d84d80c0263d58cb4016201e2694278bcd9233ca2cafd19c47fc61c",
+    "dist/2023-05-30/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "04c29db24b00c9e377f22266ad0bdb3126febfb39a35f83143ec7e2e052cf7c2",
+    "dist/2023-05-30/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "651a8fb666a1412bffe84d39e92e01ba3fea6687d92f90ba0e3a4bdfbcea8dc0",
+    "dist/2023-05-30/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "f4ea3e81bbaa7e6569c18e0f111aeca8a5cbf565403f7c0fa9c2da0858ee9548",
+    "dist/2023-05-30/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "14ac309023a66949fbd3110eb7f53035abb54f79711e848f382e2953a702eb5b",
+    "dist/2023-05-30/rust-std-beta-wasm32-unknown-unknown.tar.gz": "4bc81b56c91e6771154d30cdae66c8f09d5c1e47ead91e59a1d98c9c7f2eefa8",
+    "dist/2023-05-30/rust-std-beta-wasm32-unknown-unknown.tar.xz": "b32619fbbdd47c901c41f385b3a6c1766f5439d8f6fef36409e1a8ba4ad5d847",
+    "dist/2023-05-30/rust-std-beta-wasm32-wasi.tar.gz": "c505c26f333208c5b38229b4fcf60621748303ff23193254e321386348328afb",
+    "dist/2023-05-30/rust-std-beta-wasm32-wasi.tar.xz": "f2b675fc1f95c5c3cfc78e10ad9b1322d920d429ae98b47580b7a1a7536dbba1",
+    "dist/2023-05-30/rust-std-beta-x86_64-apple-darwin.tar.gz": "e58d900bf9a1fde7867470c2c87b41c8ba8cdcef6b9653899c53d21f7b16d43a",
+    "dist/2023-05-30/rust-std-beta-x86_64-apple-darwin.tar.xz": "4cf95d2f670c00906e89ed8539bc90a45f0398bae84916409a26ceedfbd5b9ad",
+    "dist/2023-05-30/rust-std-beta-x86_64-apple-ios.tar.gz": "a5f8ab9c9d2d4a71aacf2221e06494bbc0ff9076d3c7dadbd0d4473f6e900c79",
+    "dist/2023-05-30/rust-std-beta-x86_64-apple-ios.tar.xz": "b3d6b2795c0d50aa8f1665579f1e3a1e056071cd50f4a464863608739c8fa62b",
+    "dist/2023-05-30/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "08157017fa1d7a64078a7b2a3e7662b0f76174de3bbd1ca80bed40ec5dcb7407",
+    "dist/2023-05-30/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "0588ec9de11c46a0cb705690e2182fe5acfd0d33e71f29dde9798f9025c137e0",
+    "dist/2023-05-30/rust-std-beta-x86_64-linux-android.tar.gz": "9aa164600f3adfdcf369b23e69f9f5c81757f21b9fef1419bc06d2b9474e4120",
+    "dist/2023-05-30/rust-std-beta-x86_64-linux-android.tar.xz": "635c8d4edf68790079eacac7d5754fe7ab431787dd01ebec7184c03e65e78c4a",
+    "dist/2023-05-30/rust-std-beta-x86_64-pc-solaris.tar.gz": "622e359c4178cf626fe63f95164915ec4289c5898851a9282da9780b847e8414",
+    "dist/2023-05-30/rust-std-beta-x86_64-pc-solaris.tar.xz": "ab2b95f4104691d44d455f4e5391b187b712b632cd0ec11baf1d29291814d770",
+    "dist/2023-05-30/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "08f28724ee08b13705911c5c9be7773f8ac935329fa37548b8d46118fc5e244b",
+    "dist/2023-05-30/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "fa3fcd87e50aae6f1893b65b027ae6f705f7c42cba63cebfca1e49dd3c2af966",
+    "dist/2023-05-30/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "c208ad4e8ea70e45b6d76b7a88491a33f30f1415043a26ad96908faefdb37eb7",
+    "dist/2023-05-30/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "afa64e5bccb5138d86349f8564f82dcdcf009e7bd07121d193ead9864f2ca1f5",
+    "dist/2023-05-30/rust-std-beta-x86_64-sun-solaris.tar.gz": "e2d8fa74156623a3cdc944b1e0eb5683b661dbbecd779b5621777413d4918fb4",
+    "dist/2023-05-30/rust-std-beta-x86_64-sun-solaris.tar.xz": "2a75d1d8918febceaaaf8ea4c89827798099ab69063878a71afaef5ae17691bf",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "24cf8f9bad86110308215d52aa9ac3b0dffb8640508e718d14ee9928fc68f59c",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "0babdccec106b4cd20574c9722b36e407a1d028856989ff5e390172876ab3e28",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "0a983d8fe5aa649452f93cf4566d59b091d79da1e325f2da6b0844ef842f7a7c",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "7bf8fa91b5ecce8744e29a47740f52a57c8faf1fa4e125736103890189cc23b9",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-illumos.tar.gz": "f90b0c2fb060f84b53052852478b474d587f8c51ff1750df5922f2ea8b66fe2f",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-illumos.tar.xz": "6075598069ed92e26615e49bdc6f8c571d7f194462588b941f5479b0ab137994",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "8c9a48ec0db55f07200bc73b292a5ee7a603b6b924eb4a1044609d854e820554",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "0bcda45a340128c3e69ec0d10b08ea11edd764870e5a8fcd741a42949a025325",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "0f8b6583c8dc192253c480aee8c743013758b7ddfacb08e957c57d1feabd5824",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "a8086bb72e9ce9b9013dac6ea159fc15147a4d1658b5e11d9910f1486828796e",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f801f8382e5439a98115c0ce8a1ead8acc983f01a09bb4c6ec3add9324f16334",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "69cb7620f271d64db234166fc9db37f4b5d60b6f4b9da43d02d21baa31c5da67",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "2cf6c1f646286ecf2fe0a0e8f7eb079e7402dddb556273bc2d12be61b5ee6341",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "0a4845f220640f00b3e0a1d0957050e0c7258867f6f8d6e174277d3659214d46",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-none.tar.gz": "9a1fb11c9a5264232ba1ad2d3c89d1dfb9c135d000b812135932521932ba1b86",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-none.tar.xz": "5598a18d71f1c82e796c136ba4d09b38e24e201ca199752959f0eb094cc49c30",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-redox.tar.gz": "6ec43ffac6b70a67e08308d4869334131025c9acb0e2036a072e9e594ec46acd",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-redox.tar.xz": "eb801580d8ea50d2f7a9a9d78d9a3c10bd3596c84740b3c8b610a86157942b50",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-uefi.tar.gz": "051700f1977665f3b8119af984ece787ed84838d0ae0443bfd475d91d76f1202",
+    "dist/2023-05-30/rust-std-beta-x86_64-unknown-uefi.tar.xz": "1db1d6eff963a7d1667d1f5542de5484105d39436c0c502044222d7f749299ea",
+    "dist/2023-05-30/rustc-beta-aarch64-apple-darwin.tar.gz": "63ec87aa7b1d457171503247004d7d046dd951992ae175423986c55f7f44aaeb",
+    "dist/2023-05-30/rustc-beta-aarch64-apple-darwin.tar.xz": "aea483c5546a038aa6381cd458f9c43d5e2e5365f3d3a296ccd3e96f90bd3fdd",
+    "dist/2023-05-30/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "35e4e8c6099820f63e46ae916d9c8aa3178164856a3cde479634f0837860bf3d",
+    "dist/2023-05-30/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "7232af5edf68a4d93ba7a065f2cef5b36f43d6dae76c8141c4624dd25ac17230",
+    "dist/2023-05-30/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "c08cd6ee05e23bf777c47f8eb4a66feeb85b88175360720737d96789a82906d5",
+    "dist/2023-05-30/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "025108e1db08c5f908e36f7cc5965175a008561cefbddf313501fed7bf583a44",
+    "dist/2023-05-30/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "d41cec2d6001c6dc8079f4cae54c720a10288c86f6cd8e1cd362df9688ddd975",
+    "dist/2023-05-30/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "81ca14bd6bd18958c9c9dc27e32dabd2a2076120d860721663fbc7339d096986",
+    "dist/2023-05-30/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "260fc42ec007adac4e885feb978f32e2624f30a87f4d91c929c3932be0dbe53c",
+    "dist/2023-05-30/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "f4b3455e84d6174a3950410cb25e753d82332ce696f9be606e6b454c279034e1",
+    "dist/2023-05-30/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "9f9447025db2233c4d97d92b35eae50b02db262c6b41898fa73599c245fef3e8",
+    "dist/2023-05-30/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "0db7a3acc6c06a41ebe93b35c62f55dc8f2526fb41e1fe546fea7746505c37a1",
+    "dist/2023-05-30/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "843cbc007c36850a40f4e5f0b186b2b8bf84f74385272cc2dd3e748ecfd92181",
+    "dist/2023-05-30/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "d56d7f0be082fe314eb85640779600fb3b74bc0f3d412a4d2c26d40671d0b116",
+    "dist/2023-05-30/rustc-beta-i686-pc-windows-gnu.tar.gz": "e2f140b4f0682fd4725862daefde019e58b3033ce1d967ec2d75a578871a36ec",
+    "dist/2023-05-30/rustc-beta-i686-pc-windows-gnu.tar.xz": "2424c4a395970e4570bd9c76396986ab68b3b81de91abc9ebe9c723b6c076d8f",
+    "dist/2023-05-30/rustc-beta-i686-pc-windows-msvc.tar.gz": "401c558d7866ad3583ab2e193bf804cff46e465d8584e6b857748edb4ef6e9e3",
+    "dist/2023-05-30/rustc-beta-i686-pc-windows-msvc.tar.xz": "ff328d754f1219ce9cdc2208d4f0feeaf88a2f1eb10cb65217ad26132ecfa67a",
+    "dist/2023-05-30/rustc-beta-i686-unknown-linux-gnu.tar.gz": "04daee6f6de28ba19ad4a0bfb83e13833e436ef381f322b4442776df885c320c",
+    "dist/2023-05-30/rustc-beta-i686-unknown-linux-gnu.tar.xz": "9ea5210272aba4d012cf195e9b36756987962700cc16911de6b17455f4fec37b",
+    "dist/2023-05-30/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "fb3a38a21abc89987606fcf970a748ec007b4eac2a780c9bfc78a24855dd5068",
+    "dist/2023-05-30/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "be03d9685ef05f5f0a5c4d2f5d1abbb4168703641c47bf449b8cead28c660b36",
+    "dist/2023-05-30/rustc-beta-mips-unknown-linux-gnu.tar.gz": "51f8f6efcfc6c09e41fb1c7bf49316650aa6fc4fba6765e9eb0f0da218a327ae",
+    "dist/2023-05-30/rustc-beta-mips-unknown-linux-gnu.tar.xz": "724ac99cebbc5dfa8e5ca2d9f32c0611f0df035b9dcd79861d9c8b6151f36d17",
+    "dist/2023-05-30/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "897e21ad58b01784523a18eb3e96286b956c3d62c3f8876f9831dc22543fa0f1",
+    "dist/2023-05-30/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "fc72123993f195910034bbc99c8099b473f77ed15345b2a2cc45669680a157b1",
+    "dist/2023-05-30/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "be642818250e94732c1f989568ea96a35befdf3be8ef5a8136de40880b9a86bf",
+    "dist/2023-05-30/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "fdb42ce19f669f5a38021abb3d88edacf0d6220dd18521aa0427f683ec1ef003",
+    "dist/2023-05-30/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "47540dea37ba2885dcf8ab3456ac0e0bd193f3b40f81ea425e6acf2559a573a5",
+    "dist/2023-05-30/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "dacbb89acdf4fc587e2cccde96b14c113637f6691c1f5857322dd98b148b442f",
+    "dist/2023-05-30/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "7cf4ab6c270bea85e065b26883350173f703e266ae865e753ea45ec53775e042",
+    "dist/2023-05-30/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "4e06df0b3820503d92a4ef4782cdea2ed95b60ac4efa75e1736b8dcf360e865e",
+    "dist/2023-05-30/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "50e5879a296bd61545d0ed2558a28e328ad9eef6df906ec8a6ab17e98c4fc053",
+    "dist/2023-05-30/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "76e3e8028b6c03ece804984d3df4baf995cd09e50bebacf038fe389133f77f25",
+    "dist/2023-05-30/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "45070a86b9efe5a885c67dbb089a219aa7adb5b9ae7a37d115a37f75833ee598",
+    "dist/2023-05-30/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "02e957f9078c32d0504e15a688cefd50850428b0dad4f748a55ccba2a738c826",
+    "dist/2023-05-30/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "2ee8579fc0acd71b7a0ec40efecd7bd298e24c0453821c85d502e7eff4820ea1",
+    "dist/2023-05-30/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "758e35e9a4f1fcda8cd110cae717542768acf9f7cfef38bf8d75480b2b2e25db",
+    "dist/2023-05-30/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "d3c0fbd03833f28500403d8f7f196989fa83a0c493c7c74d435c1c201912ecea",
+    "dist/2023-05-30/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "d2a8e1690a1420dc3f55d43d7b190cda605f46a82882990e74157b98793e4fed",
+    "dist/2023-05-30/rustc-beta-x86_64-apple-darwin.tar.gz": "6f3d3069dc85d3d7e533904f79ebfa00e2276896ba469b75461c833aa3a1ac7a",
+    "dist/2023-05-30/rustc-beta-x86_64-apple-darwin.tar.xz": "b6e3b9eb821f861eb3c9f5687595fb9a8007f09b230f8eb38223903783658632",
+    "dist/2023-05-30/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "cad6269683cc3b08ae9c0dff61ea9cee963d0654aaf60caaa4294fd8592a08a8",
+    "dist/2023-05-30/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "b4cc887327b822c0dc5efb5c14e7f0d4539860f75f2af5f24755479db84b436b",
+    "dist/2023-05-30/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "f6c7cb74987f13219e62389f99a409e998a340ffdd37e59b990fa5a2209d0fd5",
+    "dist/2023-05-30/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "06b3fc13a7a0b938026bddbd08babb5c005f6ece5384aadf265710983243d561",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-freebsd.tar.gz": "635dfded9a7f4637af3ba390906f48f01ae1b426658bd7a7e8276db38c77fb3a",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-freebsd.tar.xz": "f385fe29efd16b08d8f0a7c71450a7880d640992d762f941468ecf57d6d6cd35",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-illumos.tar.gz": "832780952af4ff0b23b52e0654a68e314354b3a7ad6594aede927956172857d2",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-illumos.tar.xz": "262c369de160013c9a226fbeb3f2f351355ac76c7aec3dc9c4e3b85bdee7259f",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "08ec1e016baa2772f97dc4f51bad2fba9a31f4e78435ae62d0dc19751a1d79e3",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "6708643e5941765593ab043de8ebde6488473ea870ba863a3192e1a738b17ae2",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "64cadba75ace2843303aba0c71dc1dfe27a7fe5bcf6dcbd0ba852b6b4b09eac8",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "8357a30ac45ad29724adb68db201f05b9257de0712ffef2562ae9bbc7e2376e5",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-netbsd.tar.gz": "fb7e20647326cd2a9672d58c37f3e140c0072877f3d0a7fdfa3f728c0e1763e4",
+    "dist/2023-05-30/rustc-beta-x86_64-unknown-netbsd.tar.xz": "6eafb794492243f1a5698f3516f5c5813a9b4014693e46d2fcc6a20de7d3a58e",
+    "dist/2023-05-30/rustc-nightly-aarch64-apple-darwin.tar.gz": "237b8472a6b69ad9a3d07f28a4c8db5558774777d5f049e73f3ee47daf0ba8ff",
+    "dist/2023-05-30/rustc-nightly-aarch64-apple-darwin.tar.xz": "2bdb744db0e37fe83763742b4fdc8d8892a46a25620485cf3ef0241278aca7cc",
+    "dist/2023-05-30/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "ed67050963449f6f2ef9e64de33281cf689511aee424f345941793fcccbd9197",
+    "dist/2023-05-30/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "b90717f1d715a4488cfb95036521f21fbcf5b9f0b1c488ef44ac7854acfc9210",
+    "dist/2023-05-30/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "cc459d7779d32fcf51f24fc365806446bf4f3c2b4614e59181dd0696eab48f01",
+    "dist/2023-05-30/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "e2420872b825bd3930c426b9fd876ef1660aa7558e661175c03f5b07c1f91208",
+    "dist/2023-05-30/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "e1f1b869afa2554b2ae4981eaccf35329314161c8f427484dfb45852e6dd7e66",
+    "dist/2023-05-30/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "9f0813f8fa69d2422f234fe78c3672cf229dcaeebbd8aad83cc1242b2033c012",
+    "dist/2023-05-30/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "91a0bec37e3660f14be05799c4ff5241e7b0baee6d38bcc6aba446209b984d37",
+    "dist/2023-05-30/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "fe2798b1d67928cb05525faa420241fddacf828a6ecd07ef6374605bbb6eb07a",
+    "dist/2023-05-30/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "3906c8a388e57687d1bf13dcc6e22a51bc1af46bcc6731215477b80a446129fe",
+    "dist/2023-05-30/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b1f20ad4a1ea551e5e34aeb6a159e66da03bfb6a2814e0a1f44c1676b579361c",
+    "dist/2023-05-30/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "69c08682db15fd941c843950811b0f367854a5f6bfeff17a810f5b2536063e2b",
+    "dist/2023-05-30/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "3fa01eb5238dcde32a33183d2022f8f81eb8bdfc29af837e581ccac796add69f",
+    "dist/2023-05-30/rustc-nightly-i686-pc-windows-gnu.tar.gz": "71af89dd66588905acc5491f837da118570180176a6f6d485e3f5585cfa308b6",
+    "dist/2023-05-30/rustc-nightly-i686-pc-windows-gnu.tar.xz": "790ba712d9b4adcc6ae5d3735386909e942ea570152a10ab4b460de5df04a7d8",
+    "dist/2023-05-30/rustc-nightly-i686-pc-windows-msvc.tar.gz": "211744f84b1e1f184b3c868c971967d0af434135dbf5445826c4a291b67ba890",
+    "dist/2023-05-30/rustc-nightly-i686-pc-windows-msvc.tar.xz": "bf3699f00cdfa130563e524513bf5b227ebf67f5807c1206bc642e69b6acd515",
+    "dist/2023-05-30/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "0a16de5d417bd0c2d548e9389615137dbca6ec0c9f77c48e57af5cecc446fd6e",
+    "dist/2023-05-30/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "a621cec29e1199050f533c671949164fe608ce1a2639645dec09f7c3a662afa0",
+    "dist/2023-05-30/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "4e9dd9734ebf981cbbc116b0dc29ab69957e8ee746aa25f71abc33553db2dc6b",
+    "dist/2023-05-30/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "78b5580e81ee5b5f327be718fd09bd0711271a8bba52efff1cd4ce68c4f5cd4f",
+    "dist/2023-05-30/rustc-nightly-mips-unknown-linux-gnu.tar.gz": "889308ffa2f866dc34327c0f20195e33a3c1e8124a19635918b0a8e5220ea56d",
+    "dist/2023-05-30/rustc-nightly-mips-unknown-linux-gnu.tar.xz": "74da26ff0692a4cb1c84f3cd42c9a8c756cb588eaa40cfbfc6dbc9cbc5f018e9",
+    "dist/2023-05-30/rustc-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "1aec9abde4a1e9e042191b06848d262848c54b448ddba00c9c736207953140b3",
+    "dist/2023-05-30/rustc-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "a046b49cb6ec60ecaa8ed60f6c77b60b3d0cfa76cfd7e48b6b2a808e4d8a8e51",
+    "dist/2023-05-30/rustc-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "e6dfbe2df31c26d0df8ae413f41705039bc41f567dc8f4e81b9e908a61157d08",
+    "dist/2023-05-30/rustc-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "b4285b27d8ee3325ce4cc3755182d159376fbe93aa14d3adfeb06b5fb20ebdce",
+    "dist/2023-05-30/rustc-nightly-mipsel-unknown-linux-gnu.tar.gz": "62de5f6093791c80744267f492a0ba58f998f3e826933a396e21efba7e88ea1d",
+    "dist/2023-05-30/rustc-nightly-mipsel-unknown-linux-gnu.tar.xz": "3240f8ffa7bef40dfb2a19a1029a4b5733403c9cc94bcf7f0a66e0134e2b93fe",
+    "dist/2023-05-30/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "49f9fa5a9d3c07365a29d0dd0ac94df9ef8c7f9713724a39ade6040bb1a4a627",
+    "dist/2023-05-30/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "285b2c228c4a37dc6f5ced5c585631e2166b43c0b76bb794139f0aa690013a13",
+    "dist/2023-05-30/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "bcd1c9b4d1efd109bf29b2005f35931b92f9675ced5b71a6dcfb10bac1ed87af",
+    "dist/2023-05-30/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "7f61eef3681bb1bcc285910e596c4e11c62aca0ed1d7eb9de75fa0822ca89ecb",
+    "dist/2023-05-30/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "278473fbd38e2d395257f90bc84010e44ade32cb35a249fa0d32e92c174e9776",
+    "dist/2023-05-30/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "215a805efcfc898e3ae7cfeda427e10d252434175d8eb70613664ac84c1e38ff",
+    "dist/2023-05-30/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "3ba38b376d5c58324221466dddc95ce0917f7bcf6a7cca8c187ff999abd8f74d",
+    "dist/2023-05-30/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "d52cba02774a256db1cd40ef3c9fee10431f8ef9a738553373474bb629d8c108",
+    "dist/2023-05-30/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "4dca59e9d10f07e60bb8f522f4b97c2a8de8e186679bdc8e85a105bfba80c38d",
+    "dist/2023-05-30/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "e0d07c8f2605600d88d901dc2837c01266d28064f57e1ba7a3946a59a249b37d",
+    "dist/2023-05-30/rustc-nightly-x86_64-apple-darwin.tar.gz": "aef9c49ef3496a23567eef639f54131fd54fdedc092d39d89c7da8e41f97b100",
+    "dist/2023-05-30/rustc-nightly-x86_64-apple-darwin.tar.xz": "c78201af204ed99ae67c5f8747a1495b58e6a2b2c92a9290e703553c0fc4820a",
+    "dist/2023-05-30/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "70ff64b7f28be159fec7e518d3787e836c1a7f5a88177742215e46269a29b4aa",
+    "dist/2023-05-30/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "939bf932d60e2d343d4e00bbc48e10eb57755de14729795bd6965cf23eed74f5",
+    "dist/2023-05-30/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "e20748dcca42a84031bf2eae7a61d3b0619c383dca274287824a15c982b42bf3",
+    "dist/2023-05-30/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "4687e53fcbe7487647b876b36efca97f9b83389f35d317a76b601d43edd54c00",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "c662f8f489ec8be2ed2066140a7b40ef92ac393103e2de43a683918ec81c3ab1",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "b350dd8bd95563cf9a422bac6fd4ac44d21186324a9cda4998e5b676c9646b7e",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-illumos.tar.gz": "18396eaa0c44555bfd550018671a4ca07a2c890e08ab8a6e71e224256f01bc61",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-illumos.tar.xz": "97af9014bdd6b758b7dfaacc868f91c62729ddc70f6b766f78926d46098dc610",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "9bb5775dce7c5659ba983c1581290f3d29cab54e2e28fbeb0a89b076bce24969",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "9a2bf45136801dbb04b2cb6f7db45b731ff38d9f285c55270a2399184a422e5e",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "355e65949a17cb71b582e3a3a51a4a68c25fa1f07c5d02604869d0e1a3e83274",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "afbd2923484621716ff241998b6c4c6c3d7023e00c1f1bf94ac15e3072c15c91",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "d9d79bff98b3a5bd95aab8735a3656c494d2d275afbe313f1d1adececb82f1e0",
+    "dist/2023-05-30/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "a92f1dea5d4f811bd81a297e6b45c5253948956fa835efcbfb3174ca45cbc812",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "59b1ecc2a0cc0dd289f58e14ec8d812cba3906a486b53d991e9d61fb1aace497",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "89c70ea18ce719c8171190cca97b3f5c641999ef54952b4f0f426c05c63af698",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "164378266ab65a8d6464e914ff2dca848d6f044362bc81c38b260e52e1856147",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "b44fdc2708def8e02cf7f39e228c6698c2e0eee217cc02d60ee731859826b544",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "0d34a3f499eb7d2819090c4b923df26462d12f6261327a03a3df61af3346467f",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "add3cde0b9771e78c35f9eae1d91fe1aec94e5b255e3d741c80916dabf23d214",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "95f05d6549a3618e49b1607a04f9814aa55cb393b8c662a67dbd0909b65d9e45",
+    "dist/2023-05-30/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "e4e8ab74aa90355142d16d677452a6b17b99fe2c26c3e7d19541c00d316a9a1c",
+    "dist/2023-05-30/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "891fcd1496565388160c70030f098eae9725423a726d25cb95f81c8a5e9a7fd0",
+    "dist/2023-05-30/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "330afd31d6ef259a73f365bd57c2c8cc27f972f475519b880065ef9bbbef4417",
+    "dist/2023-05-30/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "32087f3a53706c8daeea8ee80afb16e60968cd653404e7ed98322d998b83582d",
+    "dist/2023-05-30/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "e2fe133066904154fa773a4731efbf77d46631413b77beea6ecb8f3617b0dedb",
+    "dist/2023-05-30/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "df28a8a4b90c71b9542f1327d3138d9b13caddd5bd7a3738b09aafa75480f20f",
+    "dist/2023-05-30/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "c9dabd1e26f6c94e3a2162c02bd83cc6c80cf41f075d970480fd8fa6c94f170d",
+    "dist/2023-05-30/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "b3eaa34bc2441a227de9646a1f90480cb934592e919944e2feae31be0d048f1e",
+    "dist/2023-05-30/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "dd3efd26ddf45d4366fa6c6f024e0223329c378887b636be70d89951feeb223d",
+    "dist/2023-05-30/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "50c1f997d3b7b47f0eea36397252646fe97c484345afe3c08938915bf46b1286",
+    "dist/2023-05-30/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "8da362db734f58f99d3616b3a6d0e2e0976f634bc457143fd627993a2a43cd41",
+    "dist/2023-05-30/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "bb6b790c57de3157370ec6dfb3d5c6a3e47d4a7f483d716c04ddeb6a1d370470",
+    "dist/2023-05-30/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "e83bea6b615680a2d1aff31a0302fceefe970d4d801d61c76bb59d61e16235ba",
+    "dist/2023-05-30/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "3c45423d2fee0fb2218e80760910f0f3344f67cb867e746e2bc825f74a4dad35",
+    "dist/2023-05-30/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "c3fbb683e848927b800933799d93ce9f47e3712a650e0b2462830e91fd62ec2d",
+    "dist/2023-05-30/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "f795bf82973e3d6ae90d5bfd17c3a2326dd91c787d5638fd5e0d3091fc2bd738",
+    "dist/2023-05-30/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "404217de3ead2226ba192fc2ee3a9928653272dd1b05774ae735bdf2db9596e0",
+    "dist/2023-05-30/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "f62319f4429680866c6c55c9928f864fcd478dd71b16909186aa9a14d6d4b4e6",
+    "dist/2023-05-30/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "caf648cf2d71b67393ef068715f974f43aa6d80eb6a6040b31d496d64d31b12e",
+    "dist/2023-05-30/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "e11962a76505c523d210bafa0a87e10f09bf28350149a11091222678acef9b2b",
+    "dist/2023-05-30/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "daadb0973b1acded5fbc32ba2aa4974ff25ca2cd90afa5eaecdea51ef55bf154",
+    "dist/2023-05-30/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "c501a1fd769e826eac68ba1bb14feb384236f7d87f5d3fe1d6f2373b0fb3f966",
+    "dist/2023-05-30/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "c1af630b9367b3c93d5bec0a5b4d7c3befa0d3036ca3fdd5d453b04bb74e239c",
+    "dist/2023-05-30/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "cbda874bd604c078fe023a3c4dd480cc537a3dfdf0bc5eb8f55a1e5a21691915",
+    "dist/2023-05-30/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "d795e96e1303d1a0057aabc079b0258a54361bdcf2359b2c096966098e950e57",
+    "dist/2023-05-30/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "5b699b2d9c77548d4ada3847996e0f4cf94446cb553ad9447aca2673e99c4948",
+    "dist/2023-05-30/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "39d7f7df56f1c5a92b41ad2e40ab570bee861006cdf9b93aa11b967906c60828",
+    "dist/2023-05-30/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "c745fd0580669e901d56e81050b6447e4cf7743da32e6ea95607511d9c3201d1",
+    "dist/2023-05-30/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "b360a343cb0f9e36ca9fe03d77047d600a16907416fa1e5c0cb7a4611fc5c3f2",
+    "dist/2023-05-30/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "5a98c28cc95008522ace67fd15a9e5d71b1b969f0ec2410aaadfeda618aed1be",
+    "dist/2023-05-30/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "5197422b4ef7ce51777c020f74a5fb7edc01339fcb9b31bbf9781195639794fa",
+    "dist/2023-05-30/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "6f6acce9edb006b355770f3934eba4c15b10f205164e49c587b6f9e60924ed99",
+    "dist/2023-05-30/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "1e1ebec2d56706f37afaaa23ed940e8953b5207280e83bfd0acce4a149416911",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "c1ea49dac64b7872dd194db925cda89efa596808d993dedacc8be042d529c2de",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "ddf1cd4e32ce497187f79f34edf346f6db31e9d50d2cf1870fc1f2edfbadbcdd",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "cb5d566d5b6dc6f94cd7015ad1d8074edc0fdff67e4099df7adaf0251f729d8d",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "086ef160c92e5c3eaf887b2f28d54562e7916be4758b7b9798019f5aa23f02b1",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "5447f33f134487147df663680741f94e2d58c45495dee33e16052bacf74975de",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "78104f5ecb2ac790c3958a5331316580991c7a03f1258a72b7c43f660f955461",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "e3da153242be44fd656f4bfe33371cf7b874e220698cedac207f14ce790c7a66",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "cc9c83b6dade84d6dcf390701d7cbd2613915d9af68b08e68b9ff1d72e742248",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "e0d3aeb40a6139c56000d5b8a8693aafad105d05ccb8cebb026e383da59baae6",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "96981188f60cf8dc05a6b39788f0348b57d3972961b0a2d0b5759dbfc4c7d345",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "dfed96134506c80e8c503719c7502310b17bee6d3c963764af9dc70c5721795f",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "36fb2a16bba51b765be6c82b57fccc6664699d3e476d7cd3d56c71b80c6f2c78",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "b0ea71d0f3fb18f95fe0801261ff28e9b25ff9078d8cf1c2122ac515841af2ee",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "9f03b6aab46560698e507796541d0c0347c5bffb4fb984ea6c7dc73f479c8d81",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "0c473e1e4cd1b8096e03f10d13f8e640e88a002ec798790c7423074ff49168c8",
+    "dist/2023-05-30/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "6da959be0b1c6d1fb6e56ad88672ee817b8827b8210cefd897e5aca085b2c32d"
   }
 }
diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs
index d3d2323db85..3fa970373b3 100644
--- a/src/tools/build_helper/src/lib.rs
+++ b/src/tools/build_helper/src/lib.rs
@@ -1,2 +1,3 @@
 pub mod ci;
 pub mod git;
+pub mod util;
diff --git a/src/tools/build_helper/src/util.rs b/src/tools/build_helper/src/util.rs
new file mode 100644
index 00000000000..731095023a9
--- /dev/null
+++ b/src/tools/build_helper/src/util.rs
@@ -0,0 +1,41 @@
+use std::process::Command;
+
+/// Invokes `build_helper::util::detail_exit` with `cfg!(test)`
+#[macro_export]
+macro_rules! detail_exit_macro {
+    ($code:expr) => {
+        build_helper::util::detail_exit($code, cfg!(test));
+    };
+}
+
+/// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.)
+/// If `is_test` true and code is an error code, it will cause a panic.
+pub fn detail_exit(code: i32, is_test: bool) -> ! {
+    // if in test and code is an error code, panic with status code provided
+    if is_test {
+        panic!("status code: {}", code);
+    } else {
+        // otherwise,exit with provided status code
+        std::process::exit(code);
+    }
+}
+
+pub fn fail(s: &str) -> ! {
+    eprintln!("\n\n{}\n\n", s);
+    detail_exit(1, cfg!(test));
+}
+
+pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
+    let status = match cmd.status() {
+        Ok(status) => status,
+        Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)),
+    };
+    if !status.success() && print_cmd_on_fail {
+        println!(
+            "\n\ncommand did not execute successfully: {:?}\n\
+             expected success, got: {}\n\n",
+            cmd, status
+        );
+    }
+    status.success()
+}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 64fb38c97ac4d3a327fc9032c862dd28c8833b1
+Subproject f7b95e31642e09c2b6eabb18ed75007dda6677a
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ref_to_mut.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ref_to_mut.rs
deleted file mode 100644
index 15f2f81f407..00000000000
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ref_to_mut.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-use clippy_utils::diagnostics::span_lint;
-use if_chain::if_chain;
-use rustc_hir::{Expr, ExprKind, MutTy, Mutability, TyKind, UnOp};
-use rustc_lint::LateContext;
-use rustc_middle::ty;
-
-use super::CAST_REF_TO_MUT;
-
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
-    if_chain! {
-        if let ExprKind::Unary(UnOp::Deref, e) = &expr.kind;
-        if let ExprKind::Cast(e, t) = &e.kind;
-        if let TyKind::Ptr(MutTy { mutbl: Mutability::Mut, .. }) = t.kind;
-        if let ExprKind::Cast(e, t) = &e.kind;
-        if let TyKind::Ptr(MutTy { mutbl: Mutability::Not, .. }) = t.kind;
-        if let ty::Ref(..) = cx.typeck_results().node_type(e.hir_id).kind();
-        then {
-            span_lint(
-                cx,
-                CAST_REF_TO_MUT,
-                expr.span,
-                "casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`",
-            );
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index cfeb75eed3b..0c175372aab 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -9,7 +9,6 @@ mod cast_possible_truncation;
 mod cast_possible_wrap;
 mod cast_precision_loss;
 mod cast_ptr_alignment;
-mod cast_ref_to_mut;
 mod cast_sign_loss;
 mod cast_slice_different_sizes;
 mod cast_slice_from_raw_parts;
@@ -332,41 +331,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for casts of `&T` to `&mut T` anywhere in the code.
-    ///
-    /// ### Why is this bad?
-    /// It’s basically guaranteed to be undefined behavior.
-    /// `UnsafeCell` is the only way to obtain aliasable data that is considered
-    /// mutable.
-    ///
-    /// ### Example
-    /// ```rust,ignore
-    /// fn x(r: &i32) {
-    ///     unsafe {
-    ///         *(r as *const _ as *mut _) += 1;
-    ///     }
-    /// }
-    /// ```
-    ///
-    /// Instead consider using interior mutability types.
-    ///
-    /// ```rust
-    /// use std::cell::UnsafeCell;
-    ///
-    /// fn x(r: &UnsafeCell<i32>) {
-    ///     unsafe {
-    ///         *r.get() += 1;
-    ///     }
-    /// }
-    /// ```
-    #[clippy::version = "1.33.0"]
-    pub CAST_REF_TO_MUT,
-    correctness,
-    "a cast of reference to a mutable pointer"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks for expressions where a character literal is cast
     /// to `u8` and suggests using a byte literal instead.
     ///
@@ -680,7 +644,6 @@ impl_lint_pass!(Casts => [
     CAST_POSSIBLE_TRUNCATION,
     CAST_POSSIBLE_WRAP,
     CAST_LOSSLESS,
-    CAST_REF_TO_MUT,
     CAST_PTR_ALIGNMENT,
     CAST_SLICE_DIFFERENT_SIZES,
     UNNECESSARY_CAST,
@@ -747,7 +710,6 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             }
         }
 
-        cast_ref_to_mut::check(cx, expr);
         cast_ptr_alignment::check(cx, expr);
         char_lit_as_u8::check(cx, expr);
         ptr_as_ptr::check(cx, expr, &self.msrv);
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 0ae95b045e0..212e809d4c5 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -81,7 +81,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::casts::CAST_POSSIBLE_WRAP_INFO,
     crate::casts::CAST_PRECISION_LOSS_INFO,
     crate::casts::CAST_PTR_ALIGNMENT_INFO,
-    crate::casts::CAST_REF_TO_MUT_INFO,
     crate::casts::CAST_SIGN_LOSS_INFO,
     crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO,
     crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index 7c2a100efda..4cb41830023 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -31,6 +31,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::stutter", "clippy::module_name_repetitions"),
     ("clippy::to_string_in_display", "clippy::recursive_format_impl"),
     ("clippy::zero_width_space", "clippy::invisible_characters"),
+    ("clippy::cast_ref_to_mut", "cast_ref_to_mut"),
     ("clippy::clone_double_ref", "suspicious_double_ref_op"),
     ("clippy::drop_bounds", "drop_bounds"),
     ("clippy::drop_copy", "dropping_copy_types"),
diff --git a/src/tools/clippy/tests/ui/cast_ref_to_mut.rs b/src/tools/clippy/tests/ui/cast_ref_to_mut.rs
deleted file mode 100644
index c48a734ba32..00000000000
--- a/src/tools/clippy/tests/ui/cast_ref_to_mut.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-#![warn(clippy::cast_ref_to_mut)]
-#![allow(clippy::no_effect, clippy::borrow_as_ptr)]
-
-extern "C" {
-    // N.B., mutability can be easily incorrect in FFI calls -- as
-    // in C, the default is mutable pointers.
-    fn ffi(c: *mut u8);
-    fn int_ffi(c: *mut i32);
-}
-
-fn main() {
-    let s = String::from("Hello");
-    let a = &s;
-    unsafe {
-        let num = &3i32;
-        let mut_num = &mut 3i32;
-        // Should be warned against
-        (*(a as *const _ as *mut String)).push_str(" world");
-        *(a as *const _ as *mut _) = String::from("Replaced");
-        *(a as *const _ as *mut String) += " world";
-        // Shouldn't be warned against
-        println!("{}", *(num as *const _ as *const i16));
-        println!("{}", *(mut_num as *mut _ as *mut i16));
-        ffi(a.as_ptr() as *mut _);
-        int_ffi(num as *const _ as *mut _);
-        int_ffi(&3 as *const _ as *mut _);
-        let mut value = 3;
-        let value: *const i32 = &mut value;
-        *(value as *const i16 as *mut i16) = 42;
-    }
-}
diff --git a/src/tools/clippy/tests/ui/cast_ref_to_mut.stderr b/src/tools/clippy/tests/ui/cast_ref_to_mut.stderr
deleted file mode 100644
index aacd99437d9..00000000000
--- a/src/tools/clippy/tests/ui/cast_ref_to_mut.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`
-  --> $DIR/cast_ref_to_mut.rs:18:9
-   |
-LL |         (*(a as *const _ as *mut String)).push_str(" world");
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `-D clippy::cast-ref-to-mut` implied by `-D warnings`
-
-error: casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`
-  --> $DIR/cast_ref_to_mut.rs:19:9
-   |
-LL |         *(a as *const _ as *mut _) = String::from("Replaced");
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: casting `&T` to `&mut T` may cause undefined behavior, consider instead using an `UnsafeCell`
-  --> $DIR/cast_ref_to_mut.rs:20:9
-   |
-LL |         *(a as *const _ as *mut String) += " world";
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 53ac65473b8..f7854b89ee4 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -29,6 +29,7 @@
 #![allow(clippy::recursive_format_impl)]
 #![allow(clippy::invisible_characters)]
 #![allow(suspicious_double_ref_op)]
+#![allow(cast_ref_to_mut)]
 #![allow(drop_bounds)]
 #![allow(dropping_copy_types)]
 #![allow(dropping_references)]
@@ -76,6 +77,7 @@
 #![warn(clippy::module_name_repetitions)]
 #![warn(clippy::recursive_format_impl)]
 #![warn(clippy::invisible_characters)]
+#![warn(cast_ref_to_mut)]
 #![warn(suspicious_double_ref_op)]
 #![warn(drop_bounds)]
 #![warn(dropping_copy_types)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 722c0b3eb27..fa347d395ef 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -29,6 +29,7 @@
 #![allow(clippy::recursive_format_impl)]
 #![allow(clippy::invisible_characters)]
 #![allow(suspicious_double_ref_op)]
+#![allow(cast_ref_to_mut)]
 #![allow(drop_bounds)]
 #![allow(dropping_copy_types)]
 #![allow(dropping_references)]
@@ -76,6 +77,7 @@
 #![warn(clippy::stutter)]
 #![warn(clippy::to_string_in_display)]
 #![warn(clippy::zero_width_space)]
+#![warn(clippy::cast_ref_to_mut)]
 #![warn(clippy::clone_double_ref)]
 #![warn(clippy::drop_bounds)]
 #![warn(clippy::drop_copy)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 1ff83917660..9dffe51e5d7 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,5 +1,5 @@
 error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
-  --> $DIR/rename.rs:50:9
+  --> $DIR/rename.rs:51:9
    |
 LL | #![warn(clippy::almost_complete_letter_range)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@@ -7,292 +7,298 @@ LL | #![warn(clippy::almost_complete_letter_range)]
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
 error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
-  --> $DIR/rename.rs:51:9
+  --> $DIR/rename.rs:52:9
    |
 LL | #![warn(clippy::blacklisted_name)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
 
 error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
-  --> $DIR/rename.rs:52:9
+  --> $DIR/rename.rs:53:9
    |
 LL | #![warn(clippy::block_in_if_condition_expr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
 error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
-  --> $DIR/rename.rs:53:9
+  --> $DIR/rename.rs:54:9
    |
 LL | #![warn(clippy::block_in_if_condition_stmt)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
 error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
-  --> $DIR/rename.rs:54:9
+  --> $DIR/rename.rs:55:9
    |
 LL | #![warn(clippy::box_vec)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
 
 error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
-  --> $DIR/rename.rs:55:9
+  --> $DIR/rename.rs:56:9
    |
 LL | #![warn(clippy::const_static_lifetime)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
 
 error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
-  --> $DIR/rename.rs:56:9
+  --> $DIR/rename.rs:57:9
    |
 LL | #![warn(clippy::cyclomatic_complexity)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
 
 error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
-  --> $DIR/rename.rs:57:9
+  --> $DIR/rename.rs:58:9
    |
 LL | #![warn(clippy::derive_hash_xor_eq)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
 
 error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
-  --> $DIR/rename.rs:58:9
+  --> $DIR/rename.rs:59:9
    |
 LL | #![warn(clippy::disallowed_method)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
 
 error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
-  --> $DIR/rename.rs:59:9
+  --> $DIR/rename.rs:60:9
    |
 LL | #![warn(clippy::disallowed_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
 
 error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
-  --> $DIR/rename.rs:60:9
+  --> $DIR/rename.rs:61:9
    |
 LL | #![warn(clippy::eval_order_dependence)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
 
 error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
-  --> $DIR/rename.rs:61:9
+  --> $DIR/rename.rs:62:9
    |
 LL | #![warn(clippy::identity_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
 
 error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
-  --> $DIR/rename.rs:62:9
+  --> $DIR/rename.rs:63:9
    |
 LL | #![warn(clippy::if_let_some_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
 
 error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
-  --> $DIR/rename.rs:63:9
+  --> $DIR/rename.rs:64:9
    |
 LL | #![warn(clippy::integer_arithmetic)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
 
 error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
-  --> $DIR/rename.rs:64:9
+  --> $DIR/rename.rs:65:9
    |
 LL | #![warn(clippy::logic_bug)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
 
 error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
-  --> $DIR/rename.rs:65:9
+  --> $DIR/rename.rs:66:9
    |
 LL | #![warn(clippy::new_without_default_derive)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
 
 error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
-  --> $DIR/rename.rs:66:9
+  --> $DIR/rename.rs:67:9
    |
 LL | #![warn(clippy::option_and_then_some)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
 
 error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
-  --> $DIR/rename.rs:67:9
+  --> $DIR/rename.rs:68:9
    |
 LL | #![warn(clippy::option_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:68:9
+  --> $DIR/rename.rs:69:9
    |
 LL | #![warn(clippy::option_map_unwrap_or)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:69:9
+  --> $DIR/rename.rs:70:9
    |
 LL | #![warn(clippy::option_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> $DIR/rename.rs:70:9
+  --> $DIR/rename.rs:71:9
    |
 LL | #![warn(clippy::option_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
-  --> $DIR/rename.rs:71:9
+  --> $DIR/rename.rs:72:9
    |
 LL | #![warn(clippy::ref_in_deref)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
 
 error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
-  --> $DIR/rename.rs:72:9
+  --> $DIR/rename.rs:73:9
    |
 LL | #![warn(clippy::result_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:73:9
+  --> $DIR/rename.rs:74:9
    |
 LL | #![warn(clippy::result_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> $DIR/rename.rs:74:9
+  --> $DIR/rename.rs:75:9
    |
 LL | #![warn(clippy::result_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
-  --> $DIR/rename.rs:75:9
+  --> $DIR/rename.rs:76:9
    |
 LL | #![warn(clippy::single_char_push_str)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
 
 error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
-  --> $DIR/rename.rs:76:9
+  --> $DIR/rename.rs:77:9
    |
 LL | #![warn(clippy::stutter)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
 
 error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
-  --> $DIR/rename.rs:77:9
+  --> $DIR/rename.rs:78:9
    |
 LL | #![warn(clippy::to_string_in_display)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
 
 error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
-  --> $DIR/rename.rs:78:9
+  --> $DIR/rename.rs:79:9
    |
 LL | #![warn(clippy::zero_width_space)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
 
+error: lint `clippy::cast_ref_to_mut` has been renamed to `cast_ref_to_mut`
+  --> $DIR/rename.rs:80:9
+   |
+LL | #![warn(clippy::cast_ref_to_mut)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `cast_ref_to_mut`
+
 error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
-  --> $DIR/rename.rs:79:9
+  --> $DIR/rename.rs:81:9
    |
 LL | #![warn(clippy::clone_double_ref)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
 
 error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
-  --> $DIR/rename.rs:80:9
+  --> $DIR/rename.rs:82:9
    |
 LL | #![warn(clippy::drop_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
 
 error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
-  --> $DIR/rename.rs:81:9
+  --> $DIR/rename.rs:83:9
    |
 LL | #![warn(clippy::drop_copy)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
 
 error: lint `clippy::drop_ref` has been renamed to `dropping_references`
-  --> $DIR/rename.rs:82:9
+  --> $DIR/rename.rs:84:9
    |
 LL | #![warn(clippy::drop_ref)]
    |         ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
 
 error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:83:9
+  --> $DIR/rename.rs:85:9
    |
 LL | #![warn(clippy::for_loop_over_option)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:84:9
+  --> $DIR/rename.rs:86:9
    |
 LL | #![warn(clippy::for_loop_over_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:85:9
+  --> $DIR/rename.rs:87:9
    |
 LL | #![warn(clippy::for_loops_over_fallibles)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
-  --> $DIR/rename.rs:86:9
+  --> $DIR/rename.rs:88:9
    |
 LL | #![warn(clippy::forget_copy)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
 
 error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
-  --> $DIR/rename.rs:87:9
+  --> $DIR/rename.rs:89:9
    |
 LL | #![warn(clippy::forget_ref)]
    |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
 
 error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
-  --> $DIR/rename.rs:88:9
+  --> $DIR/rename.rs:90:9
    |
 LL | #![warn(clippy::into_iter_on_array)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
 
 error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
-  --> $DIR/rename.rs:89:9
+  --> $DIR/rename.rs:91:9
    |
 LL | #![warn(clippy::invalid_atomic_ordering)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
 
 error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
-  --> $DIR/rename.rs:90:9
+  --> $DIR/rename.rs:92:9
    |
 LL | #![warn(clippy::invalid_ref)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
 
 error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
-  --> $DIR/rename.rs:91:9
+  --> $DIR/rename.rs:93:9
    |
 LL | #![warn(clippy::invalid_utf8_in_unchecked)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
 
 error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
-  --> $DIR/rename.rs:92:9
+  --> $DIR/rename.rs:94:9
    |
 LL | #![warn(clippy::let_underscore_drop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
 
 error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> $DIR/rename.rs:93:9
+  --> $DIR/rename.rs:95:9
    |
 LL | #![warn(clippy::mem_discriminant_non_enum)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
 error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> $DIR/rename.rs:94:9
+  --> $DIR/rename.rs:96:9
    |
 LL | #![warn(clippy::panic_params)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
 error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
-  --> $DIR/rename.rs:95:9
+  --> $DIR/rename.rs:97:9
    |
 LL | #![warn(clippy::positional_named_format_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
 
 error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
-  --> $DIR/rename.rs:96:9
+  --> $DIR/rename.rs:98:9
    |
 LL | #![warn(clippy::temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> $DIR/rename.rs:97:9
+  --> $DIR/rename.rs:99:9
    |
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
 error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> $DIR/rename.rs:98:9
+  --> $DIR/rename.rs:100:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
-error: aborting due to 49 previous errors
+error: aborting due to 50 previous errors
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index a799d93ce25..923b2e63f2e 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1939,6 +1939,17 @@ impl<'test> TestCx<'test> {
         // Use a single thread for efficiency and a deterministic error message order
         rustc.arg("-Zthreads=1");
 
+        // Hide libstd sources from ui tests to make sure we generate the stderr
+        // output that users will see.
+        // Without this, we may be producing good diagnostics in-tree but users
+        // will not see half the information.
+        //
+        // This also has the benefit of more effectively normalizing output between different
+        // compilers, so that we don't have to know the `/rustc/$sha` output to normalize after the
+        // fact.
+        rustc.arg("-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX");
+        rustc.arg("-Ztranslate-remapped-path-to-local-path=no");
+
         // Optionally prevent default --sysroot if specified in test compile-flags.
         if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot")) {
             // In stage 0, make sure we use `stage0-sysroot` instead of the bootstrap sysroot.
@@ -2014,13 +2025,6 @@ impl<'test> TestCx<'test> {
                 rustc.arg("-Ccodegen-units=1");
                 // Hide line numbers to reduce churn
                 rustc.arg("-Zui-testing");
-                // Hide libstd sources from ui tests to make sure we generate the stderr
-                // output that users will see.
-                // Without this, we may be producing good diagnostics in-tree but users
-                // will not see half the information.
-                rustc.arg("-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX");
-                rustc.arg("-Ztranslate-remapped-path-to-local-path=no");
-
                 rustc.arg("-Zdeduplicate-diagnostics=no");
                 // FIXME: use this for other modes too, for perf?
                 rustc.arg("-Cstrip=debuginfo");
@@ -3732,28 +3736,13 @@ impl<'test> TestCx<'test> {
             normalize_path(&remapped_parent_dir, "$DIR");
         }
 
-        let source_bases = &[
-            // Source base on the current filesystem (calculated as parent of `tests/$suite`):
-            Some(self.config.src_base.parent().unwrap().parent().unwrap().into()),
-            // Source base on the sysroot (from the src components downloaded by `download-rustc`):
-            Some(self.config.sysroot_base.join("lib").join("rustlib").join("src").join("rust")),
-            // Virtual `/rustc/$sha` remapped paths (if `remap-debuginfo` is enabled):
-            option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from),
-            // Virtual `/rustc/$sha` coming from download-rustc:
-            std::env::var_os("FAKE_DOWNLOAD_RUSTC_PREFIX").map(PathBuf::from),
-            // Tests using -Zsimulate-remapped-rust-src-base should use this fake path
-            Some("/rustc/FAKE_PREFIX".into()),
-        ];
-        for base_dir in source_bases {
-            if let Some(base_dir) = base_dir {
-                // Paths into the libstd/libcore
-                normalize_path(&base_dir.join("library"), "$SRC_DIR");
-                // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
-                // `rustc_macros`
-                // eg. /home/user/rust/compiler
-                normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR");
-            }
-        }
+        let base_dir = Path::new("/rustc/FAKE_PREFIX");
+        // Paths into the libstd/libcore
+        normalize_path(&base_dir.join("library"), "$SRC_DIR");
+        // `ui-fulldeps` tests can show paths to the compiler source when testing macros from
+        // `rustc_macros`
+        // eg. /home/user/rust/compiler
+        normalize_path(&base_dir.join("compiler"), "$COMPILER_DIR");
 
         // Paths into the build directory
         let test_build_dir = &self.config.build_base;
diff --git a/src/tools/miri/tests/fail/modifying_constants.rs b/src/tools/miri/tests/fail/modifying_constants.rs
index 2783ebd155f..40ba31dad8f 100644
--- a/src/tools/miri/tests/fail/modifying_constants.rs
+++ b/src/tools/miri/tests/fail/modifying_constants.rs
@@ -1,6 +1,8 @@
 // This should fail even without validation/SB
 //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
 
+#![allow(cast_ref_to_mut)]
+
 fn main() {
     let x = &1; // the `&1` is promoted to a constant, but it used to be that only the pointer is marked static, not the pointee
     let y = unsafe { &mut *(x as *const i32 as *mut i32) };
diff --git a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs
index d1322dc6e57..8cd59b3550d 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/shr_frozen_violation1.rs
@@ -1,3 +1,5 @@
+#![allow(cast_ref_to_mut)]
+
 fn foo(x: &mut i32) -> i32 {
     *x = 5;
     unknown_code(&*x);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs
index f7c1e683d0d..142b1229019 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs
@@ -196,10 +196,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
     ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
     ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
     gated!(
-        const_eval_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
-        const_eval_limit, experimental!(const_eval_limit)
-    ),
-    gated!(
         move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
         large_assignments, experimental!(move_size_limit)
     ),
diff --git a/src/tools/rust-installer/combine-installers.sh b/src/tools/rust-installer/combine-installers.sh
index bee5319fd55..01e5a00af4a 100755
--- a/src/tools/rust-installer/combine-installers.sh
+++ b/src/tools/rust-installer/combine-installers.sh
@@ -11,5 +11,9 @@ abs_path() {
     (unset CDPATH && cd "$path" > /dev/null && pwd)
 }
 
+# Running cargo will read the libstd Cargo.toml
+# which uses the unstable `public-dependency` feature.
+export RUSTC_BOOTSTRAP=1
+
 src_dir="$(abs_path $(dirname "$0"))"
 $CARGO run --manifest-path="$src_dir/Cargo.toml" -- combine "$@"
diff --git a/src/tools/rust-installer/gen-installer.sh b/src/tools/rust-installer/gen-installer.sh
index eabd8c95cd8..cc45b5e0803 100755
--- a/src/tools/rust-installer/gen-installer.sh
+++ b/src/tools/rust-installer/gen-installer.sh
@@ -11,5 +11,9 @@ abs_path() {
     (unset CDPATH && cd "$path" > /dev/null && pwd)
 }
 
+# Running cargo will read the libstd Cargo.toml
+# which uses the unstable `public-dependency` feature.
+export RUSTC_BOOTSTRAP=1
+
 src_dir="$(abs_path $(dirname "$0"))"
 $CARGO run --manifest-path="$src_dir/Cargo.toml" -- generate "$@"
diff --git a/src/tools/rust-installer/make-tarballs.sh b/src/tools/rust-installer/make-tarballs.sh
index e342007da37..374e103e89c 100755
--- a/src/tools/rust-installer/make-tarballs.sh
+++ b/src/tools/rust-installer/make-tarballs.sh
@@ -11,5 +11,9 @@ abs_path() {
     (unset CDPATH && cd "$path" > /dev/null && pwd)
 }
 
+# Running cargo will read the libstd Cargo.toml
+# which uses the unstable `public-dependency` feature.
+export RUSTC_BOOTSTRAP=1
+
 src_dir="$(abs_path $(dirname "$0"))"
 $CARGO run --manifest-path="$src_dir/Cargo.toml" -- tarball "$@"
diff --git a/src/tools/rustdoc-gui-test/Cargo.toml b/src/tools/rustdoc-gui-test/Cargo.toml
index f0c5b367117..4cb200ebc7c 100644
--- a/src/tools/rustdoc-gui-test/Cargo.toml
+++ b/src/tools/rustdoc-gui-test/Cargo.toml
@@ -4,6 +4,7 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
+build_helper = { path = "../build_helper" }
 compiletest = { path = "../compiletest" }
 getopts = "0.2"
 walkdir = "2"
diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs
index 8dc18dfaea2..3f60a90f87a 100644
--- a/src/tools/rustdoc-gui-test/src/main.rs
+++ b/src/tools/rustdoc-gui-test/src/main.rs
@@ -1,3 +1,4 @@
+use build_helper::util::try_run;
 use compiletest::header::TestProps;
 use config::Config;
 use std::path::{Path, PathBuf};
@@ -60,23 +61,6 @@ fn find_librs<P: AsRef<Path>>(path: P) -> Option<PathBuf> {
     None
 }
 
-// FIXME: move `bootstrap::util::try_run` into `build_helper` crate
-// and use that one instead of creating this function.
-fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
-    let status = match cmd.status() {
-        Ok(status) => status,
-        Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cmd, e),
-    };
-    if !status.success() && print_cmd_on_fail {
-        println!(
-            "\n\ncommand did not execute successfully: {:?}\n\
-             expected success, got: {}\n\n",
-            cmd, status
-        );
-    }
-    status.success()
-}
-
 fn main() {
     let config = Arc::new(Config::from_args(env::args().collect()));
 
@@ -143,6 +127,16 @@ If you want to install the `browser-ui-test` dependency, run `npm install browse
     }
 
     let mut command = Command::new(&config.nodejs);
+
+    if let Ok(current_dir) = env::current_dir() {
+        let local_node_modules = current_dir.join("node_modules");
+        if local_node_modules.exists() {
+            // Link the local node_modules if exists.
+            // This is useful when we run rustdoc-gui-test from outside of the source root.
+            env::set_var("NODE_PATH", local_node_modules);
+        }
+    }
+
     command
         .arg(config.rust_src.join("src/tools/rustdoc-gui/tester.js"))
         .arg("--jobs")
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 1c4d96c321c..e21068490b6 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -16,6 +16,12 @@ use std::sync::atomic::{AtomicBool, Ordering};
 use std::thread::{self, scope, ScopedJoinHandle};
 
 fn main() {
+    // Running Cargo will read the libstd Cargo.toml
+    // which uses the unstable `public-dependency` feature.
+    //
+    // `setenv` might not be thread safe, so run it before using multiple threads.
+    env::set_var("RUSTC_BOOTSTRAP", "1");
+
     let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into();
     let cargo: PathBuf = env::args_os().nth(2).expect("need path to cargo").into();
     let output_directory: PathBuf =
diff --git a/tests/assembly/asm/mips-types.rs b/tests/assembly/asm/mips-types.rs
index 6aa28b062db..27469b22980 100644
--- a/tests/assembly/asm/mips-types.rs
+++ b/tests/assembly/asm/mips-types.rs
@@ -72,7 +72,7 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
 
 // mips32-LABEL: sym_static_32:
 // mips32: #APP
-// mips32: lw $3, %got(extern_static)
+// mips32: lw $3, %got(extern_static)($gp)
 // mips32: #NO_APP
 #[cfg(mips32)]
 #[no_mangle]
@@ -82,7 +82,7 @@ pub unsafe fn sym_static_32() {
 
 // mips32-LABEL: sym_fn_32:
 // mips32: #APP
-// mips32: lw $3, %got(extern_func)
+// mips32: lw $3, %got(extern_func)($gp)
 // mips32: #NO_APP
 #[cfg(mips32)]
 #[no_mangle]
@@ -92,7 +92,9 @@ pub unsafe fn sym_fn_32() {
 
 // mips64-LABEL: sym_static_64:
 // mips64: #APP
-// mips64: ld $3, %got_disp(extern_static)
+// mips64: lui    $3, %got_hi(extern_static)
+// mips64: daddu  $3, $3, $gp
+// mips64: ld     $3, %got_lo(extern_static)($3)
 // mips64: #NO_APP
 #[cfg(mips64)]
 #[no_mangle]
@@ -102,7 +104,9 @@ pub unsafe fn sym_static_64() {
 
 // mips64-LABEL: sym_fn_64:
 // mips64: #APP
-// mips64: ld $3, %got_disp(extern_func)
+// mips64: lui    $3, %got_hi(extern_func)
+// mips64: daddu  $3, $3, $gp
+// mips64: ld     $3, %got_lo(extern_func)($3)
 // mips64: #NO_APP
 #[cfg(mips64)]
 #[no_mangle]
diff --git a/tests/codegen/array-map.rs b/tests/codegen/array-map.rs
index 3706ddf99fd..24f3f43d078 100644
--- a/tests/codegen/array-map.rs
+++ b/tests/codegen/array-map.rs
@@ -4,7 +4,6 @@
 // ignore-debug (the extra assertions get in the way)
 
 #![crate_type = "lib"]
-#![feature(array_zip)]
 
 // CHECK-LABEL: @short_integer_map
 #[no_mangle]
@@ -16,16 +15,6 @@ pub fn short_integer_map(x: [u32; 8]) -> [u32; 8] {
     x.map(|x| 2 * x + 1)
 }
 
-// CHECK-LABEL: @short_integer_zip_map
-#[no_mangle]
-pub fn short_integer_zip_map(x: [u32; 8], y: [u32; 8]) -> [u32; 8] {
-    // CHECK: %[[A:.+]] = load <8 x i32>
-    // CHECK: %[[B:.+]] = load <8 x i32>
-    // CHECK: sub <8 x i32> %[[B]], %[[A]]
-    // CHECK: store <8 x i32>
-    x.zip(y).map(|(x, y)| x - y)
-}
-
 // This test is checking that LLVM can SRoA away a bunch of the overhead,
 // like fully moving the iterators to registers.  Notably, previous implementations
 // of `map` ended up `alloca`ing the whole `array::IntoIterator`, meaning both a
diff --git a/tests/codegen/autovectorize-f32x4.rs b/tests/codegen/autovectorize-f32x4.rs
index 9ecea53f1c0..54392be707f 100644
--- a/tests/codegen/autovectorize-f32x4.rs
+++ b/tests/codegen/autovectorize-f32x4.rs
@@ -1,7 +1,6 @@
 // compile-flags: -C opt-level=3 -Z merge-functions=disabled
 // only-x86_64
 #![crate_type = "lib"]
-#![feature(array_zip)]
 
 // CHECK-LABEL: @auto_vectorize_direct
 #[no_mangle]
@@ -32,12 +31,12 @@ pub fn auto_vectorize_loop(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
     c
 }
 
-// CHECK-LABEL: @auto_vectorize_array_zip_map
+// CHECK-LABEL: @auto_vectorize_array_from_fn
 #[no_mangle]
-pub fn auto_vectorize_array_zip_map(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
+pub fn auto_vectorize_array_from_fn(a: [f32; 4], b: [f32; 4]) -> [f32; 4] {
 // CHECK: load <4 x float>
 // CHECK: load <4 x float>
 // CHECK: fadd <4 x float>
 // CHECK: store <4 x float>
-    a.zip(b).map(|(a, b)| a + b)
+    std::array::from_fn(|i| a[i] + b[i])
 }
diff --git a/tests/codegen/const_scalar_pair.rs b/tests/codegen/const_scalar_pair.rs
index 8f32c50b798..aa4cf7a64d5 100644
--- a/tests/codegen/const_scalar_pair.rs
+++ b/tests/codegen/const_scalar_pair.rs
@@ -2,6 +2,8 @@
 
 #![feature(inline_const)]
 
+// Test that we don't generate a memory allocation for the constant
+// and read the fields from that, but instead just create the value pair directly.
 pub fn foo() -> (i32, i32) {
     // CHECK: ret { i32, i32 } { i32 1, i32 2 }
     const { (1, 2) }
diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs
index 664e697c2a5..fe42494000e 100644
--- a/tests/codegen/intrinsics/transmute.rs
+++ b/tests/codegen/intrinsics/transmute.rs
@@ -14,10 +14,10 @@ use std::intrinsics::{transmute, transmute_unchecked};
 // Some of these need custom MIR to not get removed by MIR optimizations.
 use std::intrinsics::mir::*;
 
-enum Never {}
+pub enum ZstNever {}
 
 #[repr(align(2))]
-pub struct BigNever(Never, u16, Never);
+pub struct BigNever(ZstNever, u16, ZstNever);
 
 #[repr(align(8))]
 pub struct Scalar64(i64);
@@ -56,11 +56,13 @@ pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] {
     transmute_unchecked(x)
 }
 
-// CHECK-LABEL: @check_to_uninhabited(
+// CHECK-LABEL: @check_to_empty_array(
 #[no_mangle]
 #[custom_mir(dialect = "runtime", phase = "optimized")]
-pub unsafe fn check_to_uninhabited(x: u16) -> BigNever {
+pub unsafe fn check_to_empty_array(x: [u32; 5]) -> [u32; 0] {
+    // CHECK-NOT: trap
     // CHECK: call void @llvm.trap
+    // CHECK-NOT: trap
     mir!{
         {
             RET = CastTransmute(x);
@@ -69,6 +71,37 @@ pub unsafe fn check_to_uninhabited(x: u16) -> BigNever {
     }
 }
 
+// CHECK-LABEL: @check_from_empty_array(
+#[no_mangle]
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub unsafe fn check_from_empty_array(x: [u32; 0]) -> [u32; 5] {
+    // CHECK-NOT: trap
+    // CHECK: call void @llvm.trap
+    // CHECK-NOT: trap
+    mir!{
+        {
+            RET = CastTransmute(x);
+            Return()
+        }
+    }
+}
+
+// CHECK-LABEL: @check_to_uninhabited(
+#[no_mangle]
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub unsafe fn check_to_uninhabited(x: u16) {
+    // CHECK-NOT: trap
+    // CHECK: call void @llvm.trap
+    // CHECK-NOT: trap
+    mir!{
+        let temp: BigNever;
+        {
+            temp = CastTransmute(x);
+            Return()
+        }
+    }
+}
+
 // CHECK-LABEL: @check_from_uninhabited(
 #[no_mangle]
 #[custom_mir(dialect = "runtime", phase = "optimized")]
@@ -366,6 +399,40 @@ pub unsafe fn check_issue_109992(x: ()) -> [(); 1] {
     }
 }
 
+// CHECK-LABEL: @check_unit_to_never(
+#[no_mangle]
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub unsafe fn check_unit_to_never(x: ()) {
+    // This uses custom MIR to avoid MIR optimizations having removed ZST ops.
+
+    // CHECK-NOT: trap
+    // CHECK: call void @llvm.trap
+    // CHECK-NOT: trap
+    mir!{
+        let temp: ZstNever;
+        {
+            temp = CastTransmute(x);
+            Return()
+        }
+    }
+}
+
+// CHECK-LABEL: @check_unit_from_never(
+#[no_mangle]
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub unsafe fn check_unit_from_never(x: ZstNever) -> () {
+    // This uses custom MIR to avoid MIR optimizations having removed ZST ops.
+
+    // CHECK: start
+    // CHECK-NEXT: ret void
+    mir!{
+        {
+            RET = CastTransmute(x);
+            Return()
+        }
+    }
+}
+
 // CHECK-LABEL: @check_maybe_uninit_pair(i16 %x.0, i64 %x.1)
 #[no_mangle]
 pub unsafe fn check_maybe_uninit_pair(
diff --git a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs
index 2ee4d7cca0e..6e0eacfe400 100644
--- a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs
+++ b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs
@@ -1,4 +1,5 @@
-// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes
+// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes -Zmir-enable-passes=-ScalarReplacementOfAggregates
+// MIR SROA will decompose the closure
 // min-llvm-version: 15.0 # this test uses opaque pointer notation
 #![feature(stmt_expr_attributes)]
 
@@ -15,8 +16,8 @@ pub fn outer_function(x: S, y: S) -> usize {
 // Check that we do not attempt to load from the spilled arg before it is assigned to
 // when generating debuginfo.
 // CHECK-LABEL: @outer_function
-// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]"
-// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]]
+// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:10:23: 10:25]"
+// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:10:23: 10:25]", ptr [[spill]]
 // CHECK-NOT: [[load:%.*]] = load ptr, ptr
 // CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]])
 // CHECK: [[inner:%.*]] = getelementptr inbounds %"{{.*}}", ptr [[spill]]
diff --git a/tests/incremental/hashes/match_expressions.rs b/tests/incremental/hashes/match_expressions.rs
index 4429df6833e..ecb19480d65 100644
--- a/tests/incremental/hashes/match_expressions.rs
+++ b/tests/incremental/hashes/match_expressions.rs
@@ -225,8 +225,9 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
     }
 }
 
+// Ignore optimized_mir in cfail2, the only change to optimized MIR is a span.
 #[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
 #[rustc_clean(cfg="cfail3")]
 #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
 #[rustc_clean(cfg="cfail6")]
diff --git a/tests/incremental/issue-101518.rs b/tests/incremental/issue-101518.rs
index 501be175fce..39373da6a9f 100644
--- a/tests/incremental/issue-101518.rs
+++ b/tests/incremental/issue-101518.rs
@@ -1,7 +1,4 @@
-// revisions: cfail1
-// should-ice
-// error-pattern: forcing query
-// known-bug: #101518
+// revisions: cpass
 
 #[derive(PartialEq, Eq)]
 struct Id<'a> {
@@ -9,9 +6,7 @@ struct Id<'a> {
 }
 fn visit_struct() {
     let id = Id { ns: "random1" };
-    const FLAG: Id<'static> = Id {
-        ns: "needs_to_be_the_same",
-    };
+    const FLAG: Id<'static> = Id { ns: "needs_to_be_the_same" };
     match id {
         FLAG => {}
         _ => {}
@@ -19,9 +14,7 @@ fn visit_struct() {
 }
 fn visit_struct2() {
     let id = Id { ns: "random2" };
-    const FLAG: Id<'static> = Id {
-        ns: "needs_to_be_the_same",
-    };
+    const FLAG: Id<'static> = Id { ns: "needs_to_be_the_same" };
     match id {
         FLAG => {}
         _ => {}
diff --git a/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
index bcdb12011bc..61ce5e54fdc 100644
--- a/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
+++ b/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
@@ -35,7 +35,7 @@ fn foo(_1: Option<String>) -> i32 {
                                          // + literal: Const { ty: for<'a, 'b> fn(&'a str, &'b str) -> bool {<str as PartialEq>::eq}, val: Value(<ZST>) }
                                          // mir::Constant
                                          // + span: $DIR/string.rs:9:14: 9:17
-                                         // + literal: Const { ty: &str, val: Value(Slice(..)) }
+                                         // + literal: Const { ty: &str, val: Value(ValTree::Branch(..)) }
     }
 
     bb3: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff
index d76cd0e2bb8..e82e3f18811 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff
@@ -11,35 +11,33 @@
 +         debug self => _3;                // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
 +         debug rhs => _4;                 // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
 +         let mut _5: u16;                 // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         let mut _6: (u32,);              // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         let mut _7: u32;                 // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
 +         scope 2 {
 +             scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                 debug x => _7;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                 let mut _8: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                 let mut _9: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++                 debug x => _4;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++                 let mut _6: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++                 let mut _7: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
 +                 scope 4 {
 +                     scope 5 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                         debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
++                         debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
 +                         scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-+                             debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+                             let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+                             let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+                             let mut _12: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             let mut _10: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +                         }
 +                     }
 +                     scope 7 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                         debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+                         let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+                         let _14: u16;    // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++                         debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++                         let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++                         let _12: u16;    // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +                         scope 8 {
-+                             debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
++                             debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
 +                         }
 +                     }
 +                     scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                         debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+                         let mut _15: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+                         let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++                         debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++                         let mut _13: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++                         let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
 +                         scope 10 {
 +                             debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
 +                         }
@@ -52,7 +50,7 @@
 +                             }
 +                         }
 +                         scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
-+                             debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
++                             debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
 +                         }
 +                     }
 +                 }
@@ -70,18 +68,14 @@
 -                                          // + span: $DIR/unchecked_shifts.rs:11:7: 11:20
 -                                          // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::<impl u16>::unchecked_shl}, val: Value(<ZST>) }
 +         StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_6);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _6 = (_4,);                      // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_7);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _7 = move (_6.0: u32);           // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageLive(_11);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _11 = const 65535_u32;           // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _10 = Gt(_7, move _11);          // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageDead(_11);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageLive(_7);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageLive(_8);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_9);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _9 = const 65535_u32;            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _8 = Gt(_4, move _9);            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageDead(_9);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
       }
   
       bb1: {
@@ -92,7 +86,7 @@
 +     }
 + 
 +     bb2: {
-+         _9 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) }
@@ -100,22 +94,22 @@
 +     }
 + 
 +     bb3: {
-+         StorageLive(_12);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _12 = _7 as u16 (IntToInt);      // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _9 = Result::<u16, TryFromIntError>::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageDead(_12);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _10 = _4 as u16 (IntToInt);      // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _7 = Result::<u16, TryFromIntError>::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageDead(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +         goto -> bb4;                     // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +     }
 + 
 +     bb4: {
-+         StorageDead(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageLive(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _13 = discriminant(_9);          // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+         switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         StorageDead(_8);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         _11 = discriminant(_7);          // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +     }
 + 
 +     bb5: {
-+         _8 = Option::<u16>::None;        // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         _6 = Option::<u16>::None;        // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +         goto -> bb8;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +     }
 + 
@@ -124,25 +118,23 @@
 +     }
 + 
 +     bb7: {
-+         _14 = move ((_9 as Ok).0: u16);  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+         _8 = Option::<u16>::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
++         _12 = move ((_7 as Ok).0: u16);  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         _6 = Option::<u16>::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
 +         goto -> bb8;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +     }
 + 
 +     bb8: {
-+         StorageDead(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _16 = discriminant(_8);          // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+         switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageDead(_7);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageLive(_13);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         _14 = discriminant(_6);          // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++         switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
 +     }
 + 
 +     bb9: {
-+         _5 = move ((_8 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+         StorageDead(_15);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_7);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_6);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         _5 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_13);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageDead(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
 +         _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
 +                                          // mir::Constant
 +                                          // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir
index f4b2416eaab..8fa4fdaa49a 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir
@@ -7,38 +7,36 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23
         debug self => _1;                // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
         debug rhs => _2;                 // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
-        let mut _3: (u32,);              // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        let mut _4: u32;                 // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        let mut _13: u16;                // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        let mut _11: u16;                // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
         scope 2 {
             scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                debug x => _4;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                let mut _8: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                let mut _11: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+                debug x => _2;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+                let mut _6: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+                let mut _9: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
                 scope 4 {
                     scope 5 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                        debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+                        debug self => _2; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
                         scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-                            debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-                            let mut _5: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-                            let mut _6: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-                            let mut _7: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            debug u => _2; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            let mut _3: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            let mut _4: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            let mut _5: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
                         }
                     }
                     scope 7 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                        debug self => _8; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-                        let mut _9: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-                        let _10: u16;    // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+                        debug self => _6; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+                        let mut _7: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+                        let _8: u16;     // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
                         scope 8 {
-                            debug x => _10; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+                            debug x => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
                         }
                     }
                     scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                        debug self => _11; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-                        let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-                        let mut _14: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+                        debug self => _9; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+                        let mut _10: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+                        let mut _12: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
                         scope 10 {
-                            debug val => _13; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
+                            debug val => _11; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
                         }
                         scope 11 {
                             scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
@@ -49,7 +47,7 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
                             }
                         }
                         scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
-                            debug self => _14; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
+                            debug self => _12; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
                         }
                     }
                 }
@@ -58,31 +56,27 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     }
 
     bb0: {
-        StorageLive(_13);                // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _3 = (_2,);                      // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _4 = move (_3.0: u32);           // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_11);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_6);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageLive(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _5 = const 65535_u32;            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _6 = Gt(_4, move _5);            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageDead(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        switchInt(move _6) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_11);                // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_4);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_3);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _3 = const 65535_u32;            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _4 = Gt(_2, move _3);            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageDead(_3);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        switchInt(move _4) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
     }
 
     bb1: {
-        StorageLive(_7);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _7 = _4 as u16 (IntToInt);       // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _8 = Result::<u16, TryFromIntError>::Ok(move _7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageDead(_7);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _5 = _2 as u16 (IntToInt);       // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _6 = Result::<u16, TryFromIntError>::Ok(move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageDead(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
         goto -> bb3;                     // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
     }
 
     bb2: {
-        _8 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _6 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
                                          // mir::Constant
                                          // + span: no-location
                                          // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) }
@@ -90,45 +84,43 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     }
 
     bb3: {
-        StorageDead(_6);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageLive(_10);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _9 = discriminant(_8);           // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        StorageDead(_4);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        _7 = discriminant(_6);           // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
     }
 
     bb4: {
-        _10 = move ((_8 as Ok).0: u16);  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        _11 = Option::<u16>::Some(move _10); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+        _8 = move ((_6 as Ok).0: u16);   // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        _9 = Option::<u16>::Some(move _8); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
         goto -> bb6;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
     }
 
     bb5: {
-        _11 = Option::<u16>::None;       // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        _9 = Option::<u16>::None;        // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
         goto -> bb6;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
     }
 
     bb6: {
-        StorageDead(_10);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
         StorageDead(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _12 = discriminant(_11);         // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-        switchInt(move _12) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        _10 = discriminant(_9);          // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+        switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
     }
 
     bb7: {
-        _13 = move ((_11 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-        StorageDead(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageDead(_11);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _0 = unchecked_shl::<u16>(_1, move _13) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        _11 = move ((_9 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageDead(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        _0 = unchecked_shl::<u16>(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
                                          // mir::Constant
                                          // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) }
     }
 
     bb8: {
-        StorageDead(_13);                // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+        StorageDead(_11);                // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
         return;                          // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2
     }
 
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff
index f3d3e6090bb..f20c7da4747 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff
@@ -11,35 +11,33 @@
 +         debug self => _3;                // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
 +         debug rhs => _4;                 // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
 +         let mut _5: i16;                 // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         let mut _6: (u32,);              // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         let mut _7: u32;                 // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
 +         scope 2 {
 +             scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                 debug x => _7;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                 let mut _8: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                 let mut _9: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++                 debug x => _4;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++                 let mut _6: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++                 let mut _7: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
 +                 scope 4 {
 +                     scope 5 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                         debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
++                         debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
 +                         scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-+                             debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+                             let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+                             let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+                             let mut _12: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++                             let mut _10: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +                         }
 +                     }
 +                     scope 7 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                         debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+                         let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+                         let _14: i16;    // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++                         debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++                         let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++                         let _12: i16;    // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +                         scope 8 {
-+                             debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
++                             debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
 +                         }
 +                     }
 +                     scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+                         debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+                         let mut _15: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+                         let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++                         debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++                         let mut _13: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++                         let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
 +                         scope 10 {
 +                             debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
 +                         }
@@ -52,7 +50,7 @@
 +                             }
 +                         }
 +                         scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
-+                             debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
++                             debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
 +                         }
 +                     }
 +                 }
@@ -70,18 +68,14 @@
 -                                          // + span: $DIR/unchecked_shifts.rs:17:7: 17:20
 -                                          // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::<impl i16>::unchecked_shr}, val: Value(<ZST>) }
 +         StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_6);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _6 = (_4,);                      // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_7);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _7 = move (_6.0: u32);           // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageLive(_11);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _11 = const 32767_u32;           // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _10 = Gt(_7, move _11);          // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageDead(_11);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageLive(_7);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageLive(_8);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_9);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _9 = const 32767_u32;            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _8 = Gt(_4, move _9);            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageDead(_9);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
       }
   
       bb1: {
@@ -92,7 +86,7 @@
 +     }
 + 
 +     bb2: {
-+         _9 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +                                          // mir::Constant
 +                                          // + span: no-location
 +                                          // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) }
@@ -100,22 +94,22 @@
 +     }
 + 
 +     bb3: {
-+         StorageLive(_12);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _12 = _7 as i16 (IntToInt);      // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         _9 = Result::<i16, TryFromIntError>::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageDead(_12);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _10 = _4 as i16 (IntToInt);      // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         _7 = Result::<i16, TryFromIntError>::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageDead(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +         goto -> bb4;                     // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
 +     }
 + 
 +     bb4: {
-+         StorageDead(_10);                // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-+         StorageLive(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _13 = discriminant(_9);          // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+         switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         StorageDead(_8);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
++         StorageLive(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         _11 = discriminant(_7);          // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +     }
 + 
 +     bb5: {
-+         _8 = Option::<i16>::None;        // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         _6 = Option::<i16>::None;        // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +         goto -> bb8;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +     }
 + 
@@ -124,25 +118,23 @@
 +     }
 + 
 +     bb7: {
-+         _14 = move ((_9 as Ok).0: i16);  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-+         _8 = Option::<i16>::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
++         _12 = move ((_7 as Ok).0: i16);  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
++         _6 = Option::<i16>::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
 +         goto -> bb8;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
 +     }
 + 
 +     bb8: {
-+         StorageDead(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageLive(_15);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         _16 = discriminant(_8);          // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+         switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageDead(_7);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageLive(_13);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         _14 = discriminant(_6);          // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++         switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
 +     }
 + 
 +     bb9: {
-+         _5 = move ((_8 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-+         StorageDead(_15);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_7);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-+         StorageDead(_6);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         _5 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
++         StorageDead(_13);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
++         StorageDead(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
 +         _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
 +                                          // mir::Constant
 +                                          // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir
index 67f0fe8932f..7f737abb936 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir
@@ -7,38 +7,36 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
     scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23
         debug self => _1;                // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
         debug rhs => _2;                 // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
-        let mut _3: (u32,);              // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        let mut _4: u32;                 // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        let mut _13: i16;                // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        let mut _11: i16;                // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL
         scope 2 {
             scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                debug x => _4;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                let mut _8: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                let mut _11: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+                debug x => _2;           // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+                let mut _6: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+                let mut _9: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL
                 scope 4 {
                     scope 5 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                        debug self => _4; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+                        debug self => _2; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
                         scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-                            debug u => _4; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-                            let mut _5: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-                            let mut _6: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-                            let mut _7: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            debug u => _2; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            let mut _3: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            let mut _4: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+                            let mut _5: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
                         }
                     }
                     scope 7 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                        debug self => _8; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-                        let mut _9: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-                        let _10: i16;    // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+                        debug self => _6; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+                        let mut _7: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+                        let _8: i16;     // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
                         scope 8 {
-                            debug x => _10; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+                            debug x => _8; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
                         }
                     }
                     scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL
-                        debug self => _11; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-                        let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-                        let mut _14: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+                        debug self => _9; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+                        let mut _10: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+                        let mut _12: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
                         scope 10 {
-                            debug val => _13; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
+                            debug val => _11; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL
                         }
                         scope 11 {
                             scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL
@@ -49,7 +47,7 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
                             }
                         }
                         scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL
-                            debug self => _14; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
+                            debug self => _12; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL
                         }
                     }
                 }
@@ -58,31 +56,27 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
     }
 
     bb0: {
-        StorageLive(_13);                // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _3 = (_2,);                      // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _4 = move (_3.0: u32);           // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_11);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_6);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageLive(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _5 = const 32767_u32;            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _6 = Gt(_4, move _5);            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageDead(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        switchInt(move _6) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_11);                // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_4);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_3);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _3 = const 32767_u32;            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _4 = Gt(_2, move _3);            // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageDead(_3);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        switchInt(move _4) -> [0: bb1, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
     }
 
     bb1: {
-        StorageLive(_7);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _7 = _4 as i16 (IntToInt);       // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        _8 = Result::<i16, TryFromIntError>::Ok(move _7); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageDead(_7);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _5 = _2 as i16 (IntToInt);       // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _6 = Result::<i16, TryFromIntError>::Ok(move _5); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageDead(_5);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
         goto -> bb3;                     // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
     }
 
     bb2: {
-        _8 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        _6 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
                                          // mir::Constant
                                          // + span: no-location
                                          // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) }
@@ -90,45 +84,43 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 {
     }
 
     bb3: {
-        StorageDead(_6);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
-        StorageLive(_10);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _9 = discriminant(_8);           // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        StorageDead(_4);                 // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL
+        StorageLive(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        _7 = discriminant(_6);           // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        switchInt(move _7) -> [0: bb4, 1: bb5, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
     }
 
     bb4: {
-        _10 = move ((_8 as Ok).0: i16);  // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-        _11 = Option::<i16>::Some(move _10); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+        _8 = move ((_6 as Ok).0: i16);   // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        _9 = Option::<i16>::Some(move _8); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
         goto -> bb6;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
     }
 
     bb5: {
-        _11 = Option::<i16>::None;       // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+        _9 = Option::<i16>::None;        // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
         goto -> bb6;                     // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
     }
 
     bb6: {
-        StorageDead(_10);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
         StorageDead(_8);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageLive(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _12 = discriminant(_11);         // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-        switchInt(move _12) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_6);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageLive(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        _10 = discriminant(_9);          // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+        switchInt(move _10) -> [1: bb7, otherwise: bb9]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
     }
 
     bb7: {
-        _13 = move ((_11 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
-        StorageDead(_14);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageDead(_11);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL
-        _0 = unchecked_shr::<i16>(_1, move _13) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        _11 = move ((_9 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL
+        StorageDead(_12);                // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        StorageDead(_9);                 // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL
+        _0 = unchecked_shr::<i16>(_1, move _11) -> [return: bb8, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
                                          // mir::Constant
                                          // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL
                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) }
     }
 
     bb8: {
-        StorageDead(_13);                // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
+        StorageDead(_11);                // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL
         return;                          // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2
     }
 
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
index 50e0538c133..0cf9643dfc2 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
@@ -15,20 +15,18 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
                 scope 7 (inlined std::ptr::write::<u32>) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL
                     debug dst => _4;     // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
                     debug src => _2;     // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                    let mut _6: *mut u32; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                     scope 8 {
                         scope 9 (inlined std::ptr::write::runtime::<u32>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                            debug dst => _6; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                            debug dst => _4; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                         }
                     }
                 }
             }
             scope 4 (inlined std::ptr::read::<u32>) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL
                 debug src => _3;         // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                let mut _5: *const u32;  // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                 scope 5 {
                     scope 6 (inlined std::ptr::read::runtime::<u32>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                        debug src => _5; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                        debug src => _3; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                     }
                 }
             }
@@ -38,15 +36,11 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
     bb0: {
         StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         _3 = &raw const (*_1);           // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
-        StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         _0 = (*_3);                      // scope 5 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-        StorageDead(_5);                 // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         StorageLive(_4);                 // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         _4 = &raw mut (*_1);             // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
-        StorageLive(_6);                 // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         (*_4) = _2;                      // scope 8 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-        StorageDead(_6);                 // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         StorageDead(_4);                 // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL
         return;                          // scope 0 at $DIR/mem_replace.rs:+2:2: +2:2
     }
diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir
index 089b0c23e2c..73b5678ce04 100644
--- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir
@@ -3,24 +3,21 @@
 fn ezmap(_1: Option<i32>) -> Option<i32> {
     debug x => _1;                       // in scope 0 at $DIR/simple_option_map.rs:+0:14: +0:15
     let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map.rs:+0:33: +0:44
-    let mut _5: i32;                     // in scope 0 at $DIR/simple_option_map.rs:11:25: 11:29
     scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map.rs:18:12: 18:15]>) { // at $DIR/simple_option_map.rs:18:5: 18:22
         debug slf => _1;                 // in scope 1 at $DIR/simple_option_map.rs:6:17: 6:20
         debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:18:12: 18:15]; // in scope 1 at $DIR/simple_option_map.rs:6:33: 6:34
         let mut _2: isize;               // in scope 1 at $DIR/simple_option_map.rs:11:9: 11:16
         let _3: i32;                     // in scope 1 at $DIR/simple_option_map.rs:11:14: 11:15
-        let mut _4: (i32,);              // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29
-        let mut _6: i32;                 // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29
+        let mut _4: i32;                 // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29
         scope 2 {
             debug x => _3;               // in scope 2 at $DIR/simple_option_map.rs:11:14: 11:15
             scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map.rs:11:25: 11:29
-                debug n => _5;           // in scope 3 at $DIR/simple_option_map.rs:+1:13: +1:14
+                debug n => _3;           // in scope 3 at $DIR/simple_option_map.rs:+1:13: +1:14
             }
         }
     }
 
     bb0: {
-        StorageLive(_3);                 // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22
         _2 = discriminant(_1);           // scope 1 at $DIR/simple_option_map.rs:10:11: 10:14
         switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; // scope 1 at $DIR/simple_option_map.rs:10:5: 10:14
     }
@@ -32,21 +29,14 @@ fn ezmap(_1: Option<i32>) -> Option<i32> {
 
     bb2: {
         _3 = ((_1 as Some).0: i32);      // scope 1 at $DIR/simple_option_map.rs:11:14: 11:15
-        StorageLive(_6);                 // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
         StorageLive(_4);                 // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
-        _4 = (move _3,);                 // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
-        StorageLive(_5);                 // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
-        _5 = move (_4.0: i32);           // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
-        _6 = Add(_5, const 1_i32);       // scope 3 at $DIR/simple_option_map.rs:+1:16: +1:21
-        StorageDead(_5);                 // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
-        StorageDead(_4);                 // scope 2 at $DIR/simple_option_map.rs:11:28: 11:29
-        _0 = Option::<i32>::Some(move _6); // scope 2 at $DIR/simple_option_map.rs:11:20: 11:30
-        StorageDead(_6);                 // scope 2 at $DIR/simple_option_map.rs:11:29: 11:30
+        _4 = Add(_3, const 1_i32);       // scope 3 at $DIR/simple_option_map.rs:+1:16: +1:21
+        _0 = Option::<i32>::Some(move _4); // scope 2 at $DIR/simple_option_map.rs:11:20: 11:30
+        StorageDead(_4);                 // scope 2 at $DIR/simple_option_map.rs:11:29: 11:30
         goto -> bb3;                     // scope 1 at $DIR/simple_option_map.rs:14:1: 14:2
     }
 
     bb3: {
-        StorageDead(_3);                 // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22
         return;                          // scope 0 at $DIR/simple_option_map.rs:+2:2: +2:2
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir
index b05d44f4d60..6c306280536 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_mut_usize.PreCodegen.after.mir
@@ -21,19 +21,17 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
                     debug self => _2;    // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                     debug slice => _6;   // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                     let mut _7: *mut u32; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                    let mut _10: usize;  // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                    let mut _11: *mut [u32]; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                     scope 5 {
                         debug this => _2; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                         scope 6 {
                             scope 7 (inlined <usize as SliceIndex<[T]>>::get_unchecked_mut::runtime::<u32>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                                debug this => _10; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                                debug slice => _11; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                                debug this => _2; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                                debug slice => _6; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                                 scope 8 (inlined ptr::mut_ptr::<impl *mut [u32]>::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                                    debug self => _11; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                    let mut _12: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                    debug self => _6; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                    let mut _10: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                     scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                        debug ptr => _12; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                        debug ptr => _10; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
                                         scope 10 {
                                         }
                                     }
@@ -81,14 +79,10 @@ fn slice_get_mut_usize(_1: &mut [u32], _2: usize) -> Option<&mut u32> {
         StorageLive(_6);                 // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         _6 = &raw mut (*_1);             // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         StorageLive(_10);                // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_11);                // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_12);                // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         StorageLive(_7);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         _7 = _6 as *mut u32 (PtrToPtr);  // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
         _8 = Offset(_7, _2);             // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
         StorageDead(_7);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageDead(_12);                // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageDead(_11);                // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         StorageDead(_10);                // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         StorageDead(_6);                 // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         _9 = &mut (*_8);                 // scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir
index 6d9ec5d9a27..727ccc1de53 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir
@@ -4,65 +4,63 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
     debug slice => _1;                   // in scope 0 at $DIR/slice_index.rs:+0:45: +0:50
     debug index => _2;                   // in scope 0 at $DIR/slice_index.rs:+0:64: +0:69
     let mut _0: &mut [u32];              // return place in scope 0 at $DIR/slice_index.rs:+0:88: +0:98
+    let mut _3: usize;                   // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34
+    let mut _4: usize;                   // in scope 0 at $DIR/slice_index.rs:+1:29: +1:34
     scope 1 (inlined core::slice::<impl [u32]>::get_unchecked_mut::<std::ops::Range<usize>>) { // at $DIR/slice_index.rs:26:11: 26:35
         debug self => _1;                // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        debug index => _2;               // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        let mut _3: *mut [u32];          // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        let mut _15: *mut [u32];         // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        debug index => std::ops::Range<usize>{ .0 => _3, .1 => _4, }; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        let mut _5: *mut [u32];          // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        let mut _14: *mut [u32];         // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         scope 2 {
             scope 3 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-                debug self => _2;        // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                debug slice => _3;       // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let mut _4: usize;       // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let mut _5: usize;       // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+                debug self => std::ops::Range<usize>{ .0 => _3, .1 => _4, }; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+                debug slice => _5;       // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                 let mut _7: *mut u32;    // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let mut _8: usize;       // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let mut _9: *mut u32;    // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let mut _10: usize;      // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let _16: std::ops::Range<usize>; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                let mut _17: std::ops::Range<usize>; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                let mut _18: *mut [u32]; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                let mut _8: *mut u32;    // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+                let mut _9: usize;       // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+                let _16: usize;          // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+                let _17: usize;          // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                 scope 4 {
-                    debug this => _16;   // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+                    debug this => std::ops::Range<usize>{ .0 => _16, .1 => _17, }; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                     scope 5 {
                         let _6: usize;   // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                         scope 6 {
                             debug new_len => _6; // in scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                             scope 11 (inlined ptr::mut_ptr::<impl *mut [u32]>::as_mut_ptr) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                                debug self => _3; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                debug self => _5; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                             }
                             scope 12 (inlined ptr::mut_ptr::<impl *mut u32>::add) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL
                                 debug self => _7; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                debug count => _8; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                debug count => _3; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                 scope 13 {
                                 }
                             }
                             scope 14 (inlined slice_from_raw_parts_mut::<u32>) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                                debug data => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                                debug len => _10; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                                let mut _11: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+                                debug data => _8; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+                                debug len => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+                                let mut _10: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
                                 scope 15 (inlined ptr::mut_ptr::<impl *mut u32>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                                    debug self => _9; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                    debug self => _8; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                 }
                                 scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-                                    debug data_address => _11; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-                                    debug metadata => _10; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-                                    let mut _12: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-                                    let mut _13: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-                                    let mut _14: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                    debug data_address => _10; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                    debug metadata => _9; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                    let mut _11: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                    let mut _12: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                    let mut _13: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
                                     scope 17 {
                                     }
                                 }
                             }
                         }
                         scope 7 (inlined <std::ops::Range<usize> as SliceIndex<[T]>>::get_unchecked_mut::runtime::<u32>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                            debug this => _17; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                            debug slice => _18; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                            debug this => std::ops::Range<usize>{ .0 => _16, .1 => _17, }; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                            debug slice => _5; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                             scope 8 (inlined ptr::mut_ptr::<impl *mut [u32]>::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL
-                                debug self => _18; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                let mut _19: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                debug self => _5; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                let mut _15: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                 scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                    debug ptr => _19; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+                                    debug ptr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
                                     scope 10 {
                                     }
                                 }
@@ -75,60 +73,51 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
     }
 
     bb0: {
+        _3 = move (_2.0: usize);         // scope 0 at $DIR/slice_index.rs:+1:29: +1:34
+        _4 = move (_2.1: usize);         // scope 0 at $DIR/slice_index.rs:+1:29: +1:34
+        StorageLive(_14);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        StorageLive(_5);                 // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        _5 = &raw mut (*_1);             // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         StorageLive(_15);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        _3 = &raw mut (*_1);             // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         StorageLive(_16);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         StorageLive(_17);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        StorageLive(_18);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        StorageLive(_19);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         StorageLive(_6);                 // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_4);                 // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _4 = (_2.1: usize);              // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_5);                 // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _5 = (_2.0: usize);              // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _6 = unchecked_sub::<usize>(move _4, move _5) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        _6 = unchecked_sub::<usize>(_4, _3) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
                                          // mir::Constant
                                          // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL
                                          // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize, usize) -> usize {unchecked_sub::<usize>}, val: Value(<ZST>) }
     }
 
     bb1: {
-        StorageDead(_5);                 // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageDead(_4);                 // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_9);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_7);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _7 = _3 as *mut u32 (PtrToPtr);  // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
         StorageLive(_8);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _8 = (_2.0: usize);              // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _9 = Offset(_7, _8);             // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-        StorageDead(_8);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        StorageLive(_7);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        _7 = _5 as *mut u32 (PtrToPtr);  // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+        _8 = Offset(_7, _3);             // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
         StorageDead(_7);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_10);                // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        _10 = _6;                        // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageLive(_11);                // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-        _11 = _9 as *mut () (PtrToPtr);  // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-        StorageLive(_14);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        StorageLive(_9);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        _9 = _6;                         // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        StorageLive(_10);                // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+        _10 = _8 as *mut () (PtrToPtr);  // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
         StorageLive(_13);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
         StorageLive(_12);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        _12 = _11 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        _13 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _12, metadata: _10 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        StorageLive(_11);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        _11 = _10 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        _12 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _11, metadata: _9 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        StorageDead(_11);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        _13 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _12 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
         StorageDead(_12);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        _14 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _13 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        StorageDead(_13);                // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        _15 = (_14.1: *mut [u32]);       // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        StorageDead(_14);                // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
-        StorageDead(_11);                // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-        StorageDead(_10);                // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        _14 = (_13.1: *mut [u32]);       // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        StorageDead(_13);                // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL
+        StorageDead(_10);                // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
         StorageDead(_9);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
+        StorageDead(_8);                 // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL
         StorageDead(_6);                 // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL
-        StorageDead(_19);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        StorageDead(_18);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         StorageDead(_17);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         StorageDead(_16);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        _0 = &mut (*_15);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
-        StorageDead(_15);                // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        StorageDead(_15);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        StorageDead(_5);                 // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        _0 = &mut (*_14);                // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
+        StorageDead(_14);                // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
         return;                          // scope 0 at $DIR/slice_index.rs:+2:2: +2:2
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir
index 0cf1d68d18a..0c18fb84bcd 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir
@@ -39,21 +39,20 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                         scope 13 (inlined NonNull::<T>::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
                             debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
                             let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
-                            let mut _22: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                             scope 14 {
                                 scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                                    debug ptr => _22; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                                    debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                                     scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
-                                        debug self => _22; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                        let mut _23: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                        debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                        let mut _22: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                         scope 17 {
                                             scope 18 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                                debug ptr => _23; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                                debug ptr => _22; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                                 scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                                    debug self => _23; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                                    debug self => _22; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                                     scope 20 {
                                                         scope 21 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                                            debug self => _23; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                                            debug self => _22; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                                         }
                                                     }
                                                 }
@@ -122,10 +121,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);    // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageLive(_10);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageLive(_22);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
-        StorageLive(_23);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
         _11 = NonNull::<T> { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
-        StorageDead(_23);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageDead(_22);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageDead(_10);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageDead(_9);                 // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir
index 4fde50c6fe4..1aa05cbeb97 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir
@@ -44,21 +44,20 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                         scope 13 (inlined NonNull::<T>::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL
                             debug ptr => _9; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
                             let mut _10: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
-                            let mut _24: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                             scope 14 {
                                 scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
-                                    debug ptr => _24; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
+                                    debug ptr => _9; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
                                     scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
-                                        debug self => _24; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                        let mut _25: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                        debug self => _9; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                        let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                         scope 17 {
                                             scope 18 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                                debug ptr => _25; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                                debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                                 scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                                    debug self => _25; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                                    debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                                     scope 20 {
                                                         scope 21 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-                                                            debug self => _25; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
+                                                            debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
                                                         }
                                                     }
                                                 }
@@ -134,10 +133,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         _9 = _4 as *mut T (PtrToPtr);    // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageLive(_10);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageLive(_24);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
-        StorageLive(_25);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         _10 = _9 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
         _11 = NonNull::<T> { pointer: _10 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL
-        StorageDead(_25);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageDead(_24);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageDead(_10);                // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
         StorageDead(_9);                 // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL
diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
index bdf1de468b3..7f0e50a23f9 100644
--- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
+++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
@@ -9,70 +9,61 @@
       let mut _4: std::result::Result<i32, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
       let mut _5: isize;                   // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
       let _6: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let mut _7: !;                       // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-      let _9: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+      let mut _7: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+      let _8: i32;                         // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
       scope 1 {
           debug residual => _6;            // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
           scope 2 {
               scope 8 (inlined #[track_caller] <Result<i32, i32> as FromResidual<Result<Infallible, i32>>>::from_residual) { // at $DIR/separate_const_switch.rs:25:8: 25:10
-                  debug residual => _8;    // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                  let _14: i32;            // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-                  let mut _15: i32;        // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+                  debug residual => _6;    // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+                  let _13: i32;            // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+                  let mut _14: i32;        // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
                   scope 9 {
-                      debug e => _14;      // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
+                      debug e => _13;      // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
                       scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
-                          debug t => _14;  // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
+                          debug t => _13;  // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
                       }
                   }
               }
           }
       }
       scope 3 {
-          debug val => _9;                 // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
+          debug val => _8;                 // in scope 3 at $DIR/separate_const_switch.rs:+1:8: +1:10
           scope 4 {
           }
       }
       scope 5 (inlined <Result<i32, i32> as Try>::branch) { // at $DIR/separate_const_switch.rs:25:8: 25:10
-          debug self => _4;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let mut _10: isize;              // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          debug self => _1;                // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          let mut _9: isize;               // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          let _10: i32;                    // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
           let _11: i32;                    // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let _12: i32;                    // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          let mut _13: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          let mut _12: std::result::Result<std::convert::Infallible, i32>; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
           scope 6 {
-              debug v => _11;              // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+              debug v => _10;              // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
           }
           scope 7 {
-              debug e => _12;              // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+              debug e => _11;              // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
           }
       }
   
       bb0: {
-          StorageLive(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
           StorageLive(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageLive(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
-          _4 = _1;                         // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:9
+          StorageLive(_10);                // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
           StorageLive(_11);                // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageLive(_12);                // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          _10 = discriminant(_4);          // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          switchInt(move _10) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          _9 = discriminant(_1);           // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          switchInt(move _9) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
       }
   
       bb1: {
-          StorageDead(_12);                // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
           StorageDead(_11);                // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
+          StorageDead(_10);                // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
           _5 = discriminant(_3);           // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
           switchInt(move _5) -> [0: bb2, 1: bb4, otherwise: bb3]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
       }
   
       bb2: {
-          StorageLive(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          _9 = ((_3 as Continue).0: i32);  // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          _2 = _9;                         // scope 4 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageDead(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          _0 = Result::<i32, i32>::Ok(move _2); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
-          StorageDead(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+          _8 = ((_3 as Continue).0: i32);  // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
+          _0 = Result::<i32, i32>::Ok(_8); // scope 0 at $DIR/separate_const_switch.rs:+1:5: +1:11
           StorageDead(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
           return;                          // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
       }
@@ -82,30 +73,19 @@
       }
   
       bb4: {
-          StorageLive(_6);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
           _6 = ((_3 as Break).0: std::result::Result<std::convert::Infallible, i32>); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          StorageLive(_8);                 // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          _8 = _6;                         // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          StorageLive(_14);                // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          _14 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
-          StorageLive(_15);                // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-          _15 = move _14;                  // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
-          _0 = Result::<i32, i32>::Err(move _15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-          StorageDead(_15);                // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
-          StorageDead(_14);                // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10
-          StorageDead(_8);                 // scope 2 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          StorageDead(_6);                 // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
-          StorageDead(_2);                 // scope 0 at $DIR/separate_const_switch.rs:+1:10: +1:11
+          _13 = ((_6 as Err).0: i32);      // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
+          _0 = Result::<i32, i32>::Err(move _13); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
           StorageDead(_3);                 // scope 0 at $DIR/separate_const_switch.rs:+2:1: +2:2
           return;                          // scope 0 at $DIR/separate_const_switch.rs:+2:2: +2:2
       }
   
       bb5: {
-          _12 = move ((_4 as Err).0: i32); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          StorageLive(_13);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-          _13 = Result::<Infallible, i32>::Err(move _12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _13); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
-          StorageDead(_13);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+          _11 = ((_1 as Err).0: i32);      // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          StorageLive(_12);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+          _12 = Result::<Infallible, i32>::Err(move _11); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _12); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
+          StorageDead(_12);                // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
           goto -> bb1;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
       }
   
@@ -114,8 +94,8 @@
       }
   
       bb7: {
-          _11 = move ((_4 as Ok).0: i32);  // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
-          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _11); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
+          _10 = ((_1 as Ok).0: i32);       // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
+          _3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(move _10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
           goto -> bb1;                     // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
       }
   }
diff --git a/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
index b5e0a66d83f..f86a96dec41 100644
--- a/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
+++ b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff
@@ -34,13 +34,8 @@
       }
   
       bb1: {
-          StorageLive(_6);                 // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
           _6 = ((_1 as Err).0: usize);     // scope 0 at $DIR/separate_const_switch.rs:+8:17: +8:18
-          StorageLive(_7);                 // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
-          _7 = _6;                         // scope 2 at $DIR/separate_const_switch.rs:+8:42: +8:43
-          _2 = ControlFlow::<usize, i32>::Break(move _7); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
-          StorageDead(_7);                 // scope 2 at $DIR/separate_const_switch.rs:+8:43: +8:44
-          StorageDead(_6);                 // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
+          _2 = ControlFlow::<usize, i32>::Break(_6); // scope 2 at $DIR/separate_const_switch.rs:+8:23: +8:44
           goto -> bb4;                     // scope 0 at $DIR/separate_const_switch.rs:+8:43: +8:44
       }
   
@@ -49,13 +44,8 @@
       }
   
       bb3: {
-          StorageLive(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
           _4 = ((_1 as Ok).0: i32);        // scope 0 at $DIR/separate_const_switch.rs:+7:16: +7:17
-          StorageLive(_5);                 // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
-          _5 = _4;                         // scope 1 at $DIR/separate_const_switch.rs:+7:44: +7:45
-          _2 = ControlFlow::<usize, i32>::Continue(move _5); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
-          StorageDead(_5);                 // scope 1 at $DIR/separate_const_switch.rs:+7:45: +7:46
-          StorageDead(_4);                 // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
+          _2 = ControlFlow::<usize, i32>::Continue(_4); // scope 1 at $DIR/separate_const_switch.rs:+7:22: +7:46
           goto -> bb4;                     // scope 0 at $DIR/separate_const_switch.rs:+7:45: +7:46
       }
   
@@ -73,13 +63,8 @@
       }
   
       bb6: {
-          StorageLive(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
           _9 = ((_2 as Continue).0: i32);  // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32
-          StorageLive(_10);                // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
-          _10 = _9;                        // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43
-          _0 = Option::<i32>::Some(move _10); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
-          StorageDead(_10);                // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44
-          StorageDead(_9);                 // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
+          _0 = Option::<i32>::Some(_9);    // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44
           goto -> bb7;                     // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44
       }
   
diff --git a/tests/rustdoc-gui/codeblock-tooltip.goml b/tests/rustdoc-gui/codeblock-tooltip.goml
index e1c81ed79e4..7be5e39ba47 100644
--- a/tests/rustdoc-gui/codeblock-tooltip.goml
+++ b/tests/rustdoc-gui/codeblock-tooltip.goml
@@ -40,6 +40,7 @@ define-function: (
             "background-color": |background|,
             "border-color": |border|,
         })
+        click: ".docblock .example-wrap.compile_fail .tooltip"
 
         // should_panic block
         assert-css: (
@@ -71,6 +72,7 @@ define-function: (
             "background-color": |background|,
             "border-color": |border|,
         })
+        click: ".docblock .example-wrap.should_panic .tooltip"
 
         // ignore block
         assert-css: (
diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml
index ecb57c274a5..371931d51fc 100644
--- a/tests/rustdoc-gui/notable-trait.goml
+++ b/tests/rustdoc-gui/notable-trait.goml
@@ -122,7 +122,7 @@ assert-count: ("//*[@class='tooltip popover']", 0)
 // Now check the colors.
 define-function: (
     "check-colors",
-    (theme, header_color, content_color, type_color, trait_color),
+    (theme, header_color, content_color, type_color, trait_color, link_color),
     block {
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"
         // This is needed to ensure that the text color is computed.
@@ -133,8 +133,20 @@ define-function: (
         // We reload the page so the local storage settings are being used.
         reload:
 
+        assert-css: (
+             "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
+             {"color": |content_color|},
+             ALL,
+        )
+
         move-cursor-to: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']"
-        assert-count: (".tooltip.popover", 1)
+        wait-for-count: (".tooltip.popover", 1)
+
+        assert-css: (
+             "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
+             {"color": |link_color|},
+             ALL,
+        )
 
         assert-css: (
              ".tooltip.popover h3",
@@ -163,6 +175,7 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
+        "link_color": "rgb(57, 175, 215)",
         "content_color": "rgb(230, 225, 207)",
         "header_color": "rgb(255, 255, 255)",
         "type_color": "rgb(255, 160, 165)",
@@ -174,6 +187,7 @@ call-function: (
     "check-colors",
     {
         "theme": "dark",
+        "link_color": "rgb(210, 153, 29)",
         "content_color": "rgb(221, 221, 221)",
         "header_color": "rgb(221, 221, 221)",
         "type_color": "rgb(45, 191, 184)",
@@ -185,6 +199,7 @@ call-function: (
     "check-colors",
     {
         "theme": "light",
+        "link_color": "rgb(56, 115, 173)",
         "content_color": "rgb(0, 0, 0)",
         "header_color": "rgb(0, 0, 0)",
         "type_color": "rgb(173, 55, 138)",
diff --git a/tests/rustdoc-gui/theme-in-history.goml b/tests/rustdoc-gui/theme-in-history.goml
index 8fcd0ecd309..42c5b5e6e69 100644
--- a/tests/rustdoc-gui/theme-in-history.goml
+++ b/tests/rustdoc-gui/theme-in-history.goml
@@ -7,7 +7,7 @@ set-local-storage: {
 }
 // We reload the page so the local storage settings are being used.
 reload:
-assert-css: ("body", { "background-color": "rgb(53, 53, 53)" })
+assert-css: ("body", { "background-color": "#353535" })
 assert-local-storage: { "rustdoc-theme": "dark" }
 
 // Now we go to the settings page.
@@ -15,7 +15,7 @@ go-to: "file://" + |DOC_PATH| + "/settings.html"
 wait-for: "#settings"
 // We change the theme to "light".
 click: "#theme-light"
-wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+wait-for-css: ("body", { "background-color": "white" })
 assert-local-storage: { "rustdoc-theme": "light" }
 
 // We go back in history.
@@ -23,5 +23,5 @@ history-go-back:
 // Confirm that we're not on the settings page.
 assert-false: "#settings"
 // Check that the current theme is still "light".
-assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
+assert-css: ("body", { "background-color": "white" })
 assert-local-storage: { "rustdoc-theme": "light" }
diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/issue-108459.rs
new file mode 100644
index 00000000000..eb1c7a05e54
--- /dev/null
+++ b/tests/rustdoc/intra-doc/issue-108459.rs
@@ -0,0 +1,37 @@
+#![deny(rustdoc::broken_intra_doc_links)]
+
+pub struct S;
+pub mod char {}
+
+// Ensure this doesn't ICE due to trying to slice off non-existent backticks from "S"
+
+/// See [S] and [`S`]
+pub struct MyStruct1;
+
+// Ensure that link texts are replaced correctly even if there are multiple links with
+// the same target but different text
+
+/// See also [crate::char] and [mod@char] and [prim@char]
+// @has issue_108459/struct.MyStruct2.html '//*[@href="char/index.html"]' 'crate::char'
+// @has - '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct2;
+
+/// See also [mod@char] and [prim@char] and [crate::char]
+// @has issue_108459/struct.MyStruct3.html '//*[@href="char/index.html"]' 'crate::char'
+// @has - '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct3;
+
+// Ensure that links are correct even if there are multiple links with the same text but
+// different targets
+
+/// See also [char][mod@char] and [char][prim@char]
+// @has issue_108459/struct.MyStruct4.html '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct4;
+
+/// See also [char][prim@char] and [char][crate::char]
+// @has issue_108459/struct.MyStruct5.html '//*[@href="char/index.html"]' 'char'
+// @has - '//*[@href="{{channel}}/std/primitive.char.html"]' 'char'
+pub struct MyStruct5;
diff --git a/tests/rustdoc/intra-doc/prim-precedence.rs b/tests/rustdoc/intra-doc/prim-precedence.rs
index 25625b95277..c5a64e42a01 100644
--- a/tests/rustdoc/intra-doc/prim-precedence.rs
+++ b/tests/rustdoc/intra-doc/prim-precedence.rs
@@ -12,5 +12,5 @@ pub struct MyString;
 
 /// See also [crate::char] and [mod@char]
 // @has prim_precedence/struct.MyString2.html '//*[@href="char/index.html"]' 'crate::char'
-// @has - '//*[@href="char/index.html"]' 'mod@char'
+// @has - '//*[@href="char/index.html"]' 'char'
 pub struct MyString2;
diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport-doc-hidden-inside-private.rs
new file mode 100644
index 00000000000..1e4216d3c0c
--- /dev/null
+++ b/tests/rustdoc/reexport-doc-hidden-inside-private.rs
@@ -0,0 +1,16 @@
+// This test ensures that a re-export of  `#[doc(hidden)]` item inside a private
+// module will still be displayed (the re-export, not the item).
+
+#![crate_name = "foo"]
+
+mod private_module {
+    #[doc(hidden)]
+    pub struct Public;
+}
+
+// @has 'foo/index.html'
+// @has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
+pub use crate::private_module::Public as Foo;
+// Glob re-exports with no visible items should not be displayed.
+// @count - '//*[@class="item-table"]/li' 1
+pub use crate::private_module::*;
diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr
index 7e64e67f24c..e6d46b02706 100644
--- a/tests/ui/chalkify/bugs/async.stderr
+++ b/tests/ui/chalkify/bugs/async.stderr
@@ -13,16 +13,9 @@ error: internal compiler error: projection clauses should be implied from elsewh
 LL | async fn foo(x: u32) -> u32 {
    |                         ^^^query stack during panic:
 #0 [typeck] type-checking `foo`
-#1 [thir_body] building THIR for `foo`
-#2 [check_match] match-checking `foo`
-#3 [mir_built] building MIR for `foo`
-#4 [unsafety_check_result] unsafety-checking `foo`
-#5 [mir_const] preparing `foo` for borrow checking
-#6 [mir_promoted] promoting constants in MIR for `foo`
-#7 [mir_borrowck] borrow-checking `foo`
-#8 [type_of] computing type of `foo::{opaque#0}`
-#9 [check_mod_item_types] checking item types in top-level module
-#10 [analysis] running analysis passes on this crate
+#1 [type_of] computing type of `foo::{opaque#0}`
+#2 [check_mod_item_types] checking item types in top-level module
+#3 [analysis] running analysis passes on this crate
 end of query stack
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-100313.rs b/tests/ui/const-generics/issues/issue-100313.rs
index 4e9d3626aa8..9a9d4721c84 100644
--- a/tests/ui/const-generics/issues/issue-100313.rs
+++ b/tests/ui/const-generics/issues/issue-100313.rs
@@ -9,6 +9,7 @@ impl <const B: &'static bool> T<B> {
         unsafe {
             *(B as *const bool as *mut bool) = false;
             //~^ ERROR evaluation of constant value failed [E0080]
+            //~| ERROR casting `&T` to `&mut T` is undefined behavior
         }
     }
 }
diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr
index d4b486376ca..ffc34a3a41e 100644
--- a/tests/ui/const-generics/issues/issue-100313.stderr
+++ b/tests/ui/const-generics/issues/issue-100313.stderr
@@ -1,3 +1,11 @@
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/issue-100313.rs:10:13
+   |
+LL |             *(B as *const bool as *mut bool) = false;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(cast_ref_to_mut)]` on by default
+
 error[E0080]: evaluation of constant value failed
   --> $DIR/issue-100313.rs:10:13
    |
@@ -10,11 +18,11 @@ note: inside `T::<&true>::set_false`
 LL |             *(B as *const bool as *mut bool) = false;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: inside `_`
-  --> $DIR/issue-100313.rs:18:5
+  --> $DIR/issue-100313.rs:19:5
    |
 LL |     x.set_false();
    |     ^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/infinite_loop.rs b/tests/ui/consts/const-eval/infinite_loop.rs
index 4babc9a2850..21781490637 100644
--- a/tests/ui/consts/const-eval/infinite_loop.rs
+++ b/tests/ui/consts/const-eval/infinite_loop.rs
@@ -4,8 +4,8 @@ fn main() {
     let _ = [(); {
         let mut n = 113383; // #20 in https://oeis.org/A006884
         while n != 0 {
-            //~^ ERROR evaluation of constant value failed
-            n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
+            //~^ ERROR is taking a long time
+            n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 };
         }
         n
     }];
diff --git a/tests/ui/consts/const-eval/infinite_loop.stderr b/tests/ui/consts/const-eval/infinite_loop.stderr
index f30bfaf3f95..f0434a847ce 100644
--- a/tests/ui/consts/const-eval/infinite_loop.stderr
+++ b/tests/ui/consts/const-eval/infinite_loop.stderr
@@ -1,12 +1,27 @@
-error[E0080]: evaluation of constant value failed
+error: constant evaluation is taking a long time
   --> $DIR/infinite_loop.rs:6:9
    |
 LL | /         while n != 0 {
 LL | |
-LL | |             n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
+LL | |             n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 };
 LL | |         }
-   | |_________^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+   | |_________^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/infinite_loop.rs:4:18
+   |
+LL |       let _ = [(); {
+   |  __________________^
+LL | |         let mut n = 113383; // #20 in https://oeis.org/A006884
+LL | |         while n != 0 {
+LL | |
+...  |
+LL | |         n
+LL | |     }];
+   | |_____^
+   = note: `#[deny(long_running_const_eval)]` on by default
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-52475.rs b/tests/ui/consts/const-eval/issue-52475.rs
index 307c1a66834..ee26d280018 100644
--- a/tests/ui/consts/const-eval/issue-52475.rs
+++ b/tests/ui/consts/const-eval/issue-52475.rs
@@ -2,7 +2,8 @@ fn main() {
     let _ = [(); {
         let mut x = &0;
         let mut n = 0;
-        while n < 5 { //~ ERROR evaluation of constant value failed [E0080]
+        while n < 5 {
+            //~^ ERROR: constant evaluation is taking a long time
             n = (n + 1) % 5;
             x = &0; // Materialize a new AllocId
         }
diff --git a/tests/ui/consts/const-eval/issue-52475.stderr b/tests/ui/consts/const-eval/issue-52475.stderr
index 3aa6bd277dd..ebf9d12a66a 100644
--- a/tests/ui/consts/const-eval/issue-52475.stderr
+++ b/tests/ui/consts/const-eval/issue-52475.stderr
@@ -1,12 +1,28 @@
-error[E0080]: evaluation of constant value failed
+error: constant evaluation is taking a long time
   --> $DIR/issue-52475.rs:5:9
    |
 LL | /         while n < 5 {
+LL | |
 LL | |             n = (n + 1) % 5;
 LL | |             x = &0; // Materialize a new AllocId
 LL | |         }
-   | |_________^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+   | |_________^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/issue-52475.rs:2:18
+   |
+LL |       let _ = [(); {
+   |  __________________^
+LL | |         let mut x = &0;
+LL | |         let mut n = 0;
+LL | |         while n < 5 {
+...  |
+LL | |         0
+LL | |     }];
+   | |_____^
+   = note: `#[deny(long_running_const_eval)]` on by default
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-70723.rs b/tests/ui/consts/const-eval/issue-70723.rs
index 3c81afa67a6..c8c809a25ed 100644
--- a/tests/ui/consts/const-eval/issue-70723.rs
+++ b/tests/ui/consts/const-eval/issue-70723.rs
@@ -1,3 +1,3 @@
-static _X: () = loop {}; //~ ERROR could not evaluate static initializer
+static _X: () = loop {}; //~ ERROR taking a long time
 
 fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-70723.stderr b/tests/ui/consts/const-eval/issue-70723.stderr
index 09fb3e060dc..572a430726f 100644
--- a/tests/ui/consts/const-eval/issue-70723.stderr
+++ b/tests/ui/consts/const-eval/issue-70723.stderr
@@ -1,9 +1,17 @@
-error[E0080]: could not evaluate static initializer
+error: constant evaluation is taking a long time
   --> $DIR/issue-70723.rs:1:17
    |
 LL | static _X: () = loop {};
-   |                 ^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+   |                 ^^^^^^^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/issue-70723.rs:1:1
+   |
+LL | static _X: () = loop {};
+   | ^^^^^^^^^^^^^
+   = note: `#[deny(long_running_const_eval)]` on by default
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs b/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs
index c59596238e1..a30518170ad 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs
@@ -25,7 +25,7 @@ const fn call_foo() -> u32 {
     foo();
     foo();
     foo();
-    foo(); //~ ERROR evaluation of constant value failed [E0080]
+    foo(); //~ ERROR is taking a long time
     0
 }
 
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr
index ed70975af34..a3fd712ca46 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr
@@ -1,20 +1,17 @@
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ctfe-fn-call.rs:28:5
-   |
-LL |     foo();
-   |     ^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
-   |
-note: inside `call_foo`
+error: constant evaluation is taking a long time
   --> $DIR/ctfe-fn-call.rs:28:5
    |
 LL |     foo();
    |     ^^^^^
-note: inside `X`
-  --> $DIR/ctfe-fn-call.rs:32:16
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/ctfe-fn-call.rs:32:1
    |
 LL | const X: u32 = call_foo();
-   |                ^^^^^^^^^^
+   | ^^^^^^^^^^^^
+   = note: `#[deny(long_running_const_eval)]` on by default
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.rs b/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.rs
index c10b8d83791..f7cd04568be 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.rs
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.rs
@@ -3,9 +3,10 @@
 
 const fn labelled_loop(n: u32) -> u32 {
     let mut i = 0;
-    'mylabel: loop { //~ ERROR evaluation of constant value failed [E0080]
+    'mylabel: loop {
+        //~^ ERROR is taking a long time
         if i > n {
-            break 'mylabel
+            break 'mylabel;
         }
         i += 1;
     }
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr
index d9404edd5b1..5808ee35a6b 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr
@@ -1,30 +1,23 @@
-error[E0080]: evaluation of constant value failed
+error: constant evaluation is taking a long time
   --> $DIR/ctfe-labelled-loop.rs:6:5
    |
 LL | /     'mylabel: loop {
+LL | |
 LL | |         if i > n {
-LL | |             break 'mylabel
-LL | |         }
-LL | |         i += 1;
-LL | |     }
-   | |_____^ exceeded interpreter step limit (see `#[const_eval_limit]`)
-   |
-note: inside `labelled_loop`
-  --> $DIR/ctfe-labelled-loop.rs:6:5
-   |
-LL | /     'mylabel: loop {
-LL | |         if i > n {
-LL | |             break 'mylabel
+LL | |             break 'mylabel;
 LL | |         }
 LL | |         i += 1;
 LL | |     }
    | |_____^
-note: inside `X`
-  --> $DIR/ctfe-labelled-loop.rs:15:16
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/ctfe-labelled-loop.rs:16:1
    |
 LL | const X: u32 = labelled_loop(19);
-   |                ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^
+   = note: `#[deny(long_running_const_eval)]` on by default
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.rs b/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.rs
index 80ff835f3e8..56a39fc45b0 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.rs
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.rs
@@ -1,11 +1,12 @@
 // check-fail
 // compile-flags: -Z tiny-const-eval-limit
 
+#[rustfmt::skip]
 const fn recurse(n: u32) -> u32 {
     if n == 0 {
         n
     } else {
-        recurse(n - 1) //~ ERROR evaluation of constant value failed [E0080]
+        recurse(n - 1) //~ ERROR is taking a long time
     }
 }
 
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr
index ed9a3111942..524c8e55426 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr
@@ -1,25 +1,17 @@
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ctfe-recursion.rs:8:9
-   |
-LL |         recurse(n - 1)
-   |         ^^^^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
-   |
-note: inside `recurse`
-  --> $DIR/ctfe-recursion.rs:8:9
+error: constant evaluation is taking a long time
+  --> $DIR/ctfe-recursion.rs:9:9
    |
 LL |         recurse(n - 1)
    |         ^^^^^^^^^^^^^^
-note: [... 18 additional calls inside `recurse` ...]
-  --> $DIR/ctfe-recursion.rs:8:9
    |
-LL |         recurse(n - 1)
-   |         ^^^^^^^^^^^^^^
-note: inside `X`
-  --> $DIR/ctfe-recursion.rs:12:16
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/ctfe-recursion.rs:13:1
    |
 LL | const X: u32 = recurse(19);
-   |                ^^^^^^^^^^^
+   | ^^^^^^^^^^^^
+   = note: `#[deny(long_running_const_eval)]` on by default
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr
new file mode 100644
index 00000000000..30550f93ac1
--- /dev/null
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.allow.stderr
@@ -0,0 +1,19 @@
+warning: constant evaluation is taking a long time
+  --> $DIR/ctfe-simple-loop.rs:9:5
+   |
+LL | /     while index < n {
+LL | |
+LL | |
+LL | |
+LL | |         index = index + 1;
+LL | |     }
+   | |_____^ the const evaluator is currently interpreting this expression
+   |
+help: the constant being evaluated
+  --> $DIR/ctfe-simple-loop.rs:19:1
+   |
+LL | const Y: u32 = simple_loop(35);
+   | ^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.rs b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.rs
index ca0eec93c5d..214f33dfb36 100644
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.rs
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.rs
@@ -1,14 +1,22 @@
-// check-fail
+// check-pass
+// revisions: warn allow
+#![cfg_attr(warn, warn(long_running_const_eval))]
+#![cfg_attr(allow, allow(long_running_const_eval))]
+
 // compile-flags: -Z tiny-const-eval-limit
 const fn simple_loop(n: u32) -> u32 {
     let mut index = 0;
-    while index < n { //~ ERROR evaluation of constant value failed [E0080]
+    while index < n {
+        //~^ WARN is taking a long time
+        //[warn]~| WARN is taking a long time
+        //[warn]~| WARN is taking a long time
         index = index + 1;
     }
     0
 }
 
 const X: u32 = simple_loop(19);
+const Y: u32 = simple_loop(35);
 
 fn main() {
     println!("{X}");
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.stderr
deleted file mode 100644
index 83ff275de70..00000000000
--- a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error[E0080]: evaluation of constant value failed
-  --> $DIR/ctfe-simple-loop.rs:5:5
-   |
-LL | /     while index < n {
-LL | |         index = index + 1;
-LL | |     }
-   | |_____^ exceeded interpreter step limit (see `#[const_eval_limit]`)
-   |
-note: inside `simple_loop`
-  --> $DIR/ctfe-simple-loop.rs:5:5
-   |
-LL | /     while index < n {
-LL | |         index = index + 1;
-LL | |     }
-   | |_____^
-note: inside `X`
-  --> $DIR/ctfe-simple-loop.rs:11:16
-   |
-LL | const X: u32 = simple_loop(19);
-   |                ^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr
new file mode 100644
index 00000000000..40fc4a876e9
--- /dev/null
+++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr
@@ -0,0 +1,62 @@
+warning: constant evaluation is taking a long time
+  --> $DIR/ctfe-simple-loop.rs:9:5
+   |
+LL | /     while index < n {
+LL | |
+LL | |
+LL | |
+LL | |         index = index + 1;
+LL | |     }
+   | |_____^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/ctfe-simple-loop.rs:18:1
+   |
+LL | const X: u32 = simple_loop(19);
+   | ^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/ctfe-simple-loop.rs:3:24
+   |
+LL | #![cfg_attr(warn, warn(long_running_const_eval))]
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: constant evaluation is taking a long time
+  --> $DIR/ctfe-simple-loop.rs:9:5
+   |
+LL | /     while index < n {
+LL | |
+LL | |
+LL | |
+LL | |         index = index + 1;
+LL | |     }
+   | |_____^
+   |
+   = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
+           If your compilation actually takes a long time, you can safely allow the lint.
+help: the constant being evaluated
+  --> $DIR/ctfe-simple-loop.rs:19:1
+   |
+LL | const Y: u32 = simple_loop(35);
+   | ^^^^^^^^^^^^
+
+warning: constant evaluation is taking a long time
+  --> $DIR/ctfe-simple-loop.rs:9:5
+   |
+LL | /     while index < n {
+LL | |
+LL | |
+LL | |
+LL | |         index = index + 1;
+LL | |     }
+   | |_____^ the const evaluator is currently interpreting this expression
+   |
+help: the constant being evaluated
+  --> $DIR/ctfe-simple-loop.rs:19:1
+   |
+LL | const Y: u32 = simple_loop(35);
+   | ^^^^^^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/consts/const_limit/const_eval_limit_not_reached.rs b/tests/ui/consts/const_limit/const_eval_limit_not_reached.rs
deleted file mode 100644
index 629d1f02a30..00000000000
--- a/tests/ui/consts/const_limit/const_eval_limit_not_reached.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// check-pass
-
-#![feature(const_eval_limit)]
-
-// This needs to be higher than the number of loop iterations since each pass through the loop may
-// hit more than one terminator.
-#![const_eval_limit="4000"]
-
-const X: usize = {
-    let mut x = 0;
-    while x != 1000 {
-        x += 1;
-    }
-
-    x
-};
-
-fn main() {
-    assert_eq!(X, 1000);
-}
diff --git a/tests/ui/consts/const_limit/const_eval_limit_overflow.rs b/tests/ui/consts/const_limit/const_eval_limit_overflow.rs
deleted file mode 100644
index 1c49593cd53..00000000000
--- a/tests/ui/consts/const_limit/const_eval_limit_overflow.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(const_eval_limit)]
-#![const_eval_limit="18_446_744_073_709_551_615"]
-//~^ ERROR `limit` must be a non-negative integer
-
-const CONSTANT: usize = limit();
-
-fn main() {
-    assert_eq!(CONSTANT, 1764);
-}
-
-const fn limit() -> usize {
-    let x = 42;
-
-    x * 42
-}
diff --git a/tests/ui/consts/const_limit/const_eval_limit_overflow.stderr b/tests/ui/consts/const_limit/const_eval_limit_overflow.stderr
deleted file mode 100644
index 7f5d5e6cd4c..00000000000
--- a/tests/ui/consts/const_limit/const_eval_limit_overflow.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: `limit` must be a non-negative integer
-  --> $DIR/const_eval_limit_overflow.rs:2:1
-   |
-LL | #![const_eval_limit="18_446_744_073_709_551_615"]
-   | ^^^^^^^^^^^^^^^^^^^^----------------------------^
-   |                     |
-   |                     not a valid integer
-
-error: aborting due to previous error
-
diff --git a/tests/ui/consts/const_limit/const_eval_limit_reached.rs b/tests/ui/consts/const_limit/const_eval_limit_reached.rs
deleted file mode 100644
index 3ce038c1d3f..00000000000
--- a/tests/ui/consts/const_limit/const_eval_limit_reached.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-#![feature(const_eval_limit)]
-#![const_eval_limit = "500"]
-
-const X: usize = {
-    let mut x = 0;
-    while x != 1000 {
-        //~^ ERROR evaluation of constant value failed
-        x += 1;
-    }
-
-    x
-};
-
-fn main() {
-    assert_eq!(X, 1000);
-}
diff --git a/tests/ui/consts/const_limit/const_eval_limit_reached.stderr b/tests/ui/consts/const_limit/const_eval_limit_reached.stderr
deleted file mode 100644
index a8e8ae9bb08..00000000000
--- a/tests/ui/consts/const_limit/const_eval_limit_reached.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const_eval_limit_reached.rs:6:5
-   |
-LL | /     while x != 1000 {
-LL | |
-LL | |         x += 1;
-LL | |     }
-   | |_____^ exceeded interpreter step limit (see `#[const_eval_limit]`)
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const_limit/feature-gate-const_eval_limit.rs b/tests/ui/consts/const_limit/feature-gate-const_eval_limit.rs
deleted file mode 100644
index 61119d7511d..00000000000
--- a/tests/ui/consts/const_limit/feature-gate-const_eval_limit.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#![const_eval_limit="42"]
-//~^ ERROR the `#[const_eval_limit]` attribute is an experimental feature [E0658]
-
-const CONSTANT: usize = limit();
-
-fn main() {
-    assert_eq!(CONSTANT, 1764);
-}
-
-const fn limit() -> usize {
-    let x = 42;
-
-    x * 42
-}
diff --git a/tests/ui/consts/const_limit/feature-gate-const_eval_limit.stderr b/tests/ui/consts/const_limit/feature-gate-const_eval_limit.stderr
deleted file mode 100644
index 5bd29c7dfd2..00000000000
--- a/tests/ui/consts/const_limit/feature-gate-const_eval_limit.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: the `#[const_eval_limit]` attribute is an experimental feature
-  --> $DIR/feature-gate-const_eval_limit.rs:1:1
-   |
-LL | #![const_eval_limit="42"]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #67217 <https://github.com/rust-lang/rust/issues/67217> for more information
-   = help: add `#![feature(const_eval_limit)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/dyn-star/param-env-infer.next.stderr b/tests/ui/dyn-star/param-env-infer.next.stderr
index 64d76bb04b1..408abecc30d 100644
--- a/tests/ui/dyn-star/param-env-infer.next.stderr
+++ b/tests/ui/dyn-star/param-env-infer.next.stderr
@@ -13,41 +13,6 @@ error[E0391]: cycle detected when computing type of `make_dyn_star::{opaque#0}`
 LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
    |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: ...which requires borrow-checking `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `make_dyn_star` for borrow checking...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires unsafety-checking `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires match-checking `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building THIR for `make_dyn_star`...
-  --> $DIR/param-env-infer.rs:11:1
-   |
-LL | fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `make_dyn_star`...
   --> $DIR/param-env-infer.rs:11:1
    |
diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr
index aa4ee75bb75..c0c4cd5013e 100644
--- a/tests/ui/impl-trait/auto-trait-leak.stderr
+++ b/tests/ui/impl-trait/auto-trait-leak.stderr
@@ -4,41 +4,6 @@ error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}`
 LL | fn cycle1() -> impl Clone {
    |                ^^^^^^^^^^
    |
-note: ...which requires borrow-checking `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `cycle1` for borrow checking...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires unsafety-checking `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires match-checking `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building THIR for `cycle1`...
-  --> $DIR/auto-trait-leak.rs:12:1
-   |
-LL | fn cycle1() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `cycle1`...
   --> $DIR/auto-trait-leak.rs:14:5
    |
@@ -50,41 +15,6 @@ note: ...which requires computing type of `cycle2::{opaque#0}`...
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
-note: ...which requires borrow-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires preparing `cycle2` for borrow checking...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires unsafety-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires match-checking `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building THIR for `cycle2`...
-  --> $DIR/auto-trait-leak.rs:19:1
-   |
-LL | fn cycle2() -> impl Clone {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires type-checking `cycle2`...
   --> $DIR/auto-trait-leak.rs:20:5
    |
diff --git a/tests/ui/impl-trait/multiple-defining-usages-in-body.rs b/tests/ui/impl-trait/multiple-defining-usages-in-body.rs
index c3a6f09f86d..86661153a0d 100644
--- a/tests/ui/impl-trait/multiple-defining-usages-in-body.rs
+++ b/tests/ui/impl-trait/multiple-defining-usages-in-body.rs
@@ -4,9 +4,9 @@ impl Trait for () {}
 fn foo<T: Trait, U: Trait>() -> impl Trait {
     //~^ WARN function cannot return without recursing [unconditional_recursion]
     let a: T = foo::<T, U>();
-    //~^ ERROR concrete type differs from previous defining opaque type use
     loop {}
     let _: T = foo::<U, T>();
+    //~^ ERROR concrete type differs from previous defining opaque type use
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr b/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr
index 06991749bfa..f3c090408b4 100644
--- a/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr
+++ b/tests/ui/impl-trait/multiple-defining-usages-in-body.stderr
@@ -11,15 +11,15 @@ LL |     let a: T = foo::<T, U>();
    = note: `#[warn(unconditional_recursion)]` on by default
 
 error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-defining-usages-in-body.rs:6:16
+  --> $DIR/multiple-defining-usages-in-body.rs:8:16
    |
-LL |     let a: T = foo::<T, U>();
-   |                ^^^^^^^^^^^^^ expected `U`, got `T`
+LL |     let _: T = foo::<U, T>();
+   |                ^^^^^^^^^^^^^ expected `T`, got `U`
    |
 note: previous use here
-  --> $DIR/multiple-defining-usages-in-body.rs:9:16
+  --> $DIR/multiple-defining-usages-in-body.rs:6:16
    |
-LL |     let _: T = foo::<U, T>();
+LL |     let a: T = foo::<T, U>();
    |                ^^^^^^^^^^^^^
 
 error: aborting due to previous error; 1 warning emitted
diff --git a/tests/ui/linkage-attr/incompatible-flavor.rs b/tests/ui/linkage-attr/incompatible-flavor.rs
new file mode 100644
index 00000000000..90c2b612f22
--- /dev/null
+++ b/tests/ui/linkage-attr/incompatible-flavor.rs
@@ -0,0 +1,6 @@
+// compile-flags: --target=x86_64-unknown-linux-gnu -C linker-flavor=msvc --crate-type=rlib
+// error-pattern: linker flavor `msvc` is incompatible with the current target
+// needs-llvm-components:
+
+#![feature(no_core)]
+#![no_core]
diff --git a/tests/ui/linkage-attr/incompatible-flavor.stderr b/tests/ui/linkage-attr/incompatible-flavor.stderr
new file mode 100644
index 00000000000..e07e778521c
--- /dev/null
+++ b/tests/ui/linkage-attr/incompatible-flavor.stderr
@@ -0,0 +1,6 @@
+error: linker flavor `msvc` is incompatible with the current target
+   |
+   = note: compatible flavors are: gcc, ld, ld.lld
+
+error: aborting due to previous error
+
diff --git a/tests/ui/linkage-attr/issue-10755.rs b/tests/ui/linkage-attr/issue-10755.rs
index afd2dc46ca3..0df5d842cb2 100644
--- a/tests/ui/linkage-attr/issue-10755.rs
+++ b/tests/ui/linkage-attr/issue-10755.rs
@@ -1,6 +1,6 @@
 // build-fail
 // dont-check-compiler-stderr
-// compile-flags: -C linker=llllll -C linker-flavor=ld
+// compile-flags: -C linker=llllll
 // error-pattern: `llllll`
 
 // Before, the error-pattern checked for "not found". On WSL with appendWindowsPath=true, running
diff --git a/tests/ui/linkage-attr/unstable-flavor.bpf.stderr b/tests/ui/linkage-attr/unstable-flavor.bpf.stderr
new file mode 100644
index 00000000000..3346d12c20e
--- /dev/null
+++ b/tests/ui/linkage-attr/unstable-flavor.bpf.stderr
@@ -0,0 +1,2 @@
+error: linker flavor `bpf-linker` is unstable, `-Z unstable-options` flag must also be passed to explicitly use it
+
diff --git a/tests/ui/linkage-attr/unstable-flavor.ptx.stderr b/tests/ui/linkage-attr/unstable-flavor.ptx.stderr
new file mode 100644
index 00000000000..03ca2a01246
--- /dev/null
+++ b/tests/ui/linkage-attr/unstable-flavor.ptx.stderr
@@ -0,0 +1,2 @@
+error: linker flavor `ptx-linker` is unstable, `-Z unstable-options` flag must also be passed to explicitly use it
+
diff --git a/tests/ui/linkage-attr/unstable-flavor.rs b/tests/ui/linkage-attr/unstable-flavor.rs
new file mode 100644
index 00000000000..5487882dc24
--- /dev/null
+++ b/tests/ui/linkage-attr/unstable-flavor.rs
@@ -0,0 +1,10 @@
+// revisions: bpf ptx
+// [bpf] compile-flags: --target=bpfel-unknown-none -C linker-flavor=bpf-linker --crate-type=rlib
+// [bpf] error-pattern: linker flavor `bpf-linker` is unstable, `-Z unstable-options` flag
+// [bpf] needs-llvm-components:
+// [ptx] compile-flags: --target=nvptx64-nvidia-cuda -C linker-flavor=ptx-linker --crate-type=rlib
+// [ptx] error-pattern: linker flavor `ptx-linker` is unstable, `-Z unstable-options` flag
+// [ptx] needs-llvm-components:
+
+#![feature(no_core)]
+#![no_core]
diff --git a/tests/ui/lint/cast_ref_to_mut.rs b/tests/ui/lint/cast_ref_to_mut.rs
new file mode 100644
index 00000000000..745d7070143
--- /dev/null
+++ b/tests/ui/lint/cast_ref_to_mut.rs
@@ -0,0 +1,50 @@
+// check-fail
+
+#![feature(ptr_from_ref)]
+
+extern "C" {
+    // N.B., mutability can be easily incorrect in FFI calls -- as
+    // in C, the default is mutable pointers.
+    fn ffi(c: *mut u8);
+    fn int_ffi(c: *mut i32);
+}
+
+fn main() {
+    let s = String::from("Hello");
+    let a = &s;
+    unsafe {
+        let num = &3i32;
+        let mut_num = &mut 3i32;
+
+        (*(a as *const _ as *mut String)).push_str(" world");
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        *(a as *const _ as *mut _) = String::from("Replaced");
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        *(a as *const _ as *mut String) += " world";
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        let _num = &mut *(num as *const i32 as *mut i32);
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        let _num = &mut *(num as *const i32).cast_mut();
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        let _num = *{ num as *const i32 }.cast_mut();
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        *std::ptr::from_ref(num).cast_mut() += 1;
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        *std::ptr::from_ref({ num }).cast_mut() += 1;
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        *{ std::ptr::from_ref(num) }.cast_mut() += 1;
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+        *(std::ptr::from_ref({ num }) as *mut i32) += 1;
+        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+
+        // Shouldn't be warned against
+        println!("{}", *(num as *const _ as *const i16));
+        println!("{}", *(mut_num as *mut _ as *mut i16));
+        ffi(a.as_ptr() as *mut _);
+        int_ffi(num as *const _ as *mut _);
+        int_ffi(&3 as *const _ as *mut _);
+        let mut value = 3;
+        let value: *const i32 = &mut value;
+        *(value as *const i16 as *mut i16) = 42;
+    }
+}
diff --git a/tests/ui/lint/cast_ref_to_mut.stderr b/tests/ui/lint/cast_ref_to_mut.stderr
new file mode 100644
index 00000000000..baff00d6c04
--- /dev/null
+++ b/tests/ui/lint/cast_ref_to_mut.stderr
@@ -0,0 +1,64 @@
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:19:9
+   |
+LL |         (*(a as *const _ as *mut String)).push_str(" world");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(cast_ref_to_mut)]` on by default
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:21:9
+   |
+LL |         *(a as *const _ as *mut _) = String::from("Replaced");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:23:9
+   |
+LL |         *(a as *const _ as *mut String) += " world";
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:25:25
+   |
+LL |         let _num = &mut *(num as *const i32 as *mut i32);
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:27:25
+   |
+LL |         let _num = &mut *(num as *const i32).cast_mut();
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:29:20
+   |
+LL |         let _num = *{ num as *const i32 }.cast_mut();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:31:9
+   |
+LL |         *std::ptr::from_ref(num).cast_mut() += 1;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:33:9
+   |
+LL |         *std::ptr::from_ref({ num }).cast_mut() += 1;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:35:9
+   |
+LL |         *{ std::ptr::from_ref(num) }.cast_mut() += 1;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/cast_ref_to_mut.rs:37:9
+   |
+LL |         *(std::ptr::from_ref({ num }) as *mut i32) += 1;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/loops/dont-suggest-break-thru-item.rs b/tests/ui/loops/dont-suggest-break-thru-item.rs
new file mode 100644
index 00000000000..b46ba89e81d
--- /dev/null
+++ b/tests/ui/loops/dont-suggest-break-thru-item.rs
@@ -0,0 +1,55 @@
+// edition:2021
+
+#![feature(inline_const)]
+
+fn closure() {
+    loop {
+        let closure = || {
+            if true {
+                Err(1)
+                //~^ ERROR mismatched types
+            }
+
+            Ok(())
+        };
+    }
+}
+
+fn async_block() {
+    loop {
+        let fut = async {
+            if true {
+                Err(1)
+                //~^ ERROR mismatched types
+            }
+
+            Ok(())
+        };
+    }
+}
+
+fn fn_item() {
+    let _ = loop {
+        fn foo() -> Result<(), ()> {
+            if true {
+                Err(1)
+                //~^ ERROR mismatched types
+            }
+            Err(())
+        }
+    };
+}
+
+fn const_block() {
+    let _ = loop {
+        const {
+            if true {
+                Err(1)
+                //~^ ERROR mismatched types
+            }
+            Err(())
+        };
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr
new file mode 100644
index 00000000000..4fce4715119
--- /dev/null
+++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr
@@ -0,0 +1,55 @@
+error[E0308]: mismatched types
+  --> $DIR/dont-suggest-break-thru-item.rs:9:17
+   |
+LL | /             if true {
+LL | |                 Err(1)
+   | |                 ^^^^^^ expected `()`, found `Result<_, {integer}>`
+LL | |
+LL | |             }
+   | |_____________- expected this to be `()`
+   |
+   = note: expected unit type `()`
+                   found enum `Result<_, {integer}>`
+
+error[E0308]: mismatched types
+  --> $DIR/dont-suggest-break-thru-item.rs:22:17
+   |
+LL | /             if true {
+LL | |                 Err(1)
+   | |                 ^^^^^^ expected `()`, found `Result<_, {integer}>`
+LL | |
+LL | |             }
+   | |_____________- expected this to be `()`
+   |
+   = note: expected unit type `()`
+                   found enum `Result<_, {integer}>`
+
+error[E0308]: mismatched types
+  --> $DIR/dont-suggest-break-thru-item.rs:35:17
+   |
+LL | /             if true {
+LL | |                 Err(1)
+   | |                 ^^^^^^ expected `()`, found `Result<_, {integer}>`
+LL | |
+LL | |             }
+   | |_____________- expected this to be `()`
+   |
+   = note: expected unit type `()`
+                   found enum `Result<_, {integer}>`
+
+error[E0308]: mismatched types
+  --> $DIR/dont-suggest-break-thru-item.rs:47:17
+   |
+LL | /             if true {
+LL | |                 Err(1)
+   | |                 ^^^^^^ expected `()`, found `Result<_, {integer}>`
+LL | |
+LL | |             }
+   | |_____________- expected this to be `()`
+   |
+   = note: expected unit type `()`
+                   found enum `Result<_, {integer}>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/match/issue-70972-dyn-trait.rs b/tests/ui/match/issue-70972-dyn-trait.rs
index 97d161c59ec..df28c474ab0 100644
--- a/tests/ui/match/issue-70972-dyn-trait.rs
+++ b/tests/ui/match/issue-70972-dyn-trait.rs
@@ -4,7 +4,7 @@ fn main() {
     let a: &dyn Send = &7u32;
     match a {
         F => panic!(),
-        //~^ ERROR `&dyn Send` cannot be used in patterns
+        //~^ ERROR `dyn Send` cannot be used in patterns
         _ => {}
     }
 }
diff --git a/tests/ui/match/issue-70972-dyn-trait.stderr b/tests/ui/match/issue-70972-dyn-trait.stderr
index 7581070ebc1..f4dc910c34a 100644
--- a/tests/ui/match/issue-70972-dyn-trait.stderr
+++ b/tests/ui/match/issue-70972-dyn-trait.stderr
@@ -1,4 +1,4 @@
-error: `&dyn Send` cannot be used in patterns
+error: `dyn Send` cannot be used in patterns
   --> $DIR/issue-70972-dyn-trait.rs:6:9
    |
 LL |         F => panic!(),
diff --git a/tests/ui/offset-of/offset-of-unsized.rs b/tests/ui/offset-of/offset-of-unsized.rs
new file mode 100644
index 00000000000..666387e615e
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-unsized.rs
@@ -0,0 +1,15 @@
+// build-pass
+// regression test for #112051
+
+#![feature(offset_of)]
+
+struct S<T: ?Sized> {
+    a: u64,
+    b: T,
+}
+trait Tr {}
+
+fn main() {
+    let _a = core::mem::offset_of!(S<dyn Tr>, a);
+    let _b = core::mem::offset_of!((u64, dyn Tr), 0);
+}
diff --git a/tests/ui/pattern/issue-72565.rs b/tests/ui/pattern/issue-72565.rs
index 1e262fd5067..21edb26de08 100644
--- a/tests/ui/pattern/issue-72565.rs
+++ b/tests/ui/pattern/issue-72565.rs
@@ -3,6 +3,6 @@ const F: &'static dyn PartialEq<u32> = &7u32;
 fn main() {
     let a: &dyn PartialEq<u32> = &7u32;
     match a {
-        F => panic!(), //~ ERROR: `&dyn PartialEq<u32>` cannot be used in patterns
+        F => panic!(), //~ ERROR: `dyn PartialEq<u32>` cannot be used in patterns
     }
 }
diff --git a/tests/ui/pattern/issue-72565.stderr b/tests/ui/pattern/issue-72565.stderr
index 2f82616b277..0519720694d 100644
--- a/tests/ui/pattern/issue-72565.stderr
+++ b/tests/ui/pattern/issue-72565.stderr
@@ -1,4 +1,4 @@
-error: `&dyn PartialEq<u32>` cannot be used in patterns
+error: `dyn PartialEq<u32>` cannot be used in patterns
   --> $DIR/issue-72565.rs:6:9
    |
 LL |         F => panic!(),
diff --git a/tests/ui/suggestions/issue-88696.rs b/tests/ui/suggestions/issue-88696.rs
new file mode 100644
index 00000000000..745fdef1546
--- /dev/null
+++ b/tests/ui/suggestions/issue-88696.rs
@@ -0,0 +1,14 @@
+// This test case should ensure that miniz_oxide isn't
+// suggested, since it's not a direct dependency.
+
+fn a() -> Result<u64, i32> {
+    Err(1)
+}
+
+fn b() -> Result<u32, i32> {
+    a().into() //~ERROR [E0277]
+}
+
+fn main() {
+    let _ = dbg!(b());
+}
diff --git a/tests/ui/suggestions/issue-88696.stderr b/tests/ui/suggestions/issue-88696.stderr
new file mode 100644
index 00000000000..4947269d759
--- /dev/null
+++ b/tests/ui/suggestions/issue-88696.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `Result<u32, i32>: From<Result<u64, i32>>` is not satisfied
+  --> $DIR/issue-88696.rs:9:9
+   |
+LL |     a().into()
+   |         ^^^^ the trait `From<Result<u64, i32>>` is not implemented for `Result<u32, i32>`
+   |
+   = note: required for `Result<u64, i32>` to implement `Into<Result<u32, i32>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/track-diagnostics/track6.stderr b/tests/ui/track-diagnostics/track6.stderr
index 89438aea9ad..583b02555b4 100644
--- a/tests/ui/track-diagnostics/track6.stderr
+++ b/tests/ui/track-diagnostics/track6.stderr
@@ -3,7 +3,7 @@ error[E0658]: specialization is unstable
    |
 LL |     default fn bar() {}
    |     ^^^^^^^^^^^^^^^^^^^
--Ztrack-diagnostics: created at $COMPILER_DIR/rustc_session/src/parse.rs:LL:CC
+-Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC
    |
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: add `#![feature(specialization)]` to the crate attributes to enable
diff --git a/tests/ui/traits/new-solver/dont-remap-tait-substs.rs b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
new file mode 100644
index 00000000000..028222f4e6d
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-remap-tait-substs.rs
@@ -0,0 +1,19 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+// Makes sure we don't prepopulate the MIR typeck of `define`
+// with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
+// the param-env predicates actually apply.
+
+#![feature(type_alias_impl_trait)]
+
+type Foo<T: Send, U> = impl NeedsSend<T>;
+
+trait NeedsSend<T> {}
+impl<T: Send> NeedsSend<T> for T {}
+
+fn define<A, B: Send>(a: A, b: B) {
+    let y: Option<Foo<B, A>> = Some(b);
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/structural-resolve-field.rs b/tests/ui/traits/new-solver/structural-resolve-field.rs
index 01899c9ad64..c492d927696 100644
--- a/tests/ui/traits/new-solver/structural-resolve-field.rs
+++ b/tests/ui/traits/new-solver/structural-resolve-field.rs
@@ -1,13 +1,35 @@
 // compile-flags: -Ztrait-solver=next
 // check-pass
 
-#[derive(Default)]
 struct Foo {
     x: i32,
 }
 
+impl MyDefault for Foo {
+    fn my_default() -> Self {
+        Self {
+            x: 0,
+        }
+    }
+}
+
+trait MyDefault {
+    fn my_default() -> Self;
+}
+
+impl MyDefault for [Foo; 0]  {
+    fn my_default() -> Self {
+        []
+    }
+}
+impl MyDefault for [Foo; 1] {
+    fn my_default() -> Self {
+        [Foo::my_default(); 1]
+    }
+}
+
 fn main() {
-    let mut xs = <[Foo; 1]>::default();
+    let mut xs = <[Foo; 1]>::my_default();
     xs[0].x = 1;
     (&mut xs[0]).x = 2;
 }
diff --git a/tests/ui/type-alias-impl-trait/cross_inference.rs b/tests/ui/type-alias-impl-trait/cross_inference.rs
index dafaf40a69d..07f3dd1997b 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference.rs
@@ -1,3 +1,5 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 // check-pass
 
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
index 9ae2c34b935..da845e86147 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
@@ -8,7 +8,6 @@ type X<A, B> = impl Into<&'static A>;
 
 fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
     //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
-    //~| ERROR concrete type differs from previous defining opaque type use
     (a, a)
 }
 
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
index 0d24d42ba62..66a6b0bbf74 100644
--- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -10,15 +10,6 @@ help: consider introducing a `where` clause, but there might be an alternative b
 LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
    |                                                                ++++++++++++++++++++++++++
 
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/multiple-def-uses-in-one-fn.rs:9:45
-   |
-LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
-   |                                             ^^^^^^^^^^^^^^^^^^
-   |                                             |
-   |                                             expected `&B`, got `&A`
-   |                                             this expression supplies two conflicting concrete types for the same opaque type
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0277`.