about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock143
-rw-r--r--Cargo.toml1
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs41
-rw-r--r--compiler/rustc_borrowck/src/nll.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs3
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs6
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs11
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md26
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs42
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs49
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs75
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs12
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs41
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/explicit.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs46
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/mod.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs6
-rw-r--r--compiler/rustc_infer/src/infer/at.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs13
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs10
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/mod.rs20
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs57
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs32
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs144
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs19
-rw-r--r--compiler/rustc_infer/src/infer/undo_log.rs15
-rw-r--r--compiler/rustc_lint/messages.ftl8
-rw-r--r--compiler/rustc_lint/src/invalid_from_utf8.rs118
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs19
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/query.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs5
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs10
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs103
-rw-r--r--compiler/rustc_middle/src/ty/error.rs13
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs13
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs6
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs81
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs59
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs106
-rw-r--r--compiler/rustc_middle/src/ty/subst.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_middle/src/values.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs3
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs1
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs8
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs2
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs1
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs1182
-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_monomorphize/src/util.rs4
-rw-r--r--compiler/rustc_query_impl/Cargo.toml2
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_session/src/parse.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs2
-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_trait_selection/src/solve/assembly/structural_traits.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonicalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs111
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs12
-rw-r--r--compiler/rustc_traits/src/chalk/db.rs2
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs24
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs4
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs2
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs2
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs2
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs7
-rw-r--r--compiler/rustc_type_ir/src/lib.rs23
-rw-r--r--compiler/rustc_type_ir/src/structural_impls.rs21
-rw-r--r--compiler/rustc_type_ir/src/sty.rs72
-rw-r--r--library/alloc/tests/str.rs2
-rw-r--r--library/core/src/alloc/mod.rs5
-rw-r--r--library/core/src/array/mod.rs23
-rw-r--r--library/core/src/iter/range.rs25
-rw-r--r--library/core/src/iter/traits/marker.rs2
-rw-r--r--library/core/src/str/converts.rs4
-rw-r--r--library/portable-simd/Cargo.toml2
-rw-r--r--library/std/src/ffi/mod.rs8
-rw-r--r--library/std/src/ffi/os_str.rs82
-rw-r--r--library/std/src/path.rs52
-rw-r--r--library/std/src/sys/common/small_c_string.rs2
-rw-r--r--library/std/src/sys/common/tests.rs4
-rw-r--r--library/std/src/sys/unix/os_str.rs9
-rw-r--r--library/std/src/sys/unix/os_str/tests.rs9
-rw-r--r--library/std/src/sys/unix/path.rs2
-rw-r--r--library/std/src/sys/unix/process/process_common.rs4
-rw-r--r--library/std/src/sys/windows/args.rs6
-rw-r--r--library/std/src/sys/windows/os_str.rs10
-rw-r--r--library/std/src/sys/windows/path.rs42
-rw-r--r--library/std/src/sys/windows/process.rs4
-rw-r--r--library/std/src/sys_common/wtf8.rs8
-rw-r--r--src/bootstrap/bootstrap.py10
-rw-r--r--src/bootstrap/builder.rs48
-rw-r--r--src/bootstrap/builder/tests.rs14
-rw-r--r--src/bootstrap/check.rs79
-rw-r--r--src/bootstrap/compile.rs23
-rw-r--r--src/bootstrap/config.rs13
-rw-r--r--src/bootstrap/dist.rs6
-rw-r--r--src/bootstrap/doc.rs210
-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.rs23
-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.rs26
-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/test-various/uefi_qemu_test/Cargo.toml1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rw-r--r--src/etc/test-float-parse/Cargo.toml1
-rw-r--r--src/librustdoc/clean/blanket_impl.rs2
-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/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/json/conversions.rs5
-rw-r--r--src/librustdoc/visit_ast.rs57
-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/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs74
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs2
-rw-r--r--src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.rs20
-rw-r--r--src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.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.stderr104
-rw-r--r--src/tools/compiletest/src/runtest.rs47
-rw-r--r--src/tools/miri/tests/pass/shims/time-with-isolation2.stdout2
-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/deps.rs1
-rw-r--r--src/tools/tidy/src/ui_tests.rs4
-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.rs8
-rw-r--r--tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs90
-rw-r--r--tests/incremental/issue-110457-same-span-closures/main.rs47
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir108
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir52
-rw-r--r--tests/rustdoc-gui/target.goml8
-rw-r--r--tests/rustdoc/reexport-doc-hidden-inside-private.rs16
-rw-r--r--tests/ui/async-await/issue-78115.rs (renamed from tests/ui/issues/issue-78115.rs)0
-rw-r--r--tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs18
-rw-r--r--tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr14
-rw-r--r--tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs31
-rw-r--r--tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr15
-rw-r--r--tests/ui/coercion/issue-3794.rs (renamed from tests/ui/issues/issue-3794.rs)0
-rw-r--r--tests/ui/coherence/coherence-inherited-subtyping.re.stderr14
-rw-r--r--tests/ui/coherence/coherence-inherited-subtyping.rs2
-rw-r--r--tests/ui/coherence/coherence-inherited-subtyping.stderr (renamed from tests/ui/coherence/coherence-inherited-subtyping.old.stderr)2
-rw-r--r--tests/ui/coinduction/canonicalization-rerun.rs4
-rw-r--r--tests/ui/consts/issue-16538.mir.stderr (renamed from tests/ui/issues/issue-16538.mir.stderr)0
-rw-r--r--tests/ui/consts/issue-16538.rs (renamed from tests/ui/issues/issue-16538.rs)0
-rw-r--r--tests/ui/consts/issue-16538.thir.stderr (renamed from tests/ui/issues/issue-16538.thir.stderr)0
-rw-r--r--tests/ui/consts/issue-28822.rs (renamed from tests/ui/issues/issue-28822.rs)0
-rw-r--r--tests/ui/consts/issue-29798.rs (renamed from tests/ui/issues/issue-29798.rs)0
-rw-r--r--tests/ui/enum-discriminant/issue-50689.rs (renamed from tests/ui/issues/issue-50689.rs)0
-rw-r--r--tests/ui/extern/issue-1251.rs (renamed from tests/ui/issues/issue-1251.rs)0
-rw-r--r--tests/ui/for-loop-while/issue-1257.rs (renamed from tests/ui/issues/issue-1257.rs)0
-rw-r--r--tests/ui/higher-rank-trait-bounds/issue-95230.rs11
-rw-r--r--tests/ui/higher-ranked/higher-lifetime-bounds.rs (renamed from tests/ui/higher-lifetime-bounds.rs)0
-rw-r--r--tests/ui/higher-ranked/higher-lifetime-bounds.stderr (renamed from tests/ui/higher-lifetime-bounds.stderr)0
-rw-r--r--tests/ui/higher-ranked/leak-check-in-selection.rs24
-rw-r--r--tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr (renamed from tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr)0
-rw-r--r--tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr (renamed from tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr)0
-rw-r--r--tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr (renamed from tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr)0
-rw-r--r--tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr (renamed from tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr)0
-rw-r--r--tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr (renamed from tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr)0
-rw-r--r--tests/ui/higher-ranked/subtype/hr-subtype.rs (renamed from tests/ui/hr-subtype/hr-subtype.rs)0
-rw-r--r--tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs (renamed from tests/ui/hr-subtype/placeholder-pattern-fail.rs)0
-rw-r--r--tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr (renamed from tests/ui/hr-subtype/placeholder-pattern-fail.stderr)0
-rw-r--r--tests/ui/higher-ranked/subtype/placeholder-pattern.rs (renamed from tests/ui/hr-subtype/placeholder-pattern.rs)0
-rw-r--r--tests/ui/higher-ranked/subtype/return-static.rs (renamed from tests/ui/hr-subtype/return-static.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/complex.rs (renamed from tests/ui/higher-rank-trait-bounds/complex.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs (renamed from tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr (renamed from tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr (renamed from tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/fn-ptr.rs (renamed from tests/ui/higher-rank-trait-bounds/fn-ptr.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs (renamed from tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr (renamed from tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr)2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-parse.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs (renamed from tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr (renamed from tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-100689.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-100689.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-102899.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-102899.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-30786.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-30786.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-30786.stderr (renamed from tests/ui/higher-rank-trait-bounds/issue-30786.stderr)2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-39292.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-39292.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-42114.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-42114.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-43623.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-43623.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-46989.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-46989.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-46989.stderr (renamed from tests/ui/higher-rank-trait-bounds/issue-46989.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-57639.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-57639.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-58451.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-58451.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-58451.stderr (renamed from tests/ui/higher-rank-trait-bounds/issue-58451.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-59311.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-59311.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-59311.stderr (renamed from tests/ui/higher-rank-trait-bounds/issue-59311.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-60283.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-60283.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr (renamed from tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-88446.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-88446.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-90177.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-90177.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-95034.rs (renamed from tests/ui/higher-rank-trait-bounds/issue-95034.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr (renamed from tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-95230.rs11
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs)0
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr (renamed from tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr)0
-rw-r--r--tests/ui/impl-trait/autoderef.rs2
-rw-r--r--tests/ui/lint/invalid_from_utf8.rs93
-rw-r--r--tests/ui/lint/invalid_from_utf8.stderr110
-rw-r--r--tests/ui/mismatched_types/E0053.stderr2
-rw-r--r--tests/ui/mismatched_types/issue-112036.rs7
-rw-r--r--tests/ui/mismatched_types/issue-112036.stderr15
-rw-r--r--tests/ui/offset-of/offset-of-unsized.rs15
-rw-r--r--tests/ui/pattern/issue-94866.rs (renamed from tests/ui/issue-94866.rs)0
-rw-r--r--tests/ui/pattern/issue-94866.stderr (renamed from tests/ui/issue-94866.stderr)0
-rw-r--r--tests/ui/process/process-panic-after-fork.rs2
-rw-r--r--tests/ui/structs-enums/issue-3008-1.rs (renamed from tests/ui/issues/issue-3008-1.rs)0
-rw-r--r--tests/ui/structs-enums/issue-3008-1.stderr (renamed from tests/ui/issues/issue-3008-1.stderr)0
-rw-r--r--tests/ui/structs-enums/issue-3008-2.rs (renamed from tests/ui/issues/issue-3008-2.rs)0
-rw-r--r--tests/ui/structs-enums/issue-3008-2.stderr (renamed from tests/ui/issues/issue-3008-2.stderr)0
-rw-r--r--tests/ui/structs-enums/issue-3008-3.rs (renamed from tests/ui/issues/issue-3008-3.rs)0
-rw-r--r--tests/ui/structs-enums/issue-3008-3.stderr (renamed from tests/ui/issues/issue-3008-3.stderr)0
-rw-r--r--tests/ui/suggestions/issue-103646.rs11
-rw-r--r--tests/ui/suggestions/issue-103646.stderr21
-rw-r--r--tests/ui/thir-print/thir-flat.stdout2
-rw-r--r--tests/ui/track-diagnostics/track6.stderr2
-rw-r--r--tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs33
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_generalization.rs2
-rw-r--r--tests/ui/typeck/issue-106929.rs13
-rw-r--r--tests/ui/typeck/issue-106929.stderr15
-rw-r--r--tests/ui/typeck/issue-1871.rs (renamed from tests/ui/issues/issue-1871.rs)0
-rw-r--r--tests/ui/typeck/issue-1871.stderr (renamed from tests/ui/issues/issue-1871.stderr)0
-rw-r--r--tests/ui/typeck/issue-2063-resource.rs (renamed from tests/ui/issues/issue-2063-resource.rs)0
-rw-r--r--tests/ui/typeck/issue-2063.rs (renamed from tests/ui/issues/issue-2063.rs)0
-rw-r--r--tests/ui/where-clauses/issue-50825-1.rs (renamed from tests/ui/issues/issue-50825-1.rs)0
-rw-r--r--tests/ui/where-clauses/issue-50825.rs (renamed from tests/ui/issues/issue-50825.rs)0
370 files changed, 3780 insertions, 2944 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 443e6d09156..e7aa317ad75 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -272,17 +272,6 @@ dependencies = [
 
 [[package]]
 name = "bstr"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
-dependencies = [
- "lazy_static",
- "memchr",
- "regex-automata 0.1.10",
-]
-
-[[package]]
-name = "bstr"
 version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1"
@@ -417,9 +406,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.77"
+version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
 
 [[package]]
 name = "cfg-if"
@@ -667,16 +656,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "codespan-reporting"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
-dependencies = [
- "termcolor",
- "unicode-width",
-]
-
-[[package]]
 name = "collect-license-metadata"
 version = "0.1.0"
 dependencies = [
@@ -842,9 +821,9 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-channel"
-version = "0.5.6"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
 dependencies = [
  "cfg-if",
  "crossbeam-utils",
@@ -863,14 +842,14 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-epoch"
-version = "0.9.13"
+version = "0.9.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
+checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
 dependencies = [
  "autocfg",
  "cfg-if",
  "crossbeam-utils",
- "memoffset 0.7.1",
+ "memoffset",
  "scopeguard",
 ]
 
@@ -944,50 +923,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "cxx"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93"
-dependencies = [
- "cc",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
-]
-
-[[package]]
-name = "cxx-build"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b"
-dependencies = [
- "cc",
- "codespan-reporting",
- "once_cell",
- "proc-macro2",
- "quote",
- "scratch",
- "syn 2.0.8",
-]
-
-[[package]]
-name = "cxxbridge-flags"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.8",
-]
-
-[[package]]
 name = "datafrog"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1273,7 +1208,7 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535"
 dependencies = [
- "memoffset 0.8.0",
+ "memoffset",
  "rustc_version",
 ]
 
@@ -1548,12 +1483,12 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
 [[package]]
 name = "globset"
-version = "0.4.9"
+version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a"
+checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
 dependencies = [
  "aho-corasick",
- "bstr 0.2.17",
+ "bstr",
  "fnv",
  "log",
  "regex",
@@ -1688,12 +1623,11 @@ dependencies = [
 
 [[package]]
 name = "iana-time-zone-haiku"
-version = "0.1.1"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
 dependencies = [
- "cxx",
- "cxx-build",
+ "cc",
 ]
 
 [[package]]
@@ -1780,11 +1714,10 @@ checksum = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d"
 
 [[package]]
 name = "ignore"
-version = "0.4.18"
+version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d"
+checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
 dependencies = [
- "crossbeam-utils",
  "globset",
  "lazy_static",
  "log",
@@ -2036,15 +1969,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "link-cplusplus"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
-dependencies = [
- "cc",
-]
-
-[[package]]
 name = "linkchecker"
 version = "0.1.0"
 dependencies = [
@@ -2226,24 +2150,6 @@ dependencies = [
 
 [[package]]
 name = "memoffset"
-version = "0.6.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "memoffset"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "memoffset"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
@@ -2439,11 +2345,11 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
 
 [[package]]
 name = "opener"
-version = "0.5.0"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ea3ebcd72a54701f56345f16785a6d3ac2df7e986d273eb4395c0b01db17952"
+checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005"
 dependencies = [
- "bstr 0.2.17",
+ "bstr",
  "winapi",
 ]
 
@@ -4082,7 +3988,7 @@ version = "0.0.0"
 dependencies = [
  "field-offset",
  "measureme",
- "memoffset 0.6.5",
+ "memoffset",
  "rustc-rayon-core",
  "rustc_ast",
  "rustc_data_structures",
@@ -4383,6 +4289,7 @@ dependencies = [
 name = "rustdoc-gui-test"
 version = "0.1.0"
 dependencies = [
+ "build_helper",
  "compiletest",
  "getopts",
  "walkdir",
@@ -4531,12 +4438,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
-name = "scratch"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
-
-[[package]]
 name = "self_cell"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5234,7 +5135,7 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "191a442639ea102fa62671026047e51d574bfda44b7fdf32151d7314624c1cd2"
 dependencies = [
- "bstr 1.3.0",
+ "bstr",
  "cargo-platform",
  "cargo_metadata 0.15.3",
  "color-eyre",
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/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index b775739fed2..b719a610e07 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -50,7 +50,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
         PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
         PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
         PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
-        PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
 
         // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not
         // contain dangling references.
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index f41795d60a0..cfcf31fce32 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -180,24 +180,25 @@ trait TypeOpInfo<'tcx> {
             return;
         };
 
-        let placeholder_region = tcx.mk_re_placeholder(ty::Placeholder {
-            universe: adjusted_universe.into(),
-            bound: placeholder.bound,
-        });
-
-        let error_region =
-            if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
-                let adjusted_universe =
-                    error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
-                adjusted_universe.map(|adjusted| {
-                    tcx.mk_re_placeholder(ty::Placeholder {
-                        universe: adjusted.into(),
-                        bound: error_placeholder.bound,
-                    })
-                })
-            } else {
-                None
-            };
+        let placeholder_region = ty::Region::new_placeholder(
+            tcx,
+            ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
+        );
+
+        let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
+            error_element
+        {
+            let adjusted_universe =
+                error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
+            adjusted_universe.map(|adjusted| {
+                ty::Region::new_placeholder(
+                    tcx,
+                    ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
+                )
+            })
+        } else {
+            None
+        };
 
         debug!(?placeholder_region);
 
@@ -390,7 +391,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
         error_region,
         &region_constraints,
         |vid| ocx.infcx.region_var_origin(vid),
-        |vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_re_var(vid)),
+        |vid| ocx.infcx.universe_of_region(ty::Region::new_var(ocx.infcx.tcx, vid)),
     )
 }
 
@@ -411,7 +412,7 @@ fn try_extract_error_from_region_constraints<'tcx>(
                 }
                 // FIXME: Should this check the universe of the var?
                 Constraint::VarSubReg(vid, sup) if sup == placeholder_region => {
-                    Some((infcx.tcx.mk_re_var(vid), cause.clone()))
+                    Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
                 }
                 _ => None,
             }
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 889acb3acbe..b5014a3f479 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -441,7 +441,7 @@ fn for_each_region_constraint<'tcx>(
         let subject = match req.subject {
             ClosureOutlivesSubject::Region(subject) => format!("{:?}", subject),
             ClosureOutlivesSubject::Ty(ty) => {
-                format!("{:?}", ty.instantiate(tcx, |vid| tcx.mk_re_var(vid)))
+                format!("{:?}", ty.instantiate(tcx, |vid| ty::Region::new_var(tcx, vid)))
             }
         };
         with_msg(format!("where {}: {:?}", subject, req.outlived_free_region,))?;
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 50b246b1478..2a0cb49672b 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1158,7 +1158,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 .universal_regions_outlived_by(r_scc)
                 .filter(|&u_r| !self.universal_regions.is_local_free_region(u_r))
                 .find(|&u_r| self.eval_equal(u_r, r_vid))
-                .map(|u_r| tcx.mk_re_var(u_r))
+                .map(|u_r| ty::Region::new_var(tcx, u_r))
                 // In the case of a failure, use `ReErased`. We will eventually
                 // return `None` in this case.
                 .unwrap_or(tcx.lifetimes.re_erased)
@@ -1355,7 +1355,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             let vid = self.to_region_vid(r);
             let scc = self.constraint_sccs.scc(vid);
             let repr = self.scc_representatives[scc];
-            tcx.mk_re_var(repr)
+            ty::Region::new_var(tcx, repr)
         })
     }
 
@@ -1779,7 +1779,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
 
             // If not, report an error.
-            let member_region = infcx.tcx.mk_re_var(member_region_vid);
+            let member_region = ty::Region::new_var(infcx.tcx, member_region_vid);
             errors_buffer.push(RegionErrorKind::UnexpectedHiddenRegion {
                 span: m_c.definition_span,
                 hidden_ty: m_c.hidden_ty,
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 7fc89e89a35..33f07c1d8fc 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -92,7 +92,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     }
                     None => {
                         subst_regions.push(vid);
-                        infcx.tcx.mk_re_error_with_message(
+                        ty::Region::new_error_with_message(
+                            infcx.tcx,
                             concrete_type.span,
                             "opaque type with non-universal region substs",
                         )
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 51a84ce6cad..3b896f6540c 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -139,7 +139,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
     upvars: &[Upvar<'tcx>],
     use_polonius: bool,
 ) -> MirTypeckResults<'tcx> {
-    let implicit_region_bound = infcx.tcx.mk_re_var(universal_regions.fr_fn_body);
+    let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
     let mut constraints = MirTypeckRegionConstraints {
         placeholder_indices: PlaceholderIndices::default(),
         placeholder_index_to_region: IndexVec::default(),
@@ -766,8 +766,8 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
             PlaceContext::MutatingUse(_) => ty::Invariant,
             PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
             PlaceContext::NonMutatingUse(
-                Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | UniqueBorrow
-                | AddressOf | Projection,
+                Inspect | Copy | Move | PlaceMention | SharedBorrow | ShallowBorrow | AddressOf
+                | Projection,
             ) => ty::Covariant,
             PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
         }
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 56f078f2da8..c871703429a 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -500,7 +500,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("c-variadic")))
                     .as_var();
 
-                let region = self.infcx.tcx.mk_re_var(reg_vid);
+                let region = ty::Region::new_var(self.infcx.tcx, reg_vid);
                 let va_list_ty =
                     self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]);
 
@@ -660,7 +660,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                     kind: ty::BrEnv,
                 };
-                let env_region = tcx.mk_re_late_bound(ty::INNERMOST, br);
+                let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
                 let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
 
                 // The "inputs" of the closure in the
@@ -778,7 +778,8 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
     {
         let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
             debug!(?br);
-            let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind);
+            let liberated_region =
+                ty::Region::new_free(self.tcx, all_outlive_scope.to_def_id(), br.kind);
             let region_vid = {
                 let name = match br.kind.get_name() {
                     Some(name) => name,
@@ -889,7 +890,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        tcx.fold_regions(value, |region, _| tcx.mk_re_var(self.to_region_vid(region)))
+        tcx.fold_regions(value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region)))
     }
 }
 
@@ -929,7 +930,7 @@ fn for_each_late_bound_region_in_item<'tcx>(
 
     for bound_var in tcx.late_bound_vars(tcx.hir().local_def_id_to_hir_id(mir_def_id)) {
         let ty::BoundVariableKind::Region(bound_region) = bound_var else { continue; };
-        let liberated_region = tcx.mk_re_free(mir_def_id.to_def_id(), bound_region);
+        let liberated_region = ty::Region::new_free(tcx, mir_def_id.to_def_id(), bound_region);
         f(liberated_region);
     }
 }
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index c5222982aa7..26dccf309e1 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -42,6 +42,32 @@ This will build your project with rustc_codegen_cranelift instead of the usual L
 
 For additional ways to use rustc_codegen_cranelift like the JIT mode see [usage.md](docs/usage.md).
 
+## Building and testing with changes in rustc code
+
+This is useful when changing code in `rustc_codegen_cranelift` as part of changing [main Rust repository](https://github.com/rust-lang/rust/).
+This can happen, for example, when you are implementing a new compiler intrinsic.
+
+Instruction below uses `$RustCheckoutDir` as substitute for any folder where you cloned Rust repository.
+
+You need to do this steps to successfully compile and use the cranelift backend with your changes in rustc code:
+
+1. `cd $RustCheckoutDir`
+2. Run `python x.py setup` and choose option for compiler (`b`).
+3. Build compiler and necessary tools: `python x.py build --stage=2 compiler library/std src/tools/rustdoc src/tools/rustfmt`
+   * (Optional) You can also build cargo by adding `src/tools/cargo` to previous command.
+4. Copy exectutable files from `./build/host/stage2-tools/<your hostname triple>/release`
+to `./build/host/stage2/bin/`. Note that you would need to do this every time you rebuilt `rust` repository.
+5. Copy cargo from another toolchain: `cp $(rustup which cargo) .build/<your hostname triple>/stage2/bin/cargo`
+   * Another option is to build it at step 3 and copy with other executables at step 4.
+6. Link your new `rustc` to toolchain: `rustup toolchain link stage2 ./build/host/stage2/`.
+7. (Windows only) compile y.rs: `rustc +stage2 -O y.rs`.
+8. You need to prefix every `./y.rs` (or `y` if you built `y.rs`) command by `rustup run stage2` to make cg_clif use your local changes in rustc.
+
+  * `rustup run stage2 ./y.rs prepare`
+  * `rustup run stage2 ./y.rs build`
+  * (Optional) run tests: `rustup run stage2 ./y.rs test`
+9. Now you can use your cg_clif build to compile other Rust programs, e.g. you can open any Rust crate and run commands like `$RustCheckoutDir/compiler/rustc_codegen_cranelift/dist/cargo-clif build --release`.
+
 ## Configuration
 
 See the documentation on the `BackendConfig` struct in [config.rs](src/config.rs) for all
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 70cb6dfd66f..67fd6d793e0 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
         self.instance.subst_mir_and_normalize_erasing_regions(
             self.tcx,
             ty::ParamEnv::reveal_all(),
-            ty::EarlyBinder::new(value),
+            ty::EarlyBinder::bind(value),
         )
     }
 
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index ac04b61a306..bad87db4732 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -1,17 +1,15 @@
 use gccjit::LValue;
 use gccjit::{RValue, Type, ToRValue};
-use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::{
     BaseTypeMethods,
     ConstMethods,
-    DerivedTypeMethods,
     MiscMethods,
     StaticMethods,
 };
 use rustc_middle::mir::Mutability;
-use rustc_middle::ty::layout::{TyAndLayout, LayoutOf};
+use rustc_middle::ty::layout::{LayoutOf};
 use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
-use rustc_target::abi::{self, HasDataLayout, Pointer, Size};
+use rustc_target::abi::{self, HasDataLayout, Pointer};
 
 use crate::consts::const_alloc_to_gcc;
 use crate::context::CodegenCx;
@@ -240,28 +238,26 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         const_alloc_to_gcc(self, alloc)
     }
 
-    fn from_const_alloc(&self, layout: TyAndLayout<'tcx>, alloc: ConstAllocation<'tcx>, offset: Size) -> PlaceRef<'tcx, RValue<'gcc>> {
-        assert_eq!(alloc.inner().align, layout.align.abi);
-        let ty = self.type_ptr_to(layout.gcc_type(self));
-        let value =
-            if layout.size == Size::ZERO {
-                let value = self.const_usize(alloc.inner().align.bytes());
-                self.const_bitcast(value, ty)
-            }
-            else {
-                let init = const_alloc_to_gcc(self, alloc);
-                let base_addr = self.static_addr_of(init, alloc.inner().align, None);
-
-                let array = self.const_bitcast(base_addr, self.type_i8p());
-                let value = self.context.new_array_access(None, array, self.const_usize(offset.bytes())).get_address(None);
-                self.const_bitcast(value, ty)
-            };
-        PlaceRef::new_sized(value, layout)
-    }
-
     fn const_ptrcast(&self, val: RValue<'gcc>, ty: Type<'gcc>) -> RValue<'gcc> {
         self.context.new_cast(None, val, ty)
     }
+
+    fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
+        if value.get_type() == self.bool_type.make_pointer() {
+            if let Some(pointee) = typ.get_pointee() {
+                if pointee.dyncast_vector().is_some() {
+                    panic!()
+                }
+            }
+        }
+        // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
+        // SIMD builtins require a constant value.
+        self.bitcast_if_needed(value, typ)
+    }
+    
+    fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
+        self.context.new_array_access(None, base_addr, self.const_usize(offset.bytes())).get_address(None)
+    }
 }
 
 pub trait SignType<'gcc, 'tcx> {
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index 792ab8f890d..873f652e6f1 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -1,6 +1,6 @@
 #[cfg(feature = "master")]
 use gccjit::FnAttribute;
-use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
+use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue};
 use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, DerivedTypeMethods, StaticMethods};
 use rustc_middle::span_bug;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -16,21 +16,6 @@ use crate::context::CodegenCx;
 use crate::errors::InvalidMinimumAlignment;
 use crate::type_of::LayoutGccExt;
 
-impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
-    pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
-        if value.get_type() == self.bool_type.make_pointer() {
-            if let Some(pointee) = typ.get_pointee() {
-                if pointee.dyncast_vector().is_some() {
-                    panic!()
-                }
-            }
-        }
-        // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
-        // SIMD builtins require a constant value.
-        self.bitcast_if_needed(value, typ)
-    }
-}
-
 fn set_global_alignment<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, gv: LValue<'gcc>, mut align: Align) {
     // The target may require greater alignment for globals than the type does.
     // Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 9127fba388b..a3910fef954 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -8,16 +8,15 @@ use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
 
 use rustc_ast::Mutability;
-use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
 use rustc_hir::def_id::DefId;
 use rustc_middle::bug;
 use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
-use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType};
-use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer, Size};
+use rustc_target::abi::{self, AddressSpace, HasDataLayout, Pointer};
 use rustc_target::spec::Target;
 
 use libc::{c_char, c_uint};
@@ -307,38 +306,24 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         const_alloc_to_llvm(self, alloc)
     }
 
-    fn from_const_alloc(
-        &self,
-        layout: TyAndLayout<'tcx>,
-        alloc: ConstAllocation<'tcx>,
-        offset: Size,
-    ) -> PlaceRef<'tcx, &'ll Value> {
-        let alloc_align = alloc.inner().align;
-        assert_eq!(alloc_align, layout.align.abi);
-        let llty = self.type_ptr_to(layout.llvm_type(self));
-        let llval = if layout.size == Size::ZERO {
-            let llval = self.const_usize(alloc_align.bytes());
-            unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
-        } else {
-            let init = const_alloc_to_llvm(self, alloc);
-            let base_addr = self.static_addr_of(init, alloc_align, None);
-
-            let llval = unsafe {
-                llvm::LLVMRustConstInBoundsGEP2(
-                    self.type_i8(),
-                    self.const_bitcast(base_addr, self.type_i8p()),
-                    &self.const_usize(offset.bytes()),
-                    1,
-                )
-            };
-            self.const_bitcast(llval, llty)
-        };
-        PlaceRef::new_sized(llval, layout)
-    }
-
     fn const_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
         consts::ptrcast(val, ty)
     }
+
+    fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
+        self.const_bitcast(val, ty)
+    }
+
+    fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
+        unsafe {
+            llvm::LLVMRustConstInBoundsGEP2(
+                self.type_i8(),
+                self.const_bitcast(base_addr, self.type_i8p()),
+                &self.const_usize(offset.bytes()),
+                1,
+            )
+        }
+    }
 }
 
 /// Get the [LLVM type][Type] of a [`Value`].
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 6cb9e163b40..64961baf272 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>(
             let callee = cx.tcx.subst_and_normalize_erasing_regions(
                 instance.substs,
                 ty::ParamEnv::reveal_all(),
-                ty::EarlyBinder::new(callee),
+                ty::EarlyBinder::bind(callee),
             );
             let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
             cx.dbg_scope_fn(callee, callee_fn_abi, None)
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 835074806e9..22c1f05974d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -234,7 +234,6 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
             | PlaceContext::NonMutatingUse(
                 NonMutatingUseContext::Inspect
                 | NonMutatingUseContext::SharedBorrow
-                | NonMutatingUseContext::UniqueBorrow
                 | NonMutatingUseContext::ShallowBorrow
                 | NonMutatingUseContext::AddressOf
                 | NonMutatingUseContext::Projection,
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 51393a5d774..00414003202 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         self.instance.subst_mir_and_normalize_erasing_regions(
             self.cx.tcx(),
             ty::ParamEnv::reveal_all(),
-            ty::EarlyBinder::new(value),
+            ty::EarlyBinder::bind(value),
         )
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 2301c3ef13e..4000c9540ce 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -8,10 +8,10 @@ use crate::traits::*;
 use crate::MemFlags;
 
 use rustc_middle::mir;
-use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar};
+use rustc_middle::mir::interpret::{alloc_range, ConstValue, Pointer, Scalar};
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::Ty;
-use rustc_target::abi::{Abi, Align, Size};
+use rustc_target::abi::{self, Abi, Align, Size};
 
 use std::fmt;
 
@@ -115,13 +115,82 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                 OperandValue::Pair(a_llval, b_llval)
             }
             ConstValue::ByRef { alloc, offset } => {
-                return bx.load_operand(bx.from_const_alloc(layout, alloc, offset));
+                return Self::from_const_alloc(bx, layout, alloc, offset);
             }
         };
 
         OperandRef { val, layout }
     }
 
+    fn from_const_alloc<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+        bx: &mut Bx,
+        layout: TyAndLayout<'tcx>,
+        alloc: rustc_middle::mir::interpret::ConstAllocation<'tcx>,
+        offset: Size,
+    ) -> Self {
+        let alloc_align = alloc.inner().align;
+        assert_eq!(alloc_align, layout.align.abi);
+        let ty = bx.type_ptr_to(bx.cx().backend_type(layout));
+
+        let read_scalar = |start, size, s: abi::Scalar, ty| {
+            let val = alloc
+                .0
+                .read_scalar(
+                    bx,
+                    alloc_range(start, size),
+                    /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
+                )
+                .unwrap();
+            bx.scalar_to_backend(val, s, ty)
+        };
+
+        // It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
+        // However, `MaybeUninit<u64>` is considered a `Scalar` as far as its layout is concerned --
+        // and yet cannot be represented by an interpreter `Scalar`, since we have to handle the
+        // case where some of the bytes are initialized and others are not. So, we need an extra
+        // check that walks over the type of `mplace` to make sure it is truly correct to treat this
+        // like a `Scalar` (or `ScalarPair`).
+        match layout.abi {
+            Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => {
+                let size = s.size(bx);
+                assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
+                let val = read_scalar(Size::ZERO, size, s, ty);
+                OperandRef { val: OperandValue::Immediate(val), layout }
+            }
+            Abi::ScalarPair(
+                a @ abi::Scalar::Initialized { .. },
+                b @ abi::Scalar::Initialized { .. },
+            ) => {
+                let (a_size, b_size) = (a.size(bx), b.size(bx));
+                let b_offset = a_size.align_to(b.align(bx).abi);
+                assert!(b_offset.bytes() > 0);
+                let a_val = read_scalar(
+                    Size::ZERO,
+                    a_size,
+                    a,
+                    bx.scalar_pair_element_backend_type(layout, 0, true),
+                );
+                let b_val = read_scalar(
+                    b_offset,
+                    b_size,
+                    b,
+                    bx.scalar_pair_element_backend_type(layout, 1, true),
+                );
+                OperandRef { val: OperandValue::Pair(a_val, b_val), layout }
+            }
+            _ if layout.is_zst() => OperandRef::new_zst(bx, layout),
+            _ => {
+                // Neither a scalar nor scalar pair. Load from a place
+                let init = bx.const_data_from_alloc(alloc);
+                let base_addr = bx.static_addr_of(init, alloc_align, None);
+
+                let llval = bx.const_ptr_byte_offset(base_addr, offset);
+                let llval = bx.const_bitcast(llval, ty);
+                bx.load_operand(PlaceRef::new_sized(llval, layout))
+            }
+        }
+    }
+
     /// Asserts that this operand refers to a scalar and returns
     /// a reference to its value.
     pub fn immediate(self) -> V {
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 6e7065713b8..0255b660380 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -668,11 +668,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()
                     }
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index 61906302779..dc2fc396480 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -1,8 +1,6 @@
 use super::BackendTypes;
-use crate::mir::place::PlaceRef;
 use rustc_middle::mir::interpret::{ConstAllocation, Scalar};
-use rustc_middle::ty::layout::TyAndLayout;
-use rustc_target::abi::{self, Size};
+use rustc_target::abi;
 
 pub trait ConstMethods<'tcx>: BackendTypes {
     // Constant constructors
@@ -30,12 +28,8 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     fn const_data_from_alloc(&self, alloc: ConstAllocation<'tcx>) -> Self::Value;
 
     fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value;
-    fn from_const_alloc(
-        &self,
-        layout: TyAndLayout<'tcx>,
-        alloc: ConstAllocation<'tcx>,
-        offset: Size,
-    ) -> PlaceRef<'tcx, Self::Value>;
 
     fn const_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
+    fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
+    fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value;
 }
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 9195ae163bc..91ccdef7215 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -497,7 +497,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             .try_subst_mir_and_normalize_erasing_regions(
                 *self.tcx,
                 self.param_env,
-                ty::EarlyBinder::new(value),
+                ty::EarlyBinder::bind(value),
             )
             .map_err(|_| err_inval!(TooGeneric))
     }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 138bc3eb74a..57d939747aa 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -412,9 +412,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                         BorrowKind::Shallow => {
                             PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
                         }
-                        BorrowKind::Unique => {
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
-                        }
+                        BorrowKind::Unique => PlaceContext::MutatingUse(MutatingUseContext::Borrow),
                         BorrowKind::Mut { .. } => {
                             PlaceContext::MutatingUse(MutatingUseContext::Borrow)
                         }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 284ae0e1e58..3d78ea9aa9b 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -239,7 +239,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     var: ty::BoundVar::from_u32(index),
                     kind: ty::BrNamed(def_id, name),
                 };
-                tcx.mk_re_late_bound(debruijn, br)
+                ty::Region::new_late_bound(tcx, debruijn, br)
             }
 
             Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
@@ -247,12 +247,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.param_def_id_to_index[&def_id];
-                tcx.mk_re_early_bound(ty::EarlyBoundRegion { def_id, index, name })
+                ty::Region::new_early_bound(tcx, ty::EarlyBoundRegion { def_id, index, name })
             }
 
             Some(rbv::ResolvedArg::Free(scope, id)) => {
                 let name = lifetime_name(id.expect_local());
-                tcx.mk_re_free(scope, ty::BrNamed(id, name))
+                ty::Region::new_free(tcx, scope, ty::BrNamed(id, name))
 
                 // (*) -- not late-bound, won't change
             }
@@ -269,7 +269,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     // elision. `resolve_lifetime` should have
                     // reported an error in this case -- but if
                     // not, let's error out.
-                    tcx.mk_re_error_with_message(
+                    ty::Region::new_error_with_message(
+                        tcx,
                         lifetime.ident.span,
                         "unelided lifetime in signature",
                     )
@@ -485,7 +486,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             debug!(?param, "unelided lifetime in signature");
 
                             // This indicates an illegal lifetime in a non-assoc-trait position
-                            tcx.mk_re_error_with_message(
+                            ty::Region::new_error_with_message(
+                                tcx,
                                 self.span,
                                 "unelided lifetime in signature",
                             )
@@ -1219,15 +1221,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             let substs =
                 candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| {
                     let subst = match param.kind {
-                        GenericParamDefKind::Lifetime => tcx
-                            .mk_re_late_bound(
-                                ty::INNERMOST,
-                                ty::BoundRegion {
-                                    var: ty::BoundVar::from_usize(num_bound_vars),
-                                    kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name),
-                                },
-                            )
-                            .into(),
+                        GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
+                            tcx,
+                            ty::INNERMOST,
+                            ty::BoundRegion {
+                                var: ty::BoundVar::from_usize(num_bound_vars),
+                                kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name),
+                            },
+                        )
+                        .into(),
                         GenericParamDefKind::Type { .. } => tcx
                             .mk_bound(
                                 ty::INNERMOST,
@@ -1278,7 +1280,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             // params (and trait ref's late bound params). This logic is very similar to
             // `Predicate::subst_supertrait`, and it's no coincidence why.
             let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
-            let subst_output = ty::EarlyBinder::new(shifted_output).subst(tcx, substs);
+            let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs);
 
             let bound_vars = tcx.late_bound_vars(binding.hir_id);
             ty::Binder::bind_with_vars(subst_output, bound_vars)
@@ -1804,7 +1806,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         } else {
                             err.emit()
                         };
-                        tcx.mk_re_error(e)
+                        ty::Region::new_error(tcx, e)
                     })
                 }
             })
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index e33330e259c..31b89525f15 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -472,7 +472,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
         if let ty::ReFree(fr) = *r {
-            self.tcx.mk_re_free(
+            ty::Region::new_free(
+                self.tcx,
                 fr.scope,
                 self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region),
             )
@@ -786,23 +787,23 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                     }
                     let Some(ty::ReEarlyBound(e)) = map.get(&region.into()).map(|r| r.expect_region().kind())
                     else {
-                        return tcx.mk_re_error_with_message(return_span, "expected ReFree to map to ReEarlyBound")
+                        return ty::Region::new_error_with_message(tcx, return_span, "expected ReFree to map to ReEarlyBound")
                     };
-                    tcx.mk_re_early_bound(ty::EarlyBoundRegion {
+                    ty::Region::new_early_bound(tcx, ty::EarlyBoundRegion {
                         def_id: e.def_id,
                         name: e.name,
                         index: (e.index as usize - num_trait_substs + num_impl_substs) as u32,
                     })
                 });
                 debug!(%ty);
-                collected_tys.insert(def_id, ty::EarlyBinder::new(ty));
+                collected_tys.insert(def_id, ty::EarlyBinder::bind(ty));
             }
             Err(err) => {
                 let reported = tcx.sess.delay_span_bug(
                     return_span,
                     format!("could not fully resolve: {ty} => {err:?}"),
                 );
-                collected_tys.insert(def_id, ty::EarlyBinder::new(tcx.ty_error(reported)));
+                collected_tys.insert(def_id, ty::EarlyBinder::bind(tcx.ty_error(reported)));
             }
         }
     }
@@ -902,7 +903,7 @@ fn report_trait_method_mismatch<'tcx>(
             if trait_m.fn_has_self_parameter =>
         {
             let ty = trait_sig.inputs()[0];
-            let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty()) {
+            let sugg = match ExplicitSelf::determine(ty, |ty| ty == impl_trait_ref.self_ty()) {
                 ExplicitSelf::ByValue => "self".to_owned(),
                 ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
                 ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
@@ -1933,7 +1934,8 @@ pub(super) fn check_type_bounds<'tcx>(
                 let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
                 let bound_var = ty::BoundVariableKind::Region(kind);
                 bound_vars.push(bound_var);
-                tcx.mk_re_late_bound(
+                ty::Region::new_late_bound(
+                    tcx,
                     ty::INNERMOST,
                     ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
                 )
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index eeb69c389cd..13d1abe2a65 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -128,7 +128,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
     // We don't need to normalize this param-env or anything, since we're only
     // substituting it with free params, so no additional param-env normalization
     // can occur on top of what has been done in the param_env query itself.
-    let param_env = ty::EarlyBinder::new(tcx.param_env(adt_def_id))
+    let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
         .subst(tcx, adt_to_impl_substs)
         .with_constness(tcx.constness(drop_impl_def_id));
 
@@ -183,7 +183,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                 }
                 RegionResolutionError::SubSupConflict(_, _, _, a, _, b, _) => format!("{b}: {a}"),
                 RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => {
-                    format!("{b}: {a}", a = tcx.mk_re_var(a))
+                    format!("{b}: {a}", a = ty::Region::new_var(tcx, a))
                 }
             };
             guar = Some(
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index fbd4a577d68..1f18017f00b 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -145,11 +145,13 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     ]);
     let mk_va_list_ty = |mutbl| {
         tcx.lang_items().va_list().map(|did| {
-            let region = tcx.mk_re_late_bound(
+            let region = ty::Region::new_late_bound(
+                tcx,
                 ty::INNERMOST,
                 ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
             );
-            let env_region = tcx.mk_re_late_bound(
+            let env_region = ty::Region::new_late_bound(
+                tcx,
                 ty::INNERMOST,
                 ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
             );
@@ -393,7 +395,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
                 (
                     1,
-                    vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))],
+                    vec![
+                        tcx.mk_imm_ref(
+                            ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
+                            param(0),
+                        ),
+                    ],
                     tcx.mk_projection(discriminant_def_id, tcx.mk_substs(&[param(0).into()])),
                 )
             }
@@ -443,7 +450,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
 
             sym::raw_eq => {
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
-                let param_ty = tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0));
+                let param_ty =
+                    tcx.mk_imm_ref(ty::Region::new_late_bound(tcx, ty::INNERMOST, br), param(0));
                 (1, vec![param_ty; 2], tcx.types.bool)
             }
 
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 4c513c4d8cc..fff417fcb29 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -556,11 +556,14 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
                 // Same for the region. In our example, 'a corresponds
                 // to the 'me parameter.
                 let region_param = gat_generics.param_at(*region_a_idx, tcx);
-                let region_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
-                    def_id: region_param.def_id,
-                    index: region_param.index,
-                    name: region_param.name,
-                });
+                let region_param = ty::Region::new_early_bound(
+                    tcx,
+                    ty::EarlyBoundRegion {
+                        def_id: region_param.def_id,
+                        index: region_param.index,
+                        name: region_param.name,
+                    },
+                );
                 // The predicate we expect to see. (In our example,
                 // `Self: 'me`.)
                 let clause = ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
@@ -593,18 +596,24 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
                 debug!("required clause: {region_a} must outlive {region_b}");
                 // Translate into the generic parameters of the GAT.
                 let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
-                let region_a_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
-                    def_id: region_a_param.def_id,
-                    index: region_a_param.index,
-                    name: region_a_param.name,
-                });
+                let region_a_param = ty::Region::new_early_bound(
+                    tcx,
+                    ty::EarlyBoundRegion {
+                        def_id: region_a_param.def_id,
+                        index: region_a_param.index,
+                        name: region_a_param.name,
+                    },
+                );
                 // Same for the region.
                 let region_b_param = gat_generics.param_at(*region_b_idx, tcx);
-                let region_b_param = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
-                    def_id: region_b_param.def_id,
-                    index: region_b_param.index,
-                    name: region_b_param.name,
-                });
+                let region_b_param = ty::Region::new_early_bound(
+                    tcx,
+                    ty::EarlyBoundRegion {
+                        def_id: region_b_param.def_id,
+                        index: region_b_param.index,
+                        name: region_b_param.name,
+                    },
+                );
                 // The predicate we expect to see.
                 let clause = ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
                     ty::OutlivesPredicate(region_a_param, region_b_param),
@@ -1398,7 +1407,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
             }
             let mut param_count = CountParams::default();
             let has_region = pred.visit_with(&mut param_count).is_break();
-            let substituted_pred = ty::EarlyBinder::new(pred).subst(tcx, substs);
+            let substituted_pred = ty::EarlyBinder::bind(pred).subst(tcx, substs);
             // Don't check non-defaulted params, dependent defaults (including lifetimes)
             // or preds with multiple params.
             if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 75d99fee152..2f7d465839c 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -440,7 +440,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
                                     self.tcx.replace_late_bound_regions_uncached(
                                         poly_trait_ref,
                                         |_| {
-                                            self.tcx.mk_re_early_bound(ty::EarlyBoundRegion {
+                                            ty::Region::new_early_bound(self.tcx, ty::EarlyBoundRegion {
                                                 def_id: item_def_id,
                                                 index: 0,
                                                 name: Symbol::intern(&lt_name),
@@ -1124,7 +1124,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
             bug!("unexpected sort of node in fn_sig(): {:?}", x);
         }
     };
-    ty::EarlyBinder::new(output)
+    ty::EarlyBinder::bind(output)
 }
 
 fn infer_return_ty_for_fn_sig<'tcx>(
@@ -1312,7 +1312,7 @@ fn impl_trait_ref(
                 check_impl_constness(tcx, impl_.constness, ast_trait_ref),
             )
         })
-        .map(ty::EarlyBinder::new)
+        .map(ty::EarlyBinder::bind)
 }
 
 fn check_impl_constness(
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 03c8c59402e..b92d561fb86 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -86,7 +86,7 @@ pub(super) fn explicit_item_bounds(
         Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
             let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item();
             let opaque_ty = item.expect_opaque_ty();
-            return ty::EarlyBinder::new(opaque_type_bounds(
+            return ty::EarlyBinder::bind(opaque_type_bounds(
                 tcx,
                 opaque_def_id.expect_local(),
                 opaque_ty.bounds,
@@ -124,7 +124,7 @@ pub(super) fn explicit_item_bounds(
         }
         _ => bug!("item_bounds called on {:?}", def_id),
     };
-    ty::EarlyBinder::new(bounds)
+    ty::EarlyBinder::bind(bounds)
 }
 
 pub(super) fn item_bounds(
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index e5b5dae551e..70d950eddd8 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -306,11 +306,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
 
             let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() };
 
-            let dup_region = tcx.mk_re_early_bound(ty::EarlyBoundRegion {
-                def_id: dup_def,
-                index: dup_index,
-                name: duplicate.name.ident().name,
-            });
+            let dup_region = ty::Region::new_early_bound(
+                tcx,
+                ty::EarlyBoundRegion {
+                    def_id: dup_def,
+                    index: dup_index,
+                    name: duplicate.name.ident().name,
+                },
+            );
             predicates.push((
                 ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
                     ty::OutlivesPredicate(orig_region, dup_region),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 0b57d696585..65ab00fda81 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -323,7 +323,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
                 return map[&assoc_item.trait_item_def_id.unwrap()];
             }
             Err(_) => {
-                return ty::EarlyBinder::new(tcx.ty_error_with_message(
+                return ty::EarlyBinder::bind(tcx.ty_error_with_message(
                     DUMMY_SP,
                     "Could not collect return position impl trait in trait tys",
                 ));
@@ -497,7 +497,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             bug!("unexpected sort of node in type_of(): {:?}", x);
         }
     };
-    ty::EarlyBinder::new(output)
+    ty::EarlyBinder::bind(output)
 }
 
 fn infer_placeholder_type<'a>(
diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
index d7f11d3fd9d..7ce48fe1c01 100644
--- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
@@ -68,7 +68,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
                 }
             }
 
-            ty::EarlyBinder::new(required_predicates)
+            ty::EarlyBinder::bind(required_predicates)
         })
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index ced994aa636..71dca918fc5 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -74,7 +74,7 @@ pub(super) fn infer_predicates(
             if item_required_predicates.len() > item_predicates_len {
                 predicates_added = true;
                 global_inferred_outlives
-                    .insert(item_did.to_def_id(), ty::EarlyBinder::new(item_required_predicates));
+                    .insert(item_did.to_def_id(), ty::EarlyBinder::bind(item_required_predicates));
             }
         }
 
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 655ab94eb48..4389ad6ef26 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -420,20 +420,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .steal_diagnostic(segment.ident.span, StashKey::CallIntoMethod)
                 {
                     // Try suggesting `foo(a)` -> `a.foo()` if possible.
-                    if let Some(ty) =
-                        self.suggest_call_as_method(
-                            &mut diag,
-                            segment,
-                            arg_exprs,
-                            call_expr,
-                            expected
-                        )
-                    {
-                        diag.emit();
-                        return ty;
-                    } else {
-                        diag.emit();
-                    }
+                    self.suggest_call_as_method(
+                        &mut diag,
+                        segment,
+                        arg_exprs,
+                        call_expr,
+                        expected
+                    );
+                    diag.emit();
                 }
 
                 let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
@@ -496,9 +490,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         arg_exprs: &'tcx [hir::Expr<'tcx>],
         call_expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
-    ) -> Option<Ty<'tcx>> {
+    ) {
         if let [callee_expr, rest @ ..] = arg_exprs {
-            let callee_ty = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr)?;
+            let Some(callee_ty) = self.typeck_results.borrow().expr_ty_adjusted_opt(callee_expr) else {
+                return;
+            };
 
             // First, do a probe with `IsSuggestion(true)` to avoid emitting
             // any strange errors. If it's successful, then we'll do a true
@@ -513,7 +509,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ProbeScope::AllTraits,
                 expected.only_has_type(self),
             ) else {
-                return None;
+                return;
             };
 
             let pick = self.confirm_method(
@@ -525,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 segment,
             );
             if pick.illegal_sized_bound.is_some() {
-                return None;
+                return;
             }
 
             let up_to_rcvr_span = segment.ident.span.until(callee_expr.span);
@@ -567,22 +563,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     sugg,
                     Applicability::MaybeIncorrect,
                 );
-
-                // Let's check the method fully now
-                let return_ty = self.check_method_argument_types(
-                    segment.ident.span,
-                    call_expr,
-                    Ok(pick.callee),
-                    rest,
-                    TupleArgumentsFlag::DontTupleArguments,
-                    expected,
-                );
-
-                return Some(return_ty);
             }
         }
-
-        None
     }
 
     fn report_invalid_callee(
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 08c4082e885..905781ec8f5 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -62,6 +62,7 @@ use rustc_span::{self, BytePos, DesugaringKind, Span};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{
     self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
@@ -144,12 +145,28 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
         self.commit_if_ok(|_| {
             let at = self.at(&self.cause, self.fcx.param_env);
-            if self.use_lub {
+
+            let res = if self.use_lub {
                 at.lub(DefineOpaqueTypes::Yes, b, a)
             } else {
                 at.sup(DefineOpaqueTypes::Yes, b, a)
                     .map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
+            };
+
+            // In the new solver, lazy norm may allow us to shallowly equate
+            // more types, but we emit possibly impossible-to-satisfy obligations.
+            // Filter these cases out to make sure our coercion is more accurate.
+            if self.tcx.trait_solver_next() {
+                if let Ok(res) = &res {
+                    for obligation in &res.obligations {
+                        if !self.predicate_may_hold(&obligation) {
+                            return Err(TypeError::Mismatch);
+                        }
+                    }
+                }
             }
+
+            res
         })
     }
 
@@ -791,6 +808,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
     {
         self.commit_if_ok(|snapshot| {
+            let outer_universe = self.infcx.universe();
+
             let result = if let ty::FnPtr(fn_ty_b) = b.kind()
                 && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) =
                     (fn_ty_a.unsafety(), fn_ty_b.unsafety())
@@ -807,7 +826,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             // want the coerced type to be the actual supertype of these two,
             // but for now, we want to just error to ensure we don't lock
             // ourselves into a specific behavior with NLL.
-            self.leak_check(false, snapshot)?;
+            self.leak_check(outer_universe, Some(snapshot))?;
 
             result
         })
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
index 427d6f8803c..fb28233bfb1 100644
--- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
+++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
@@ -269,7 +269,7 @@ pub fn resolve_interior<'a, 'tcx>(
                     },
                     _ => mk_bound_region(ty::BrAnon(None)),
                 };
-                let r = fcx.tcx.mk_re_late_bound(current_depth, br);
+                let r = ty::Region::new_late_bound(fcx.tcx, current_depth, br);
                 r
             });
             captured_tys.insert(ty).then(|| {
@@ -295,7 +295,11 @@ pub fn resolve_interior<'a, 'tcx>(
                     let var = ty::BoundVar::from_usize(bound_vars.len());
                     bound_vars.push(ty::BoundVariableKind::Region(kind));
                     counter += 1;
-                    fcx.tcx.mk_re_late_bound(ty::INNERMOST, ty::BoundRegion { var, kind })
+                    ty::Region::new_late_bound(
+                        fcx.tcx,
+                        ty::INNERMOST,
+                        ty::BoundRegion { var, kind },
+                    )
                 },
                 types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"),
                 consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 8555c20204a..9ee967dc7a9 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -473,6 +473,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut custom_span_label = false;
 
         let static_candidates = &mut no_match_data.static_candidates;
+
+        // `static_candidates` may have same candidates appended by
+        // inherent and extension, which may result in incorrect
+        // diagnostic.
+        static_candidates.dedup();
+
         if !static_candidates.is_empty() {
             err.note(
                 "found the following associated functions; to be used as methods, \
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 0c8854e962a..6b2dd0a2b4f 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -70,8 +70,8 @@ impl<'tcx> InferCtxt<'tcx> {
             tcx: self.tcx,
             defining_use_anchor: self.defining_use_anchor,
             considering_regions: self.considering_regions,
+            skip_leak_check: self.skip_leak_check,
             inner: self.inner.clone(),
-            skip_leak_check: self.skip_leak_check.clone(),
             lexical_region_resolutions: self.lexical_region_resolutions.clone(),
             selection_cache: self.selection_cache.clone(),
             evaluation_cache: self.evaluation_cache.clone(),
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 427d05c8b4d..bf53a73f398 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -771,7 +771,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     ) -> ty::Region<'tcx> {
         let var = self.canonical_var(info, r.into());
         let br = ty::BoundRegion { var, kind: ty::BrAnon(None) };
-        self.interner().mk_re_late_bound(self.binder_index, br)
+        ty::Region::new_late_bound(self.interner(), self.binder_index, br)
     }
 
     /// Given a type variable `ty_var` of the given kind, first check
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 2abdd5b0aec..c8c318c3f02 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -141,7 +141,7 @@ impl<'tcx> InferCtxt<'tcx> {
             CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, bound }) => {
                 let universe_mapped = universe_map(universe);
                 let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, bound };
-                self.tcx.mk_re_placeholder(placeholder_mapped).into()
+                ty::Region::new_placeholder(self.tcx, placeholder_mapped).into()
             }
 
             CanonicalVarKind::Const(ui, ty) => self
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 88256c819f4..2cf8d8c702d 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -668,14 +668,15 @@ pub fn make_query_region_constraints<'tcx>(
             let constraint = match *k {
                 // Swap regions because we are going from sub (<=) to outlives
                 // (>=).
-                Constraint::VarSubVar(v1, v2) => {
-                    ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), tcx.mk_re_var(v1))
-                }
+                Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
+                    ty::Region::new_var(tcx, v2).into(),
+                    ty::Region::new_var(tcx, v1),
+                ),
                 Constraint::VarSubReg(v1, r2) => {
-                    ty::OutlivesPredicate(r2.into(), tcx.mk_re_var(v1))
+                    ty::OutlivesPredicate(r2.into(), ty::Region::new_var(tcx, v1))
                 }
                 Constraint::RegSubVar(r1, v2) => {
-                    ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), r1)
+                    ty::OutlivesPredicate(ty::Region::new_var(tcx, v2).into(), r1)
                 }
                 Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
             };
@@ -719,7 +720,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
     }
 
     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
-        self.infcx.tcx.mk_re_placeholder(placeholder)
+        ty::Region::new_placeholder(self.infcx.tcx, placeholder)
     }
 
     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index c9c1f0aeaac..0b3bc1ce6b3 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -79,7 +79,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
                 _,
             )) => self.try_report_trait_placeholder_mismatch(
-                Some(self.tcx().mk_re_var(*vid)),
+                Some(ty::Region::new_var(self.tcx(), *vid)),
                 cause,
                 Some(*sub_placeholder),
                 Some(*sup_placeholder),
@@ -95,7 +95,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                 _,
                 _,
             )) => self.try_report_trait_placeholder_mismatch(
-                Some(self.tcx().mk_re_var(*vid)),
+                Some(ty::Region::new_var(self.tcx(), *vid)),
                 cause,
                 Some(*sub_placeholder),
                 None,
@@ -111,7 +111,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
                 _,
             )) => self.try_report_trait_placeholder_mismatch(
-                Some(self.tcx().mk_re_var(*vid)),
+                Some(ty::Region::new_var(self.tcx(), *vid)),
                 cause,
                 None,
                 Some(*sup_placeholder),
@@ -127,7 +127,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
                 _,
             )) => self.try_report_trait_placeholder_mismatch(
-                Some(self.tcx().mk_re_var(*vid)),
+                Some(ty::Region::new_var(self.tcx(), *vid)),
                 cause,
                 None,
                 Some(*sup_placeholder),
@@ -141,7 +141,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                 SubregionOrigin::Subtype(box TypeTrace { cause, values }),
                 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
             )) => self.try_report_trait_placeholder_mismatch(
-                Some(self.tcx().mk_re_var(*vid)),
+                Some(ty::Region::new_var(self.tcx(), *vid)),
                 cause,
                 None,
                 Some(*sup_placeholder),
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
index c304cd25c9c..974bc2f1153 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
@@ -82,8 +82,10 @@ impl<'tcx> InferCtxt<'tcx> {
 
         let delegate = FnMutDelegate {
             regions: &mut |br: ty::BoundRegion| {
-                self.tcx
-                    .mk_re_placeholder(ty::PlaceholderRegion { universe: next_universe, bound: br })
+                ty::Region::new_placeholder(
+                    self.tcx,
+                    ty::PlaceholderRegion { universe: next_universe, bound: br },
+                )
             },
             types: &mut |bound_ty: ty::BoundTy| {
                 self.tcx.mk_placeholder(ty::PlaceholderType {
@@ -103,13 +105,15 @@ impl<'tcx> InferCtxt<'tcx> {
         self.tcx.replace_bound_vars_uncached(binder, delegate)
     }
 
-    /// See [RegionConstraintCollector::leak_check][1].
+    /// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
+    /// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
+    /// universe.
     ///
     /// [1]: crate::infer::region_constraints::RegionConstraintCollector::leak_check
     pub fn leak_check(
         &self,
-        overly_polymorphic: bool,
-        snapshot: &CombinedSnapshot<'tcx>,
+        outer_universe: ty::UniverseIndex,
+        only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
     ) -> RelateResult<'tcx, ()> {
         // If the user gave `-Zno-leak-check`, or we have been
         // configured to skip the leak check, then skip the leak check
@@ -117,15 +121,15 @@ impl<'tcx> InferCtxt<'tcx> {
         // subtyping errors that it would have caught will now be
         // caught later on, during region checking. However, we
         // continue to use it for a transition period.
-        if self.tcx.sess.opts.unstable_opts.no_leak_check || self.skip_leak_check.get() {
+        if self.tcx.sess.opts.unstable_opts.no_leak_check || self.skip_leak_check {
             return Ok(());
         }
 
         self.inner.borrow_mut().unwrap_region_constraints().leak_check(
             self.tcx,
-            overly_polymorphic,
+            outer_universe,
             self.universe(),
-            snapshot,
+            only_consider_snapshot,
         )
     }
 }
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 8482ae2aa38..485e34fe2bf 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -347,7 +347,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                     // name the placeholder, then the placeholder is
                     // larger; otherwise, the only ancestor is `'static`.
                     Err(placeholder) if empty_ui.can_name(placeholder.universe) => {
-                        self.tcx().mk_re_placeholder(placeholder)
+                        ty::Region::new_placeholder(self.tcx(), placeholder)
                     }
                     Err(_) => self.tcx().lifetimes.re_static,
                 };
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index cd99fc31212..447d4c9f84b 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -251,14 +251,13 @@ pub struct InferCtxt<'tcx> {
     /// solving is left to borrowck instead.
     pub considering_regions: bool,
 
-    pub inner: RefCell<InferCtxtInner<'tcx>>,
-
     /// If set, this flag causes us to skip the 'leak check' during
     /// higher-ranked subtyping operations. This flag is a temporary one used
     /// to manage the removal of the leak-check: for the time being, we still run the
-    /// leak-check, but we issue warnings. This flag can only be set to true
-    /// when entering a snapshot.
-    skip_leak_check: Cell<bool>,
+    /// leak-check, but we issue warnings.
+    skip_leak_check: bool,
+
+    pub inner: RefCell<InferCtxtInner<'tcx>>,
 
     /// Once region inference is done, the values for each variable.
     lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
@@ -543,6 +542,7 @@ pub struct InferCtxtBuilder<'tcx> {
     tcx: TyCtxt<'tcx>,
     defining_use_anchor: DefiningAnchor,
     considering_regions: bool,
+    skip_leak_check: bool,
     /// Whether we are in coherence mode.
     intercrate: bool,
 }
@@ -557,6 +557,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
             tcx: self,
             defining_use_anchor: DefiningAnchor::Error,
             considering_regions: true,
+            skip_leak_check: false,
             intercrate: false,
         }
     }
@@ -584,6 +585,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
         self
     }
 
+    pub fn skip_leak_check(mut self, skip_leak_check: bool) -> Self {
+        self.skip_leak_check = skip_leak_check;
+        self
+    }
+
     /// Given a canonical value `C` as a starting point, create an
     /// inference context that contains each of the bound values
     /// within instantiated as a fresh variable. The `f` closure is
@@ -605,11 +611,18 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     }
 
     pub fn build(&mut self) -> InferCtxt<'tcx> {
-        let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
+        let InferCtxtBuilder {
+            tcx,
+            defining_use_anchor,
+            considering_regions,
+            skip_leak_check,
+            intercrate,
+        } = *self;
         InferCtxt {
             tcx,
             defining_use_anchor,
             considering_regions,
+            skip_leak_check,
             inner: RefCell::new(InferCtxtInner::new()),
             lexical_region_resolutions: RefCell::new(None),
             selection_cache: Default::default(),
@@ -619,7 +632,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             tainted_by_errors: Cell::new(None),
             err_count_on_creation: tcx.sess.err_count(),
             in_snapshot: Cell::new(false),
-            skip_leak_check: Cell::new(false),
             universe: Cell::new(ty::UniverseIndex::ROOT),
             intercrate,
         }
@@ -815,32 +827,9 @@ impl<'tcx> InferCtxt<'tcx> {
         r
     }
 
-    /// If `should_skip` is true, then execute `f` then unroll any bindings it creates.
-    #[instrument(skip(self, f), level = "debug")]
-    pub fn probe_maybe_skip_leak_check<R, F>(&self, should_skip: bool, f: F) -> R
-    where
-        F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
-    {
-        let snapshot = self.start_snapshot();
-        let was_skip_leak_check = self.skip_leak_check.get();
-        if should_skip {
-            self.skip_leak_check.set(true);
-        }
-        let r = f(&snapshot);
-        self.rollback_to("probe", snapshot);
-        self.skip_leak_check.set(was_skip_leak_check);
-        r
-    }
-
-    /// Scan the constraints produced since `snapshot` began and returns:
-    ///
-    /// - `None` -- if none of them involves "region outlives" constraints.
-    /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder.
-    /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders.
-    pub fn region_constraints_added_in_snapshot(
-        &self,
-        snapshot: &CombinedSnapshot<'tcx>,
-    ) -> Option<bool> {
+    /// Scan the constraints produced since `snapshot` and check whether
+    /// we added any region constraints.
+    pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
         self.inner
             .borrow_mut()
             .unwrap_region_constraints()
@@ -1065,7 +1054,7 @@ impl<'tcx> InferCtxt<'tcx> {
     ) -> ty::Region<'tcx> {
         let region_var =
             self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin);
-        self.tcx.mk_re_var(region_var)
+        ty::Region::new_var(self.tcx, region_var)
     }
 
     /// Return the universe that the region `r` was created in. For
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 9d5ec228d82..105a3f08c82 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -533,17 +533,29 @@ impl<'tcx> InferCtxt<'tcx> {
         // these are the same span, but not in cases like `-> (impl
         // Foo, impl Bar)`.
         let span = cause.span;
-        let prev = self.inner.borrow_mut().opaque_types().register(
-            opaque_type_key,
-            OpaqueHiddenType { ty: hidden_ty, span },
-            origin,
-        );
-        let mut obligations = if let Some(prev) = prev {
-            self.at(&cause, param_env)
-                .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
-                .obligations
+        let mut obligations = if self.intercrate {
+            // During intercrate we do not define opaque types but instead always
+            // force ambiguity unless the hidden type is known to not implement
+            // our trait.
+            vec![traits::Obligation::new(
+                self.tcx,
+                cause.clone(),
+                param_env,
+                ty::PredicateKind::Ambiguous,
+            )]
         } else {
-            Vec::new()
+            let prev = self.inner.borrow_mut().opaque_types().register(
+                opaque_type_key,
+                OpaqueHiddenType { ty: hidden_ty, span },
+                origin,
+            );
+            if let Some(prev) = prev {
+                self.at(&cause, param_env)
+                    .eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
+                    .obligations
+            } else {
+                Vec::new()
+            }
         };
 
         self.add_item_bounds_for_hidden_type(
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 89cfc9ea3d1..dd65f66ccd1 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -3,7 +3,6 @@ use crate::infer::CombinedSnapshot;
 use rustc_data_structures::{
     fx::FxIndexMap,
     graph::{scc::Sccs, vec_graph::VecGraph},
-    undo_log::UndoLogs,
 };
 use rustc_index::Idx;
 use rustc_middle::ty::error::TypeError;
@@ -13,7 +12,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     /// Searches new universes created during `snapshot`, looking for
     /// placeholders that may "leak" out from the universes they are contained
     /// in. If any leaking placeholders are found, then an `Err` is returned
-    /// (typically leading to the snapshot being reversed).
+    /// (typically leading to the snapshot being reversed). This algorithm
+    /// only looks at placeholders which cannot be named by `outer_universe`,
+    /// as this is the universe we're currently checking for a leak.
     ///
     /// The leak check *used* to be the only way we had to handle higher-ranked
     /// obligations. Now that we have integrated universes into the region
@@ -55,6 +56,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     ///   * if they must also be equal to a placeholder P, and U cannot name P, report an error, as that
     ///     indicates `P: R` and `R` is in an incompatible universe
     ///
+    /// To improve performance and for the old trait solver caching to be sound, this takes
+    /// an optional snapshot in which case we only look at region constraints added in that
+    /// snapshot. If we were to not do that the `leak_check` during evaluation can rely on
+    /// region constraints added outside of that evaluation. As that is not reflected in the
+    /// cache key this would be unsound.
+    ///
     /// # Historical note
     ///
     /// Older variants of the leak check used to report errors for these
@@ -62,36 +69,21 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     ///
     /// * R: P1, even if R cannot name P1, because R = 'static is a valid sol'n
     /// * R: P1, R: P2, as above
+    #[instrument(level = "debug", skip(self, tcx, only_consider_snapshot), ret)]
     pub fn leak_check(
         &mut self,
         tcx: TyCtxt<'tcx>,
-        overly_polymorphic: bool,
+        outer_universe: ty::UniverseIndex,
         max_universe: ty::UniverseIndex,
-        snapshot: &CombinedSnapshot<'tcx>,
+        only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
     ) -> RelateResult<'tcx, ()> {
-        debug!(
-            "leak_check(max_universe={:?}, snapshot.universe={:?}, overly_polymorphic={:?})",
-            max_universe, snapshot.universe, overly_polymorphic
-        );
-
-        assert!(UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));
-
-        let universe_at_start_of_snapshot = snapshot.universe;
-        if universe_at_start_of_snapshot == max_universe {
+        if outer_universe == max_universe {
             return Ok(());
         }
 
-        let mini_graph =
-            &MiniGraph::new(tcx, self.undo_log.region_constraints(), &self.storage.data.verifys);
+        let mini_graph = &MiniGraph::new(tcx, &self, only_consider_snapshot);
 
-        let mut leak_check = LeakCheck::new(
-            tcx,
-            universe_at_start_of_snapshot,
-            max_universe,
-            overly_polymorphic,
-            mini_graph,
-            self,
-        );
+        let mut leak_check = LeakCheck::new(tcx, outer_universe, max_universe, mini_graph, self);
         leak_check.assign_placeholder_values()?;
         leak_check.propagate_scc_value()?;
         Ok(())
@@ -100,9 +92,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
 
 struct LeakCheck<'me, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    universe_at_start_of_snapshot: ty::UniverseIndex,
-    /// Only used when reporting region errors.
-    overly_polymorphic: bool,
+    outer_universe: ty::UniverseIndex,
     mini_graph: &'me MiniGraph<'tcx>,
     rcc: &'me RegionConstraintCollector<'me, 'tcx>,
 
@@ -130,17 +120,15 @@ struct LeakCheck<'me, 'tcx> {
 impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
     fn new(
         tcx: TyCtxt<'tcx>,
-        universe_at_start_of_snapshot: ty::UniverseIndex,
+        outer_universe: ty::UniverseIndex,
         max_universe: ty::UniverseIndex,
-        overly_polymorphic: bool,
         mini_graph: &'me MiniGraph<'tcx>,
         rcc: &'me RegionConstraintCollector<'me, 'tcx>,
     ) -> Self {
         let dummy_scc_universe = SccUniverse { universe: max_universe, region: None };
         Self {
             tcx,
-            universe_at_start_of_snapshot,
-            overly_polymorphic,
+            outer_universe,
             mini_graph,
             rcc,
             scc_placeholders: IndexVec::from_elem_n(None, mini_graph.sccs.num_sccs()),
@@ -165,7 +153,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
 
             // Detect those SCCs that directly contain a placeholder
             if let ty::RePlaceholder(placeholder) = **region {
-                if self.universe_at_start_of_snapshot.cannot_name(placeholder.universe) {
+                if self.outer_universe.cannot_name(placeholder.universe) {
                     self.assign_scc_value(scc, placeholder)?;
                 }
             }
@@ -280,7 +268,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
         placeholder1: ty::PlaceholderRegion,
         placeholder2: ty::PlaceholderRegion,
     ) -> TypeError<'tcx> {
-        self.error(placeholder1, self.tcx.mk_re_placeholder(placeholder2))
+        self.error(placeholder1, ty::Region::new_placeholder(self.tcx, placeholder2))
     }
 
     fn error(
@@ -289,11 +277,7 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
         other_region: ty::Region<'tcx>,
     ) -> TypeError<'tcx> {
         debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region);
-        if self.overly_polymorphic {
-            TypeError::RegionsOverlyPolymorphic(placeholder.bound.kind, other_region)
-        } else {
-            TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound.kind, other_region)
-        }
+        TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound.kind, other_region)
     }
 }
 
@@ -379,56 +363,70 @@ struct MiniGraph<'tcx> {
 }
 
 impl<'tcx> MiniGraph<'tcx> {
-    fn new<'a>(
+    fn new(
         tcx: TyCtxt<'tcx>,
-        undo_log: impl Iterator<Item = &'a UndoLog<'tcx>>,
-        verifys: &[Verify<'tcx>],
-    ) -> Self
-    where
-        'tcx: 'a,
-    {
+        region_constraints: &RegionConstraintCollector<'_, 'tcx>,
+        only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
+    ) -> Self {
         let mut nodes = FxIndexMap::default();
         let mut edges = Vec::new();
 
         // Note that if `R2: R1`, we get a callback `r1, r2`, so `target` is first parameter.
-        Self::iterate_undo_log(tcx, undo_log, verifys, |target, source| {
-            let source_node = Self::add_node(&mut nodes, source);
-            let target_node = Self::add_node(&mut nodes, target);
-            edges.push((source_node, target_node));
-        });
+        Self::iterate_region_constraints(
+            tcx,
+            region_constraints,
+            only_consider_snapshot,
+            |target, source| {
+                let source_node = Self::add_node(&mut nodes, source);
+                let target_node = Self::add_node(&mut nodes, target);
+                edges.push((source_node, target_node));
+            },
+        );
         let graph = VecGraph::new(nodes.len(), edges);
         let sccs = Sccs::new(&graph);
         Self { nodes, sccs }
     }
 
     /// Invokes `each_edge(R1, R2)` for each edge where `R2: R1`
-    fn iterate_undo_log<'a>(
+    fn iterate_region_constraints(
         tcx: TyCtxt<'tcx>,
-        undo_log: impl Iterator<Item = &'a UndoLog<'tcx>>,
-        verifys: &[Verify<'tcx>],
+        region_constraints: &RegionConstraintCollector<'_, 'tcx>,
+        only_consider_snapshot: Option<&CombinedSnapshot<'tcx>>,
         mut each_edge: impl FnMut(ty::Region<'tcx>, ty::Region<'tcx>),
-    ) where
-        'tcx: 'a,
-    {
-        for undo_entry in undo_log {
-            match undo_entry {
-                &AddConstraint(Constraint::VarSubVar(a, b)) => {
-                    each_edge(tcx.mk_re_var(a), tcx.mk_re_var(b));
-                }
-                &AddConstraint(Constraint::RegSubVar(a, b)) => {
-                    each_edge(a, tcx.mk_re_var(b));
-                }
-                &AddConstraint(Constraint::VarSubReg(a, b)) => {
-                    each_edge(tcx.mk_re_var(a), b);
-                }
-                &AddConstraint(Constraint::RegSubReg(a, b)) => {
-                    each_edge(a, b);
+    ) {
+        let mut each_constraint = |constraint| match constraint {
+            &Constraint::VarSubVar(a, b) => {
+                each_edge(ty::Region::new_var(tcx, a), ty::Region::new_var(tcx, b));
+            }
+            &Constraint::RegSubVar(a, b) => {
+                each_edge(a, ty::Region::new_var(tcx, b));
+            }
+            &Constraint::VarSubReg(a, b) => {
+                each_edge(ty::Region::new_var(tcx, a), b);
+            }
+            &Constraint::RegSubReg(a, b) => {
+                each_edge(a, b);
+            }
+        };
+
+        if let Some(snapshot) = only_consider_snapshot {
+            for undo_entry in
+                region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
+            {
+                match undo_entry {
+                    AddConstraint(constraint) => {
+                        each_constraint(constraint);
+                    }
+                    &AddVerify(i) => span_bug!(
+                        region_constraints.data().verifys[i].origin.span(),
+                        "we never add verifications while doing higher-ranked things",
+                    ),
+                    &AddCombination(..) | &AddVar(..) => {}
                 }
-                &AddVerify(i) => span_bug!(
-                    verifys[i].origin.span(),
-                    "we never add verifications while doing higher-ranked things",
-                ),
-                &AddCombination(..) | &AddVar(..) => {}
+            }
+        } else {
+            for (constraint, _origin) in &region_constraints.data().constraints {
+                each_constraint(constraint)
             }
         }
     }
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index c7a307b89e4..613da8a0b45 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -400,7 +400,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
         data
     }
 
-    pub(super) fn data(&self) -> &RegionConstraintData<'tcx> {
+    pub fn data(&self) -> &RegionConstraintData<'tcx> {
         &self.data
     }
 
@@ -610,13 +610,13 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
         let resolved = ut
             .probe_value(root_vid)
             .get_value_ignoring_universes()
-            .unwrap_or_else(|| tcx.mk_re_var(root_vid));
+            .unwrap_or_else(|| ty::Region::new_var(tcx, root_vid));
 
         // Don't resolve a variable to a region that it cannot name.
         if self.var_universe(vid).can_name(self.universe(resolved)) {
             resolved
         } else {
-            tcx.mk_re_var(vid)
+            ty::Region::new_var(tcx, vid)
         }
     }
 
@@ -637,7 +637,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     ) -> Region<'tcx> {
         let vars = TwoRegions { a, b };
         if let Some(&c) = self.combine_map(t).get(&vars) {
-            return tcx.mk_re_var(c);
+            return ty::Region::new_var(tcx, c);
         }
         let a_universe = self.universe(a);
         let b_universe = self.universe(b);
@@ -645,7 +645,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
         let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
         self.combine_map(t).insert(vars, c);
         self.undo_log.push(AddCombination(t, vars));
-        let new_r = tcx.mk_re_var(c);
+        let new_r = ty::Region::new_var(tcx, c);
         for old_r in [a, b] {
             match t {
                 Glb => self.make_subregion(origin.clone(), new_r, old_r),
@@ -683,15 +683,10 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     }
 
     /// See `InferCtxt::region_constraints_added_in_snapshot`.
-    pub fn region_constraints_added_in_snapshot(&self, mark: &Snapshot<'tcx>) -> Option<bool> {
+    pub fn region_constraints_added_in_snapshot(&self, mark: &Snapshot<'tcx>) -> bool {
         self.undo_log
             .region_constraints_in_snapshot(mark)
-            .map(|&elt| match elt {
-                AddConstraint(constraint) => Some(constraint.involves_placeholders()),
-                _ => None,
-            })
-            .max()
-            .unwrap_or(None)
+            .any(|&elt| matches!(elt, AddConstraint(_)))
     }
 
     #[inline]
diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs
index 955c54e8515..25d06b21ec8 100644
--- a/compiler/rustc_infer/src/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/undo_log.rs
@@ -138,11 +138,9 @@ impl<'tcx> InferCtxtInner<'tcx> {
         }
 
         if self.undo_log.num_open_snapshots == 1 {
-            // The root snapshot. It's safe to clear the undo log because
-            // there's no snapshot further out that we might need to roll back
-            // to.
+            // After the root snapshot the undo log should be empty.
             assert!(snapshot.undo_len == 0);
-            self.undo_log.logs.clear();
+            assert!(self.undo_log.logs.is_empty());
         }
 
         self.undo_log.num_open_snapshots -= 1;
@@ -183,15 +181,6 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> {
         self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..)))
     }
 
-    pub(crate) fn region_constraints(
-        &self,
-    ) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {
-        self.logs.iter().filter_map(|log| match log {
-            UndoLog::RegionConstraintCollector(log) => Some(log),
-            _ => None,
-        })
-    }
-
     fn assert_open_snapshot(&self, snapshot: &Snapshot<'tcx>) {
         // Failures here may indicate a failure to follow a stack discipline.
         assert!(self.logs.len() >= snapshot.undo_len);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index d34a3afcba5..e707ac41a05 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -304,6 +304,14 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
 lint_improper_ctypes_union_layout_reason = this union has unspecified layout
 lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
 
+# FIXME: we should ordinalize $valid_up_to when we add support for doing so
+lint_invalid_from_utf8_checked = calls to `{$method}` with a invalid literal always return an error
+    .label = the literal was valid UTF-8 up to the {$valid_up_to} bytes
+
+# FIXME: we should ordinalize $valid_up_to when we add support for doing so
+lint_invalid_from_utf8_unchecked = calls to `{$method}` with a invalid literal are undefined behavior
+    .label = the literal was valid UTF-8 up to the {$valid_up_to} bytes
+
 lint_lintpass_by_hand = implementing `LintPass` by hand
     .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs
new file mode 100644
index 00000000000..3291286ad67
--- /dev/null
+++ b/compiler/rustc_lint/src/invalid_from_utf8.rs
@@ -0,0 +1,118 @@
+use std::str::Utf8Error;
+
+use rustc_ast::{BorrowKind, LitKind};
+use rustc_hir::{Expr, ExprKind};
+use rustc_span::source_map::Spanned;
+use rustc_span::sym;
+
+use crate::lints::InvalidFromUtf8Diag;
+use crate::{LateContext, LateLintPass, LintContext};
+
+declare_lint! {
+    /// The `invalid_from_utf8_unchecked` lint checks for calls to
+    /// `std::str::from_utf8_unchecked` and `std::str::from_utf8_unchecked_mut`
+    /// with an invalid UTF-8 literal.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// # #[allow(unused)]
+    /// unsafe {
+    ///     std::str::from_utf8_unchecked(b"Ru\x82st");
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Creating such a `str` would result in undefined behavior as per documentation
+    /// for `std::str::from_utf8_unchecked` and `std::str::from_utf8_unchecked_mut`.
+    pub INVALID_FROM_UTF8_UNCHECKED,
+    Deny,
+    "using a non UTF-8 literal in `std::str::from_utf8_unchecked`"
+}
+
+declare_lint! {
+    /// The `invalid_from_utf8` lint checks for calls to
+    /// `std::str::from_utf8` and `std::str::from_utf8_mut`
+    /// with an invalid UTF-8 literal.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// # #[allow(unused)]
+    /// std::str::from_utf8(b"Ru\x82st");
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Trying to create such a `str` would always return an error as per documentation
+    /// for `std::str::from_utf8` and `std::str::from_utf8_mut`.
+    pub INVALID_FROM_UTF8,
+    Warn,
+    "using a non UTF-8 literal in `std::str::from_utf8`"
+}
+
+declare_lint_pass!(InvalidFromUtf8 => [INVALID_FROM_UTF8_UNCHECKED, INVALID_FROM_UTF8]);
+
+impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if let ExprKind::Call(path, [arg]) = expr.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id)
+            && [sym::str_from_utf8, sym::str_from_utf8_mut,
+                sym::str_from_utf8_unchecked, sym::str_from_utf8_unchecked_mut].contains(&diag_item)
+        {
+            let lint = |utf8_error: Utf8Error| {
+                let label = arg.span;
+                let method = diag_item.as_str().strip_prefix("str_").unwrap();
+                let method = format!("std::str::{method}");
+                let valid_up_to = utf8_error.valid_up_to();
+                let is_unchecked_variant = diag_item.as_str().contains("unchecked");
+
+                cx.emit_spanned_lint(
+                    if is_unchecked_variant { INVALID_FROM_UTF8_UNCHECKED } else { INVALID_FROM_UTF8 },
+                    expr.span,
+                    if is_unchecked_variant {
+                        InvalidFromUtf8Diag::Unchecked { method,  valid_up_to, label }
+                    } else {
+                        InvalidFromUtf8Diag::Checked { method,  valid_up_to, label }
+                    }
+                )
+            };
+
+            match &arg.kind {
+                ExprKind::Lit(Spanned { node: lit, .. }) => {
+                    if let LitKind::ByteStr(bytes, _) = &lit
+                        && let Err(utf8_error) = std::str::from_utf8(bytes)
+                    {
+                        lint(utf8_error);
+                    }
+                },
+                ExprKind::AddrOf(BorrowKind::Ref, _, Expr { kind: ExprKind::Array(args), .. }) => {
+                    let elements = args.iter().map(|e|{
+                        match &e.kind {
+                            ExprKind::Lit(Spanned { node: lit, .. }) => match lit {
+                                LitKind::Byte(b) => Some(*b),
+                                LitKind::Int(b, _) => Some(*b as u8),
+                                _ => None
+                            }
+                            _ => None
+                        }
+                    }).collect::<Option<Vec<_>>>();
+
+                    if let Some(elements) = elements
+                        && let Err(utf8_error) = std::str::from_utf8(&elements)
+                    {
+                        lint(utf8_error);
+                    }
+                }
+                _ => {}
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index dfddfe09ab3..c62109b2986 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -60,6 +60,7 @@ mod expect;
 mod for_loops_over_fallibles;
 pub mod hidden_unicode_codepoints;
 mod internal;
+mod invalid_from_utf8;
 mod late;
 mod let_underscore;
 mod levels;
@@ -102,6 +103,7 @@ use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
 use for_loops_over_fallibles::*;
 use hidden_unicode_codepoints::*;
 use internal::*;
+use invalid_from_utf8::*;
 use let_underscore::*;
 use map_unit_fn::*;
 use methods::*;
@@ -207,6 +209,7 @@ late_lint_methods!(
             HardwiredLints: HardwiredLints,
             ImproperCTypesDeclarations: ImproperCTypesDeclarations,
             ImproperCTypesDefinitions: ImproperCTypesDefinitions,
+            InvalidFromUtf8: InvalidFromUtf8,
             VariantSizeDifferences: VariantSizeDifferences,
             BoxPointers: BoxPointers,
             PathStatements: PathStatements,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 6b4d01551ae..746abebeb37 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -699,6 +699,25 @@ pub struct ForgetCopyDiag<'a> {
     pub label: Span,
 }
 
+// invalid_from_utf8.rs
+#[derive(LintDiagnostic)]
+pub enum InvalidFromUtf8Diag {
+    #[diag(lint_invalid_from_utf8_unchecked)]
+    Unchecked {
+        method: String,
+        valid_up_to: usize,
+        #[label]
+        label: Span,
+    },
+    #[diag(lint_invalid_from_utf8_checked)]
+    Checked {
+        method: String,
+        valid_up_to: usize,
+        #[label]
+        label: Span,
+    },
+}
+
 // hidden_unicode_codepoints.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_hidden_unicode_codepoints)]
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 06fdc6fe030..09e24e012af 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -858,7 +858,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         } else {
             tcx.arena.alloc_from_iter(lazy.decode((self, tcx)))
         };
-        ty::EarlyBinder::new(&*output)
+        ty::EarlyBinder::bind(&*output)
     }
 
     fn get_variant(
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index f2a7762f003..c673eb5afc7 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1730,7 +1730,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             ty::Closure(_, substs) => {
                 let constness = self.tcx.constness(def_id.to_def_id());
                 self.tables.constness.set_some(def_id.to_def_id().index, constness);
-                record!(self.tables.fn_sig[def_id.to_def_id()] <- ty::EarlyBinder::new(substs.as_closure().sig()));
+                record!(self.tables.fn_sig[def_id.to_def_id()] <- ty::EarlyBinder::bind(substs.as_closure().sig()));
             }
 
             _ => bug!("closure that is neither generator nor closure"),
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 56171314944..29dae67bfca 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -415,7 +415,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
                                 var: ty::BoundVar::from_usize(i),
                                 kind: ty::BrAnon(None),
                             };
-                            tcx.mk_re_late_bound(ty::INNERMOST, br).into()
+                            ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into()
                         }
                         CanonicalVarKind::Const(_, ty)
                         | CanonicalVarKind::PlaceholderConst(_, ty) => tcx
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 34e47de969c..63cdba7f327 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -476,7 +476,7 @@ impl<'tcx> Body<'tcx> {
     /// Returns the return type; it always return first element from `local_decls` array.
     #[inline]
     pub fn bound_return_ty(&self) -> ty::EarlyBinder<Ty<'tcx>> {
-        ty::EarlyBinder::new(self.local_decls[RETURN_PLACE].ty)
+        ty::EarlyBinder::bind(self.local_decls[RETURN_PLACE].ty)
     }
 
     /// Gets the location of the terminator for the given block.
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 53fd2dd23a7..a15c419da7a 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -413,7 +413,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
             ty::ReVar(vid) => {
                 let br =
                     ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon(None) };
-                tcx.mk_re_late_bound(depth, br)
+                ty::Region::new_late_bound(tcx, depth, br)
             }
             _ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
         });
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 6d6d71bc87b..3e474c1d377 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -220,6 +220,11 @@ pub enum BorrowKind {
     /// immutable, but not aliasable. This solves the problem. For
     /// simplicity, we don't give users the way to express this
     /// borrow, it's just used when translating closures.
+    ///
+    // FIXME(#112072): This is wrong. Unique borrows are mutable borrows except
+    // that they do not require their pointee to be marked as a mutable.
+    // They should still be treated as mutable borrows in every other way,
+    // e.g. for variance or overlap checking.
     Unique,
 
     /// Data is mutable and not aliasable.
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 942654b3074..8d44e929afd 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -650,8 +650,8 @@ macro_rules! make_mir_visitor {
                             BorrowKind::Shallow => PlaceContext::NonMutatingUse(
                                 NonMutatingUseContext::ShallowBorrow
                             ),
-                            BorrowKind::Unique => PlaceContext::NonMutatingUse(
-                                NonMutatingUseContext::UniqueBorrow
+                            BorrowKind::Unique => PlaceContext::MutatingUse(
+                                MutatingUseContext::Borrow
                             ),
                             BorrowKind::Mut { .. } =>
                                 PlaceContext::MutatingUse(MutatingUseContext::Borrow),
@@ -1265,8 +1265,6 @@ pub enum NonMutatingUseContext {
     SharedBorrow,
     /// Shallow borrow.
     ShallowBorrow,
-    /// Unique borrow.
-    UniqueBorrow,
     /// AddressOf for *const pointer.
     AddressOf,
     /// PlaceMention statement.
@@ -1345,9 +1343,7 @@ impl PlaceContext {
         matches!(
             self,
             PlaceContext::NonMutatingUse(
-                NonMutatingUseContext::SharedBorrow
-                    | NonMutatingUseContext::ShallowBorrow
-                    | NonMutatingUseContext::UniqueBorrow
+                NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::ShallowBorrow
             ) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
         )
     }
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 2b99fcad267..e067d2a984f 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -573,7 +573,7 @@ impl<'tcx> AdtDef<'tcx> {
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer (e.g., issue #31299).
     pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
-        ty::EarlyBinder::new(tcx.adt_sized_constraint(self.did()))
+        ty::EarlyBinder::bind(tcx.adt_sized_constraint(self.did()))
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 7fc75674da5..76f52bc34ed 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -264,7 +264,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for mir::Place<'tcx> {
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Region<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        decoder.interner().mk_region_from_kind(Decodable::decode(decoder))
+        ty::Region::new_from_kind(decoder.interner(), Decodable::decode(decoder))
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 5fcbc4a9ed4..aecb46556b0 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -254,5 +254,5 @@ pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBind
             "`const_param_default` expected a generic parameter with a constant"
         ),
     };
-    ty::EarlyBinder::new(Const::from_anon_const(tcx, default_def_id))
+    ty::EarlyBinder::bind(Const::from_anon_const(tcx, default_def_id))
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 0464336627f..77725f0b3b6 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -115,6 +115,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     type FreeRegion = ty::FreeRegion;
     type RegionVid = ty::RegionVid;
     type PlaceholderRegion = ty::PlaceholderRegion;
+
+    fn ty_and_mut_to_parts(
+        TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>,
+    ) -> (Self::Ty, Self::Mutability) {
+        (ty, mutbl)
+    }
+
+    fn mutability_is_mut(mutbl: Self::Mutability) -> bool {
+        mutbl.is_mut()
+    }
 }
 
 type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
@@ -713,34 +723,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_ty_from_kind(Error(reported))
     }
 
-    /// Constructs a `RegionKind::ReError` lifetime.
-    #[track_caller]
-    pub fn mk_re_error(self, reported: ErrorGuaranteed) -> Region<'tcx> {
-        self.intern_region(ty::ReError(reported))
-    }
-
-    /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` to ensure it
-    /// gets used.
-    #[track_caller]
-    pub fn mk_re_error_misc(self) -> Region<'tcx> {
-        self.mk_re_error_with_message(
-            DUMMY_SP,
-            "RegionKind::ReError constructed but no error reported",
-        )
-    }
-
-    /// Constructs a `RegionKind::ReError` lifetime and registers a `delay_span_bug` with the given
-    /// `msg` to ensure it gets used.
-    #[track_caller]
-    pub fn mk_re_error_with_message<S: Into<MultiSpan>>(
-        self,
-        span: S,
-        msg: &'static str,
-    ) -> Region<'tcx> {
-        let reported = self.sess.delay_span_bug(span, msg);
-        self.mk_re_error(reported)
-    }
-
     /// Like [TyCtxt::ty_error] but for constants, with current `ErrorGuaranteed`
     #[track_caller]
     pub fn const_error(self, ty: Ty<'tcx>, reported: ErrorGuaranteed) -> Const<'tcx> {
@@ -1519,9 +1501,9 @@ macro_rules! direct_interners {
 
 // Functions with a `mk_` prefix are intended for use outside this file and
 // crate. Functions with an `intern_` prefix are intended for use within this
-// file only, and have a corresponding `mk_` function.
+// crate only, and have a corresponding `mk_` function.
 direct_interners! {
-    region: intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
+    region: pub(crate) intern_region(RegionKind<'tcx>): Region -> Region<'tcx>,
     const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>,
     const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
     layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>,
@@ -1996,7 +1978,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
         match param.kind {
             GenericParamDefKind::Lifetime => {
-                self.mk_re_early_bound(param.to_early_bound_region_data()).into()
+                ty::Region::new_early_bound(self, param.to_early_bound_region_data()).into()
             }
             GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
             GenericParamDefKind::Const { .. } => self
@@ -2036,65 +2018,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_alias(ty::Opaque, self.mk_alias_ty(def_id, substs))
     }
 
-    #[inline]
-    pub fn mk_re_early_bound(self, early_bound_region: ty::EarlyBoundRegion) -> Region<'tcx> {
-        self.intern_region(ty::ReEarlyBound(early_bound_region))
-    }
-
-    #[inline]
-    pub fn mk_re_late_bound(
-        self,
-        debruijn: ty::DebruijnIndex,
-        bound_region: ty::BoundRegion,
-    ) -> Region<'tcx> {
-        // Use a pre-interned one when possible.
-        if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region
-            && let Some(inner) = self.lifetimes.re_late_bounds.get(debruijn.as_usize())
-            && let Some(re) = inner.get(var.as_usize()).copied()
-        {
-            re
-        } else {
-            self.intern_region(ty::ReLateBound(debruijn, bound_region))
-        }
-    }
-
-    #[inline]
-    pub fn mk_re_free(self, scope: DefId, bound_region: ty::BoundRegionKind) -> Region<'tcx> {
-        self.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region }))
-    }
-
-    #[inline]
-    pub fn mk_re_var(self, v: ty::RegionVid) -> Region<'tcx> {
-        // Use a pre-interned one when possible.
-        self.lifetimes
-            .re_vars
-            .get(v.as_usize())
-            .copied()
-            .unwrap_or_else(|| self.intern_region(ty::ReVar(v)))
-    }
-
-    #[inline]
-    pub fn mk_re_placeholder(self, placeholder: ty::PlaceholderRegion) -> Region<'tcx> {
-        self.intern_region(ty::RePlaceholder(placeholder))
-    }
-
-    // Avoid this in favour of more specific `mk_re_*` methods, where possible,
-    // to avoid the cost of the `match`.
-    pub fn mk_region_from_kind(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> {
-        match kind {
-            ty::ReEarlyBound(region) => self.mk_re_early_bound(region),
-            ty::ReLateBound(debruijn, region) => self.mk_re_late_bound(debruijn, region),
-            ty::ReFree(ty::FreeRegion { scope, bound_region }) => {
-                self.mk_re_free(scope, bound_region)
-            }
-            ty::ReStatic => self.lifetimes.re_static,
-            ty::ReVar(vid) => self.mk_re_var(vid),
-            ty::RePlaceholder(region) => self.mk_re_placeholder(region),
-            ty::ReErased => self.lifetimes.re_erased,
-            ty::ReError(reported) => self.mk_re_error(reported),
-        }
-    }
-
     pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> {
         self.mk_place_elem(place, PlaceElem::Field(f, ty))
     }
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 49ab9b79e96..66293f19eef 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -45,7 +45,6 @@ pub enum TypeError<'tcx> {
 
     RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
     RegionsInsufficientlyPolymorphic(BoundRegionKind, Region<'tcx>),
-    RegionsOverlyPolymorphic(BoundRegionKind, Region<'tcx>),
     RegionsPlaceholderMismatch,
 
     Sorts(ExpectedFound<Ty<'tcx>>),
@@ -74,7 +73,6 @@ impl TypeError<'_> {
         match self {
             TypeError::RegionsDoesNotOutlive(_, _)
             | TypeError::RegionsInsufficientlyPolymorphic(_, _)
-            | TypeError::RegionsOverlyPolymorphic(_, _)
             | TypeError::RegionsPlaceholderMismatch => true,
             _ => false,
         }
@@ -98,11 +96,6 @@ impl<'tcx> TypeError<'tcx> {
             }
         }
 
-        let br_string = |br: ty::BoundRegionKind| match br {
-            ty::BrNamed(_, name) => format!(" {}", name),
-            _ => String::new(),
-        };
-
         match self {
             CyclicTy(_) => "cyclic type of infinite size".into(),
             CyclicConst(_) => "encountered a self-referencing constant".into(),
@@ -144,11 +137,6 @@ impl<'tcx> TypeError<'tcx> {
             RegionsInsufficientlyPolymorphic(..) => {
                 "one type is more general than the other".into()
             }
-            RegionsOverlyPolymorphic(br, _) => format!(
-                "expected concrete lifetime, found bound lifetime parameter{}",
-                br_string(br)
-            )
-            .into(),
             RegionsPlaceholderMismatch => "one type is more general than the other".into(),
             ArgumentSorts(values, _) | Sorts(values) => {
                 let expected = values.expected.sort_string(tcx);
@@ -228,7 +216,6 @@ impl<'tcx> TypeError<'tcx> {
             | FieldMisMatch(..)
             | RegionsDoesNotOutlive(..)
             | RegionsInsufficientlyPolymorphic(..)
-            | RegionsOverlyPolymorphic(..)
             | RegionsPlaceholderMismatch
             | Traits(_)
             | ProjectionMismatched(_)
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 25890eb15cd..149ce29b8d9 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -213,7 +213,7 @@ where
                     // debruijn index. Then we adjust it to the
                     // correct depth.
                     assert_eq!(debruijn1, ty::INNERMOST);
-                    self.tcx.mk_re_late_bound(debruijn, br)
+                    ty::Region::new_late_bound(self.tcx, debruijn, br)
                 } else {
                     region
                 }
@@ -328,7 +328,7 @@ impl<'tcx> TyCtxt<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         self.replace_late_bound_regions_uncached(value, |br| {
-            self.mk_re_free(all_outlive_scope, br.kind)
+            ty::Region::new_free(self, all_outlive_scope, br.kind)
         })
     }
 
@@ -341,7 +341,8 @@ impl<'tcx> TyCtxt<'tcx> {
             value,
             FnMutDelegate {
                 regions: &mut |r: ty::BoundRegion| {
-                    self.mk_re_late_bound(
+                    ty::Region::new_late_bound(
+                        self,
                         ty::INNERMOST,
                         ty::BoundRegion { var: shift_bv(r.var), kind: r.kind },
                     )
@@ -383,7 +384,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon(None)))
                     .expect_region();
                 let br = ty::BoundRegion { var, kind };
-                self.tcx.mk_re_late_bound(ty::INNERMOST, br)
+                ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br)
             }
             fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
                 let entry = self.map.entry(bt.var);
@@ -451,7 +452,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> {
         match *r {
             ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
                 let debruijn = debruijn.shifted_in(self.amount);
-                self.tcx.mk_re_late_bound(debruijn, br)
+                ty::Region::new_late_bound(self.tcx, debruijn, br)
             }
             _ => r,
         }
@@ -492,7 +493,7 @@ pub fn shift_region<'tcx>(
 ) -> ty::Region<'tcx> {
     match *region {
         ty::ReLateBound(debruijn, br) if amount > 0 => {
-            tcx.mk_re_late_bound(debruijn.shifted_in(amount), br)
+            ty::Region::new_late_bound(tcx, debruijn.shifted_in(amount), br)
         }
         _ => region,
     }
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index b27ee8cbad0..30f92b91cb7 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -100,7 +100,7 @@ impl GenericParamDef {
         preceding_substs: &[ty::GenericArg<'tcx>],
     ) -> ty::GenericArg<'tcx> {
         match &self.kind {
-            ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(),
+            ty::GenericParamDefKind::Lifetime => ty::Region::new_error_misc(tcx).into(),
             ty::GenericParamDefKind::Type { .. } => tcx.ty_error_misc().into(),
             ty::GenericParamDefKind::Const { .. } => {
                 tcx.const_error_misc(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into()
@@ -343,7 +343,7 @@ impl<'tcx> GenericPredicates<'tcx> {
         substs: SubstsRef<'tcx>,
     ) -> impl Iterator<Item = (Predicate<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
     {
-        EarlyBinder::new(self.predicates).subst_iter_copied(tcx, substs)
+        EarlyBinder::bind(self.predicates).subst_iter_copied(tcx, substs)
     }
 
     #[instrument(level = "debug", skip(self, tcx))]
@@ -358,7 +358,7 @@ impl<'tcx> GenericPredicates<'tcx> {
         }
         instantiated
             .predicates
-            .extend(self.predicates.iter().map(|(p, _)| EarlyBinder::new(*p).subst(tcx, substs)));
+            .extend(self.predicates.iter().map(|(p, _)| EarlyBinder::bind(*p).subst(tcx, substs)));
         instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp));
     }
 
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index b3cc27e3f78..d48672b2baa 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -158,7 +158,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
     fn subst_opt(self, tcx: TyCtxt<'tcx>, substs: ty::SubstsRef<'tcx>) -> Option<Self> {
         match self {
             Self::ConstIsZero(c) => {
-                let c = ty::EarlyBinder::new(c).subst(tcx, substs);
+                let c = ty::EarlyBinder::bind(c).subst(tcx, substs);
                 let pred = match c.kind().try_to_target_usize(tcx) {
                     Some(0) => Self::True,
                     Some(1..) => Self::False,
@@ -167,7 +167,7 @@ impl<'tcx> InhabitedPredicate<'tcx> {
                 Some(pred)
             }
             Self::GenericType(t) => {
-                Some(ty::EarlyBinder::new(t).subst(tcx, substs).inhabited_predicate(tcx))
+                Some(ty::EarlyBinder::bind(t).subst(tcx, substs).inhabited_predicate(tcx))
             }
             Self::And(&[a, b]) => match a.subst_opt(tcx, substs) {
                 None => b.subst_opt(tcx, substs).map(|b| a.and(tcx, b)),
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 4b2c7e8ef31..72341e656e2 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -764,7 +764,7 @@ impl<'tcx> Predicate<'tcx> {
         let shifted_pred =
             tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
         // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
-        let new = EarlyBinder::new(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
+        let new = EarlyBinder::bind(shifted_pred).subst(tcx, trait_ref.skip_binder().substs);
         // 3) ['x] + ['b] -> ['x, 'b]
         let bound_vars =
             tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars));
@@ -1496,7 +1496,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
 /// identified by both a universe, as well as a name residing within that universe. Distinct bound
 /// regions/types/consts within the same universe simply have an unknown relationship to one
 /// another.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 #[derive(HashStable, TyEncodable, TyDecodable)]
 pub struct Placeholder<T> {
     pub universe: UniverseIndex,
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 1b336b7bfc6..d1ed7be3d2e 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -141,7 +141,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                     )
                     .emit();
 
-                self.interner().mk_re_error(e)
+                ty::Region::new_error(self.interner(), e)
             }
         }
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index d6c88ea96ca..6156fdf7eac 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -184,7 +184,7 @@ impl<'tcx> RegionHighlightMode<'tcx> {
 
     /// Convenience wrapper for `highlighting_region`.
     pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) {
-        self.highlighting_region(self.tcx.mk_re_var(vid), number)
+        self.highlighting_region(ty::Region::new_var(self.tcx, vid), number)
     }
 
     /// Returns `Some(n)` with the number to use for the given region, if any.
@@ -685,29 +685,30 @@ pub trait PrettyPrinter<'tcx>:
             }
             ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
             ty::Infer(infer_ty) => {
-                let verbose = self.should_print_verbose();
+                if self.should_print_verbose() {
+                    p!(write("{:?}", ty.kind()));
+                    return Ok(self);
+                }
+
                 if let ty::TyVar(ty_vid) = infer_ty {
                     if let Some(name) = self.ty_infer_name(ty_vid) {
                         p!(write("{}", name))
                     } else {
-                        if verbose {
-                            p!(write("{:?}", infer_ty))
-                        } else {
-                            p!(write("{}", infer_ty))
-                        }
+                        p!(write("{}", infer_ty))
                     }
                 } else {
-                    if verbose { p!(write("{:?}", infer_ty)) } else { p!(write("{}", infer_ty)) }
+                    p!(write("{}", infer_ty))
                 }
             }
             ty::Error(_) => p!("{{type error}}"),
             ty::Param(ref param_ty) => p!(print(param_ty)),
             ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
-                ty::BoundTyKind::Anon => debug_bound_var(&mut self, debruijn, bound_ty.var)?,
+                ty::BoundTyKind::Anon => {
+                    rustc_type_ir::debug_bound_var(&mut self, debruijn, bound_ty.var)?
+                }
                 ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() {
-                    true if debruijn == ty::INNERMOST => p!(write("^{}", s)),
-                    true => p!(write("^{}_{}", debruijn.index(), s)),
-                    false => p!(write("{}", s)),
+                    true => p!(write("{:?}", ty.kind())),
+                    false => p!(write("{s}")),
                 },
             },
             ty::Adt(def, substs) => {
@@ -740,10 +741,11 @@ pub trait PrettyPrinter<'tcx>:
                 }
             }
             ty::Placeholder(placeholder) => match placeholder.bound.kind {
-                ty::BoundTyKind::Anon => {
-                    debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound.var)?;
-                }
-                ty::BoundTyKind::Param(_, name) => p!(write("{}", name)),
+                ty::BoundTyKind::Anon => p!(write("{placeholder:?}")),
+                ty::BoundTyKind::Param(_, name) => match self.should_print_verbose() {
+                    true => p!(write("{:?}", ty.kind())),
+                    false => p!(write("{name}")),
+                },
             },
             ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
                 // We use verbose printing in 'NO_QUERIES' mode, to
@@ -1372,11 +1374,9 @@ pub trait PrettyPrinter<'tcx>:
             }
 
             ty::ConstKind::Bound(debruijn, bound_var) => {
-                debug_bound_var(&mut self, debruijn, bound_var)?
+                rustc_type_ir::debug_bound_var(&mut self, debruijn, bound_var)?
             }
-            ty::ConstKind::Placeholder(placeholder) => {
-                debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound)?;
-            },
+            ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
             // FIXME(generic_const_exprs):
             // write out some legible representation of an abstract const?
             ty::ConstKind::Expr(_) => p!("{{const expr}}"),
@@ -2303,7 +2303,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
         };
         if let ty::ReLateBound(debruijn1, br) = *region {
             assert_eq!(debruijn1, ty::INNERMOST);
-            self.tcx.mk_re_late_bound(self.current_index, br)
+            ty::Region::new_late_bound(self.tcx, self.current_index, br)
         } else {
             region
         }
@@ -2415,7 +2415,8 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                         if let Some(lt_idx) = lifetime_idx {
                             if lt_idx > binder_level_idx {
                                 let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
-                                return tcx.mk_re_late_bound(
+                                return ty::Region::new_late_bound(
+                                    tcx,
                                     ty::INNERMOST,
                                     ty::BoundRegion { var: br.var, kind },
                                 );
@@ -2430,7 +2431,8 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                         if let Some(lt_idx) = lifetime_idx {
                             if lt_idx > binder_level_idx {
                                 let kind = ty::BrNamed(def_id, name);
-                                return tcx.mk_re_late_bound(
+                                return ty::Region::new_late_bound(
+                                    tcx,
                                     ty::INNERMOST,
                                     ty::BoundRegion { var: br.var, kind },
                                 );
@@ -2443,7 +2445,8 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                         if let Some(lt_idx) = lifetime_idx {
                             if lt_idx > binder_level_idx {
                                 let kind = br.kind;
-                                return tcx.mk_re_late_bound(
+                                return ty::Region::new_late_bound(
+                                    tcx,
                                     ty::INNERMOST,
                                     ty::BoundRegion { var: br.var, kind },
                                 );
@@ -2458,7 +2461,11 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                     start_or_continue(&mut self, "for<", ", ");
                     do_continue(&mut self, name);
                 }
-                tcx.mk_re_late_bound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind })
+                ty::Region::new_late_bound(
+                    tcx,
+                    ty::INNERMOST,
+                    ty::BoundRegion { var: br.var, kind },
+                )
             };
             let mut folder = RegionFolder {
                 tcx,
@@ -3065,27 +3072,3 @@ pub struct OpaqueFnEntry<'tcx> {
     fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
     return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
 }
-
-pub fn debug_bound_var<T: std::fmt::Write>(
-    fmt: &mut T,
-    debruijn: ty::DebruijnIndex,
-    var: ty::BoundVar,
-) -> Result<(), std::fmt::Error> {
-    if debruijn == ty::INNERMOST {
-        write!(fmt, "^{}", var.index())
-    } else {
-        write!(fmt, "^{}_{}", debruijn.index(), var.index())
-    }
-}
-
-pub fn debug_placeholder_var<T: std::fmt::Write>(
-    fmt: &mut T,
-    universe: ty::UniverseIndex,
-    bound: ty::BoundVar,
-) -> Result<(), std::fmt::Error> {
-    if universe == ty::UniverseIndex::ROOT {
-        write!(fmt, "!{}", bound.index())
-    } else {
-        write!(fmt, "!{}_{}", universe.index(), bound.index())
-    }
-}
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 16cb6c91046..a965450d27d 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -88,7 +88,35 @@ impl fmt::Debug for ty::FreeRegion {
 
 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
+        let ty::FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = self;
+
+        write!(f, "{}", unsafety.prefix_str())?;
+        match abi {
+            rustc_target::spec::abi::Abi::Rust => (),
+            abi => write!(f, "extern \"{abi:?}\" ")?,
+        };
+
+        write!(f, "fn(")?;
+        let inputs = self.inputs();
+        match inputs.len() {
+            0 if *c_variadic => write!(f, "...)")?,
+            0 => write!(f, ")")?,
+            _ => {
+                for ty in &self.inputs()[0..(self.inputs().len() - 1)] {
+                    write!(f, "{ty:?}, ")?;
+                }
+                write!(f, "{:?}", self.inputs().last().unwrap())?;
+                if *c_variadic {
+                    write!(f, "...")?;
+                }
+                write!(f, ")")?;
+            }
+        }
+
+        match self.output().kind() {
+            ty::Tuple(list) if list.is_empty() => Ok(()),
+            _ => write!(f, " -> {:?}", self.output()),
+        }
     }
 }
 
@@ -216,20 +244,37 @@ impl<'tcx> fmt::Debug for ty::ConstKind<'tcx> {
         match self {
             Param(param) => write!(f, "{param:?}"),
             Infer(var) => write!(f, "{var:?}"),
-            Bound(debruijn, var) => ty::print::debug_bound_var(f, *debruijn, *var),
-            Placeholder(placeholder) => {
-                ty::print::debug_placeholder_var(f, placeholder.universe, placeholder.bound)
-            }
+            Bound(debruijn, var) => rustc_type_ir::debug_bound_var(f, *debruijn, *var),
+            Placeholder(placeholder) => write!(f, "{placeholder:?}"),
             Unevaluated(uv) => {
                 f.debug_tuple("Unevaluated").field(&uv.substs).field(&uv.def).finish()
             }
             Value(valtree) => write!(f, "{valtree:?}"),
-            Error(_) => write!(f, "[const error]"),
+            Error(_) => write!(f, "{{const error}}"),
             Expr(expr) => write!(f, "{expr:?}"),
         }
     }
 }
 
+impl fmt::Debug for ty::BoundTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.kind {
+            ty::BoundTyKind::Anon => write!(f, "{:?}", self.var),
+            ty::BoundTyKind::Param(_, sym) => write!(f, "{sym:?}"),
+        }
+    }
+}
+
+impl<T: fmt::Debug> fmt::Debug for ty::Placeholder<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if self.universe == ty::UniverseIndex::ROOT {
+            write!(f, "!{:?}", self.bound)
+        } else {
+            write!(f, "!{}_{:?}", self.universe.index(), self.bound)
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Atomic structs
 //
@@ -294,6 +339,7 @@ TrivialTypeTraversalAndLiftImpls! {
     crate::ty::AliasRelationDirection,
     crate::ty::Placeholder<crate::ty::BoundRegion>,
     crate::ty::Placeholder<crate::ty::BoundTy>,
+    crate::ty::Placeholder<ty::BoundVar>,
     crate::ty::ClosureKind,
     crate::ty::FreeRegion,
     crate::ty::InferTy,
@@ -310,7 +356,6 @@ TrivialTypeTraversalAndLiftImpls! {
     interpret::Scalar,
     rustc_target::abi::Size,
     ty::BoundVar,
-    ty::Placeholder<ty::BoundVar>,
 }
 
 TrivialTypeTraversalAndLiftImpls! {
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 82f79a0c088..d19a7bcde79 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -15,14 +15,14 @@ use hir::def::DefKind;
 use polonius_engine::Atom;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::intern::Interned;
-use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
+use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
 use rustc_index::Idx;
 use rustc_macros::HashStable;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
 use rustc_target::spec::abi::{self, Abi};
 use std::borrow::Cow;
@@ -568,7 +568,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
         let layout = tcx.generator_layout(def_id).unwrap();
         layout.variant_fields.iter().map(move |variant| {
             variant.iter().map(move |field| {
-                ty::EarlyBinder::new(layout.field_tys[*field].ty).subst(tcx, self.substs)
+                ty::EarlyBinder::bind(layout.field_tys[*field].ty).subst(tcx, self.substs)
             })
         })
     }
@@ -1459,6 +1459,103 @@ impl ParamConst {
 #[rustc_pass_by_value]
 pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
 
+impl<'tcx> Region<'tcx> {
+    #[inline]
+    pub fn new_early_bound(
+        tcx: TyCtxt<'tcx>,
+        early_bound_region: ty::EarlyBoundRegion,
+    ) -> Region<'tcx> {
+        tcx.intern_region(ty::ReEarlyBound(early_bound_region))
+    }
+
+    #[inline]
+    pub fn new_late_bound(
+        tcx: TyCtxt<'tcx>,
+        debruijn: ty::DebruijnIndex,
+        bound_region: ty::BoundRegion,
+    ) -> Region<'tcx> {
+        // Use a pre-interned one when possible.
+        if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region
+            && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize())
+            && let Some(re) = inner.get(var.as_usize()).copied()
+        {
+            re
+        } else {
+            tcx.intern_region(ty::ReLateBound(debruijn, bound_region))
+        }
+    }
+
+    #[inline]
+    pub fn new_free(
+        tcx: TyCtxt<'tcx>,
+        scope: DefId,
+        bound_region: ty::BoundRegionKind,
+    ) -> Region<'tcx> {
+        tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region }))
+    }
+
+    #[inline]
+    pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> {
+        // Use a pre-interned one when possible.
+        tcx.lifetimes
+            .re_vars
+            .get(v.as_usize())
+            .copied()
+            .unwrap_or_else(|| tcx.intern_region(ty::ReVar(v)))
+    }
+
+    #[inline]
+    pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Region<'tcx> {
+        tcx.intern_region(ty::RePlaceholder(placeholder))
+    }
+
+    /// Constructs a `RegionKind::ReError` region.
+    #[track_caller]
+    pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Region<'tcx> {
+        tcx.intern_region(ty::ReError(reported))
+    }
+
+    /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it
+    /// gets used.
+    #[track_caller]
+    pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
+        Region::new_error_with_message(
+            tcx,
+            DUMMY_SP,
+            "RegionKind::ReError constructed but no error reported",
+        )
+    }
+
+    /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given
+    /// `msg` to ensure it gets used.
+    #[track_caller]
+    pub fn new_error_with_message<S: Into<MultiSpan>>(
+        tcx: TyCtxt<'tcx>,
+        span: S,
+        msg: &'static str,
+    ) -> Region<'tcx> {
+        let reported = tcx.sess.delay_span_bug(span, msg);
+        Region::new_error(tcx, reported)
+    }
+
+    /// Avoid this in favour of more specific `new_*` methods, where possible,
+    /// to avoid the cost of the `match`.
+    pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
+        match kind {
+            ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region),
+            ty::ReLateBound(debruijn, region) => Region::new_late_bound(tcx, debruijn, region),
+            ty::ReFree(ty::FreeRegion { scope, bound_region }) => {
+                Region::new_free(tcx, scope, bound_region)
+            }
+            ty::ReStatic => tcx.lifetimes.re_static,
+            ty::ReVar(vid) => Region::new_var(tcx, vid),
+            ty::RePlaceholder(region) => Region::new_placeholder(tcx, region),
+            ty::ReErased => tcx.lifetimes.re_erased,
+            ty::ReError(reported) => Region::new_error(tcx, reported),
+        }
+    }
+}
+
 impl<'tcx> Deref for Region<'tcx> {
     type Target = RegionKind<'tcx>;
 
@@ -1511,10 +1608,11 @@ impl Atom for RegionVid {
 
 rustc_index::newtype_index! {
     #[derive(HashStable)]
+    #[debug_format = "{}"]
     pub struct BoundVar {}
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub struct BoundTy {
     pub var: BoundVar,
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs
index 8691a3070bc..8685a22d9ca 100644
--- a/compiler/rustc_middle/src/ty/subst.rs
+++ b/compiler/rustc_middle/src/ty/subst.rs
@@ -545,7 +545,7 @@ impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
 impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {}
 
 impl<T> EarlyBinder<T> {
-    pub fn new(inner: T) -> EarlyBinder<T> {
+    pub fn bind(inner: T) -> EarlyBinder<T> {
         EarlyBinder(inner)
     }
 
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index dade50df5d9..311f63adc7f 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -709,7 +709,7 @@ impl<'tcx> TyCtxt<'tcx> {
             .as_ref()
             .map_or_else(|| [].iter(), |l| l.field_tys.iter())
             .filter(|decl| !decl.ignore_for_traits)
-            .map(|decl| ty::EarlyBinder::new(decl.ty))
+            .map(|decl| ty::EarlyBinder::bind(decl.ty))
     }
 
     /// Normalizes all opaque types in the given value, replacing them
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 58374f6b3bd..a00c77ccbcd 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -96,13 +96,13 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Representability {
 
 impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<Ty<'_>> {
     fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
-        ty::EarlyBinder::new(Ty::from_cycle_error(tcx, cycle))
+        ty::EarlyBinder::bind(Ty::from_cycle_error(tcx, cycle))
     }
 }
 
 impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>> {
     fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
-        ty::EarlyBinder::new(ty::Binder::from_cycle_error(tcx, cycle))
+        ty::EarlyBinder::bind(ty::Binder::from_cycle_error(tcx, cycle))
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index 463f639defe..d00fb754c64 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -142,7 +142,7 @@ impl<'tcx> Cx<'tcx> {
                     var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                     kind: ty::BrEnv,
                 };
-                let env_region = self.tcx.mk_re_late_bound(ty::INNERMOST, br);
+                let env_region = ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br);
                 let closure_env_ty =
                     self.tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
                 let liberated_closure_env_ty = self.tcx.erase_late_bound_regions(
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index aeca0073304..6ae6bdc17d5 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -199,8 +199,7 @@ impl DefUse {
                 | NonMutatingUseContext::Move
                 | NonMutatingUseContext::PlaceMention
                 | NonMutatingUseContext::ShallowBorrow
-                | NonMutatingUseContext::SharedBorrow
-                | NonMutatingUseContext::UniqueBorrow,
+                | NonMutatingUseContext::SharedBorrow,
             ) => Some(DefUse::Use),
 
             PlaceContext::MutatingUse(MutatingUseContext::Projection)
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index a5d18fff89b..1ba1951afde 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -772,7 +772,6 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
             // mutation.
             | NonMutatingUse(NonMutatingUseContext::SharedBorrow)
             | NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
-            | NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
             | NonMutatingUse(NonMutatingUseContext::AddressOf)
             | MutatingUse(MutatingUseContext::Borrow)
             | MutatingUse(MutatingUseContext::AddressOf) => {
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index 319f3a79705..3df459dfa79 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -130,7 +130,6 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
             PlaceContext::NonMutatingUse(
                 NonMutatingUseContext::SharedBorrow
                 | NonMutatingUseContext::ShallowBorrow
-                | NonMutatingUseContext::UniqueBorrow
                 | NonMutatingUseContext::AddressOf,
             ) => true,
             // For debuginfo, merging locals is ok.
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index c0458126840..b1c9c4acc40 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -83,7 +83,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
                         // If the inner type matches the type bound by `Pointer`
                         if inner_ty == bound_ty {
                             // Do a substitution using the parameters from the callsite
-                            let subst_ty = EarlyBinder::new(inner_ty).subst(self.tcx, substs_ref);
+                            let subst_ty = EarlyBinder::bind(inner_ty).subst(self.tcx, substs_ref);
                             if let Some((fn_id, fn_substs)) =
                                 FunctionItemRefChecker::is_fn_ref(subst_ty)
                             {
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index e27d48fa8f6..55b9f084c39 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -192,7 +192,7 @@ impl<'tcx> Inliner<'tcx> {
         let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
             self.tcx,
             self.param_env,
-            ty::EarlyBinder::new(callee_body.clone()),
+            ty::EarlyBinder::bind(callee_body.clone()),
         ) else {
             return Err("failed to normalize callee body");
         };
@@ -455,7 +455,7 @@ impl<'tcx> Inliner<'tcx> {
                 // If the place doesn't actually need dropping, treat it like a regular goto.
                 let ty = callsite
                     .callee
-                    .subst_mir(self.tcx, ty::EarlyBinder::new(&place.ty(callee_body, tcx).ty));
+                    .subst_mir(self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty));
                 if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
                     work_list.push(unwind);
                 }
@@ -790,7 +790,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
                 // If the place doesn't actually need dropping, treat it like a regular goto.
                 let ty = self
                     .instance
-                    .subst_mir(tcx, ty::EarlyBinder::new(&place.ty(self.callee_body, tcx).ty));
+                    .subst_mir(tcx, ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty));
                 if ty.needs_drop(tcx, self.param_env) {
                     self.cost += CALL_PENALTY;
                     if let UnwindAction::Cleanup(_) = unwind {
@@ -801,7 +801,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
                 }
             }
             TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
-                let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::new(&f.literal.ty()));
+                let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.literal.ty()));
                 self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
                     // Don't give intrinsics the extra penalty for calls
                     INSTR_COST
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 00842e9d665..8a10445f837 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -47,7 +47,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
             let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions(
                 tcx,
                 param_env,
-                ty::EarlyBinder::new(substs),
+                ty::EarlyBinder::bind(substs),
             ) else {
                 trace!(?caller, ?param_env, ?substs, "cannot normalize, skipping");
                 continue;
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 522220f3d77..ae726dea944 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -69,7 +69,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
             // of this function. Is this intentional?
             if let Some(ty::Generator(gen_def_id, substs, _)) = ty.map(Ty::kind) {
                 let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap();
-                let body = EarlyBinder::new(body.clone()).subst(tcx, substs);
+                let body = EarlyBinder::bind(body.clone()).subst(tcx, substs);
                 debug!("make_shim({:?}) = {:?}", instance, body);
                 return body;
             }
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index e8e4246b797..7a0d3a025f3 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -216,7 +216,6 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
             PlaceContext::NonMutatingUse(
                 NonMutatingUseContext::SharedBorrow
                 | NonMutatingUseContext::ShallowBorrow
-                | NonMutatingUseContext::UniqueBorrow
                 | NonMutatingUseContext::AddressOf,
             )
             | PlaceContext::MutatingUse(_) => {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 8874aa7d3ca..cefa64d27ac 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -677,7 +677,7 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> {
         self.instance.subst_mir_and_normalize_erasing_regions(
             self.tcx,
             ty::ParamEnv::reveal_all(),
-            ty::EarlyBinder::new(value),
+            ty::EarlyBinder::bind(value),
         )
     }
 }
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
new file mode 100644
index 00000000000..be9c349c384
--- /dev/null
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -0,0 +1,1182 @@
+//! 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(*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<'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_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs
index 772f1520153..f6a80b0431f 100644
--- a/compiler/rustc_monomorphize/src/util.rs
+++ b/compiler/rustc_monomorphize/src/util.rs
@@ -29,12 +29,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
         let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
             closure_instance.substs,
             param_env,
-            ty::EarlyBinder::new(before_feature_tys),
+            ty::EarlyBinder::bind(before_feature_tys),
         );
         let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
             closure_instance.substs,
             param_env,
-            ty::EarlyBinder::new(after_feature_tys),
+            ty::EarlyBinder::bind(after_feature_tys),
         );
 
         let new_size = tcx
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index e596993465c..c9353b6fc9f 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 
 
 [dependencies]
-memoffset = { version = "0.6.0", features = ["unstable_const"] }
+memoffset = { version = "0.8.0", features = ["unstable_const"] }
 field-offset = "0.3.5"
 measureme = "10.0.0"
 rustc_ast = { path = "../rustc_ast" }
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_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 874d578fe1d..1185563ea80 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1454,6 +1454,10 @@ symbols! {
         stop_after_dataflow,
         store,
         str,
+        str_from_utf8,
+        str_from_utf8_mut,
+        str_from_utf8_unchecked,
+        str_from_utf8_unchecked_mut,
         str_split_whitespace,
         str_trim,
         str_trim_end,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 55901bfbde9..0a805e2422d 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -274,7 +274,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
 
         let mut param_env = self.tcx.param_env_reveal_all_normalized(impl_def_id);
         if !substs.is_empty() {
-            param_env = EarlyBinder::new(param_env).subst(self.tcx, substs);
+            param_env = EarlyBinder::bind(param_env).subst(self.tcx, substs);
         }
 
         match &mut impl_trait_ref {
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_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 1071b8fc702..0f3f8f1ac2c 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -96,7 +96,7 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
             let br =
                 ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None) };
             counter += 1;
-            tcx.mk_re_late_bound(current_depth, br)
+            ty::Region::new_late_bound(tcx, current_depth, br)
         }
         // All free regions should be erased here.
         r => bug!("unexpected region: {r:?}"),
diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
index ff4bff10cc8..29bdb5ff67d 100644
--- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
@@ -255,7 +255,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
             }),
         );
         let br = ty::BoundRegion { var, kind: BrAnon(None) };
-        self.interner().mk_re_late_bound(self.binder_index, br)
+        ty::Region::new_late_bound(self.interner(), self.binder_index, br)
     }
 
     fn fold_ty(&mut self, mut t: Ty<'tcx>) -> Ty<'tcx> {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index fdb209fbff8..bca2343e424 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -137,6 +137,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
     #[instrument(level = "debug", skip(self), ret)]
     fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
+        // We only check for leaks from universes which were entered inside
+        // of the query.
+        self.infcx.leak_check(self.max_input_universe, None).map_err(|e| {
+            debug!(?e, "failed the leak check");
+            NoSolution
+        })?;
+
         // Cannot use `take_registered_region_obligations` as we may compute the response
         // inside of a `probe` whenever we have multiple choices inside of the solver.
         let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index e8c5a8fab2a..d6fd457de06 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -5,7 +5,7 @@
 //! [trait-specialization]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
 
 use crate::infer::outlives::env::OutlivesEnvironment;
-use crate::infer::{CombinedSnapshot, InferOk};
+use crate::infer::InferOk;
 use crate::traits::outlives_bounds::InferCtxtExt as _;
 use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::util::impl_subject_and_oblig;
@@ -62,6 +62,21 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
     );
 }
 
+#[derive(Debug, Clone, Copy)]
+enum TrackAmbiguityCauses {
+    Yes,
+    No,
+}
+
+impl TrackAmbiguityCauses {
+    fn is_yes(self) -> bool {
+        match self {
+            TrackAmbiguityCauses::Yes => true,
+            TrackAmbiguityCauses::No => false,
+        }
+    }
+}
+
 /// If there are types that satisfy both impls, returns `Some`
 /// with a suitably-freshened `ImplHeader` with those types
 /// substituted. Otherwise, returns `None`.
@@ -97,29 +112,28 @@ pub fn overlapping_impls(
         return None;
     }
 
-    let infcx = tcx
-        .infer_ctxt()
-        .with_opaque_type_inference(DefiningAnchor::Bubble)
-        .intercrate(true)
-        .build();
-    let selcx = &mut SelectionContext::new(&infcx);
-    let overlaps =
-        overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
-    if !overlaps {
-        return None;
-    }
+    let _overlap_with_bad_diagnostics = overlap(
+        tcx,
+        TrackAmbiguityCauses::No,
+        skip_leak_check,
+        impl1_def_id,
+        impl2_def_id,
+        overlap_mode,
+    )?;
 
     // In the case where we detect an error, run the check again, but
     // this time tracking intercrate ambiguity causes for better
     // diagnostics. (These take time and can lead to false errors.)
-    let infcx = tcx
-        .infer_ctxt()
-        .with_opaque_type_inference(DefiningAnchor::Bubble)
-        .intercrate(true)
-        .build();
-    let selcx = &mut SelectionContext::new(&infcx);
-    selcx.enable_tracking_intercrate_ambiguity_causes();
-    Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
+    let overlap = overlap(
+        tcx,
+        TrackAmbiguityCauses::Yes,
+        skip_leak_check,
+        impl1_def_id,
+        impl2_def_id,
+        overlap_mode,
+    )
+    .unwrap();
+    Some(overlap)
 }
 
 fn with_fresh_ty_vars<'cx, 'tcx>(
@@ -146,40 +160,34 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
 
 /// Can both impl `a` and impl `b` be satisfied by a common type (including
 /// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls.
-fn overlap<'cx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'tcx>,
+#[instrument(level = "debug", skip(tcx))]
+fn overlap<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    track_ambiguity_causes: TrackAmbiguityCauses,
     skip_leak_check: SkipLeakCheck,
     impl1_def_id: DefId,
     impl2_def_id: DefId,
     overlap_mode: OverlapMode,
 ) -> Option<OverlapResult<'tcx>> {
-    debug!(
-        "overlap(impl1_def_id={:?}, impl2_def_id={:?}, overlap_mode={:?})",
-        impl1_def_id, impl2_def_id, overlap_mode
-    );
-
-    selcx.infcx.probe_maybe_skip_leak_check(skip_leak_check.is_yes(), |snapshot| {
-        overlap_within_probe(selcx, impl1_def_id, impl2_def_id, overlap_mode, snapshot)
-    })
-}
-
-fn overlap_within_probe<'cx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'tcx>,
-    impl1_def_id: DefId,
-    impl2_def_id: DefId,
-    overlap_mode: OverlapMode,
-    snapshot: &CombinedSnapshot<'tcx>,
-) -> Option<OverlapResult<'tcx>> {
-    let infcx = selcx.infcx;
-
     if overlap_mode.use_negative_impl() {
-        if negative_impl(infcx.tcx, impl1_def_id, impl2_def_id)
-            || negative_impl(infcx.tcx, impl2_def_id, impl1_def_id)
+        if negative_impl(tcx, impl1_def_id, impl2_def_id)
+            || negative_impl(tcx, impl2_def_id, impl1_def_id)
         {
             return None;
         }
     }
 
+    let infcx = tcx
+        .infer_ctxt()
+        .with_opaque_type_inference(DefiningAnchor::Bubble)
+        .skip_leak_check(skip_leak_check.is_yes())
+        .intercrate(true)
+        .build();
+    let selcx = &mut SelectionContext::new(&infcx);
+    if track_ambiguity_causes.is_yes() {
+        selcx.enable_tracking_intercrate_ambiguity_causes();
+    }
+
     // For the purposes of this check, we don't bring any placeholder
     // types into scope; instead, we replace the generic types with
     // fresh type variables, and hence we do our evaluations in an
@@ -198,18 +206,23 @@ fn overlap_within_probe<'cx, 'tcx>(
         }
     }
 
-    // We disable the leak when creating the `snapshot` by using
-    // `infcx.probe_maybe_disable_leak_check`.
-    if infcx.leak_check(true, snapshot).is_err() {
+    // We toggle the `leak_check` by using `skip_leak_check` when constructing the
+    // inference context, so this may be a noop.
+    if infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
         debug!("overlap: leak check failed");
         return None;
     }
 
     let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
     debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
-
-    let involves_placeholder =
-        matches!(selcx.infcx.region_constraints_added_in_snapshot(snapshot), Some(true));
+    let involves_placeholder = infcx
+        .inner
+        .borrow_mut()
+        .unwrap_region_constraints()
+        .data()
+        .constraints
+        .iter()
+        .any(|c| c.0.involves_placeholders());
 
     let impl_header = selcx.infcx.resolve_vars_if_possible(impl1_header);
     Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 0f84032d9ef..4b38687eebe 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -487,7 +487,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
                 tcx,
                 ObligationCause::dummy_with_span(*span),
                 param_env,
-                ty::EarlyBinder::new(*pred).subst(tcx, impl_trait_ref.substs),
+                ty::EarlyBinder::bind(*pred).subst(tcx, impl_trait_ref.substs),
             )
         })
     });
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 0be21156b6c..9582479941b 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -642,7 +642,7 @@ fn receiver_for_self_ty<'tcx>(
         if param.index == 0 { self_ty.into() } else { tcx.mk_param_from_def(param) }
     });
 
-    let result = EarlyBinder::new(receiver_ty).subst(tcx, substs);
+    let result = EarlyBinder::bind(receiver_ty).subst(tcx, substs);
     debug!(
         "receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
         receiver_ty, self_ty, method_def_id, result
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 51069897120..65af0bb1c4e 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -824,7 +824,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> {
                 let universe = self.universe_for(debruijn);
                 let p = ty::PlaceholderRegion { universe, bound: br };
                 self.mapped_regions.insert(p, br);
-                self.infcx.tcx.mk_re_placeholder(p)
+                ty::Region::new_placeholder(self.infcx.tcx, p)
             }
             _ => r,
         }
@@ -945,7 +945,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
                         let db = ty::DebruijnIndex::from_usize(
                             self.universe_indices.len() - index + self.current_index.as_usize() - 1,
                         );
-                        self.interner().mk_re_late_bound(db, *replace_var)
+                        ty::Region::new_late_bound(self.interner(), db, *replace_var)
                     }
                     None => r1,
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 0a1b1b10b00..709c3f432e6 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -307,13 +307,13 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             // there, but that needs some way to handle cycles.
             constraints
                 .dtorck_types
-                .extend(dtorck_types.iter().map(|t| EarlyBinder::new(*t).subst(tcx, substs)));
+                .extend(dtorck_types.iter().map(|t| EarlyBinder::bind(*t).subst(tcx, substs)));
             constraints
                 .outlives
-                .extend(outlives.iter().map(|t| EarlyBinder::new(*t).subst(tcx, substs)));
+                .extend(outlives.iter().map(|t| EarlyBinder::bind(*t).subst(tcx, substs)));
             constraints
                 .overflows
-                .extend(overflows.iter().map(|t| EarlyBinder::new(*t).subst(tcx, substs)));
+                .extend(overflows.iter().map(|t| EarlyBinder::bind(*t).subst(tcx, substs)));
         }
 
         // Objects must be alive in order for their destructor
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index edbe2de8105..a8a74d7501a 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -90,7 +90,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
                     Ok(EvaluationResult::EvaluatedToAmbig)
                 } else if self.opaque_types_added_in_snapshot(snapshot) {
                     Ok(EvaluationResult::EvaluatedToOkModuloOpaqueTypes)
-                } else if self.region_constraints_added_in_snapshot(snapshot).is_some() {
+                } else if self.region_constraints_added_in_snapshot(snapshot) {
                     Ok(EvaluationResult::EvaluatedToOkModuloRegions)
                 } else {
                     Ok(EvaluationResult::EvaluatedToOk)
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 0245dfd333b..4e961c3ee73 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -550,7 +550,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
                                 let bound_var = ty::BoundVariableKind::Region(kind);
                                 bound_vars.push(bound_var);
-                                tcx.mk_re_late_bound(
+                                ty::Region::new_late_bound(
+                                    tcx,
                                     ty::INNERMOST,
                                     ty::BoundRegion {
                                         var: ty::BoundVar::from_usize(bound_vars.len() - 1),
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index ed380f32b72..42c1b629ac2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -561,9 +561,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
     ) -> Result<EvaluationResult, OverflowError> {
         self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
+            let outer_universe = self.infcx.universe();
             let result = op(self)?;
 
-            match self.infcx.leak_check(true, snapshot) {
+            match self.infcx.leak_check(outer_universe, Some(snapshot)) {
                 Ok(()) => {}
                 Err(_) => return Ok(EvaluatedToErr),
             }
@@ -572,9 +573,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 return Ok(result.max(EvaluatedToOkModuloOpaqueTypes));
             }
 
-            match self.infcx.region_constraints_added_in_snapshot(snapshot) {
-                None => Ok(result),
-                Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
+            if self.infcx.region_constraints_added_in_snapshot(snapshot) {
+                Ok(result.max(EvaluatedToOkModuloRegions))
+            } else {
+                Ok(result)
             }
         })
     }
@@ -3027,7 +3029,7 @@ fn bind_generator_hidden_types_above<'tcx>(
                             kind: ty::BrAnon(None),
                         };
                         counter += 1;
-                        tcx.mk_re_late_bound(current_depth, br)
+                        ty::Region::new_late_bound(tcx, current_depth, br)
                     }
                     r => bug!("unexpected region: {r:?}"),
                 })
diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs
index 1d3ea96666f..38f94c38861 100644
--- a/compiler/rustc_traits/src/chalk/db.rs
+++ b/compiler/rustc_traits/src/chalk/db.rs
@@ -727,7 +727,7 @@ fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> {
                 var: ty::BoundVar::from_usize(substs.len()),
                 kind: ty::BrAnon(None),
             };
-            tcx.mk_re_late_bound(ty::INNERMOST, br).into()
+            ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into()
         }
 
         ty::GenericParamDefKind::Const { .. } => tcx
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index e447ab94f64..e6c6e0f13df 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -542,7 +542,8 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
     fn lower_into(self, interner: RustInterner<'tcx>) -> Region<'tcx> {
         let tcx = interner.tcx;
         match self.data(interner) {
-            chalk_ir::LifetimeData::BoundVar(var) => tcx.mk_re_late_bound(
+            chalk_ir::LifetimeData::BoundVar(var) => ty::Region::new_late_bound(
+                tcx,
                 ty::DebruijnIndex::from_u32(var.debruijn.depth()),
                 ty::BoundRegion {
                     var: ty::BoundVar::from_usize(var.index),
@@ -550,13 +551,16 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
                 },
             ),
             chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(),
-            chalk_ir::LifetimeData::Placeholder(p) => tcx.mk_re_placeholder(ty::Placeholder {
-                universe: ty::UniverseIndex::from_usize(p.ui.counter),
-                bound: ty::BoundRegion {
-                    var: ty::BoundVar::from_usize(p.idx),
-                    kind: ty::BoundRegionKind::BrAnon(None),
+            chalk_ir::LifetimeData::Placeholder(p) => ty::Region::new_placeholder(
+                tcx,
+                ty::Placeholder {
+                    universe: ty::UniverseIndex::from_usize(p.ui.counter),
+                    bound: ty::BoundRegion {
+                        var: ty::BoundVar::from_usize(p.idx),
+                        kind: ty::BoundRegionKind::BrAnon(None),
+                    },
                 },
-            }),
+            ),
             chalk_ir::LifetimeData::Static => tcx.lifetimes.re_static,
             chalk_ir::LifetimeData::Erased => tcx.lifetimes.re_erased,
             chalk_ir::LifetimeData::Phantom(void, _) => match *void {},
@@ -1051,7 +1055,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> {
                 ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
                     Some(_) => {
                         let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(None) };
-                        return self.tcx.mk_re_late_bound(index, new_br);
+                        return ty::Region::new_late_bound(self.tcx, index, new_br);
                     }
                     None => panic!("Missing `BrNamed`."),
                 },
@@ -1142,7 +1146,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> {
                         var: ty::BoundVar::from_u32(*idx),
                         kind: ty::BrAnon(None),
                     };
-                    self.tcx.mk_re_late_bound(self.binder_index, br)
+                    ty::Region::new_late_bound(self.tcx, self.binder_index, br)
                 }
                 None => {
                     let idx = self.named_regions.len() as u32;
@@ -1151,7 +1155,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> {
                         kind: ty::BrAnon(None),
                     };
                     self.named_regions.insert(_re.def_id, idx);
-                    self.tcx.mk_re_late_bound(self.binder_index, br)
+                    ty::Region::new_late_bound(self.tcx, self.binder_index, br)
                 }
             },
 
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 15c19104616..5b3ffc9fc36 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -81,7 +81,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                 kind: ty::BoundRegionKind::BrEnv,
             };
-            let env_region = tcx.mk_re_late_bound(ty::INNERMOST, br);
+            let env_region = ty::Region::new_late_bound(tcx, ty::INNERMOST, br);
             let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
 
             let sig = sig.skip_binder();
@@ -106,7 +106,7 @@ fn fn_sig_for_fn_abi<'tcx>(
                 var: ty::BoundVar::from_usize(bound_vars.len() - 1),
                 kind: ty::BoundRegionKind::BrEnv,
             };
-            let env_ty = tcx.mk_mut_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), ty);
+            let env_ty = tcx.mk_mut_ref(ty::Region::new_late_bound(tcx, ty::INNERMOST, br), ty);
 
             let pin_did = tcx.require_lang_item(LangItem::Pin, None);
             let pin_adt_ref = tcx.adt_def(pin_did);
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 0925b3956de..57b4183d336 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -301,7 +301,7 @@ fn associated_type_for_impl_trait_in_trait(
     trait_assoc_ty.impl_defaultness(tcx.impl_defaultness(fn_def_id));
 
     // Copy type_of of the opaque.
-    trait_assoc_ty.type_of(ty::EarlyBinder::new(tcx.mk_opaque(
+    trait_assoc_ty.type_of(ty::EarlyBinder::bind(tcx.mk_opaque(
         opaque_ty_def_id.to_def_id(),
         InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
     )));
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index bb723c9997a..ce77df0df5d 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -419,7 +419,7 @@ pub fn thir_abstract_const(
 
     let root_span = body.exprs[body_id].span;
 
-    Ok(Some(ty::EarlyBinder::new(recurse_build(tcx, body, body_id, root_span)?)))
+    Ok(Some(ty::EarlyBinder::bind(recurse_build(tcx, body, body_id, root_span)?)))
 }
 
 pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 0e5b23ca423..7015778e24b 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -610,7 +610,7 @@ fn generator_layout<'tcx>(
 ) -> Result<Layout<'tcx>, LayoutError<'tcx>> {
     use SavedLocalEligibility::*;
     let tcx = cx.tcx;
-    let subst_field = |ty: Ty<'tcx>| EarlyBinder::new(ty).subst(tcx, substs);
+    let subst_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).subst(tcx, substs);
 
     let Some(info) = tcx.generator_layout(def_id) else {
         return Err(LayoutError::Unknown(ty));
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 075fde6ddb6..9d593dc5e04 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -210,7 +210,7 @@ fn drop_tys_helper<'tcx>(
             match subty.kind() {
                 ty::Adt(adt_id, subst) => {
                     for subty in tcx.adt_drop_tys(adt_id.did())? {
-                        vec.push(EarlyBinder::new(subty).subst(tcx, subst));
+                        vec.push(EarlyBinder::bind(subty).subst(tcx, subst));
                     }
                 }
                 _ => vec.push(subty),
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 52bc386cb00..12ad8b0842f 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -287,12 +287,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
             let shifted_alias_ty = self.tcx.fold_regions(unshifted_alias_ty, |re, depth| {
                 if let ty::ReLateBound(index, bv) = re.kind() {
                     if depth != ty::INNERMOST {
-                        return self.tcx.mk_re_error_with_message(
+                        return ty::Region::new_error_with_message(
+                            self.tcx,
                             DUMMY_SP,
                             "we shouldn't walk non-predicate binders with `impl Trait`...",
                         );
                     }
-                    self.tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv)
+                    ty::Region::new_late_bound(self.tcx, index.shifted_out_to_binder(self.depth), bv)
                 } else {
                     re
                 }
@@ -506,7 +507,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'
 
     if self_ty_matches {
         debug!("issue33140_self_ty - MATCHES!");
-        Some(EarlyBinder::new(self_ty))
+        Some(EarlyBinder::bind(self_ty))
     } else {
         debug!("issue33140_self_ty - non-matching self type");
         None
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index f6b44bdf27e..ae16fbb162e 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -52,7 +52,7 @@ pub trait Interner: Sized {
     type PolyFnSig: Clone + Debug + Hash + Ord;
     type ListBinderExistentialPredicate: Clone + Debug + Hash + Ord;
     type BinderListTy: Clone + Debug + Hash + Ord;
-    type ListTy: Clone + Debug + Hash + Ord;
+    type ListTy: Clone + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
     type AliasTy: Clone + Debug + Hash + Ord;
     type ParamTy: Clone + Debug + Hash + Ord;
     type BoundTy: Clone + Debug + Hash + Ord;
@@ -67,6 +67,9 @@ pub trait Interner: Sized {
     type FreeRegion: Clone + Debug + Hash + Ord;
     type RegionVid: Clone + Debug + Hash + Ord;
     type PlaceholderRegion: Clone + Debug + Hash + Ord;
+
+    fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Self::Mutability);
+    fn mutability_is_mut(mutbl: Self::Mutability) -> bool;
 }
 
 /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
@@ -390,7 +393,19 @@ impl DebruijnIndex {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub fn debug_bound_var<T: std::fmt::Write>(
+    fmt: &mut T,
+    debruijn: DebruijnIndex,
+    var: impl std::fmt::Debug,
+) -> Result<(), std::fmt::Error> {
+    if debruijn == INNERMOST {
+        write!(fmt, "^{:?}", var)
+    } else {
+        write!(fmt, "^{}_{:?}", debruijn.index(), var)
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum IntTy {
     Isize,
@@ -448,7 +463,7 @@ impl IntTy {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum UintTy {
     Usize,
@@ -506,7 +521,7 @@ impl UintTy {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Encodable, Decodable, HashStable_Generic)]
 pub enum FloatTy {
     F32,
diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs
index 45a2e9023c9..553d7f31b2d 100644
--- a/compiler/rustc_type_ir/src/structural_impls.rs
+++ b/compiler/rustc_type_ir/src/structural_impls.rs
@@ -4,11 +4,12 @@
 
 use crate::fold::{FallibleTypeFolder, TypeFoldable};
 use crate::visit::{TypeVisitable, TypeVisitor};
-use crate::Interner;
+use crate::{FloatTy, IntTy, Interner, UintTy};
 use rustc_data_structures::functor::IdFunctor;
 use rustc_data_structures::sync::Lrc;
 use rustc_index::{Idx, IndexVec};
 
+use core::fmt;
 use std::ops::ControlFlow;
 
 ///////////////////////////////////////////////////////////////////////////
@@ -163,3 +164,21 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix
         self.iter().try_for_each(|t| t.visit_with(visitor))
     }
 }
+
+impl fmt::Debug for IntTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.name_str())
+    }
+}
+
+impl fmt::Debug for UintTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.name_str())
+    }
+}
+
+impl fmt::Debug for FloatTy {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.name_str())
+    }
+}
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index f7344bacc02..fa18f921ee4 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -294,7 +294,7 @@ impl<I: Interner> Clone for TyKind<I> {
             Str => Str,
             Array(t, c) => Array(t.clone(), c.clone()),
             Slice(t) => Slice(t.clone()),
-            RawPtr(t) => RawPtr(t.clone()),
+            RawPtr(p) => RawPtr(p.clone()),
             Ref(r, t, m) => Ref(r.clone(), t.clone(), m.clone()),
             FnDef(d, s) => FnDef(d.clone(), s.clone()),
             FnPtr(s) => FnPtr(s.clone()),
@@ -499,33 +499,65 @@ impl<I: Interner> hash::Hash for TyKind<I> {
 impl<I: Interner> fmt::Debug for TyKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Bool => f.write_str("Bool"),
-            Char => f.write_str("Char"),
-            Int(i) => f.debug_tuple_field1_finish("Int", i),
-            Uint(u) => f.debug_tuple_field1_finish("Uint", u),
-            Float(float) => f.debug_tuple_field1_finish("Float", float),
+            Bool => write!(f, "bool"),
+            Char => write!(f, "char"),
+            Int(i) => write!(f, "{i:?}"),
+            Uint(u) => write!(f, "{u:?}"),
+            Float(float) => write!(f, "{float:?}"),
             Adt(d, s) => f.debug_tuple_field2_finish("Adt", d, s),
             Foreign(d) => f.debug_tuple_field1_finish("Foreign", d),
-            Str => f.write_str("Str"),
-            Array(t, c) => f.debug_tuple_field2_finish("Array", t, c),
-            Slice(t) => f.debug_tuple_field1_finish("Slice", t),
-            RawPtr(t) => f.debug_tuple_field1_finish("RawPtr", t),
-            Ref(r, t, m) => f.debug_tuple_field3_finish("Ref", r, t, m),
+            Str => write!(f, "str"),
+            Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
+            Slice(t) => write!(f, "[{t:?}]"),
+            RawPtr(p) => {
+                let (ty, mutbl) = I::ty_and_mut_to_parts(p.clone());
+                match I::mutability_is_mut(mutbl) {
+                    true => write!(f, "*mut "),
+                    false => write!(f, "*const "),
+                }?;
+                write!(f, "{ty:?}")
+            }
+            Ref(r, t, m) => match I::mutability_is_mut(m.clone()) {
+                true => write!(f, "&{r:?} mut {t:?}"),
+                false => write!(f, "&{r:?} {t:?}"),
+            },
             FnDef(d, s) => f.debug_tuple_field2_finish("FnDef", d, s),
-            FnPtr(s) => f.debug_tuple_field1_finish("FnPtr", s),
-            Dynamic(p, r, repr) => f.debug_tuple_field3_finish("Dynamic", p, r, repr),
+            FnPtr(s) => write!(f, "{s:?}"),
+            Dynamic(p, r, repr) => match repr {
+                DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
+                DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
+            },
             Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, s),
             Generator(d, s, m) => f.debug_tuple_field3_finish("Generator", d, s, m),
             GeneratorWitness(g) => f.debug_tuple_field1_finish("GeneratorWitness", g),
             GeneratorWitnessMIR(d, s) => f.debug_tuple_field2_finish("GeneratorWitnessMIR", d, s),
-            Never => f.write_str("Never"),
-            Tuple(t) => f.debug_tuple_field1_finish("Tuple", t),
+            Never => write!(f, "!"),
+            Tuple(t) => {
+                let mut iter = t.clone().into_iter();
+
+                write!(f, "(")?;
+
+                match iter.next() {
+                    None => return write!(f, ")"),
+                    Some(ty) => write!(f, "{ty:?}")?,
+                };
+
+                match iter.next() {
+                    None => return write!(f, ",)"),
+                    Some(ty) => write!(f, "{ty:?})")?,
+                }
+
+                for ty in iter {
+                    write!(f, ", {ty:?}")?;
+                }
+                write!(f, ")")
+            }
             Alias(i, a) => f.debug_tuple_field2_finish("Alias", i, a),
-            Param(p) => f.debug_tuple_field1_finish("Param", p),
-            Bound(d, b) => f.debug_tuple_field2_finish("Bound", d, b),
-            Placeholder(p) => f.debug_tuple_field1_finish("Placeholder", p),
-            Infer(t) => f.debug_tuple_field1_finish("Infer", t),
-            TyKind::Error(e) => f.debug_tuple_field1_finish("Error", e),
+            Param(p) => write!(f, "{p:?}"),
+            Bound(d, b) => crate::debug_bound_var(f, *d, b),
+            Placeholder(p) => write!(f, "{p:?}"),
+            Infer(t) => write!(f, "{t:?}"),
+            TyKind::Error(_) => write!(f, "{{type error}}"),
         }
     }
 }
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index c1dbbde08b6..0ba5d088f61 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(invalid_from_utf8))]
+
 use std::assert_matches::assert_matches;
 use std::borrow::Cow;
 use std::cmp::Ordering::{Equal, Greater, Less};
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index d6ae2b8213f..78091c01729 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -94,8 +94,9 @@ impl fmt::Display for AllocError {
 ///
 /// # Safety
 ///
-/// * Memory blocks returned from an allocator must point to valid memory and retain their validity
-///   until the instance and all of its copies and clones are dropped,
+/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to
+///   valid memory and retain their validity while they are [*currently allocated*] and at
+///   least one of the instance and all of its clones has not been dropped.
 ///
 /// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this
 ///   allocator. A copied or cloned allocator must behave like the same allocator, and
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/iter/range.rs b/library/core/src/iter/range.rs
index 0171d89812f..462f7170a55 100644
--- a/library/core/src/iter/range.rs
+++ b/library/core/src/iter/range.rs
@@ -619,9 +619,10 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
     #[inline]
     fn spec_next(&mut self) -> Option<T> {
         if self.start < self.end {
+            let old = self.start;
             // SAFETY: just checked precondition
-            let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
-            Some(mem::replace(&mut self.start, n))
+            self.start = unsafe { Step::forward_unchecked(old, 1) };
+            Some(old)
         } else {
             None
         }
@@ -629,15 +630,15 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
 
     #[inline]
     fn spec_nth(&mut self, n: usize) -> Option<T> {
-        if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
+        if let Some(plus_n) = Step::forward_checked(self.start, n) {
             if plus_n < self.end {
                 // SAFETY: just checked precondition
-                self.start = unsafe { Step::forward_unchecked(plus_n.clone(), 1) };
+                self.start = unsafe { Step::forward_unchecked(plus_n, 1) };
                 return Some(plus_n);
             }
         }
 
-        self.start = self.end.clone();
+        self.start = self.end;
         None
     }
 
@@ -655,7 +656,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
         // then steps_between either returns a bound to which we clamp or returns None which
         // together with the initial inequality implies more than usize::MAX steps.
         // Otherwise 0 is returned which always safe to use.
-        self.start = unsafe { Step::forward_unchecked(self.start.clone(), taken) };
+        self.start = unsafe { Step::forward_unchecked(self.start, taken) };
 
         NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
     }
@@ -664,8 +665,8 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
     fn spec_next_back(&mut self) -> Option<T> {
         if self.start < self.end {
             // SAFETY: just checked precondition
-            self.end = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
-            Some(self.end.clone())
+            self.end = unsafe { Step::backward_unchecked(self.end, 1) };
+            Some(self.end)
         } else {
             None
         }
@@ -673,15 +674,15 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
 
     #[inline]
     fn spec_nth_back(&mut self, n: usize) -> Option<T> {
-        if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
+        if let Some(minus_n) = Step::backward_checked(self.end, n) {
             if minus_n > self.start {
                 // SAFETY: just checked precondition
                 self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
-                return Some(self.end.clone());
+                return Some(self.end);
             }
         }
 
-        self.end = self.start.clone();
+        self.end = self.start;
         None
     }
 
@@ -696,7 +697,7 @@ impl<T: TrustedStep> RangeIteratorImpl for ops::Range<T> {
         let taken = available.min(n);
 
         // SAFETY: same as the spec_advance_by() implementation
-        self.end = unsafe { Step::backward_unchecked(self.end.clone(), taken) };
+        self.end = unsafe { Step::backward_unchecked(self.end, taken) };
 
         NonZeroUsize::new(n - taken).map_or(Ok(()), Err)
     }
diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs
index af02848233d..c21a2aac1c9 100644
--- a/library/core/src/iter/traits/marker.rs
+++ b/library/core/src/iter/traits/marker.rs
@@ -86,4 +86,4 @@ pub unsafe trait InPlaceIterable: Iterator {}
 /// for details. Consumers are free to rely on the invariants in unsafe code.
 #[unstable(feature = "trusted_step", issue = "85731")]
 #[rustc_specialization_trait]
-pub unsafe trait TrustedStep: Step {}
+pub unsafe trait TrustedStep: Step + Copy {}
diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs
index 5f8748206d7..0f23cf7ae23 100644
--- a/library/core/src/str/converts.rs
+++ b/library/core/src/str/converts.rs
@@ -84,6 +84,7 @@ use super::Utf8Error;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "const_str_from_utf8_shared", since = "1.63.0")]
 #[rustc_allow_const_fn_unstable(str_internals)]
+#[rustc_diagnostic_item = "str_from_utf8"]
 pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
     // FIXME: This should use `?` again, once it's `const`
     match run_utf8_validation(v) {
@@ -127,6 +128,7 @@ pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
 /// errors that can be returned.
 #[stable(feature = "str_mut_extras", since = "1.20.0")]
 #[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")]
+#[rustc_diagnostic_item = "str_from_utf8_mut"]
 pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
     // This should use `?` again, once it's `const`
     match run_utf8_validation(v) {
@@ -167,6 +169,7 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
+#[rustc_diagnostic_item = "str_from_utf8_unchecked"]
 pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
     // SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
     // Also relies on `&str` and `&[u8]` having the same layout.
@@ -194,6 +197,7 @@ pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
 #[must_use]
 #[stable(feature = "str_mut_extras", since = "1.20.0")]
 #[rustc_const_unstable(feature = "const_str_from_utf8_unchecked_mut", issue = "91005")]
+#[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"]
 pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
     // SAFETY: the caller must guarantee that the bytes `v`
     // are valid UTF-8, thus the cast to `*mut str` is safe.
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/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index d987bf69b25..3ddb8748753 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -127,6 +127,14 @@
 //! trait, which provides a [`from_wide`] method to convert a native Windows
 //! string (without the terminating nul character) to an [`OsString`].
 //!
+//! ## On all platforms
+//!
+//! On all platforms, [`OsStr`] consists of a sequence of bytes that is encoded as a superset of
+//! UTF-8; see [`OsString`] for more details on its encoding on different platforms.
+//!
+//! For limited, inexpensive conversions from and to bytes, see [`OsStr::as_os_str_bytes`] and
+//! [`OsStr::from_os_str_bytes_unchecked`].
+//!
 //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value
 //! [Unicode code point]: https://www.unicode.org/glossary/#code_point
 //! [`env::set_var()`]: crate::env::set_var "env::set_var"
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 5c0541d3caf..bb577acf769 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -667,6 +667,51 @@ impl OsStr {
         s.as_ref()
     }
 
+    /// Converts a slice of bytes to an OS string slice without checking that the string contains
+    /// valid `OsStr`-encoded data.
+    ///
+    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
+    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
+    /// ASCII.
+    ///
+    /// See the [module's toplevel documentation about conversions][conversions] for safe,
+    /// cross-platform [conversions] from/to native representations.
+    ///
+    /// # Safety
+    ///
+    /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
+    /// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version
+    /// built for the same target platform.  For example, reconstructing an `OsStr` from bytes sent
+    /// over the network or stored in a file will likely violate these safety rules.
+    ///
+    /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be
+    /// split either immediately before or immediately after any valid non-empty UTF-8 substring.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(os_str_bytes)]
+    ///
+    /// use std::ffi::OsStr;
+    ///
+    /// let os_str = OsStr::new("Mary had a little lamb");
+    /// let bytes = os_str.as_os_str_bytes();
+    /// let words = bytes.split(|b| *b == b' ');
+    /// let words: Vec<&OsStr> = words.map(|word| {
+    ///     // SAFETY:
+    ///     // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes`
+    ///     // - Only split with ASCII whitespace which is a non-empty UTF-8 substring
+    ///     unsafe { OsStr::from_os_str_bytes_unchecked(word) }
+    /// }).collect();
+    /// ```
+    ///
+    /// [conversions]: super#conversions
+    #[inline]
+    #[unstable(feature = "os_str_bytes", issue = "111544")]
+    pub unsafe fn from_os_str_bytes_unchecked(bytes: &[u8]) -> &Self {
+        Self::from_inner(Slice::from_os_str_bytes_unchecked(bytes))
+    }
+
     #[inline]
     fn from_inner(inner: &Slice) -> &OsStr {
         // SAFETY: OsStr is just a wrapper of Slice,
@@ -837,13 +882,24 @@ impl OsStr {
         OsString { inner: Buf::from_box(boxed) }
     }
 
-    /// Gets the underlying byte representation.
+    /// Converts an OS string slice to a byte slice.  To convert the byte slice back into an OS
+    /// string slice, use the [`OsStr::from_os_str_bytes_unchecked`] function.
+    ///
+    /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8.
+    /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit
+    /// ASCII.
+    ///
+    /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should
+    /// be treated as opaque and only comparable within the same rust version built for the same
+    /// target platform.  For example, sending the slice over the network or storing it in a file
+    /// will likely result in incompatible byte slices.  See [`OsString`] for more encoding details
+    /// and [`std::ffi`] for platform-specific, specified conversions.
     ///
-    /// Note: it is *crucial* that this API is not externally public, to avoid
-    /// revealing the internal, platform-specific encodings.
+    /// [`std::ffi`]: crate::ffi
     #[inline]
-    pub(crate) fn bytes(&self) -> &[u8] {
-        unsafe { &*(&self.inner as *const _ as *const [u8]) }
+    #[unstable(feature = "os_str_bytes", issue = "111544")]
+    pub fn as_os_str_bytes(&self) -> &[u8] {
+        self.inner.as_os_str_bytes()
     }
 
     /// Converts this string to its ASCII lower case equivalent in-place.
@@ -1131,7 +1187,7 @@ impl Default for &OsStr {
 impl PartialEq for OsStr {
     #[inline]
     fn eq(&self, other: &OsStr) -> bool {
-        self.bytes().eq(other.bytes())
+        self.as_os_str_bytes().eq(other.as_os_str_bytes())
     }
 }
 
@@ -1158,23 +1214,23 @@ impl Eq for OsStr {}
 impl PartialOrd for OsStr {
     #[inline]
     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
-        self.bytes().partial_cmp(other.bytes())
+        self.as_os_str_bytes().partial_cmp(other.as_os_str_bytes())
     }
     #[inline]
     fn lt(&self, other: &OsStr) -> bool {
-        self.bytes().lt(other.bytes())
+        self.as_os_str_bytes().lt(other.as_os_str_bytes())
     }
     #[inline]
     fn le(&self, other: &OsStr) -> bool {
-        self.bytes().le(other.bytes())
+        self.as_os_str_bytes().le(other.as_os_str_bytes())
     }
     #[inline]
     fn gt(&self, other: &OsStr) -> bool {
-        self.bytes().gt(other.bytes())
+        self.as_os_str_bytes().gt(other.as_os_str_bytes())
     }
     #[inline]
     fn ge(&self, other: &OsStr) -> bool {
-        self.bytes().ge(other.bytes())
+        self.as_os_str_bytes().ge(other.as_os_str_bytes())
     }
 }
 
@@ -1193,7 +1249,7 @@ impl PartialOrd<str> for OsStr {
 impl Ord for OsStr {
     #[inline]
     fn cmp(&self, other: &OsStr) -> cmp::Ordering {
-        self.bytes().cmp(other.bytes())
+        self.as_os_str_bytes().cmp(other.as_os_str_bytes())
     }
 }
 
@@ -1243,7 +1299,7 @@ impl_cmp!(Cow<'a, OsStr>, OsString);
 impl Hash for OsStr {
     #[inline]
     fn hash<H: Hasher>(&self, state: &mut H) {
-        self.bytes().hash(state)
+        self.as_os_str_bytes().hash(state)
     }
 }
 
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index febdeb51463..28cd3c4e4db 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -193,7 +193,7 @@ impl<'a> Prefix<'a> {
     fn len(&self) -> usize {
         use self::Prefix::*;
         fn os_str_len(s: &OsStr) -> usize {
-            s.bytes().len()
+            s.as_os_str_bytes().len()
         }
         match *self {
             Verbatim(x) => 4 + os_str_len(x),
@@ -299,20 +299,6 @@ where
     }
 }
 
-unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
-    // SAFETY: See note at the top of this module to understand why this and
-    // `OsStr::bytes` are used:
-    //
-    // This casts are safe as OsStr is internally a wrapper around [u8] on all
-    // platforms.
-    //
-    // Note that currently this relies on the special knowledge that std has;
-    // these types are single-element structs but are not marked
-    // repr(transparent) or repr(C) which would make these casts not allowable
-    // outside std.
-    unsafe { &*(s as *const [u8] as *const OsStr) }
-}
-
 // Detect scheme on Redox
 fn has_redox_scheme(s: &[u8]) -> bool {
     cfg!(target_os = "redox") && s.contains(&b':')
@@ -330,7 +316,7 @@ fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool {
 
 // basic workhorse for splitting stem and extension
 fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
-    if file.bytes() == b".." {
+    if file.as_os_str_bytes() == b".." {
         return (Some(file), None);
     }
 
@@ -338,18 +324,23 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
     // and back. This is safe to do because (1) we only look at ASCII
     // contents of the encoding and (2) new &OsStr values are produced
     // only from ASCII-bounded slices of existing &OsStr values.
-    let mut iter = file.bytes().rsplitn(2, |b| *b == b'.');
+    let mut iter = file.as_os_str_bytes().rsplitn(2, |b| *b == b'.');
     let after = iter.next();
     let before = iter.next();
     if before == Some(b"") {
         (Some(file), None)
     } else {
-        unsafe { (before.map(|s| u8_slice_as_os_str(s)), after.map(|s| u8_slice_as_os_str(s))) }
+        unsafe {
+            (
+                before.map(|s| OsStr::from_os_str_bytes_unchecked(s)),
+                after.map(|s| OsStr::from_os_str_bytes_unchecked(s)),
+            )
+        }
     }
 }
 
 fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
-    let slice = file.bytes();
+    let slice = file.as_os_str_bytes();
     if slice == b".." {
         return (file, None);
     }
@@ -364,7 +355,12 @@ fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
     };
     let before = &slice[..i];
     let after = &slice[i + 1..];
-    unsafe { (u8_slice_as_os_str(before), Some(u8_slice_as_os_str(after))) }
+    unsafe {
+        (
+            OsStr::from_os_str_bytes_unchecked(before),
+            Some(OsStr::from_os_str_bytes_unchecked(after)),
+        )
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -743,7 +739,7 @@ impl<'a> Components<'a> {
             // separately via `include_cur_dir`
             b".." => Some(Component::ParentDir),
             b"" => None,
-            _ => Some(Component::Normal(unsafe { u8_slice_as_os_str(comp) })),
+            _ => Some(Component::Normal(unsafe { OsStr::from_os_str_bytes_unchecked(comp) })),
         }
     }
 
@@ -900,7 +896,7 @@ impl<'a> Iterator for Components<'a> {
                     let raw = &self.path[..self.prefix_len()];
                     self.path = &self.path[self.prefix_len()..];
                     return Some(Component::Prefix(PrefixComponent {
-                        raw: unsafe { u8_slice_as_os_str(raw) },
+                        raw: unsafe { OsStr::from_os_str_bytes_unchecked(raw) },
                         parsed: self.prefix.unwrap(),
                     }));
                 }
@@ -972,7 +968,7 @@ impl<'a> DoubleEndedIterator for Components<'a> {
                 State::Prefix if self.prefix_len() > 0 => {
                     self.back = State::Done;
                     return Some(Component::Prefix(PrefixComponent {
-                        raw: unsafe { u8_slice_as_os_str(self.path) },
+                        raw: unsafe { OsStr::from_os_str_bytes_unchecked(self.path) },
                         parsed: self.prefix.unwrap(),
                     }));
                 }
@@ -1481,17 +1477,17 @@ impl PathBuf {
     fn _set_extension(&mut self, extension: &OsStr) -> bool {
         let file_stem = match self.file_stem() {
             None => return false,
-            Some(f) => f.bytes(),
+            Some(f) => f.as_os_str_bytes(),
         };
 
         // truncate until right after the file stem
         let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr();
-        let start = self.inner.bytes().as_ptr().addr();
+        let start = self.inner.as_os_str_bytes().as_ptr().addr();
         let v = self.as_mut_vec();
         v.truncate(end_file_stem.wrapping_sub(start));
 
         // add the new extension, if any
-        let new = extension.bytes();
+        let new = extension.as_os_str_bytes();
         if !new.is_empty() {
             v.reserve_exact(new.len() + 1);
             v.push(b'.');
@@ -2011,11 +2007,11 @@ impl Path {
     // The following (private!) function allows construction of a path from a u8
     // slice, which is only safe when it is known to follow the OsStr encoding.
     unsafe fn from_u8_slice(s: &[u8]) -> &Path {
-        unsafe { Path::new(u8_slice_as_os_str(s)) }
+        unsafe { Path::new(OsStr::from_os_str_bytes_unchecked(s)) }
     }
     // The following (private!) function reveals the byte encoding used for OsStr.
     fn as_u8_slice(&self) -> &[u8] {
-        self.inner.bytes()
+        self.inner.as_os_str_bytes()
     }
 
     /// Directly wraps a string slice as a `Path` slice.
diff --git a/library/std/src/sys/common/small_c_string.rs b/library/std/src/sys/common/small_c_string.rs
index 01acd519135..963d17a47e4 100644
--- a/library/std/src/sys/common/small_c_string.rs
+++ b/library/std/src/sys/common/small_c_string.rs
@@ -19,7 +19,7 @@ pub fn run_path_with_cstr<T, F>(path: &Path, f: F) -> io::Result<T>
 where
     F: FnOnce(&CStr) -> io::Result<T>,
 {
-    run_with_cstr(path.as_os_str().bytes(), f)
+    run_with_cstr(path.as_os_str().as_os_str_bytes(), f)
 }
 
 #[inline]
diff --git a/library/std/src/sys/common/tests.rs b/library/std/src/sys/common/tests.rs
index fb6f5d6af83..0a1cbcbe8ef 100644
--- a/library/std/src/sys/common/tests.rs
+++ b/library/std/src/sys/common/tests.rs
@@ -8,7 +8,7 @@ use core::iter::repeat;
 fn stack_allocation_works() {
     let path = Path::new("abc");
     let result = run_path_with_cstr(path, |p| {
-        assert_eq!(p, &*CString::new(path.as_os_str().bytes()).unwrap());
+        assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap());
         Ok(42)
     });
     assert_eq!(result.unwrap(), 42);
@@ -25,7 +25,7 @@ fn heap_allocation_works() {
     let path = repeat("a").take(384).collect::<String>();
     let path = Path::new(&path);
     let result = run_path_with_cstr(path, |p| {
-        assert_eq!(p, &*CString::new(path.as_os_str().bytes()).unwrap());
+        assert_eq!(p, &*CString::new(path.as_os_str().as_os_str_bytes()).unwrap());
         Ok(42)
     });
     assert_eq!(result.unwrap(), 42);
diff --git a/library/std/src/sys/unix/os_str.rs b/library/std/src/sys/unix/os_str.rs
index 488217f3941..142fcb9ed0b 100644
--- a/library/std/src/sys/unix/os_str.rs
+++ b/library/std/src/sys/unix/os_str.rs
@@ -193,13 +193,18 @@ impl Buf {
 
 impl Slice {
     #[inline]
-    fn from_u8_slice(s: &[u8]) -> &Slice {
+    pub fn as_os_str_bytes(&self) -> &[u8] {
+        &self.inner
+    }
+
+    #[inline]
+    pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
         unsafe { mem::transmute(s) }
     }
 
     #[inline]
     pub fn from_str(s: &str) -> &Slice {
-        Slice::from_u8_slice(s.as_bytes())
+        unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) }
     }
 
     pub fn to_str(&self) -> Option<&str> {
diff --git a/library/std/src/sys/unix/os_str/tests.rs b/library/std/src/sys/unix/os_str/tests.rs
index 22ba0c92350..91bc0e61a4a 100644
--- a/library/std/src/sys/unix/os_str/tests.rs
+++ b/library/std/src/sys/unix/os_str/tests.rs
@@ -2,7 +2,7 @@ use super::*;
 
 #[test]
 fn slice_debug_output() {
-    let input = Slice::from_u8_slice(b"\xF0hello,\tworld");
+    let input = unsafe { Slice::from_os_str_bytes_unchecked(b"\xF0hello,\tworld") };
     let expected = r#""\xF0hello,\tworld""#;
     let output = format!("{input:?}");
 
@@ -11,8 +11,7 @@ fn slice_debug_output() {
 
 #[test]
 fn display() {
-    assert_eq!(
-        "Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye",
-        Slice::from_u8_slice(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string(),
-    );
+    assert_eq!("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye", unsafe {
+        Slice::from_os_str_bytes_unchecked(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
+    },);
 }
diff --git a/library/std/src/sys/unix/path.rs b/library/std/src/sys/unix/path.rs
index a98a69e2db8..935245f637b 100644
--- a/library/std/src/sys/unix/path.rs
+++ b/library/std/src/sys/unix/path.rs
@@ -30,7 +30,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
 
     // Get the components, skipping the redundant leading "." component if it exists.
     let mut components = path.strip_prefix(".").unwrap_or(path).components();
-    let path_os = path.as_os_str().bytes();
+    let path_os = path.as_os_str().as_os_str_bytes();
 
     let mut normalized = if path.is_absolute() {
         // "If a pathname begins with two successive <slash> characters, the
diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs
index afd03d79c0b..640648e8707 100644
--- a/library/std/src/sys/unix/process/process_common.rs
+++ b/library/std/src/sys/unix/process/process_common.rs
@@ -164,9 +164,9 @@ pub enum ProgramKind {
 
 impl ProgramKind {
     fn new(program: &OsStr) -> Self {
-        if program.bytes().starts_with(b"/") {
+        if program.as_os_str_bytes().starts_with(b"/") {
             Self::Absolute
-        } else if program.bytes().contains(&b'/') {
+        } else if program.as_os_str_bytes().contains(&b'/') {
             // If the program has more than one component in it, it is a relative path.
             Self::Relative
         } else {
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 5bfd8b52ed0..6b597f499bc 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -226,7 +226,7 @@ pub(crate) fn append_arg(cmd: &mut Vec<u16>, arg: &Arg, force_quotes: bool) -> i
     // that it actually gets passed through on the command line or otherwise
     // it will be dropped entirely when parsed on the other end.
     ensure_no_nuls(arg)?;
-    let arg_bytes = arg.bytes();
+    let arg_bytes = arg.as_os_str_bytes();
     let (quote, escape) = match quote {
         Quote::Always => (true, true),
         Quote::Auto => {
@@ -297,7 +297,9 @@ pub(crate) fn make_bat_command_line(
         // * `|<>` pipe/redirect characters.
         const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>";
         let force_quotes = match arg {
-            Arg::Regular(arg) if !force_quotes => arg.bytes().iter().any(|c| SPECIAL.contains(c)),
+            Arg::Regular(arg) if !force_quotes => {
+                arg.as_os_str_bytes().iter().any(|c| SPECIAL.contains(c))
+            }
             _ => force_quotes,
         };
         append_arg(&mut cmd, arg, force_quotes)?;
diff --git a/library/std/src/sys/windows/os_str.rs b/library/std/src/sys/windows/os_str.rs
index 2f2b0e56e08..611f0d040f0 100644
--- a/library/std/src/sys/windows/os_str.rs
+++ b/library/std/src/sys/windows/os_str.rs
@@ -152,6 +152,16 @@ impl Buf {
 
 impl Slice {
     #[inline]
+    pub fn as_os_str_bytes(&self) -> &[u8] {
+        self.inner.as_bytes()
+    }
+
+    #[inline]
+    pub unsafe fn from_os_str_bytes_unchecked(s: &[u8]) -> &Slice {
+        mem::transmute(Wtf8::from_bytes_unchecked(s))
+    }
+
+    #[inline]
     pub fn from_str(s: &str) -> &Slice {
         unsafe { mem::transmute(Wtf8::from_str(s)) }
     }
diff --git a/library/std/src/sys/windows/path.rs b/library/std/src/sys/windows/path.rs
index c3573d14c7f..c9c2d10e6c4 100644
--- a/library/std/src/sys/windows/path.rs
+++ b/library/std/src/sys/windows/path.rs
@@ -1,7 +1,6 @@
 use super::{c, fill_utf16_buf, to_u16s};
 use crate::ffi::{OsStr, OsString};
 use crate::io;
-use crate::mem;
 use crate::path::{Path, PathBuf, Prefix};
 use crate::ptr;
 
@@ -11,16 +10,6 @@ mod tests;
 pub const MAIN_SEP_STR: &str = "\\";
 pub const MAIN_SEP: char = '\\';
 
-/// # Safety
-///
-/// `bytes` must be a valid wtf8 encoded slice
-#[inline]
-unsafe fn bytes_as_os_str(bytes: &[u8]) -> &OsStr {
-    // &OsStr is layout compatible with &Slice, which is compatible with &Wtf8,
-    // which is compatible with &[u8].
-    mem::transmute(bytes)
-}
-
 #[inline]
 pub fn is_sep_byte(b: u8) -> bool {
     b == b'/' || b == b'\\'
@@ -33,12 +22,12 @@ pub fn is_verbatim_sep(b: u8) -> bool {
 
 /// Returns true if `path` looks like a lone filename.
 pub(crate) fn is_file_name(path: &OsStr) -> bool {
-    !path.bytes().iter().copied().any(is_sep_byte)
+    !path.as_os_str_bytes().iter().copied().any(is_sep_byte)
 }
 pub(crate) fn has_trailing_slash(path: &OsStr) -> bool {
-    let is_verbatim = path.bytes().starts_with(br"\\?\");
+    let is_verbatim = path.as_os_str_bytes().starts_with(br"\\?\");
     let is_separator = if is_verbatim { is_verbatim_sep } else { is_sep_byte };
-    if let Some(&c) = path.bytes().last() { is_separator(c) } else { false }
+    if let Some(&c) = path.as_os_str_bytes().last() { is_separator(c) } else { false }
 }
 
 /// Appends a suffix to a path.
@@ -60,7 +49,7 @@ impl<'a, const LEN: usize> PrefixParser<'a, LEN> {
     fn get_prefix(path: &OsStr) -> [u8; LEN] {
         let mut prefix = [0; LEN];
         // SAFETY: Only ASCII characters are modified.
-        for (i, &ch) in path.bytes().iter().take(LEN).enumerate() {
+        for (i, &ch) in path.as_os_str_bytes().iter().take(LEN).enumerate() {
             prefix[i] = if ch == b'/' { b'\\' } else { ch };
         }
         prefix
@@ -93,7 +82,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
     }
 
     fn prefix_bytes(&self) -> &'a [u8] {
-        &self.path.bytes()[..self.index]
+        &self.path.as_os_str_bytes()[..self.index]
     }
 
     fn finish(self) -> &'a OsStr {
@@ -101,7 +90,7 @@ impl<'a> PrefixParserSlice<'a, '_> {
         // &[u8] and back. This is safe to do because (1) we only look at ASCII
         // contents of the encoding and (2) new &OsStr values are produced only
         // from ASCII-bounded slices of existing &OsStr values.
-        unsafe { bytes_as_os_str(&self.path.bytes()[self.index..]) }
+        unsafe { OsStr::from_os_str_bytes_unchecked(&self.path.as_os_str_bytes()[self.index..]) }
     }
 }
 
@@ -173,7 +162,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
         drive.is_ascii_alphabetic()
     }
 
-    match path.bytes() {
+    match path.as_os_str_bytes() {
         [drive, b':', ..] if is_valid_drive_letter(drive) => Some(drive.to_ascii_uppercase()),
         _ => None,
     }
@@ -182,7 +171,7 @@ fn parse_drive(path: &OsStr) -> Option<u8> {
 // Parses a drive prefix exactly, e.g. "C:"
 fn parse_drive_exact(path: &OsStr) -> Option<u8> {
     // only parse two bytes: the drive letter and the drive separator
-    if path.bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
+    if path.as_os_str_bytes().get(2).map(|&x| is_sep_byte(x)).unwrap_or(true) {
         parse_drive(path)
     } else {
         None
@@ -196,21 +185,26 @@ fn parse_drive_exact(path: &OsStr) -> Option<u8> {
 fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
     let separator = if verbatim { is_verbatim_sep } else { is_sep_byte };
 
-    match path.bytes().iter().position(|&x| separator(x)) {
+    match path.as_os_str_bytes().iter().position(|&x| separator(x)) {
         Some(separator_start) => {
             let separator_end = separator_start + 1;
 
-            let component = &path.bytes()[..separator_start];
+            let component = &path.as_os_str_bytes()[..separator_start];
 
             // Panic safe
             // The max `separator_end` is `bytes.len()` and `bytes[bytes.len()..]` is a valid index.
-            let path = &path.bytes()[separator_end..];
+            let path = &path.as_os_str_bytes()[separator_end..];
 
             // SAFETY: `path` is a valid wtf8 encoded slice and each of the separators ('/', '\')
             // is encoded in a single byte, therefore `bytes[separator_start]` and
             // `bytes[separator_end]` must be code point boundaries and thus
             // `bytes[..separator_start]` and `bytes[separator_end..]` are valid wtf8 slices.
-            unsafe { (bytes_as_os_str(component), bytes_as_os_str(path)) }
+            unsafe {
+                (
+                    OsStr::from_os_str_bytes_unchecked(component),
+                    OsStr::from_os_str_bytes_unchecked(path),
+                )
+            }
         }
         None => (path, OsStr::new("")),
     }
@@ -329,7 +323,7 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
     // Verbatim paths should not be modified.
     if prefix.map(|x| x.is_verbatim()).unwrap_or(false) {
         // NULs in verbatim paths are rejected for consistency.
-        if path.bytes().contains(&0) {
+        if path.as_os_str_bytes().contains(&0) {
             return Err(io::const_io_error!(
                 io::ErrorKind::InvalidInput,
                 "strings passed to WinAPI cannot contain NULs",
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index df3667c0fd7..a573a05c39c 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -395,7 +395,7 @@ fn resolve_exe<'a>(
     // Test if the file name has the `exe` extension.
     // This does a case-insensitive `ends_with`.
     let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() {
-        exe_path.bytes()[exe_path.len() - EXE_SUFFIX.len()..]
+        exe_path.as_os_str_bytes()[exe_path.len() - EXE_SUFFIX.len()..]
             .eq_ignore_ascii_case(EXE_SUFFIX.as_bytes())
     } else {
         false
@@ -425,7 +425,7 @@ fn resolve_exe<'a>(
         // From the `CreateProcessW` docs:
         // > If the file name does not contain an extension, .exe is appended.
         // Note that this rule only applies when searching paths.
-        let has_extension = exe_path.bytes().contains(&b'.');
+        let has_extension = exe_path.as_os_str_bytes().contains(&b'.');
 
         // Search the directories given by `search_paths`.
         let result = search_paths(parent_paths, child_paths, |mut path| {
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index ff96c35fb0b..31bb0ad25a6 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -570,7 +570,7 @@ impl Wtf8 {
     /// Since the byte slice is not checked for valid WTF-8, this functions is
     /// marked unsafe.
     #[inline]
-    unsafe fn from_bytes_unchecked(value: &[u8]) -> &Wtf8 {
+    pub unsafe fn from_bytes_unchecked(value: &[u8]) -> &Wtf8 {
         mem::transmute(value)
     }
 
@@ -614,6 +614,12 @@ impl Wtf8 {
         Wtf8CodePoints { bytes: self.bytes.iter() }
     }
 
+    /// Access raw bytes of WTF-8 data
+    #[inline]
+    pub fn as_bytes(&self) -> &[u8] {
+        &self.bytes
+    }
+
     /// Tries to convert the string to UTF-8 and return a `&str` slice.
     ///
     /// Returns `None` if the string contains surrogates.
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 06c30842e17..473fdbe1edc 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -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"]
@@ -916,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)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 2fa445506bc..43c859b0063 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -103,11 +103,14 @@ impl RunConfig<'_> {
     }
 
     /// Return a list of crate names selected by `run.paths`.
+    #[track_caller]
     pub fn cargo_crates_in_set(&self) -> Interned<Vec<String>> {
         let mut crates = Vec::new();
         for krate in &self.paths {
             let path = krate.assert_single_path();
-            let crate_name = self.builder.crate_paths[&path.path];
+            let Some(crate_name) = self.builder.crate_paths.get(&path.path) else {
+                panic!("missing crate for path {}", path.path.display())
+            };
             crates.push(crate_name.to_string());
         }
         INTERNER.intern_list(crates)
@@ -378,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);
         }
     }
 }
@@ -430,25 +433,6 @@ impl<'a> ShouldRun<'a> {
     /// Indicates it should run if the command-line selects the given crate or
     /// any of its (local) dependencies.
     ///
-    /// Compared to `krate`, this treats the dependencies as aliases for the
-    /// same job. Generally it is preferred to use `krate`, and treat each
-    /// individual path separately. For example `./x.py test src/liballoc`
-    /// (which uses `krate`) will test just `liballoc`. However, `./x.py check
-    /// src/liballoc` (which uses `all_krates`) will check all of `libtest`.
-    /// `all_krates` should probably be removed at some point.
-    pub fn all_krates(mut self, name: &str) -> Self {
-        let mut set = BTreeSet::new();
-        for krate in self.builder.in_tree_crates(name, None) {
-            let path = krate.local_path(self.builder);
-            set.insert(TaskPath { path, kind: Some(self.kind) });
-        }
-        self.paths.insert(PathSet::Set(set));
-        self
-    }
-
-    /// Indicates it should run if the command-line selects the given crate or
-    /// any of its (local) dependencies.
-    ///
     /// `make_run` will be called a single time with all matching command-line paths.
     pub fn crate_or_deps(self, name: &str) -> Self {
         let crates = self.builder.in_tree_crates(name, None);
@@ -458,6 +442,8 @@ impl<'a> ShouldRun<'a> {
     /// Indicates it should run if the command-line selects any of the given crates.
     ///
     /// `make_run` will be called a single time with all matching command-line paths.
+    ///
+    /// Prefer [`ShouldRun::crate_or_deps`] to this function where possible.
     pub(crate) fn crates(mut self, crates: Vec<&Crate>) -> Self {
         for krate in crates {
             let path = krate.local_path(self.builder);
@@ -487,7 +473,15 @@ impl<'a> ShouldRun<'a> {
         self.paths(&[path])
     }
 
-    // multiple aliases for the same job
+    /// Multiple aliases for the same job.
+    ///
+    /// This differs from [`path`] in that multiple calls to path will end up calling `make_run`
+    /// multiple times, whereas a single call to `paths` will only ever generate a single call to
+    /// `paths`.
+    ///
+    /// This is analogous to `all_krates`, although `all_krates` is gone now. Prefer [`path`] where possible.
+    ///
+    /// [`path`]: ShouldRun::path
     pub fn paths(mut self, paths: &[&str]) -> Self {
         static SUBMODULES_PATHS: OnceCell<Vec<String>> = OnceCell::new();
 
@@ -641,12 +635,16 @@ impl Kind {
         }
     }
 
-    pub fn test_description(&self) -> &'static str {
+    pub fn description(&self) -> String {
         match self {
             Kind::Test => "Testing",
             Kind::Bench => "Benchmarking",
-            _ => panic!("not a test command: {}!", self.as_str()),
+            Kind::Doc => "Documenting",
+            Kind::Run => "Running",
+            Kind::Suggest => "Suggesting",
+            _ => return format!("{self:?}"),
         }
+        .to_owned()
     }
 }
 
@@ -1357,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/builder/tests.rs b/src/bootstrap/builder/tests.rs
index edca8fe9b13..d76b830b0e5 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -1,5 +1,6 @@
 use super::*;
 use crate::config::{Config, DryRun, TargetSelection};
+use crate::doc::DocumentationFormat;
 use std::thread;
 
 fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
@@ -66,6 +67,16 @@ macro_rules! std {
     };
 }
 
+macro_rules! doc_std {
+    ($host:ident => $target:ident, stage = $stage:literal) => {
+        doc::Std::new(
+            $stage,
+            TargetSelection::from_user(stringify!($target)),
+            DocumentationFormat::HTML,
+        )
+    };
+}
+
 macro_rules! rustc {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Rustc::new(
@@ -144,6 +155,9 @@ fn alias_and_path_for_library() {
         first(cache.all::<compile::Std>()),
         &[std!(A => A, stage = 0), std!(A => A, stage = 1)]
     );
+
+    let mut cache = run_build(&["library".into(), "core".into()], configure("doc", &["A"], &["A"]));
+    assert_eq!(first(cache.all::<doc::Std>()), &[doc_std!(A => A, stage = 0)]);
 }
 
 #[test]
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index b11be96cefe..f5a93854bf2 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -1,8 +1,10 @@
 //! Implementation of compiling the compiler and standard library, in "check"-based modes.
 
-use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
+use crate::builder::{crate_description, Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::cache::Interned;
-use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo};
+use crate::compile::{
+    add_to_sysroot, make_run_crates, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo,
+};
 use crate::config::TargetSelection;
 use crate::tool::{prepare_tool_cargo, SourceType};
 use crate::INTERNER;
@@ -12,6 +14,12 @@ use std::path::{Path, PathBuf};
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Std {
     pub target: TargetSelection,
+    /// Whether to build only a subset of crates.
+    ///
+    /// This shouldn't be used from other steps; see the comment on [`compile::Rustc`].
+    ///
+    /// [`compile::Rustc`]: crate::compile::Rustc
+    crates: Interned<Vec<String>>,
 }
 
 /// Returns args for the subcommand itself (not for cargo)
@@ -66,16 +74,23 @@ fn cargo_subcommand(kind: Kind) -> &'static str {
     }
 }
 
+impl Std {
+    pub fn new(target: TargetSelection) -> Self {
+        Self { target, crates: INTERNER.intern_list(vec![]) }
+    }
+}
+
 impl Step for Std {
     type Output = ();
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("sysroot").path("library")
+        run.crate_or_deps("sysroot").path("library")
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Std { target: run.target });
+        let crates = make_run_crates(&run, "library");
+        run.builder.ensure(Std { target: run.target, crates });
     }
 
     fn run(self, builder: &Builder<'_>) {
@@ -97,7 +112,14 @@ impl Step for Std {
             cargo.arg("--lib");
         }
 
-        let _guard = builder.msg_check("library artifacts", target);
+        for krate in &*self.crates {
+            cargo.arg("-p").arg(krate);
+        }
+
+        let _guard = builder.msg_check(
+            format_args!("library artifacts{}", crate_description(&self.crates)),
+            target,
+        );
         run_cargo(
             builder,
             cargo,
@@ -117,7 +139,8 @@ impl Step for Std {
         }
 
         // don't run on std twice with x.py clippy
-        if builder.kind == Kind::Clippy {
+        // don't check test dependencies if we haven't built libtest
+        if builder.kind == Kind::Clippy || !self.crates.is_empty() {
             return;
         }
 
@@ -147,8 +170,8 @@ impl Step for Std {
         // Explicitly pass -p for all dependencies krates -- this will force cargo
         // to also check the tests/benches/examples for these crates, rather
         // than just the leaf crate.
-        for krate in builder.in_tree_crates("test", Some(target)) {
-            cargo.arg("-p").arg(krate.name);
+        for krate in &*self.crates {
+            cargo.arg("-p").arg(krate);
         }
 
         let _guard = builder.msg_check("library test/bench/example targets", target);
@@ -167,6 +190,22 @@ impl Step for Std {
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Rustc {
     pub target: TargetSelection,
+    /// Whether to build only a subset of crates.
+    ///
+    /// This shouldn't be used from other steps; see the comment on [`compile::Rustc`].
+    ///
+    /// [`compile::Rustc`]: crate::compile::Rustc
+    crates: Interned<Vec<String>>,
+}
+
+impl Rustc {
+    pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
+        let mut crates = vec![];
+        for krate in builder.in_tree_crates("rustc-main", None) {
+            crates.push(krate.name.to_string());
+        }
+        Self { target, crates: INTERNER.intern_list(crates) }
+    }
 }
 
 impl Step for Rustc {
@@ -175,11 +214,12 @@ impl Step for Rustc {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("rustc-main").path("compiler")
+        run.crate_or_deps("rustc-main").path("compiler")
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Rustc { target: run.target });
+        let crates = make_run_crates(&run, "compiler");
+        run.builder.ensure(Rustc { target: run.target, crates });
     }
 
     /// Builds the compiler.
@@ -200,7 +240,7 @@ impl Step for Rustc {
             builder.ensure(crate::compile::Std::new(compiler, compiler.host));
             builder.ensure(crate::compile::Std::new(compiler, target));
         } else {
-            builder.ensure(Std { target });
+            builder.ensure(Std::new(target));
         }
 
         let mut cargo = builder.cargo(
@@ -218,14 +258,17 @@ impl Step for Rustc {
             cargo.arg("--all-targets");
         }
 
-        // Explicitly pass -p for all compiler krates -- this will force cargo
+        // Explicitly pass -p for all compiler crates -- this will force cargo
         // to also check the tests/benches/examples for these crates, rather
         // than just the leaf crate.
-        for krate in builder.in_tree_crates("rustc-main", Some(target)) {
-            cargo.arg("-p").arg(krate.name);
+        for krate in &*self.crates {
+            cargo.arg("-p").arg(krate);
         }
 
-        let _guard = builder.msg_check("compiler artifacts", target);
+        let _guard = builder.msg_check(
+            format_args!("compiler artifacts{}", crate_description(&self.crates)),
+            target,
+        );
         run_cargo(
             builder,
             cargo,
@@ -268,7 +311,7 @@ impl Step for CodegenBackend {
         let target = self.target;
         let backend = self.backend;
 
-        builder.ensure(Rustc { target });
+        builder.ensure(Rustc::new(target, builder));
 
         let mut cargo = builder.cargo(
             compiler,
@@ -318,7 +361,7 @@ impl Step for RustAnalyzer {
         let compiler = builder.compiler(builder.top_stage, builder.config.build);
         let target = self.target;
 
-        builder.ensure(Std { target });
+        builder.ensure(Std::new(target));
 
         let mut cargo = prepare_tool_cargo(
             builder,
@@ -386,7 +429,7 @@ macro_rules! tool_check_step {
                 let compiler = builder.compiler(builder.top_stage, builder.config.build);
                 let target = self.target;
 
-                builder.ensure(Rustc { target });
+                builder.ensure(Rustc::new(target, builder));
 
                 let mut cargo = prepare_tool_cargo(
                     builder,
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 33addb90da3..1c66c00eda7 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -48,6 +48,17 @@ impl Std {
     }
 }
 
+/// Given an `alias` selected by the `Step` and the paths passed on the command line,
+/// return a list of the crates that should be built.
+///
+/// Normally, people will pass *just* `library` if they pass it.
+/// But it's possible (although strange) to pass something like `library std core`.
+/// Build all crates anyway, as if they hadn't passed the other args.
+pub(crate) fn make_run_crates(run: &RunConfig<'_>, alias: &str) -> Interned<Vec<String>> {
+    let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias));
+    if has_alias { Default::default() } else { run.cargo_crates_in_set() }
+}
+
 impl Step for Std {
     type Output = ();
     const DEFAULT: bool = true;
@@ -62,16 +73,10 @@ impl Step for Std {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        // Normally, people will pass *just* library if they pass it.
-        // But it's possible (although strange) to pass something like `library std core`.
-        // Build all crates anyway, as if they hadn't passed the other args.
-        let has_library =
-            run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
-        let crates = if has_library { Default::default() } else { run.cargo_crates_in_set() };
         run.builder.ensure(Std {
             compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
             target: run.target,
-            crates,
+            crates: make_run_crates(&run, "library"),
         });
     }
 
@@ -615,6 +620,8 @@ impl Step for Rustc {
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let mut crates = run.builder.in_tree_crates("rustc-main", None);
         for (i, krate) in crates.iter().enumerate() {
+            // We can't allow `build rustc` as an alias for this Step, because that's reserved by `Assemble`.
+            // Ideally Assemble would use `build compiler` instead, but that seems too confusing to be worth the breaking change.
             if krate.name == "rustc-main" {
                 crates.swap_remove(i);
                 break;
@@ -1679,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 b49845386da..46fc5b80e99 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -106,11 +106,7 @@ impl Step for JsonDocs {
     /// Builds the `rust-docs-json` installer component.
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let host = self.host;
-        builder.ensure(crate::doc::Std {
-            stage: builder.top_stage,
-            target: host,
-            format: DocumentationFormat::JSON,
-        });
+        builder.ensure(crate::doc::Std::new(builder.top_stage, host, DocumentationFormat::JSON));
 
         let dest = "share/doc/rust/json";
 
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index b52c3b68cc4..3de85c91516 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -7,7 +7,6 @@
 //! Everything here is basically just a shim around calling either `rustbook` or
 //! `rustdoc`.
 
-use std::ffi::OsStr;
 use std::fs;
 use std::io;
 use std::path::{Path, PathBuf};
@@ -16,6 +15,7 @@ use crate::builder::crate_description;
 use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
 use crate::cache::{Interned, INTERNER};
 use crate::compile;
+use crate::compile::make_run_crates;
 use crate::config::{Config, TargetSelection};
 use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
 use crate::util::{symlink_dir, t, up_to_date};
@@ -87,15 +87,6 @@ book!(
     StyleGuide, "src/doc/style-guide", "style-guide";
 );
 
-// "library/std" -> ["library", "std"]
-//
-// Used for deciding whether a particular step is one requested by the user on
-// the `x.py doc` command line, which determines whether `--open` will open that
-// page.
-pub(crate) fn components_simplified(path: &PathBuf) -> Vec<&str> {
-    path.iter().map(|component| component.to_str().unwrap_or("???")).collect()
-}
-
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct UnstableBook {
     target: TargetSelection,
@@ -425,11 +416,18 @@ impl Step for SharedAssets {
     }
 }
 
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
 pub struct Std {
     pub stage: u32,
     pub target: TargetSelection,
     pub format: DocumentationFormat,
+    crates: Interned<Vec<String>>,
+}
+
+impl Std {
+    pub(crate) fn new(stage: u32, target: TargetSelection, format: DocumentationFormat) -> Self {
+        Std { stage, target, format, crates: INTERNER.intern_list(vec![]) }
+    }
 }
 
 impl Step for Std {
@@ -438,7 +436,7 @@ impl Step for Std {
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run.all_krates("sysroot").path("library").default_condition(builder.config.docs)
+        run.crate_or_deps("sysroot").path("library").default_condition(builder.config.docs)
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -450,6 +448,7 @@ impl Step for Std {
             } else {
                 DocumentationFormat::HTML
             },
+            crates: make_run_crates(&run, "library"),
         });
     }
 
@@ -457,7 +456,7 @@ impl Step for Std {
     ///
     /// This will generate all documentation for the standard library and its
     /// dependencies. This is largely just a wrapper around `cargo doc`.
-    fn run(self, builder: &Builder<'_>) {
+    fn run(mut self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
         let out = match self.format {
@@ -471,41 +470,24 @@ impl Step for Std {
             builder.ensure(SharedAssets { target: self.target });
         }
 
-        let index_page = builder.src.join("src/doc/index.md").into_os_string();
+        let index_page = builder
+            .src
+            .join("src/doc/index.md")
+            .into_os_string()
+            .into_string()
+            .expect("non-utf8 paths are unsupported");
         let mut extra_args = match self.format {
-            DocumentationFormat::HTML => vec![
-                OsStr::new("--markdown-css"),
-                OsStr::new("rust.css"),
-                OsStr::new("--markdown-no-toc"),
-                OsStr::new("--index-page"),
-                &index_page,
-            ],
-            DocumentationFormat::JSON => vec![OsStr::new("--output-format"), OsStr::new("json")],
+            DocumentationFormat::HTML => {
+                vec!["--markdown-css", "rust.css", "--markdown-no-toc", "--index-page", &index_page]
+            }
+            DocumentationFormat::JSON => vec!["--output-format", "json"],
         };
 
         if !builder.config.docs_minification {
-            extra_args.push(OsStr::new("--disable-minification"));
+            extra_args.push("--disable-minification");
         }
 
-        let requested_crates = builder
-            .paths
-            .iter()
-            .map(components_simplified)
-            .filter_map(|path| {
-                if path.len() >= 2 && path.get(0) == Some(&"library") {
-                    // single crate
-                    Some(path[1].to_owned())
-                } else if !path.is_empty() {
-                    // ??
-                    Some(path[0].to_owned())
-                } else {
-                    // all library crates
-                    None
-                }
-            })
-            .collect::<Vec<_>>();
-
-        doc_std(builder, self.format, stage, target, &out, &extra_args, &requested_crates);
+        doc_std(builder, self.format, stage, target, &out, &extra_args, &self.crates);
 
         // Don't open if the format is json
         if let DocumentationFormat::JSON = self.format {
@@ -514,7 +496,11 @@ impl Step for Std {
 
         // Look for library/std, library/core etc in the `x.py doc` arguments and
         // open the corresponding rendered docs.
-        for requested_crate in requested_crates {
+        if self.crates.is_empty() {
+            self.crates = INTERNER.intern_list(vec!["library".to_owned()]);
+        };
+
+        for requested_crate in &*self.crates {
             if requested_crate == "library" {
                 // For `x.py doc library --open`, open `std` by default.
                 let index = out.join("std").join("index.html");
@@ -538,7 +524,7 @@ impl Step for Std {
 /// or remote link.
 const STD_PUBLIC_CRATES: [&str; 5] = ["core", "alloc", "std", "proc_macro", "test"];
 
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
 pub enum DocumentationFormat {
     HTML,
     JSON,
@@ -563,24 +549,22 @@ fn doc_std(
     stage: u32,
     target: TargetSelection,
     out: &Path,
-    extra_args: &[&OsStr],
+    extra_args: &[&str],
     requested_crates: &[String],
 ) {
-    builder.info(&format!(
-        "Documenting{} stage{} library ({}) in {} format",
-        crate_description(requested_crates),
-        stage,
-        target,
-        format.as_str()
-    ));
     if builder.no_std(target) == Some(true) {
         panic!(
             "building std documentation for no_std target {target} is not supported\n\
-             Set `docs = false` in the config to disable documentation."
+             Set `docs = false` in the config to disable documentation, or pass `--exclude doc::library`."
         );
     }
+
     let compiler = builder.compiler(stage, builder.config.build);
 
+    let description =
+        format!("library{} in {} format", crate_description(&requested_crates), format.as_str());
+    let _guard = builder.msg(Kind::Doc, stage, &description, compiler.host, target);
+
     let target_doc_dir_name = if format == DocumentationFormat::JSON { "json-doc" } else { "doc" };
     let target_dir =
         builder.stage_out(compiler, Mode::Std).join(target.triple).join(target_doc_dir_name);
@@ -590,35 +574,42 @@ fn doc_std(
     // as a function parameter.
     let out_dir = target_dir.join(target.triple).join("doc");
 
-    let run_cargo_rustdoc_for = |package: &str| {
-        let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
-        compile::std_cargo(builder, target, compiler.stage, &mut cargo);
-        cargo
-            .arg("--target-dir")
-            .arg(&*target_dir.to_string_lossy())
-            .arg("-p")
-            .arg(package)
-            .arg("-Zskip-rustdoc-fingerprint")
-            .arg("--")
-            .arg("-Z")
-            .arg("unstable-options")
-            .arg("--resource-suffix")
-            .arg(&builder.version)
-            .args(extra_args);
-        if builder.config.library_docs_private_items {
-            cargo.arg("--document-private-items").arg("--document-hidden-items");
-        }
-        builder.run(&mut cargo.into());
+    let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "doc");
+    compile::std_cargo(builder, target, compiler.stage, &mut cargo);
+    cargo
+        .arg("--no-deps")
+        .arg("--target-dir")
+        .arg(&*target_dir.to_string_lossy())
+        .arg("-Zskip-rustdoc-fingerprint")
+        .rustdocflag("-Z")
+        .rustdocflag("unstable-options")
+        .rustdocflag("--resource-suffix")
+        .rustdocflag(&builder.version);
+    for arg in extra_args {
+        cargo.rustdocflag(arg);
+    }
+
+    if builder.config.library_docs_private_items {
+        cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items");
+    }
+
+    // HACK: because we use `--manifest-path library/sysroot/Cargo.toml`, cargo thinks we only want to document that specific crate, not its dependencies.
+    // Override its default.
+    let built_crates = if requested_crates.is_empty() {
+        builder
+            .in_tree_crates("sysroot", None)
+            .into_iter()
+            .map(|krate| krate.name.to_string())
+            .collect()
+    } else {
+        requested_crates.to_vec()
     };
 
-    for krate in STD_PUBLIC_CRATES {
-        run_cargo_rustdoc_for(krate);
-        if requested_crates.iter().any(|p| p == krate) {
-            // No need to document more of the libraries if we have the one we want.
-            break;
-        }
+    for krate in built_crates {
+        cargo.arg("-p").arg(krate);
     }
 
+    builder.run(&mut cargo.into());
     builder.cp_r(&out_dir, &out);
 }
 
@@ -626,6 +617,28 @@ fn doc_std(
 pub struct Rustc {
     pub stage: u32,
     pub target: TargetSelection,
+    crates: Interned<Vec<String>>,
+}
+
+impl Rustc {
+    pub(crate) fn new(stage: u32, target: TargetSelection, builder: &Builder<'_>) -> Self {
+        // Find dependencies for top level crates.
+        let root_crates = vec![
+            INTERNER.intern_str("rustc_driver"),
+            INTERNER.intern_str("rustc_codegen_llvm"),
+            INTERNER.intern_str("rustc_codegen_ssa"),
+        ];
+        let crates: Vec<_> = root_crates
+            .iter()
+            .flat_map(|krate| {
+                builder
+                    .in_tree_crates(krate, Some(target))
+                    .into_iter()
+                    .map(|krate| krate.name.to_string())
+            })
+            .collect();
+        Self { stage, target, crates: INTERNER.intern_list(crates) }
+    }
 }
 
 impl Step for Rustc {
@@ -641,7 +654,11 @@ impl Step for Rustc {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Rustc { stage: run.builder.top_stage, target: run.target });
+        run.builder.ensure(Rustc {
+            stage: run.builder.top_stage,
+            target: run.target,
+            crates: make_run_crates(&run, "compiler"),
+        });
     }
 
     /// Generates compiler documentation.
@@ -654,15 +671,6 @@ impl Step for Rustc {
         let stage = self.stage;
         let target = self.target;
 
-        let paths = builder
-            .paths
-            .iter()
-            .filter(|path| {
-                let components = components_simplified(path);
-                components.len() >= 2 && components[0] == "compiler"
-            })
-            .collect::<Vec<_>>();
-
         // This is the intended out directory for compiler documentation.
         let out = builder.compiler_doc_out(target);
         t!(fs::create_dir_all(&out));
@@ -672,7 +680,13 @@ impl Step for Rustc {
         let compiler = builder.compiler(stage, builder.config.build);
         builder.ensure(compile::Std::new(compiler, builder.config.build));
 
-        builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
+        let _guard = builder.msg(
+            Kind::Doc,
+            stage,
+            &format!("compiler{}", crate_description(&self.crates)),
+            compiler.host,
+            target,
+        );
 
         // This uses a shared directory so that librustdoc documentation gets
         // correctly built and merged with the rustc documentation. This is
@@ -710,22 +724,8 @@ impl Step for Rustc {
         cargo.rustdocflag("--extern-html-root-url");
         cargo.rustdocflag("ena=https://docs.rs/ena/latest/");
 
-        let root_crates = if paths.is_empty() {
-            vec![
-                INTERNER.intern_str("rustc_driver"),
-                INTERNER.intern_str("rustc_codegen_llvm"),
-                INTERNER.intern_str("rustc_codegen_ssa"),
-            ]
-        } else {
-            paths.into_iter().map(|p| builder.crate_paths[p]).collect()
-        };
-        // Find dependencies for top level crates.
-        let compiler_crates = root_crates.iter().flat_map(|krate| {
-            builder.in_tree_crates(krate, Some(target)).into_iter().map(|krate| krate.name)
-        });
-
         let mut to_open = None;
-        for krate in compiler_crates {
+        for krate in &*self.crates {
             // Create all crate output directories first to make sure rustdoc uses
             // relative links.
             // FIXME: Cargo should probably do this itself.
@@ -785,7 +785,7 @@ macro_rules! tool_doc {
 
                 if true $(&& $rustc_tool)? {
                     // Build rustc docs so that we generate relative links.
-                    builder.ensure(Rustc { stage, target });
+                    builder.ensure(Rustc::new(stage, target, builder));
 
                     // Rustdoc needs the rustc sysroot available to build.
                     // FIXME: is there a way to only ensure `check::Rustc` here? Last time I tried it failed
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 fb76dffd071..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")]
@@ -1020,8 +1021,8 @@ impl Build {
         host: impl Into<Option<TargetSelection>>,
         target: impl Into<Option<TargetSelection>>,
     ) -> Option<gha::Group> {
-        let action = action.into();
-        let msg = |fmt| format!("{action:?}ing stage{stage} {what}{fmt}");
+        let action = action.into().description();
+        let msg = |fmt| format!("{action} stage{stage} {what}{fmt}");
         let msg = if let Some(target) = target.into() {
             let host = host.into().unwrap();
             if host == target {
@@ -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/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 44cd84be705..3290e6e0309 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -101,7 +101,7 @@ impl Step for CrateBootstrap {
         );
         builder.info(&format!(
             "{} {} stage0 ({})",
-            builder.kind.test_description(),
+            builder.kind.description(),
             path,
             bootstrap_host,
         ));
@@ -220,7 +220,7 @@ impl Step for HtmlCheck {
         }
         // Ensure that a few different kinds of documentation are available.
         builder.default_doc(&[]);
-        builder.ensure(crate::doc::Rustc { target: self.target, stage: builder.top_stage });
+        builder.ensure(crate::doc::Rustc::new(builder.top_stage, self.target, builder));
 
         try_run(builder, builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)));
     }
@@ -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");
@@ -886,11 +886,11 @@ impl Step for RustdocJSStd {
                     command.arg("--test-file").arg(path);
                 }
             }
-            builder.ensure(crate::doc::Std {
-                target: self.target,
-                stage: builder.top_stage,
-                format: DocumentationFormat::HTML,
-            });
+            builder.ensure(crate::doc::Std::new(
+                builder.top_stage,
+                self.target,
+                DocumentationFormat::HTML,
+            ));
             builder.run(&mut command);
         } else {
             builder.info("No nodejs found, skipping \"tests/rustdoc-js-std\" tests");
@@ -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")]
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/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/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index 806935b827f..3ccca1e8b89 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.16.4
\ No newline at end of file
+0.16.5
\ No newline at end of file
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/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 7d3ccb9def3..83887cc44b9 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -40,7 +40,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                 let infcx = cx.tcx.infer_ctxt().build();
                 let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id);
                 let impl_ty = ty.subst(infcx.tcx, substs);
-                let param_env = EarlyBinder::new(param_env).subst(infcx.tcx, substs);
+                let param_env = EarlyBinder::bind(param_env).subst(infcx.tcx, substs);
 
                 let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
                 let impl_trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
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/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/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/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/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 423eee47742..0ae95b045e0 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -212,7 +212,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO,
     crate::int_plus_one::INT_PLUS_ONE_INFO,
     crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
-    crate::invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED_INFO,
     crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
     crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO,
     crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index a418a910ba8..a1d2147cb49 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1219,7 +1219,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
                 return false;
             }
 
-            let predicate = EarlyBinder::new(predicate).subst(cx.tcx, &substs_with_referent_ty);
+            let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, &substs_with_referent_ty);
             let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
             let infcx = cx.tcx.infer_ctxt().build();
             infcx.predicate_must_hold_modulo_regions(&obligation)
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index af2aac6ac0d..c919b4de65d 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -243,7 +243,7 @@ fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs
                 | ty::Ref(..)
                 | ty::Slice(_)
                 | ty::Tuple(_) => {
-                    format!("<{}>", EarlyBinder::new(ty).subst(cx.tcx, substs))
+                    format!("<{}>", EarlyBinder::bind(ty).subst(cx.tcx, substs))
                 },
                 _ => ty.to_string(),
             }
diff --git a/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs b/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs
deleted file mode 100644
index 6a4861747d2..00000000000
--- a/src/tools/clippy/clippy_lints/src/invalid_utf8_in_unchecked.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{match_function_call, paths};
-use rustc_ast::{BorrowKind, LitKind};
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Spanned;
-use rustc_span::Span;
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `std::str::from_utf8_unchecked` with an invalid UTF-8 literal
-    ///
-    /// ### Why is this bad?
-    /// Creating such a `str` would result in undefined behavior
-    ///
-    /// ### Example
-    /// ```rust
-    /// # #[allow(unused)]
-    /// unsafe {
-    ///     std::str::from_utf8_unchecked(b"cl\x82ippy");
-    /// }
-    /// ```
-    #[clippy::version = "1.64.0"]
-    pub INVALID_UTF8_IN_UNCHECKED,
-    correctness,
-    "using a non UTF-8 literal in `std::std::from_utf8_unchecked`"
-}
-declare_lint_pass!(InvalidUtf8InUnchecked => [INVALID_UTF8_IN_UNCHECKED]);
-
-impl<'tcx> LateLintPass<'tcx> for InvalidUtf8InUnchecked {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if let Some([arg]) = match_function_call(cx, expr, &paths::STR_FROM_UTF8_UNCHECKED) {
-            match &arg.kind {
-                ExprKind::Lit(Spanned { node: lit, .. }) => {
-                    if let LitKind::ByteStr(bytes, _) = &lit
-                        && std::str::from_utf8(bytes).is_err()
-                    {
-                        lint(cx, expr.span);
-                    }
-                },
-                ExprKind::AddrOf(BorrowKind::Ref, _, Expr { kind: ExprKind::Array(args), .. }) => {
-                    let elements = args.iter().map(|e|{
-                        match &e.kind {
-                            ExprKind::Lit(Spanned { node: lit, .. }) => match lit {
-                                LitKind::Byte(b) => Some(*b),
-                                #[allow(clippy::cast_possible_truncation)]
-                                LitKind::Int(b, _) => Some(*b as u8),
-                                _ => None
-                            }
-                            _ => None
-                        }
-                    }).collect::<Option<Vec<_>>>();
-
-                    if let Some(elements) = elements
-                        && std::str::from_utf8(&elements).is_err()
-                    {
-                        lint(cx, expr.span);
-                    }
-                }
-                _ => {}
-            }
-        }
-    }
-}
-
-fn lint(cx: &LateContext<'_>, span: Span) {
-    span_lint(
-        cx,
-        INVALID_UTF8_IN_UNCHECKED,
-        span,
-        "non UTF-8 literal in `std::str::from_utf8_unchecked`",
-    );
-}
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index b442a4ac5f6..fcca595c2bc 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -157,7 +157,6 @@ mod inline_fn_without_body;
 mod instant_subtraction;
 mod int_plus_one;
 mod invalid_upcast_comparisons;
-mod invalid_utf8_in_unchecked;
 mod items_after_statements;
 mod items_after_test_module;
 mod iter_not_returning_iterator;
@@ -937,7 +936,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv())));
     let verbose_bit_mask_threshold = conf.verbose_bit_mask_threshold;
     store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
-    store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
     store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
     store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv())));
     store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index d4cc14bb856..99f810c27cf 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -241,7 +241,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
         && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
         && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
     {
-        item_ty == EarlyBinder::new(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))
+        item_ty == EarlyBinder::bind(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))
     } else {
         false
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index fdacfa49e92..309d2157b76 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -428,7 +428,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                                      }));
 
                         if trait_predicates.any(|predicate| {
-                            let predicate = EarlyBinder::new(predicate).subst(cx.tcx, new_subst);
+                            let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, new_subst);
                             let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
                             !cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
                         }) {
@@ -438,7 +438,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                         let output_ty = fn_sig.output();
                         if output_ty.contains(*param_ty) {
                             if let Ok(new_ty)  = cx.tcx.try_subst_and_normalize_erasing_regions(
-                                new_subst, cx.param_env, EarlyBinder::new(output_ty)) {
+                                new_subst, cx.param_env, EarlyBinder::bind(output_ty)) {
                                 expr = parent_expr;
                                 ty = new_ty;
                                 continue;
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index b0db56bb417..7c2a100efda 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -43,6 +43,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::into_iter_on_array", "array_into_iter"),
     ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
     ("clippy::invalid_ref", "invalid_value"),
+    ("clippy::invalid_utf8_in_unchecked", "invalid_from_utf8_unchecked"),
     ("clippy::let_underscore_drop", "let_underscore_drop"),
     ("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums"),
     ("clippy::panic_params", "non_fmt_panics"),
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 843538e1eb2..cc3183759ae 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -462,7 +462,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                 let substs = if self.substs.is_empty() {
                     substs
                 } else {
-                    EarlyBinder::new(substs).subst(self.lcx.tcx, self.substs)
+                    EarlyBinder::bind(substs).subst(self.lcx.tcx, self.substs)
                 };
 
                 let result = self
diff --git a/src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.rs b/src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.rs
deleted file mode 100644
index 3dc096d3197..00000000000
--- a/src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-#![warn(clippy::invalid_utf8_in_unchecked)]
-
-fn main() {
-    // Valid
-    unsafe {
-        std::str::from_utf8_unchecked(&[99, 108, 105, 112, 112, 121]);
-        std::str::from_utf8_unchecked(&[b'c', b'l', b'i', b'p', b'p', b'y']);
-        std::str::from_utf8_unchecked(b"clippy");
-
-        let x = 0xA0;
-        std::str::from_utf8_unchecked(&[0xC0, x]);
-    }
-
-    // Invalid
-    unsafe {
-        std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
-        std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
-        std::str::from_utf8_unchecked(b"cl\x82ippy");
-    }
-}
diff --git a/src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.stderr b/src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.stderr
deleted file mode 100644
index c89cd2758ee..00000000000
--- a/src/tools/clippy/tests/ui/invalid_utf8_in_unchecked.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: non UTF-8 literal in `std::str::from_utf8_unchecked`
-  --> $DIR/invalid_utf8_in_unchecked.rs:16:9
-   |
-LL |         std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `-D clippy::invalid-utf8-in-unchecked` implied by `-D warnings`
-
-error: non UTF-8 literal in `std::str::from_utf8_unchecked`
-  --> $DIR/invalid_utf8_in_unchecked.rs:17:9
-   |
-LL |         std::str::from_utf8_unchecked(&[b'c', b'l', b'/x82', b'i', b'p', b'p', b'y']);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: non UTF-8 literal in `std::str::from_utf8_unchecked`
-  --> $DIR/invalid_utf8_in_unchecked.rs:18:9
-   |
-LL |         std::str::from_utf8_unchecked(b"cl/x82ippy");
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-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 dfe45dec8a7..53ac65473b8 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -38,6 +38,7 @@
 #![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
 #![allow(invalid_value)]
+#![allow(invalid_from_utf8_unchecked)]
 #![allow(let_underscore_drop)]
 #![allow(enum_intrinsics_non_enums)]
 #![allow(non_fmt_panics)]
@@ -87,6 +88,7 @@
 #![warn(array_into_iter)]
 #![warn(invalid_atomic_ordering)]
 #![warn(invalid_value)]
+#![warn(invalid_from_utf8_unchecked)]
 #![warn(let_underscore_drop)]
 #![warn(enum_intrinsics_non_enums)]
 #![warn(non_fmt_panics)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index ce8eca5a308..722c0b3eb27 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -38,6 +38,7 @@
 #![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
 #![allow(invalid_value)]
+#![allow(invalid_from_utf8_unchecked)]
 #![allow(let_underscore_drop)]
 #![allow(enum_intrinsics_non_enums)]
 #![allow(non_fmt_panics)]
@@ -87,6 +88,7 @@
 #![warn(clippy::into_iter_on_array)]
 #![warn(clippy::invalid_atomic_ordering)]
 #![warn(clippy::invalid_ref)]
+#![warn(clippy::invalid_utf8_in_unchecked)]
 #![warn(clippy::let_underscore_drop)]
 #![warn(clippy::mem_discriminant_non_enum)]
 #![warn(clippy::panic_params)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 3fca60aa2eb..1ff83917660 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:49:9
+  --> $DIR/rename.rs:50:9
    |
 LL | #![warn(clippy::almost_complete_letter_range)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@@ -7,286 +7,292 @@ 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:50:9
+  --> $DIR/rename.rs:51: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:51:9
+  --> $DIR/rename.rs:52: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:52:9
+  --> $DIR/rename.rs:53: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:53:9
+  --> $DIR/rename.rs:54: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:54:9
+  --> $DIR/rename.rs:55: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:55:9
+  --> $DIR/rename.rs:56: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:56:9
+  --> $DIR/rename.rs:57: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:57:9
+  --> $DIR/rename.rs:58: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:58:9
+  --> $DIR/rename.rs:59: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:59:9
+  --> $DIR/rename.rs:60: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:60:9
+  --> $DIR/rename.rs:61: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:61:9
+  --> $DIR/rename.rs:62: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:62:9
+  --> $DIR/rename.rs:63: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:63:9
+  --> $DIR/rename.rs:64: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:64:9
+  --> $DIR/rename.rs:65: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:65:9
+  --> $DIR/rename.rs:66: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:66:9
+  --> $DIR/rename.rs:67: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:67:9
+  --> $DIR/rename.rs:68: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:68:9
+  --> $DIR/rename.rs:69: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:69:9
+  --> $DIR/rename.rs:70: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:70:9
+  --> $DIR/rename.rs:71: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:71:9
+  --> $DIR/rename.rs:72: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:72:9
+  --> $DIR/rename.rs:73: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:73:9
+  --> $DIR/rename.rs:74: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:74:9
+  --> $DIR/rename.rs:75: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:75:9
+  --> $DIR/rename.rs:76: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:76:9
+  --> $DIR/rename.rs:77: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:77:9
+  --> $DIR/rename.rs:78:9
    |
 LL | #![warn(clippy::zero_width_space)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
 
 error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
-  --> $DIR/rename.rs:78:9
+  --> $DIR/rename.rs:79: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:79:9
+  --> $DIR/rename.rs:80: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:80:9
+  --> $DIR/rename.rs:81: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:81:9
+  --> $DIR/rename.rs:82: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:82:9
+  --> $DIR/rename.rs:83: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:83:9
+  --> $DIR/rename.rs:84: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:84:9
+  --> $DIR/rename.rs:85: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:85:9
+  --> $DIR/rename.rs:86: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:86:9
+  --> $DIR/rename.rs:87: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:87:9
+  --> $DIR/rename.rs:88: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:88:9
+  --> $DIR/rename.rs:89: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:89:9
+  --> $DIR/rename.rs:90: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
+   |
+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:90:9
+  --> $DIR/rename.rs:92: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:91:9
+  --> $DIR/rename.rs:93: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:92:9
+  --> $DIR/rename.rs:94: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:93:9
+  --> $DIR/rename.rs:95: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:94:9
+  --> $DIR/rename.rs:96: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:95:9
+  --> $DIR/rename.rs:97: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:96:9
+  --> $DIR/rename.rs:98:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
-error: aborting due to 48 previous errors
+error: aborting due to 49 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/pass/shims/time-with-isolation2.stdout b/src/tools/miri/tests/pass/shims/time-with-isolation2.stdout
index 641e469f50c..c68b40b744b 100644
--- a/src/tools/miri/tests/pass/shims/time-with-isolation2.stdout
+++ b/src/tools/miri/tests/pass/shims/time-with-isolation2.stdout
@@ -1 +1 @@
-The loop took around 13s
+The loop took around 7s
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/deps.rs b/src/tools/tidy/src/deps.rs
index 2e778110931..db2b7910b71 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -38,7 +38,6 @@ const LICENSES: &[&str] = &[
 const EXCEPTIONS: &[(&str, &str)] = &[
     // tidy-alphabetical-start
     ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc
-    ("codespan-reporting", "Apache-2.0"),                    // cxx via iana-time-zone-haiku via time, only on haiku
     ("colored", "MPL-2.0"),                                  // rustfmt
     ("dissimilar", "Apache-2.0"),                            // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
     ("fluent-langneg", "Apache-2.0"),                        // rustc (fluent translations)
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index be3a5d3aa0f..01ef4abd3dc 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -10,8 +10,8 @@ use std::path::{Path, PathBuf};
 
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1920;
-const ROOT_ENTRY_LIMIT: usize = 896;
+const ISSUES_ENTRY_LIMIT: usize = 1898;
+const ROOT_ENTRY_LIMIT: usize = 891;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
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
new file mode 100644
index 00000000000..8f32c50b798
--- /dev/null
+++ b/tests/codegen/const_scalar_pair.rs
@@ -0,0 +1,8 @@
+// compile-flags: --crate-type=lib -Copt-level=0 -Zmir-opt-level=0 -C debuginfo=2
+
+#![feature(inline_const)]
+
+pub fn foo() -> (i32, i32) {
+    // CHECK: ret { i32, i32 } { i32 1, i32 2 }
+    const { (1, 2) }
+}
diff --git a/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs b/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs
new file mode 100644
index 00000000000..e7d91235e73
--- /dev/null
+++ b/tests/incremental/issue-110457-same-span-closures/auxiliary/egui_inspect_derive.rs
@@ -0,0 +1,90 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn expand(_: TokenStream) -> TokenStream {
+    // Hand expansion/rewriting of
+    // ```
+    // quote! {
+    //     output_mut(|o| o.copied_text = "".into());
+    //     output_mut(|o| o.copied_text = format!("{:?}", self.tile_db));
+    // }.into()
+    // ```
+    stream([
+        ident("output_mut"),
+        group(
+            Delimiter::Parenthesis,
+            [
+                or(),
+                ident("o"),
+                or(),
+                ident("o"),
+                dot(),
+                ident("copied_text"),
+                eq(),
+                string(""),
+                dot(),
+                ident("into"),
+                group(Delimiter::Parenthesis, []),
+            ],
+        ),
+        semi(),
+        ident("output_mut"),
+        group(
+            Delimiter::Parenthesis,
+            [
+                or(),
+                ident("o"),
+                or(),
+                ident("o"),
+                dot(),
+                ident("copied_text"),
+                eq(),
+                ident("format"),
+                bang(),
+                group(
+                    Delimiter::Parenthesis,
+                    [string("{:?}"), comma(), ident("self"), dot(), ident("tile_db")],
+                ),
+            ],
+        ),
+        semi(),
+    ])
+}
+
+fn stream(s: impl IntoIterator<Item = TokenTree>) -> TokenStream {
+    s.into_iter().collect()
+}
+
+fn ident(i: &str) -> TokenTree {
+    TokenTree::Ident(Ident::new(i, Span::call_site()))
+}
+fn group(d: Delimiter, s: impl IntoIterator<Item = TokenTree>) -> TokenTree {
+    TokenTree::Group(Group::new(d, s.into_iter().collect()))
+}
+fn semi() -> TokenTree {
+    TokenTree::Punct(Punct::new(';', Spacing::Alone))
+}
+fn or() -> TokenTree {
+    TokenTree::Punct(Punct::new('|', Spacing::Alone))
+}
+fn dot() -> TokenTree {
+    TokenTree::Punct(Punct::new('.', Spacing::Alone))
+}
+fn eq() -> TokenTree {
+    TokenTree::Punct(Punct::new('=', Spacing::Alone))
+}
+fn bang() -> TokenTree {
+    TokenTree::Punct(Punct::new('!', Spacing::Alone))
+}
+fn comma() -> TokenTree {
+    TokenTree::Punct(Punct::new(',', Spacing::Alone))
+}
+fn string(s: &str) -> TokenTree {
+    TokenTree::Literal(Literal::string(s))
+}
diff --git a/tests/incremental/issue-110457-same-span-closures/main.rs b/tests/incremental/issue-110457-same-span-closures/main.rs
new file mode 100644
index 00000000000..b44fda3d36a
--- /dev/null
+++ b/tests/incremental/issue-110457-same-span-closures/main.rs
@@ -0,0 +1,47 @@
+// aux-build: egui_inspect_derive.rs
+// revisions: cpass1 cpass2
+
+extern crate egui_inspect_derive;
+
+pub struct TileDef {
+    pub layer: (),
+    #[cfg(cpass2)]
+    pub blend_graphic: String,
+}
+
+pub(crate) struct GameState {
+    pub(crate) tile_db: TileDb,
+}
+
+impl GameState {
+    fn inspect_mut(&mut self) {
+        egui_inspect_derive::expand! {}
+    }
+}
+
+fn new() -> GameState {
+    loop {}
+}
+
+fn main() {
+    let mut app = new();
+    app.inspect_mut();
+}
+// this is actually used
+pub struct TileDb {
+    unknown_bg: TileDef,
+}
+
+impl std::fmt::Debug for TileDb {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        loop {}
+    }
+}
+
+pub struct PlatformOutput {
+    pub copied_text: String,
+}
+
+pub fn output_mut<R>(writer: impl FnOnce(&mut PlatformOutput) -> R) -> R {
+    loop {}
+}
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir
index 9856cdd5688..693939e75f4 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir
@@ -8,19 +8,32 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     let mut _4: std::ops::Range<u32>;    // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
     let mut _5: std::ops::Range<u32>;    // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
     let mut _6: &mut std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
-    let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
-    let mut _8: isize;                   // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6
-    let mut _10: &impl Fn(u32);          // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10
-    let mut _11: (u32,);                 // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13
-    let _12: ();                         // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
+    let mut _10: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
+    let mut _13: isize;                  // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6
+    let mut _15: &impl Fn(u32);          // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10
+    let mut _16: (u32,);                 // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13
+    let _17: ();                         // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
     scope 1 {
         debug iter => _5;                // in scope 1 at $DIR/range_iter.rs:+1:14: +1:24
-        let _9: u32;                     // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10
+        let _14: u32;                    // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10
         scope 2 {
-            debug x => _9;               // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10
+            debug x => _14;              // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10
         }
         scope 4 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:21:14: 21:24
             debug self => _6;            // in scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            scope 5 (inlined <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                debug self => _6;        // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                let mut _7: &u32;        // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                let mut _8: &u32;        // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                let mut _9: bool;        // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                let _11: u32;            // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                let mut _12: u32;        // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                scope 6 {
+                    debug old => _11;    // in scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                    scope 7 {
+                    }
+                }
+            }
         }
     }
     scope 3 (inlined <std::ops::Range<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:21:14: 21:24
@@ -35,57 +48,92 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
     }
 
     bb1: {
-        StorageLive(_7);                 // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
+        StorageLive(_10);                // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
         _6 = &mut _5;                    // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
-        _7 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_6) -> [return: bb2, unwind: bb8]; // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_11);                // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_9);                 // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_7);                 // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _7 = &((*_6).0: u32);            // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_8);                 // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _8 = &((*_6).1: u32);            // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _9 = <u32 as PartialOrd>::lt(move _7, move _8) -> [return: bb2, unwind: bb12]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
                                          // mir::Constant
                                          // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
-                                         // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
+                                         // + literal: Const { ty: for<'a, 'b> fn(&'a u32, &'b u32) -> bool {<u32 as PartialOrd>::lt}, val: Value(<ZST>) }
     }
 
     bb2: {
-        _8 = discriminant(_7);           // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
-        switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
+        StorageDead(_8);                 // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageDead(_7);                 // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        switchInt(move _9) -> [0: bb3, otherwise: bb4]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
     }
 
     bb3: {
-        StorageDead(_7);                 // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
-        StorageDead(_5);                 // scope 0 at $DIR/range_iter.rs:+3:5: +3:6
-        drop(_3) -> bb4;                 // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
+        _10 = Option::<u32>::None;       // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        goto -> bb6;                     // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
     }
 
     bb4: {
-        return;                          // scope 0 at $DIR/range_iter.rs:+4:2: +4:2
+        _11 = ((*_6).0: u32);            // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_12);                // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _12 = <u32 as Step>::forward_unchecked(_11, const 1_usize) -> [return: bb5, unwind: bb12]; // scope 7 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
+                                         // + literal: Const { ty: unsafe fn(u32, usize) -> u32 {<u32 as Step>::forward_unchecked}, val: Value(<ZST>) }
     }
 
     bb5: {
-        _9 = ((_7 as Some).0: u32);      // scope 1 at $DIR/range_iter.rs:+1:9: +1:10
-        StorageLive(_10);                // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
-        _10 = &_3;                       // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
-        StorageLive(_11);                // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
-        _11 = (_9,);                     // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
-        _12 = <impl Fn(u32) as Fn<(u32,)>>::call(move _10, move _11) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
+        ((*_6).0: u32) = move _12;       // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageDead(_12);                // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _10 = Option::<u32>::Some(_11);  // scope 6 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        goto -> bb6;                     // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+    }
+
+    bb6: {
+        StorageDead(_9);                 // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageDead(_11);                // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _13 = discriminant(_10);         // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
+        switchInt(move _13) -> [0: bb7, 1: bb9, otherwise: bb11]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
+    }
+
+    bb7: {
+        StorageDead(_10);                // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
+        StorageDead(_5);                 // scope 0 at $DIR/range_iter.rs:+3:5: +3:6
+        drop(_3) -> bb8;                 // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
+    }
+
+    bb8: {
+        return;                          // scope 0 at $DIR/range_iter.rs:+4:2: +4:2
+    }
+
+    bb9: {
+        _14 = ((_10 as Some).0: u32);    // scope 1 at $DIR/range_iter.rs:+1:9: +1:10
+        StorageLive(_15);                // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
+        _15 = &_3;                       // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
+        StorageLive(_16);                // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
+        _16 = (_14,);                    // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
+        _17 = <impl Fn(u32) as Fn<(u32,)>>::call(move _15, move _16) -> [return: bb10, unwind: bb12]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
                                          // mir::Constant
                                          // + span: $DIR/range_iter.rs:22:9: 22:10
                                          // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) }
     }
 
-    bb6: {
-        StorageDead(_11);                // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
-        StorageDead(_10);                // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
-        StorageDead(_7);                 // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
+    bb10: {
+        StorageDead(_16);                // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
+        StorageDead(_15);                // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
+        StorageDead(_10);                // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
         goto -> bb1;                     // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
     }
 
-    bb7: {
+    bb11: {
         unreachable;                     // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
     }
 
-    bb8 (cleanup): {
-        drop(_3) -> [return: bb9, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
+    bb12 (cleanup): {
+        drop(_3) -> [return: bb13, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
     }
 
-    bb9 (cleanup): {
+    bb13 (cleanup): {
         resume;                          // scope 0 at $DIR/range_iter.rs:+0:1: +4:2
     }
 }
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir
index cae46e2b0bb..668ec31c6c1 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir
@@ -5,16 +5,64 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
     let mut _0: std::option::Option<u32>; // return place in scope 0 at $DIR/range_iter.rs:+0:48: +0:59
     scope 1 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:11:8: 11:14
         debug self => _1;                // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        scope 2 (inlined <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next) { // at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            debug self => _1;            // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            let mut _2: &u32;            // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            let mut _3: &u32;            // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            let mut _4: bool;            // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            let _5: u32;                 // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            let mut _6: u32;             // in scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+            scope 3 {
+                debug old => _5;         // in scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                scope 4 {
+                }
+            }
+        }
     }
 
     bb0: {
-        _0 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_1) -> bb1; // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_5);                 // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_4);                 // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_2);                 // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _2 = &((*_1).0: u32);            // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_3);                 // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _3 = &((*_1).1: u32);            // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _4 = <u32 as PartialOrd>::lt(move _2, move _3) -> bb1; // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
                                          // mir::Constant
                                          // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
-                                         // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
+                                         // + literal: Const { ty: for<'a, 'b> fn(&'a u32, &'b u32) -> bool {<u32 as PartialOrd>::lt}, val: Value(<ZST>) }
     }
 
     bb1: {
+        StorageDead(_3);                 // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageDead(_2);                 // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        switchInt(move _4) -> [0: bb2, otherwise: bb3]; // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+    }
+
+    bb2: {
+        _0 = Option::<u32>::None;        // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        goto -> bb5;                     // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+    }
+
+    bb3: {
+        _5 = ((*_1).0: u32);             // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageLive(_6);                 // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _6 = <u32 as Step>::forward_unchecked(_5, const 1_usize) -> bb4; // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+                                         // mir::Constant
+                                         // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
+                                         // + literal: Const { ty: unsafe fn(u32, usize) -> u32 {<u32 as Step>::forward_unchecked}, val: Value(<ZST>) }
+    }
+
+    bb4: {
+        ((*_1).0: u32) = move _6;        // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageDead(_6);                 // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        _0 = Option::<u32>::Some(_5);    // scope 3 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        goto -> bb5;                     // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+    }
+
+    bb5: {
+        StorageDead(_4);                 // scope 2 at $SRC_DIR/core/src/iter/range.rs:LL:COL
+        StorageDead(_5);                 // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
         return;                          // scope 0 at $DIR/range_iter.rs:+2:2: +2:2
     }
 }
diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml
index 0c514fc6864..c5e7f813dd1 100644
--- a/tests/rustdoc-gui/target.goml
+++ b/tests/rustdoc-gui/target.goml
@@ -25,11 +25,11 @@ call-function: ("check-style", {
 })
 call-function: ("check-style", {
     "theme": "dark",
-    "background": "rgb(73, 74, 61)",
-    "border": "rgb(187, 116, 16)",
+    "background": "#494a3d",
+    "border": "#bb7410",
 })
 call-function: ("check-style", {
     "theme": "light",
-    "background": "rgb(253, 255, 211)",
-    "border": "rgb(173, 124, 55)",
+    "background": "#fdffd3",
+    "border": "#ad7c37",
 })
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/issues/issue-78115.rs b/tests/ui/async-await/issue-78115.rs
index ac18470c621..ac18470c621 100644
--- a/tests/ui/issues/issue-78115.rs
+++ b/tests/ui/async-await/issue-78115.rs
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs
new file mode 100644
index 00000000000..f21ef43fb7c
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.rs
@@ -0,0 +1,18 @@
+// edition:2021
+
+// regression test for #112056
+
+fn extend_lifetime<'a, 'b>(x: &mut (&'a str,), y: &'b str) {
+    let mut closure = |input| x.0 = input;
+    //~^ ERROR: lifetime may not live long enough
+    closure(y);
+}
+
+fn main() {
+    let mut tuple = ("static",);
+    {
+        let x = String::from("temporary");
+        extend_lifetime(&mut tuple, &x);
+    }
+    println!("{}", tuple.0);
+}
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr
new file mode 100644
index 00000000000..730823281ab
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-1.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/unique-borrows-are-invariant-1.rs:6:31
+   |
+LL | fn extend_lifetime<'a, 'b>(x: &mut (&'a str,), y: &'b str) {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     let mut closure = |input| x.0 = input;
+   |                               ^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs
new file mode 100644
index 00000000000..dd9d986c208
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.rs
@@ -0,0 +1,31 @@
+// edition:2021
+
+// regression test for #112056
+
+struct Spooky<'b> {
+    owned: Option<&'static u32>,
+    borrowed: &'b &'static u32,
+}
+
+impl<'b> Spooky<'b> {
+    fn create_self_reference<'a>(&'a mut self) {
+        let mut closure = || {
+            if let Some(owned) = &self.owned {
+                let borrow: &'a &'static u32 = owned;
+                self.borrowed = borrow;
+                //~^ ERROR: lifetime may not live long enough
+            }
+        };
+        closure();
+    }
+}
+
+fn main() {
+    let mut spooky: Spooky<'static> = Spooky {
+        owned: Some(&1),
+        borrowed: &&1,
+    };
+    spooky.create_self_reference();
+    spooky.owned = None;
+    println!("{}", **spooky.borrowed);
+}
diff --git a/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr
new file mode 100644
index 00000000000..66ba0fe3547
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/unique-borrows-are-invariant-2.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/unique-borrows-are-invariant-2.rs:15:17
+   |
+LL | impl<'b> Spooky<'b> {
+   |      -- lifetime `'b` defined here
+LL |     fn create_self_reference<'a>(&'a mut self) {
+   |                              -- lifetime `'a` defined here
+...
+LL |                 self.borrowed = borrow;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/issues/issue-3794.rs b/tests/ui/coercion/issue-3794.rs
index b1f028fbccb..b1f028fbccb 100644
--- a/tests/ui/issues/issue-3794.rs
+++ b/tests/ui/coercion/issue-3794.rs
diff --git a/tests/ui/coherence/coherence-inherited-subtyping.re.stderr b/tests/ui/coherence/coherence-inherited-subtyping.re.stderr
deleted file mode 100644
index 4701bc0b139..00000000000
--- a/tests/ui/coherence/coherence-inherited-subtyping.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0592]: duplicate definitions with name `method1`
-  --> $DIR/coherence-inherited-subtyping.rs:14:5
-   |
-LL |     fn method1(&self) {}
-   |     ^^^^^^^^^^^^^^^^^ duplicate definitions for `method1`
-...
-LL |     fn method1(&self) {}
-   |     ----------------- other definition for `method1`
-   |
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0592`.
diff --git a/tests/ui/coherence/coherence-inherited-subtyping.rs b/tests/ui/coherence/coherence-inherited-subtyping.rs
index 8587eb77950..f35cd2103da 100644
--- a/tests/ui/coherence/coherence-inherited-subtyping.rs
+++ b/tests/ui/coherence/coherence-inherited-subtyping.rs
@@ -4,8 +4,6 @@
 // Note: This scenario is currently accepted, but as part of the
 // universe transition (#56105) may eventually become an error.
 
-// revisions: old re
-
 struct Foo<T> {
     t: T,
 }
diff --git a/tests/ui/coherence/coherence-inherited-subtyping.old.stderr b/tests/ui/coherence/coherence-inherited-subtyping.stderr
index 4701bc0b139..f60b2aa2735 100644
--- a/tests/ui/coherence/coherence-inherited-subtyping.old.stderr
+++ b/tests/ui/coherence/coherence-inherited-subtyping.stderr
@@ -1,5 +1,5 @@
 error[E0592]: duplicate definitions with name `method1`
-  --> $DIR/coherence-inherited-subtyping.rs:14:5
+  --> $DIR/coherence-inherited-subtyping.rs:12:5
    |
 LL |     fn method1(&self) {}
    |     ^^^^^^^^^^^^^^^^^ duplicate definitions for `method1`
diff --git a/tests/ui/coinduction/canonicalization-rerun.rs b/tests/ui/coinduction/canonicalization-rerun.rs
index b10ba3a810f..c68895fc4e6 100644
--- a/tests/ui/coinduction/canonicalization-rerun.rs
+++ b/tests/ui/coinduction/canonicalization-rerun.rs
@@ -1,6 +1,6 @@
 // check-pass
-// revisions: old new
-//[new] compile-flags: -Ztrait-solver=next
+// revisions: old next
+//[next] compile-flags: -Ztrait-solver=next
 
 // If we use canonical goals during trait solving we have to reevaluate
 // the root goal of a cycle until we hit a fixpoint.
diff --git a/tests/ui/issues/issue-16538.mir.stderr b/tests/ui/consts/issue-16538.mir.stderr
index e320df4b7ad..e320df4b7ad 100644
--- a/tests/ui/issues/issue-16538.mir.stderr
+++ b/tests/ui/consts/issue-16538.mir.stderr
diff --git a/tests/ui/issues/issue-16538.rs b/tests/ui/consts/issue-16538.rs
index 270fa301414..270fa301414 100644
--- a/tests/ui/issues/issue-16538.rs
+++ b/tests/ui/consts/issue-16538.rs
diff --git a/tests/ui/issues/issue-16538.thir.stderr b/tests/ui/consts/issue-16538.thir.stderr
index 4a862869274..4a862869274 100644
--- a/tests/ui/issues/issue-16538.thir.stderr
+++ b/tests/ui/consts/issue-16538.thir.stderr
diff --git a/tests/ui/issues/issue-28822.rs b/tests/ui/consts/issue-28822.rs
index 10e5d1dd0ac..10e5d1dd0ac 100644
--- a/tests/ui/issues/issue-28822.rs
+++ b/tests/ui/consts/issue-28822.rs
diff --git a/tests/ui/issues/issue-29798.rs b/tests/ui/consts/issue-29798.rs
index 5eff5d1915b..5eff5d1915b 100644
--- a/tests/ui/issues/issue-29798.rs
+++ b/tests/ui/consts/issue-29798.rs
diff --git a/tests/ui/issues/issue-50689.rs b/tests/ui/enum-discriminant/issue-50689.rs
index b49f2950020..b49f2950020 100644
--- a/tests/ui/issues/issue-50689.rs
+++ b/tests/ui/enum-discriminant/issue-50689.rs
diff --git a/tests/ui/issues/issue-1251.rs b/tests/ui/extern/issue-1251.rs
index c2c047c7961..c2c047c7961 100644
--- a/tests/ui/issues/issue-1251.rs
+++ b/tests/ui/extern/issue-1251.rs
diff --git a/tests/ui/issues/issue-1257.rs b/tests/ui/for-loop-while/issue-1257.rs
index de5a6d35925..de5a6d35925 100644
--- a/tests/ui/issues/issue-1257.rs
+++ b/tests/ui/for-loop-while/issue-1257.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-95230.rs b/tests/ui/higher-rank-trait-bounds/issue-95230.rs
deleted file mode 100644
index 769b6a92537..00000000000
--- a/tests/ui/higher-rank-trait-bounds/issue-95230.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// revisions: old new
-//[new] compile-flags: -Ztrait-solver=next
-//[old] check-pass
-//[new] known-bug: #109764
-
-
-pub struct Bar
-where
-    for<'a> &'a mut Self:;
-
-fn main() {}
diff --git a/tests/ui/higher-lifetime-bounds.rs b/tests/ui/higher-ranked/higher-lifetime-bounds.rs
index f3393347d90..f3393347d90 100644
--- a/tests/ui/higher-lifetime-bounds.rs
+++ b/tests/ui/higher-ranked/higher-lifetime-bounds.rs
diff --git a/tests/ui/higher-lifetime-bounds.stderr b/tests/ui/higher-ranked/higher-lifetime-bounds.stderr
index bc6d2288cdf..bc6d2288cdf 100644
--- a/tests/ui/higher-lifetime-bounds.stderr
+++ b/tests/ui/higher-ranked/higher-lifetime-bounds.stderr
diff --git a/tests/ui/higher-ranked/leak-check-in-selection.rs b/tests/ui/higher-ranked/leak-check-in-selection.rs
new file mode 100644
index 00000000000..e8d6cff856c
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check-in-selection.rs
@@ -0,0 +1,24 @@
+// run-pass
+// revisions: old next
+//[next] compile-flags: -Ztrait-solver=next
+#![allow(coherence_leak_check)]
+
+trait Trait: Sized {
+    fn is_higher_ranked(self) -> bool;
+}
+
+impl Trait for for<'a> fn(&'a ()) {
+    fn is_higher_ranked(self) -> bool {
+        true
+    }
+}
+impl<'a> Trait for fn(&'a ()) {
+    fn is_higher_ranked(self) -> bool {
+        false
+    }
+}
+
+fn main() {
+    let x: for<'a> fn(&'a ()) = |&()| ();
+    assert!(x.is_higher_ranked());
+}
diff --git a/tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr
index b7264c7e933..b7264c7e933 100644
--- a/tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr
+++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr
diff --git a/tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr
index 2355979b0f9..2355979b0f9 100644
--- a/tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr
+++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr
diff --git a/tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr
index a73c03feb87..a73c03feb87 100644
--- a/tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr
+++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr
diff --git a/tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr
index 31d36d7168b..31d36d7168b 100644
--- a/tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr
+++ b/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr
diff --git a/tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr
index 269cde54c7e..269cde54c7e 100644
--- a/tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr
+++ b/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr
diff --git a/tests/ui/hr-subtype/hr-subtype.rs b/tests/ui/higher-ranked/subtype/hr-subtype.rs
index c770e0de85c..c770e0de85c 100644
--- a/tests/ui/hr-subtype/hr-subtype.rs
+++ b/tests/ui/higher-ranked/subtype/hr-subtype.rs
diff --git a/tests/ui/hr-subtype/placeholder-pattern-fail.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs
index bd4533e0433..bd4533e0433 100644
--- a/tests/ui/hr-subtype/placeholder-pattern-fail.rs
+++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs
diff --git a/tests/ui/hr-subtype/placeholder-pattern-fail.stderr b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
index 73b0a317364..73b0a317364 100644
--- a/tests/ui/hr-subtype/placeholder-pattern-fail.stderr
+++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
diff --git a/tests/ui/hr-subtype/placeholder-pattern.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern.rs
index 061e66e54d2..061e66e54d2 100644
--- a/tests/ui/hr-subtype/placeholder-pattern.rs
+++ b/tests/ui/higher-ranked/subtype/placeholder-pattern.rs
diff --git a/tests/ui/hr-subtype/return-static.rs b/tests/ui/higher-ranked/subtype/return-static.rs
index 6455854f34d..6455854f34d 100644
--- a/tests/ui/hr-subtype/return-static.rs
+++ b/tests/ui/higher-ranked/subtype/return-static.rs
diff --git a/tests/ui/higher-rank-trait-bounds/complex.rs b/tests/ui/higher-ranked/trait-bounds/complex.rs
index 8cdfe247e02..8cdfe247e02 100644
--- a/tests/ui/higher-rank-trait-bounds/complex.rs
+++ b/tests/ui/higher-ranked/trait-bounds/complex.rs
diff --git a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs
index 1afd15613b5..1afd15613b5 100644
--- a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs
+++ b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs
diff --git a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr
index 520938a6335..520938a6335 100644
--- a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr b/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr
index 9af6bc45c7a..9af6bc45c7a 100644
--- a/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/fn-ptr.rs b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs
index 853160f9612..853160f9612 100644
--- a/tests/ui/higher-rank-trait-bounds/fn-ptr.rs
+++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs
index d34b7a29623..d34b7a29623 100644
--- a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
index 3662cbfb9ba..a9d649b8285 100644
--- a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
@@ -14,7 +14,7 @@ LL |       f
    |       ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&...)))`, found `&dyn Fn(u32)`
    |
    = note: expected reference `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...)))))))))))`
-           the full type name has been written to '$TEST_BUILD_DIR/higher-rank-trait-bounds/hang-on-deeply-nested-dyn/hang-on-deeply-nested-dyn.long-type-hash.txt'
+           the full type name has been written to '$TEST_BUILD_DIR/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn/hang-on-deeply-nested-dyn.long-type-hash.txt'
               found reference `&dyn Fn(u32)`
 
 error: aborting due to previous error
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs
index cc766c0605c..cc766c0605c 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs
index a20d03c7747..a20d03c7747 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr
index f014eab8601..f014eab8601 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs
index e83686404a3..e83686404a3 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr
index 46f5308dd87..46f5308dd87 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs
index 05d3e1a434e..05d3e1a434e 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr
index fa391ecba8a..fa391ecba8a 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs
index 8431226a3ec..8431226a3ec 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs
index 56780237618..56780237618 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr
index 9914783d976..9914783d976 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs
index 921061916fc..921061916fc 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr
index 364b613fc77..364b613fc77 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs
index f95496a6c3c..f95496a6c3c 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs
index 9b9e4496a87..9b9e4496a87 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr
index cb2ce8a4116..cb2ce8a4116 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs
index ff84ad9d298..ff84ad9d298 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs
index afab9986ce2..afab9986ce2 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs
index f9ae1429ee4..f9ae1429ee4 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
index b1b8ffa8c54..b1b8ffa8c54 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
index 48ebe5017aa..48ebe5017aa 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
index 7f96909b6e7..7f96909b6e7 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs
index 89fc4705a78..89fc4705a78 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr
index 25af011e3fc..25af011e3fc 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs
index 8fb4218f8a4..8fb4218f8a4 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr
index 31e11e12835..31e11e12835 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs
index 4b096be591a..4b096be591a 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr
index e8f6d63b5ab..e8f6d63b5ab 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs
index 04519f11600..04519f11600 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-parse.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs
index 1fab9758c5c..1fab9758c5c 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-parse.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr
index a94c80eb30b..a94c80eb30b 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs
index d45fa183c0c..d45fa183c0c 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr
index 727b9e6bec8..727b9e6bec8 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs
index 42247798f66..42247798f66 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs
index 6834c392d4e..6834c392d4e 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs
index b97fdf4df50..b97fdf4df50 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs
index d8c726cdd71..d8c726cdd71 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs
index 41ebb3f5a14..41ebb3f5a14 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs
index 88d396101db..88d396101db 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs
index a4a8a5ac6cc..a4a8a5ac6cc 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs
index 1a9bb252340..1a9bb252340 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs
diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr
index 765ea9f7854..765ea9f7854 100644
--- a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/issue-100689.rs b/tests/ui/higher-ranked/trait-bounds/issue-100689.rs
index 2db7f8a354c..2db7f8a354c 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-100689.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-100689.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-102899.rs b/tests/ui/higher-ranked/trait-bounds/issue-102899.rs
index 952b81584f3..952b81584f3 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-102899.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-102899.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-30786.rs b/tests/ui/higher-ranked/trait-bounds/issue-30786.rs
index 4a6399c8f62..4a6399c8f62 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-30786.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-30786.stderr b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
index 6ec34d11a7e..f32ba57200d 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-30786.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
@@ -31,7 +31,7 @@ LL | pub struct Filter<S, F> {
 LL |     let count = filter.countx();
    |                        ^^^^^^ method cannot be called due to unsatisfied trait bounds
    |
-   = note: the full type name has been written to '$TEST_BUILD_DIR/higher-rank-trait-bounds/issue-30786/issue-30786.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/higher-ranked/trait-bounds/issue-30786/issue-30786.long-type-hash.txt'
 note: the following trait bounds were not satisfied:
       `&'a mut &Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream`
       `&'a mut &mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream`
diff --git a/tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs b/tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs
index 2d49151ffcc..2d49151ffcc 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-39292.rs b/tests/ui/higher-ranked/trait-bounds/issue-39292.rs
index 968cf08916f..968cf08916f 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-39292.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-39292.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-42114.rs b/tests/ui/higher-ranked/trait-bounds/issue-42114.rs
index 01515fdc9d2..01515fdc9d2 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-42114.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-42114.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-43623.rs b/tests/ui/higher-ranked/trait-bounds/issue-43623.rs
index cedcf7c361c..cedcf7c361c 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-43623.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-43623.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-46989.rs b/tests/ui/higher-ranked/trait-bounds/issue-46989.rs
index 4a09f4be156..4a09f4be156 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-46989.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-46989.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-46989.stderr b/tests/ui/higher-ranked/trait-bounds/issue-46989.stderr
index 3f874220a27..3f874220a27 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-46989.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-46989.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/issue-57639.rs b/tests/ui/higher-ranked/trait-bounds/issue-57639.rs
index 392e7233b56..392e7233b56 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-57639.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-57639.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-58451.rs b/tests/ui/higher-ranked/trait-bounds/issue-58451.rs
index 6006a108c5c..6006a108c5c 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-58451.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-58451.stderr b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr
index 0f051be2128..0f051be2128 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-58451.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/issue-59311.rs b/tests/ui/higher-ranked/trait-bounds/issue-59311.rs
index 3ad548450e5..3ad548450e5 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-59311.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr
index c01ab8e347c..c01ab8e347c 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-59311.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/issue-60283.rs b/tests/ui/higher-ranked/trait-bounds/issue-60283.rs
index 05315b3f9f5..05315b3f9f5 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-60283.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-60283.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs
index e70f6fc3430..e70f6fc3430 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr
index 4d470ae7022..4d470ae7022 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/issue-88446.rs b/tests/ui/higher-ranked/trait-bounds/issue-88446.rs
index 571b8531757..571b8531757 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-88446.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-88446.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs b/tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs
index 92b7c5deb81..92b7c5deb81 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-90177.rs b/tests/ui/higher-ranked/trait-bounds/issue-90177.rs
index b151a9d3ab6..b151a9d3ab6 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-90177.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-90177.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-95034.rs b/tests/ui/higher-ranked/trait-bounds/issue-95034.rs
index af4946a187f..af4946a187f 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-95034.rs
+++ b/tests/ui/higher-ranked/trait-bounds/issue-95034.rs
diff --git a/tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr b/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr
index d4bc5b67220..d4bc5b67220 100644
--- a/tests/ui/higher-rank-trait-bounds/issue-95230.new.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs
new file mode 100644
index 00000000000..49a1584d54e
--- /dev/null
+++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs
@@ -0,0 +1,11 @@
+// revisions: old next
+//[next] compile-flags: -Ztrait-solver=next
+//[old] check-pass
+//[next] known-bug: #109764
+
+
+pub struct Bar
+where
+    for<'a> &'a mut Self:;
+
+fn main() {}
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs
index f255eac0c4b..f255eac0c4b 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs
index 4d38cb19e9b..4d38cb19e9b 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs
index c6f29fa5908..c6f29fa5908 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs
index 00205473291..00205473291 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs
index d84e30f4984..d84e30f4984 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr
index b30dd36d2ad..b30dd36d2ad 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs
index 8c2a59868ca..8c2a59868ca 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs
index 03f257a029c..03f257a029c 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs
index 74a4785e478..74a4785e478 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs
index 3ced40230f0..3ced40230f0 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr
index 0f38f8e3283..0f38f8e3283 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs
index 1d90226a3f4..1d90226a3f4 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr
index 4ef96cd9541..4ef96cd9541 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs
index 93ccb42684c..93ccb42684c 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs
index 583470080a2..583470080a2 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs
index 00a866f220b..00a866f220b 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs
index 6316ceea156..6316ceea156 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs
index f6ab9c203b5..f6ab9c203b5 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs
index 8aa29926d4f..8aa29926d4f 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr
index 3240518fbbe..3240518fbbe 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs
index fffb54f86ca..fffb54f86ca 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr
index edef6ccd34e..edef6ccd34e 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs
index f7e467b3786..f7e467b3786 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs
index effc329456d..effc329456d 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs
index 628b5cba104..628b5cba104 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs
index ffd6857d84a..ffd6857d84a 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
index ab9d9a7ce6f..ab9d9a7ce6f 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr
index 5be33bccdc3..5be33bccdc3 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
index 7693b118247..7693b118247 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
index 73388a72574..73388a72574 100644
--- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
diff --git a/tests/ui/impl-trait/autoderef.rs b/tests/ui/impl-trait/autoderef.rs
index 5e4f4995447..0d07a549640 100644
--- a/tests/ui/impl-trait/autoderef.rs
+++ b/tests/ui/impl-trait/autoderef.rs
@@ -1,3 +1,5 @@
+// revisions: current next
+//[next] compile-flag: -Ztrait-solver=next
 // check-pass
 
 use std::path::Path;
diff --git a/tests/ui/lint/invalid_from_utf8.rs b/tests/ui/lint/invalid_from_utf8.rs
new file mode 100644
index 00000000000..9c8c636812e
--- /dev/null
+++ b/tests/ui/lint/invalid_from_utf8.rs
@@ -0,0 +1,93 @@
+// check-pass
+
+#![feature(concat_bytes)]
+#![warn(invalid_from_utf8_unchecked)]
+#![warn(invalid_from_utf8)]
+
+pub fn from_utf8_unchecked_mut() {
+    // Valid
+    unsafe {
+        std::str::from_utf8_unchecked_mut(&mut [99, 108, 105, 112, 112, 121]);
+        std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'i', b'p', b'p', b'y']);
+
+        let x = 0xA0;
+        std::str::from_utf8_unchecked_mut(&mut [0xC0, x]);
+    }
+
+    // Invalid
+    unsafe {
+        std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
+        //~^ WARN calls to `std::str::from_utf8_unchecked_mut`
+        std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+        //~^ WARN calls to `std::str::from_utf8_unchecked_mut`
+    }
+}
+
+pub fn from_utf8_unchecked() {
+    // Valid
+    unsafe {
+        std::str::from_utf8_unchecked(&[99, 108, 105, 112, 112, 121]);
+        std::str::from_utf8_unchecked(&[b'c', b'l', b'i', b'p', b'p', b'y']);
+        std::str::from_utf8_unchecked(b"clippy");
+
+        let x = 0xA0;
+        std::str::from_utf8_unchecked(&[0xC0, x]);
+    }
+
+    // Invalid
+    unsafe {
+        std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
+        //~^ WARN calls to `std::str::from_utf8_unchecked`
+        std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+        //~^ WARN calls to `std::str::from_utf8_unchecked`
+        std::str::from_utf8_unchecked(b"cl\x82ippy");
+        //~^ WARN calls to `std::str::from_utf8_unchecked`
+        std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
+        //~^ WARN calls to `std::str::from_utf8_unchecked`
+    }
+}
+
+pub fn from_utf8_mut() {
+    // Valid
+    {
+        std::str::from_utf8_mut(&mut [99, 108, 105, 112, 112, 121]);
+        std::str::from_utf8_mut(&mut [b'c', b'l', b'i', b'p', b'p', b'y']);
+
+        let x = 0xa0;
+        std::str::from_utf8_mut(&mut [0xc0, x]);
+    }
+
+    // Invalid
+    {
+        std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
+        //~^ WARN calls to `std::str::from_utf8_mut`
+        std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+        //~^ WARN calls to `std::str::from_utf8_mut`
+    }
+}
+
+pub fn from_utf8() {
+    // Valid
+    {
+        std::str::from_utf8(&[99, 108, 105, 112, 112, 121]);
+        std::str::from_utf8(&[b'c', b'l', b'i', b'p', b'p', b'y']);
+        std::str::from_utf8(b"clippy");
+
+        let x = 0xA0;
+        std::str::from_utf8(&[0xC0, x]);
+    }
+
+    // Invalid
+    {
+        std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
+        //~^ WARN calls to `std::str::from_utf8`
+        std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+        //~^ WARN calls to `std::str::from_utf8`
+        std::str::from_utf8(b"cl\x82ippy");
+        //~^ WARN calls to `std::str::from_utf8`
+        std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
+        //~^ WARN calls to `std::str::from_utf8`
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/invalid_from_utf8.stderr b/tests/ui/lint/invalid_from_utf8.stderr
new file mode 100644
index 00000000000..8e00d3bf872
--- /dev/null
+++ b/tests/ui/lint/invalid_from_utf8.stderr
@@ -0,0 +1,110 @@
+warning: calls to `std::str::from_utf8_unchecked_mut` with a invalid literal are undefined behavior
+  --> $DIR/invalid_from_utf8.rs:19:9
+   |
+LL |         std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------^
+   |                                           |
+   |                                           the literal was valid UTF-8 up to the 2 bytes
+   |
+note: the lint level is defined here
+  --> $DIR/invalid_from_utf8.rs:4:9
+   |
+LL | #![warn(invalid_from_utf8_unchecked)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: calls to `std::str::from_utf8_unchecked_mut` with a invalid literal are undefined behavior
+  --> $DIR/invalid_from_utf8.rs:21:9
+   |
+LL |         std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------------------^
+   |                                           |
+   |                                           the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior
+  --> $DIR/invalid_from_utf8.rs:39:9
+   |
+LL |         std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^
+   |                                       |
+   |                                       the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior
+  --> $DIR/invalid_from_utf8.rs:41:9
+   |
+LL |         std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------------------^
+   |                                       |
+   |                                       the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior
+  --> $DIR/invalid_from_utf8.rs:43:9
+   |
+LL |         std::str::from_utf8_unchecked(b"cl\x82ippy");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^
+   |                                       |
+   |                                       the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior
+  --> $DIR/invalid_from_utf8.rs:45:9
+   |
+LL |         std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^
+   |                                       |
+   |                                       the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8_mut` with a invalid literal always return an error
+  --> $DIR/invalid_from_utf8.rs:62:9
+   |
+LL |         std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------^
+   |                                 |
+   |                                 the literal was valid UTF-8 up to the 2 bytes
+   |
+note: the lint level is defined here
+  --> $DIR/invalid_from_utf8.rs:5:9
+   |
+LL | #![warn(invalid_from_utf8)]
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: calls to `std::str::from_utf8_mut` with a invalid literal always return an error
+  --> $DIR/invalid_from_utf8.rs:64:9
+   |
+LL |         std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------------------^
+   |                                 |
+   |                                 the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8` with a invalid literal always return an error
+  --> $DIR/invalid_from_utf8.rs:82:9
+   |
+LL |         std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
+   |         ^^^^^^^^^^^^^^^^^^^^-----------------------------------^
+   |                             |
+   |                             the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8` with a invalid literal always return an error
+  --> $DIR/invalid_from_utf8.rs:84:9
+   |
+LL |         std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
+   |         ^^^^^^^^^^^^^^^^^^^^----------------------------------------------^
+   |                             |
+   |                             the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8` with a invalid literal always return an error
+  --> $DIR/invalid_from_utf8.rs:86:9
+   |
+LL |         std::str::from_utf8(b"cl\x82ippy");
+   |         ^^^^^^^^^^^^^^^^^^^^-------------^
+   |                             |
+   |                             the literal was valid UTF-8 up to the 2 bytes
+
+warning: calls to `std::str::from_utf8` with a invalid literal always return an error
+  --> $DIR/invalid_from_utf8.rs:88:9
+   |
+LL |         std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
+   |         ^^^^^^^^^^^^^^^^^^^^---------------------------------^
+   |                             |
+   |                             the literal was valid UTF-8 up to the 2 bytes
+
+warning: 12 warnings emitted
+
diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr
index 154f2fcbee0..d0bd5b46cf5 100644
--- a/tests/ui/mismatched_types/E0053.stderr
+++ b/tests/ui/mismatched_types/E0053.stderr
@@ -22,7 +22,7 @@ LL |     fn bar(&mut self) { }
    |            ^^^^^^^^^
    |            |
    |            types differ in mutability
-   |            help: change the self-receiver type to match the trait: `self: &Bar`
+   |            help: change the self-receiver type to match the trait: `&self`
    |
 note: type in trait
   --> $DIR/E0053.rs:3:12
diff --git a/tests/ui/mismatched_types/issue-112036.rs b/tests/ui/mismatched_types/issue-112036.rs
new file mode 100644
index 00000000000..e63471e9747
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-112036.rs
@@ -0,0 +1,7 @@
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(self) {} //~ ERROR method `drop` has an incompatible type for trait
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr
new file mode 100644
index 00000000000..a883aba35bf
--- /dev/null
+++ b/tests/ui/mismatched_types/issue-112036.stderr
@@ -0,0 +1,15 @@
+error[E0053]: method `drop` has an incompatible type for trait
+  --> $DIR/issue-112036.rs:4:13
+   |
+LL |     fn drop(self) {}
+   |             ^^^^
+   |             |
+   |             expected `&mut Foo`, found `Foo`
+   |             help: change the self-receiver type to match the trait: `&mut self`
+   |
+   = note: expected signature `fn(&mut Foo)`
+              found signature `fn(Foo)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
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/issue-94866.rs b/tests/ui/pattern/issue-94866.rs
index c4203487936..c4203487936 100644
--- a/tests/ui/issue-94866.rs
+++ b/tests/ui/pattern/issue-94866.rs
diff --git a/tests/ui/issue-94866.stderr b/tests/ui/pattern/issue-94866.stderr
index b3c17ce8974..b3c17ce8974 100644
--- a/tests/ui/issue-94866.stderr
+++ b/tests/ui/pattern/issue-94866.stderr
diff --git a/tests/ui/process/process-panic-after-fork.rs b/tests/ui/process/process-panic-after-fork.rs
index da268312173..7c2fc296bb0 100644
--- a/tests/ui/process/process-panic-after-fork.rs
+++ b/tests/ui/process/process-panic-after-fork.rs
@@ -11,6 +11,8 @@
 #![feature(never_type)]
 #![feature(panic_always_abort)]
 
+#![allow(invalid_from_utf8)]
+
 extern crate libc;
 
 use std::alloc::{GlobalAlloc, Layout};
diff --git a/tests/ui/issues/issue-3008-1.rs b/tests/ui/structs-enums/issue-3008-1.rs
index 1124969e6d0..1124969e6d0 100644
--- a/tests/ui/issues/issue-3008-1.rs
+++ b/tests/ui/structs-enums/issue-3008-1.rs
diff --git a/tests/ui/issues/issue-3008-1.stderr b/tests/ui/structs-enums/issue-3008-1.stderr
index be25b9091d5..be25b9091d5 100644
--- a/tests/ui/issues/issue-3008-1.stderr
+++ b/tests/ui/structs-enums/issue-3008-1.stderr
diff --git a/tests/ui/issues/issue-3008-2.rs b/tests/ui/structs-enums/issue-3008-2.rs
index 5846c69da41..5846c69da41 100644
--- a/tests/ui/issues/issue-3008-2.rs
+++ b/tests/ui/structs-enums/issue-3008-2.rs
diff --git a/tests/ui/issues/issue-3008-2.stderr b/tests/ui/structs-enums/issue-3008-2.stderr
index 858a8fd6af8..858a8fd6af8 100644
--- a/tests/ui/issues/issue-3008-2.stderr
+++ b/tests/ui/structs-enums/issue-3008-2.stderr
diff --git a/tests/ui/issues/issue-3008-3.rs b/tests/ui/structs-enums/issue-3008-3.rs
index 212eb2eb8e0..212eb2eb8e0 100644
--- a/tests/ui/issues/issue-3008-3.rs
+++ b/tests/ui/structs-enums/issue-3008-3.rs
diff --git a/tests/ui/issues/issue-3008-3.stderr b/tests/ui/structs-enums/issue-3008-3.stderr
index a1a81e29367..a1a81e29367 100644
--- a/tests/ui/issues/issue-3008-3.stderr
+++ b/tests/ui/structs-enums/issue-3008-3.stderr
diff --git a/tests/ui/suggestions/issue-103646.rs b/tests/ui/suggestions/issue-103646.rs
new file mode 100644
index 00000000000..f679640c5dc
--- /dev/null
+++ b/tests/ui/suggestions/issue-103646.rs
@@ -0,0 +1,11 @@
+trait Cat {
+    fn nya() {}
+}
+
+fn uwu<T: Cat>(c: T) {
+    c.nya();
+    //~^ ERROR no method named `nya` found for type parameter `T` in the current scope
+    //~| Suggestion T::nya()
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-103646.stderr b/tests/ui/suggestions/issue-103646.stderr
new file mode 100644
index 00000000000..3ae9813d491
--- /dev/null
+++ b/tests/ui/suggestions/issue-103646.stderr
@@ -0,0 +1,21 @@
+error[E0599]: no method named `nya` found for type parameter `T` in the current scope
+  --> $DIR/issue-103646.rs:6:7
+   |
+LL | fn uwu<T: Cat>(c: T) {
+   |        - method `nya` not found for this type parameter
+LL |     c.nya();
+   |     --^^^--
+   |     | |
+   |     | this is an associated function, not a method
+   |     help: use associated function syntax instead: `T::nya()`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in the trait `Cat`
+  --> $DIR/issue-103646.rs:2:5
+   |
+LL |     fn nya() {}
+   |     ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/thir-print/thir-flat.stdout b/tests/ui/thir-print/thir-flat.stdout
index 9d467f73d09..b0aa44b56aa 100644
--- a/tests/ui/thir-print/thir-flat.stdout
+++ b/tests/ui/thir-print/thir-flat.stdout
@@ -1,7 +1,7 @@
 DefId(0:3 ~ thir_flat[7b97]::main):
 Thir {
     body_type: Fn(
-        ([]; c_variadic: false)->(),
+        fn(),
     ),
     arms: [],
     blocks: [
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/leak-check-coinductive-cycle.rs b/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs
new file mode 100644
index 00000000000..1f7d4a49c90
--- /dev/null
+++ b/tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs
@@ -0,0 +1,33 @@
+// check-pass
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs)]
+
+#[rustc_coinductive]
+trait Trait<T> {}
+impl<'a, 'b, T> Trait<T> for (&'a (), &'b ())
+where
+    'b: 'a,
+    &'a (): Trait<T>,
+{}
+
+impl Trait<i32> for &'static () {}
+impl<'a> Trait<u32> for &'a ()
+where
+    for<'b> (&'a (), &'b ()): Trait<u32>,
+{}
+
+
+fn impls_trait<T: Trait<U>, U>() {}
+
+fn main() {
+    // This infers to `impls_trait::<(&'static (), &'static ()), i32>();`
+    //
+    // In the first attempt we have 2 candidates for `&'a (): Trait<_>`
+    // and we get ambiguity. The result is therefore ambiguity with a `'b: 'a`
+    // constraint. The next attempt then uses that provisional result when
+    // trying to apply `impl<'a> Trait<u32> for &'a ()`. This means we get a
+    // `for<'b> 'b: 'a` bound which fails the leak check. Because of this we
+    // end up with a single impl for `&'a (): Trait<_>` which infers `_` to `i32`
+    // and succeeds.
+    impls_trait::<(&(), &()), _>();
+}
diff --git a/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs
new file mode 100644
index 00000000000..39b3d535ad4
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs
@@ -0,0 +1,25 @@
+// When checking whether these two impls overlap, we could detect that we
+// would require the hidden type of `TAIT` to be equal to both `u32` and `i32`
+// and therefore accept them as disjoint. That is annoying to implement with
+// the current system because we would have to add the following to each
+// returning branch in coherence.
+//
+//    let _ = infcx.take_opaque_types();
+//
+// @lcnr: Because of this I decided to not bother and cause this to fail instead.
+// In the future we can definitely modify the compiler to accept this
+// again.
+#![feature(type_alias_impl_trait)]
+
+trait Trait {}
+
+type TAIT = impl Sized;
+
+impl Trait for (TAIT, TAIT) {}
+
+impl Trait for (u32, i32) {}
+//~^ ERROR conflicting implementations of trait `Trait` for type `(TAIT, TAIT)`
+
+fn define() -> TAIT {}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.stderr b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.stderr
new file mode 100644
index 00000000000..f2aee798608
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `(TAIT, TAIT)`
+  --> $DIR/coherence_different_hidden_ty.rs:20:1
+   |
+LL | impl Trait for (TAIT, TAIT) {}
+   | --------------------------- first implementation here
+LL |
+LL | impl Trait for (u32, i32) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(TAIT, TAIT)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.rs b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
index 5c9ad9498b6..679b2b0f188 100644
--- a/tests/ui/type-alias-impl-trait/coherence_generalization.rs
+++ b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+// FIXME(type_alias_impl_trait): What does this test? This needs a comment
+// explaining what we're worried about here.
 #![feature(type_alias_impl_trait)]
 trait Trait {}
 type Opaque<T> = impl Sized;
diff --git a/tests/ui/typeck/issue-106929.rs b/tests/ui/typeck/issue-106929.rs
new file mode 100644
index 00000000000..91342229ae1
--- /dev/null
+++ b/tests/ui/typeck/issue-106929.rs
@@ -0,0 +1,13 @@
+struct Client;
+
+impl Client {
+    fn post<T: std::ops::Add>(&self, _: T, _: T) {}
+}
+
+fn f() {
+    let c = Client;
+    post(c, ());
+    //~^ ERROR cannot find function `post` in this scope
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/issue-106929.stderr b/tests/ui/typeck/issue-106929.stderr
new file mode 100644
index 00000000000..f744e5a41f0
--- /dev/null
+++ b/tests/ui/typeck/issue-106929.stderr
@@ -0,0 +1,15 @@
+error[E0425]: cannot find function `post` in this scope
+  --> $DIR/issue-106929.rs:9:5
+   |
+LL |     post(c, ());
+   |     ^^^^ not found in this scope
+   |
+help: use the `.` operator to call the method `post` on `&Client`
+   |
+LL -     post(c, ());
+LL +     c.post(());
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/issues/issue-1871.rs b/tests/ui/typeck/issue-1871.rs
index f7a2bdd5659..f7a2bdd5659 100644
--- a/tests/ui/issues/issue-1871.rs
+++ b/tests/ui/typeck/issue-1871.rs
diff --git a/tests/ui/issues/issue-1871.stderr b/tests/ui/typeck/issue-1871.stderr
index b774ca22dd7..b774ca22dd7 100644
--- a/tests/ui/issues/issue-1871.stderr
+++ b/tests/ui/typeck/issue-1871.stderr
diff --git a/tests/ui/issues/issue-2063-resource.rs b/tests/ui/typeck/issue-2063-resource.rs
index 1d0527447ba..1d0527447ba 100644
--- a/tests/ui/issues/issue-2063-resource.rs
+++ b/tests/ui/typeck/issue-2063-resource.rs
diff --git a/tests/ui/issues/issue-2063.rs b/tests/ui/typeck/issue-2063.rs
index f08f9d4cfe4..f08f9d4cfe4 100644
--- a/tests/ui/issues/issue-2063.rs
+++ b/tests/ui/typeck/issue-2063.rs
diff --git a/tests/ui/issues/issue-50825-1.rs b/tests/ui/where-clauses/issue-50825-1.rs
index ee4316029a8..ee4316029a8 100644
--- a/tests/ui/issues/issue-50825-1.rs
+++ b/tests/ui/where-clauses/issue-50825-1.rs
diff --git a/tests/ui/issues/issue-50825.rs b/tests/ui/where-clauses/issue-50825.rs
index 1ece2e9fc84..1ece2e9fc84 100644
--- a/tests/ui/issues/issue-50825.rs
+++ b/tests/ui/where-clauses/issue-50825.rs