about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-07 05:45:07 +0000
committerbors <bors@rust-lang.org>2024-06-07 05:45:07 +0000
commit60f7aabd8e8274950aff8dcf93a71cf9becef606 (patch)
tree2cadc6259056d688361a2af6ab6187d42ed46934
parent56438c397151bba4ba8949755ce1fea002d27cc4 (diff)
parentf0ea91c60f60765fb4effcc05844008810a70b16 (diff)
downloadrust-60f7aabd8e8274950aff8dcf93a71cf9becef606.tar.gz
rust-60f7aabd8e8274950aff8dcf93a71cf9becef606.zip
Auto merge of #3652 - rust-lang:rustup-2024-06-07, r=RalfJung
Automatic Rustup
-rw-r--r--.github/workflows/ci.yml3
-rw-r--r--Cargo.lock148
-rw-r--r--compiler/rustc_ast/src/ast.rs6
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs10
-rw-r--r--compiler/rustc_ast/src/token.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs27
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/messages.ftl5
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs81
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs16
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs11
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cmdline_attrs.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath/tests.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs71
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs4
-rw-r--r--compiler/rustc_const_eval/src/check_consts/qualifs.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs31
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs4
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs10
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0582.md34
-rw-r--r--compiler/rustc_expand/messages.ftl3
-rw-r--r--compiler/rustc_expand/src/base.rs100
-rw-r--r--compiler/rustc_expand/src/build.rs5
-rw-r--r--compiler/rustc_expand/src/errors.rs10
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs1
-rw-r--r--compiler/rustc_expand/src/module.rs5
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs26
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs47
-rw-r--r--compiler/rustc_feature/src/removed.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs6
-rw-r--r--compiler/rustc_hir/src/def.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs14
-rw-r--r--compiler/rustc_hir/src/intravisit.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check/errs.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs138
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs243
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs48
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs52
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs49
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs62
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs167
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs27
-rw-r--r--compiler/rustc_infer/src/infer/canonical/instantiate.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs11
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs4
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs9
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs58
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs20
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs3
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/fudge.rs2
-rw-r--r--compiler/rustc_interface/src/interface.rs6
-rw-r--r--compiler/rustc_interface/src/passes.rs19
-rw-r--r--compiler/rustc_lint/messages.ftl6
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs6
-rw-r--r--compiler/rustc_lint/src/lints.rs15
-rw-r--r--compiler/rustc_lint/src/types.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs86
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs7
-rw-r--r--compiler/rustc_macros/src/query.rs21
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs12
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs12
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs12
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/lib.rs11
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs69
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs26
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs10
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs2
-rw-r--r--compiler/rustc_middle/src/query/erase.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs17
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/abstract_const.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs4
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs177
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs8
-rw-r--r--compiler/rustc_middle/src/ty/context.rs59
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs4
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs7
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs20
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs6
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs12
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs28
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs27
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs17
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs30
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs22
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs4
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs28
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs8
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs87
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs20
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs19
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs110
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs200
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs5
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs82
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs2
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs52
-rw-r--r--compiler/rustc_next_trait_solver/src/resolve.rs7
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs4
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs50
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs75
-rw-r--r--compiler/rustc_parse/src/lib.rs158
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs39
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs22
-rw-r--r--compiler/rustc_passes/src/diagnostic_items.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs21
-rw-r--r--compiler/rustc_passes/src/stability.rs4
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs2
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs3
-rw-r--r--compiler/rustc_resolve/messages.ftl8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs21
-rw-r--r--compiler/rustc_resolve/src/errors.rs17
-rw-r--r--compiler/rustc_resolve/src/ident.rs29
-rw-r--r--compiler/rustc_resolve/src/imports.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs52
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs41
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs14
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs9
-rw-r--r--compiler/rustc_span/src/lib.rs7
-rw-r--r--compiler/rustc_span/src/span_encoding.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_span/src/tests.rs57
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs8
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs67
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs19
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs46
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs9
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs60
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs77
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs68
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs25
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs4
-rw-r--r--compiler/rustc_transmute/src/lib.rs4
-rw-r--r--compiler/rustc_ty_utils/src/consts.rs40
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs55
-rw-r--r--compiler/rustc_type_ir/src/const_kind.rs6
-rw-r--r--compiler/rustc_type_ir/src/debug.rs4
-rw-r--r--compiler/rustc_type_ir/src/fold.rs2
-rw-r--r--compiler/rustc_type_ir/src/infcx.rs7
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs17
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs1
-rw-r--r--library/alloc/src/collections/linked_list.rs4
-rw-r--r--library/alloc/src/collections/linked_list/tests.rs39
-rw-r--r--library/alloc/src/rc.rs2
-rw-r--r--library/alloc/src/sync.rs2
-rw-r--r--library/alloc/tests/vec_deque_alloc_error.rs1
-rw-r--r--library/core/src/cell.rs17
-rw-r--r--library/core/src/intrinsics.rs1
-rw-r--r--library/core/src/iter/adapters/chain.rs37
-rw-r--r--library/core/src/iter/adapters/mod.rs3
-rw-r--r--library/core/src/iter/mod.rs2
-rw-r--r--library/core/src/macros/mod.rs7
-rw-r--r--library/core/src/mem/maybe_uninit.rs17
-rw-r--r--library/core/src/prelude/common.rs3
-rw-r--r--library/core/src/ptr/mod.rs2
-rw-r--r--library/core/src/slice/raw.rs1
-rw-r--r--library/core/src/sync/atomic.rs3
-rw-r--r--library/core/tests/iter/adapters/chain.rs8
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs2
-rw-r--r--library/proc_macro/src/bridge/fxhash.rs1
-rw-r--r--library/std/src/collections/hash/map.rs2
-rw-r--r--library/std/src/io/error/repr_bitpacked.rs1
-rw-r--r--library/std/src/io/stdio.rs5
-rw-r--r--library/std/src/os/unix/net/ancillary.rs2
-rw-r--r--library/std/src/prelude/common.rs3
-rw-r--r--library/std/src/prelude/mod.rs4
-rw-r--r--library/std/src/sync/lazy_lock.rs36
-rw-r--r--library/std/src/sync/mod.rs5
-rw-r--r--library/std/src/sync/once_lock.rs91
-rw-r--r--library/std/src/sys/pal/sgx/thread.rs18
-rw-r--r--library/std/src/sys/pal/uefi/thread.rs2
-rw-r--r--library/std/src/sys/pal/unix/fs.rs22
-rw-r--r--library/std/src/sys/pal/unsupported/thread.rs2
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs2
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs2
-rw-r--r--library/std/src/thread/mod.rs5
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/bootstrap.py18
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs40
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs54
-rw-r--r--src/bootstrap/src/core/config/config.rs19
-rw-r--r--src/bootstrap/src/core/config/tests.rs28
-rw-r--r--src/bootstrap/src/core/download.rs22
-rw-r--r--src/bootstrap/src/core/sanity.rs51
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh2
-rw-r--r--src/ci/github-actions/jobs.yml1
-rwxr-xr-xsrc/ci/publish_toolstate.sh4
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/check-cfg/cargo-specifics.md14
-rw-r--r--src/doc/rustc/src/platform-support.md8
-rw-r--r--src/doc/rustc/src/platform-support/armv4t-none-eabi.md1
-rw-r--r--src/doc/rustc/src/platform-support/fuchsia.md4
-rw-r--r--src/doc/unstable-book/src/compiler-flags/codegen-backend.md5
-rw-r--r--src/librustdoc/clean/inline.rs28
-rw-r--r--src/librustdoc/clean/mod.rs40
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs2
-rw-r--r--src/librustdoc/clean/types.rs10
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/librustdoc/doctest.rs23
-rw-r--r--src/librustdoc/fold.rs2
-rw-r--r--src/librustdoc/formats/cache.rs2
-rw-r--r--src/librustdoc/html/format.rs19
-rw-r--r--src/librustdoc/html/render/print_item.rs17
-rw-r--r--src/librustdoc/json/conversions.rs7
-rw-r--r--src/librustdoc/json/mod.rs2
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs8
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs2
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs8
-rw-r--r--src/librustdoc/scrape_examples.rs2
-rw-r--r--src/librustdoc/visit.rs2
m---------src/llvm-project0
-rw-r--r--src/rustdoc-json-types/lib.rs11
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_arrays.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs6
-rw-r--r--src/tools/compiletest/src/header.rs28
-rw-r--r--src/tools/compiletest/src/runtest.rs24
-rw-r--r--src/tools/jsondoclint/src/item_kind.rs2
-rw-r--r--src/tools/jsondoclint/src/validator.rs9
-rw-r--r--src/tools/libcxx-version/main.cpp26
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/helpers.rs4
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs1
-rw-r--r--src/tools/miri/tests/pass/function_calls/abi_compat.rs16
-rw-r--r--src/tools/opt-dist/src/environment.rs7
-rw-r--r--src/tools/opt-dist/src/main.rs6
-rw-r--r--src/tools/opt-dist/src/training.rs14
-rw-r--r--src/tools/run-make-support/src/cc.rs9
-rw-r--r--src/tools/run-make-support/src/clang.rs6
-rw-r--r--src/tools/run-make-support/src/lib.rs36
-rw-r--r--src/tools/run-make-support/src/llvm_readobj.rs6
-rw-r--r--src/tools/run-make-support/src/run.rs14
-rw-r--r--src/tools/run-make-support/src/rustc.rs11
-rw-r--r--src/tools/run-make-support/src/rustdoc.rs7
-rw-r--r--src/tools/rustbook/Cargo.toml1
-rw-r--r--src/tools/rustbook/src/main.rs13
m---------src/tools/rustc-perf0
-rw-r--r--src/tools/rustdoc-gui-test/src/main.rs4
-rw-r--r--src/tools/rustfmt/src/parse/macros/mod.rs4
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs27
-rw-r--r--src/tools/rustfmt/src/utils.rs1
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt4
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--src/tools/tidy/src/walk.rs1
-rw-r--r--tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs17
-rw-r--r--tests/codegen/riscv-abi/call-llvm-intrinsics.rs2
-rw-r--r--tests/codegen/riscv-abi/riscv64-lp64d-abi.rs25
-rw-r--r--tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs21
-rw-r--r--tests/coverage/closure_macro.cov-map8
-rw-r--r--tests/coverage/closure_macro_async.cov-map8
-rw-r--r--tests/crashes/122908.rs4
-rw-r--r--tests/crashes/124490.rs16
-rw-r--r--tests/crashes/124552.rs12
-rw-r--r--tests/crashes/125013-1.rs5
-rw-r--r--tests/crashes/125013-2.rs16
-rw-r--r--tests/crashes/125556.rs14
-rw-r--r--tests/debuginfo/function-names.rs5
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.32bit.mir2
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.64bit.mir2
-rw-r--r--tests/pretty/hir-fn-variadic.pp2
-rw-r--r--tests/run-make-fulldeps/README.md4
-rw-r--r--tests/run-make-fulldeps/hotplug_codegen_backend/Makefile25
-rw-r--r--tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs2
-rw-r--r--tests/run-make-fulldeps/issue-19371/Makefile9
-rw-r--r--tests/run-make-fulldeps/obtain-borrowck/Makefile26
-rw-r--r--tests/run-make-fulldeps/pretty-expanded/Makefile4
-rw-r--r--tests/run-make-fulldeps/pretty-expanded/input.rs25
-rw-r--r--tests/run-make/alloc-no-oom-handling/rmake.rs4
-rw-r--r--tests/run-make/alloc-no-rc/rmake.rs4
-rw-r--r--tests/run-make/alloc-no-sync/rmake.rs4
-rw-r--r--tests/run-make/compiler-builtins/rmake.rs11
-rw-r--r--tests/run-make/core-no-fp-fmt-parse/rmake.rs4
-rw-r--r--tests/run-make/core-no-oom-handling/rmake.rs4
-rw-r--r--tests/run-make/incr-prev-body-beyond-eof/Makefile19
-rw-r--r--tests/run-make/incr-prev-body-beyond-eof/rmake.rs27
-rw-r--r--tests/run-make/issue-125484-used-dependencies/dependency.rs1
-rw-r--r--tests/run-make/issue-125484-used-dependencies/main.rs9
-rw-r--r--tests/run-make/issue-125484-used-dependencies/rmake.rs18
-rw-r--r--tests/run-make/manual-crate-name/Makefile5
-rw-r--r--tests/run-make/manual-crate-name/rmake.rs6
-rw-r--r--tests/run-make/resolve-rename/Makefile7
-rw-r--r--tests/run-make/resolve-rename/rmake.rs16
-rw-r--r--tests/run-make/rustdoc-scrape-examples-remap/scrape.rs2
-rw-r--r--tests/run-make/rustdoc-themes/rmake.rs4
-rw-r--r--tests/run-make/suspicious-library/Makefile8
-rw-r--r--tests/run-make/suspicious-library/rmake.rs14
-rw-r--r--tests/run-make/windows-binary-no-external-deps/rmake.rs5
-rw-r--r--tests/rustdoc/async-fn.rs2
-rw-r--r--tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html3
-rw-r--r--tests/rustdoc/decl-trailing-whitespace.declaration.html4
-rw-r--r--tests/rustdoc/inline_cross/impl_trait.rs2
-rw-r--r--tests/rustdoc/line-breaks.rs2
-rw-r--r--tests/rustdoc/reexports-priv.rs2
-rw-r--r--tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs (renamed from tests/run-make-fulldeps/obtain-borrowck/test.rs)2
-rw-r--r--tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs (renamed from tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs)6
-rw-r--r--tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout4
-rw-r--r--tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout3
-rw-r--r--tests/ui-fulldeps/codegen-backend/hotplug.normal.stdout1
-rw-r--r--tests/ui-fulldeps/codegen-backend/hotplug.rs20
-rw-r--r--tests/ui-fulldeps/mod_dir_path_canonicalized.rs4
-rw-r--r--tests/ui-fulldeps/obtain-borrowck.rs (renamed from tests/run-make-fulldeps/obtain-borrowck/driver.rs)7
-rw-r--r--tests/ui-fulldeps/obtain-borrowck.run.stdout (renamed from tests/run-make-fulldeps/obtain-borrowck/output.stdout)0
-rw-r--r--tests/ui-fulldeps/pprust-expr-roundtrip.rs7
-rw-r--r--tests/ui-fulldeps/run-compiler-twice.rs (renamed from tests/run-make-fulldeps/issue-19371/foo.rs)38
-rw-r--r--tests/ui/async-await/no-async-const.rs2
-rw-r--r--tests/ui/async-await/no-async-const.stderr4
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr21
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr21
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.rs31
-rw-r--r--tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs3
-rw-r--r--tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr16
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr14
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr14
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/error_in_ty.rs21
-rw-r--r--tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr45
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.rs5
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-71381.full.stderr18
-rw-r--r--tests/ui/const-generics/issues/issue-71381.min.stderr20
-rw-r--r--tests/ui/const-generics/issues/issue-71381.rs1
-rw-r--r--tests/ui/const-generics/not_wf_param_in_rpitit.rs14
-rw-r--r--tests/ui/const-generics/not_wf_param_in_rpitit.stderr113
-rw-r--r--tests/ui/const-generics/transmute-fail.stderr2
-rw-r--r--tests/ui/const-generics/type_not_in_scope.rs3
-rw-r--r--tests/ui/const-generics/type_not_in_scope.stderr14
-rw-r--r--tests/ui/consts/issue-103790.rs2
-rw-r--r--tests/ui/consts/issue-103790.stderr27
-rw-r--r--tests/ui/coroutine/async_gen_fn.none.stderr4
-rw-r--r--tests/ui/coroutine/async_gen_fn.rs2
-rw-r--r--tests/ui/coroutine/gen_fn.none.stderr4
-rw-r--r--tests/ui/coroutine/gen_fn.rs2
-rw-r--r--tests/ui/cross-crate/auxiliary/static_init_aux.rs6
-rw-r--r--tests/ui/cross-crate/static-init.rs2
-rw-r--r--tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs1
-rw-r--r--tests/ui/derives/derive-hrtb-for-bare-fn-field-with-lifetime.rs13
-rw-r--r--tests/ui/extern-flag/empty-extern-arg.stderr9
-rw-r--r--tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs14
-rw-r--r--tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr49
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs5
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr8
-rw-r--r--tests/ui/impl-header-lifetime-elision/assoc-type.rs2
-rw-r--r--tests/ui/impl-header-lifetime-elision/assoc-type.stderr4
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs38
-rw-r--r--tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr15
-rw-r--r--tests/ui/imports/cycle-import-in-diff-module-0.rs14
-rw-r--r--tests/ui/imports/cycle-import-in-diff-module-1.rs14
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-1.rs17
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-1.stderr23
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-2.rs19
-rw-r--r--tests/ui/imports/shadow-glob-module-resolution-2.stderr26
-rw-r--r--tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr4
-rw-r--r--tests/ui/issues/issue-28344.stderr2
-rw-r--r--tests/ui/issues/issue-53498.rs17
-rw-r--r--tests/ui/lifetimes/no_lending_iterators.rs35
-rw-r--r--tests/ui/lifetimes/no_lending_iterators.stderr30
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.rs15
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.stderr10
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs15
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs39
-rw-r--r--tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr160
-rw-r--r--tests/ui/match/ref_pat_everywhere-fail.rs12
-rw-r--r--tests/ui/match/ref_pat_everywhere-fail.stderr38
-rw-r--r--tests/ui/match/ref_pat_everywhere.rs24
-rw-r--r--tests/ui/parser/duplicate-visibility.rs4
-rw-r--r--tests/ui/parser/duplicate-visibility.stderr4
-rw-r--r--tests/ui/parser/fn-header-semantic-fail.rs7
-rw-r--r--tests/ui/parser/fn-header-semantic-fail.stderr14
-rw-r--r--tests/ui/parser/issues/issue-76437-async.rs2
-rw-r--r--tests/ui/parser/issues/issue-76437-async.stderr4
-rw-r--r--tests/ui/parser/issues/issue-76437-const-async.rs2
-rw-r--r--tests/ui/parser/issues/issue-76437-const-async.stderr4
-rw-r--r--tests/ui/parser/issues/issue-76437-const.rs2
-rw-r--r--tests/ui/parser/issues/issue-76437-const.stderr4
-rw-r--r--tests/ui/parser/issues/issue-86895.rs2
-rw-r--r--tests/ui/parser/issues/issue-86895.stderr4
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs4
-rw-r--r--tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr4
-rw-r--r--tests/ui/parser/issues/issue-87694-duplicated-pub.rs4
-rw-r--r--tests/ui/parser/issues/issue-87694-duplicated-pub.stderr4
-rw-r--r--tests/ui/parser/issues/issue-87694-misplaced-pub.rs4
-rw-r--r--tests/ui/parser/issues/issue-87694-misplaced-pub.stderr4
-rw-r--r--tests/ui/parser/no-const-fn-in-extern-block.rs2
-rw-r--r--tests/ui/parser/no-const-fn-in-extern-block.stderr8
-rw-r--r--tests/ui/parser/unsafe-foreign-mod-2.rs6
-rw-r--r--tests/ui/parser/unsafe-foreign-mod-2.stderr6
-rw-r--r--tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs14
-rw-r--r--tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr31
-rw-r--r--tests/ui/pattern/match_ergonomics_2024.fixed2
-rw-r--r--tests/ui/pattern/match_ergonomics_2024.rs2
-rw-r--r--tests/ui/pattern/mut_preserve_binding_mode_2021.rs2
-rw-r--r--tests/ui/pattern/mut_preserve_binding_mode_2024.rs2
-rw-r--r--tests/ui/pattern/no_ref_mut_behind_and.rs9
-rw-r--r--tests/ui/privacy/ufc-method-call.different_name.stderr15
-rw-r--r--tests/ui/privacy/ufc-method-call.rs30
-rw-r--r--tests/ui/privacy/ufc-method-call.same_name.stderr (renamed from tests/ui/issues/issue-53498.stderr)2
-rw-r--r--tests/ui/privacy/where-priv-type.rs45
-rw-r--r--tests/ui/privacy/where-priv-type.stderr26
-rw-r--r--tests/ui/proc-macro/pretty-print-hack-show.local.stderr183
-rw-r--r--tests/ui/proc-macro/pretty-print-hack-show.local.stdout44
-rw-r--r--tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr183
-rw-r--r--tests/ui/proc-macro/pretty-print-hack-show.remapped.stdout44
-rw-r--r--tests/ui/resolve/filter-intrinsics.rs4
-rw-r--r--tests/ui/resolve/filter-intrinsics.stderr8
-rw-r--r--tests/ui/resolve/issue-82865.stderr7
-rw-r--r--tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs6
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr32
-rw-r--r--tests/ui/rust-2024/unsafe-env.e2021.stderr27
-rw-r--r--tests/ui/rust-2024/unsafe-env.e2024.stderr49
-rw-r--r--tests/ui/rust-2024/unsafe-env.rs12
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr19
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr19
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs25
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr12
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs20
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs18
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr20
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr32
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs20
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.fixed19
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.rs19
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr25
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr19
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr19
-rw-r--r--tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs25
-rw-r--r--tests/ui/specialization/dont-drop-upcast-candidate.rs13
-rw-r--r--tests/ui/specialization/dont-drop-upcast-candidate.stderr11
-rw-r--r--tests/ui/static/duplicated-fields-issue-124464.rs (renamed from tests/crashes/124464.rs)6
-rw-r--r--tests/ui/static/duplicated-fields-issue-124464.stderr22
-rw-r--r--tests/ui/static/duplicated-fields-issue-125842.rs21
-rw-r--r--tests/ui/static/duplicated-fields-issue-125842.stderr11
-rw-r--r--tests/ui/traits/item-privacy.stderr9
-rw-r--r--tests/ui/traits/next-solver/generalize/bivariant-alias.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.classic.stderr (renamed from tests/ui/type-alias-impl-trait/coherence.stderr)2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.next.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/const_generic_type.rs4
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.rs5
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.stdout5
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs27
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr44
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs16
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr93
-rw-r--r--triagebot.toml2
518 files changed, 5023 insertions, 3782 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c9d6c56076a..d2d4a7e3d42 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -38,6 +38,8 @@ concurrency:
   cancel-in-progress: true
 env:
   TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
+  # This will be empty in PR jobs.
+  TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
 jobs:
   # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml.
   # It calculates which jobs should be executed, based on the data of the ${{ github }} context.
@@ -242,6 +244,5 @@ jobs:
         shell: bash
         if: needs.calculate_matrix.outputs.run_type == 'auto'
         env:
-          TOOLSTATE_REPO_ACCESS_TOKEN: ${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}
           TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/rust-lang/rust/issues
           TOOLSTATE_PUBLISH: 1
diff --git a/Cargo.lock b/Cargo.lock
index 1018eac13ff..0e950e28807 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -372,7 +372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
 dependencies = [
  "memchr",
- "regex-automata 0.3.9",
+ "regex-automata 0.3.7",
  "serde",
 ]
 
@@ -2207,6 +2207,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "line-wrap"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e"
+
+[[package]]
+name = "linereader"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d921fea6860357575519aca014c6e22470585accdd543b370c404a8a72d0dd1d"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "linkchecker"
 version = "0.1.0"
 dependencies = [
@@ -2215,6 +2230,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "linked-hash-map"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+
+[[package]]
 name = "lint-docs"
 version = "0.1.0"
 dependencies = [
@@ -2365,6 +2386,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "mdbook-i18n-helpers"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1f71f5961d6f3376e1ff3e5989c2e3ecccc3e8a00f3a3acde446847f84852e4"
+dependencies = [
+ "anyhow",
+ "chrono",
+ "mdbook",
+ "polib",
+ "pulldown-cmark 0.10.3",
+ "pulldown-cmark-to-cmark",
+ "regex",
+ "semver",
+ "serde_json",
+ "syntect",
+ "textwrap",
+]
+
+[[package]]
 name = "mdbook-trpl-listing"
 version = "0.1.0"
 dependencies = [
@@ -2651,6 +2691,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
 
 [[package]]
+name = "onig"
+version = "6.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
+dependencies = [
+ "bitflags 1.3.2",
+ "libc",
+ "once_cell",
+ "onig_sys",
+]
+
+[[package]]
+name = "onig_sys"
+version = "69.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
+dependencies = [
+ "cc",
+ "pkg-config",
+]
+
+[[package]]
 name = "opener"
 version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2969,6 +3031,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
 
 [[package]]
+name = "plist"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9"
+dependencies = [
+ "base64",
+ "indexmap",
+ "line-wrap",
+ "quick-xml",
+ "serde",
+ "time",
+]
+
+[[package]]
+name = "polib"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b393b155cf9be86249cba1b56cc81be0e6212c66d94ac0d76d37a1761f3bb1b"
+dependencies = [
+ "linereader",
+]
+
+[[package]]
 name = "polonius-engine"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3127,6 +3212,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e9e1dcb320d6839f6edb64f7a4a59d39b30480d4d1765b56873f7c858538a5fe"
 
 [[package]]
+name = "quick-xml"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "quine-mc_cluskey"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3261,12 +3355,13 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.8.4"
+version = "1.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
+checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
 dependencies = [
  "aho-corasick",
  "memchr",
+ "regex-automata 0.3.7",
  "regex-syntax 0.7.5",
 ]
 
@@ -3290,9 +3385,14 @@ dependencies = [
 
 [[package]]
 name = "regex-automata"
-version = "0.3.9"
+version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
+checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.7.5",
+]
 
 [[package]]
 name = "regex-lite"
@@ -3367,6 +3467,7 @@ dependencies = [
  "clap",
  "env_logger",
  "mdbook",
+ "mdbook-i18n-helpers",
  "mdbook-trpl-listing",
  "mdbook-trpl-note",
 ]
@@ -5373,6 +5474,28 @@ dependencies = [
 ]
 
 [[package]]
+name = "syntect"
+version = "5.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
+dependencies = [
+ "bincode",
+ "bitflags 1.3.2",
+ "flate2",
+ "fnv",
+ "once_cell",
+ "onig",
+ "plist",
+ "regex-syntax 0.8.3",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "thiserror",
+ "walkdir",
+ "yaml-rust",
+]
+
+[[package]]
 name = "sysinfo"
 version = "0.30.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5498,6 +5621,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "textwrap"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
+
+[[package]]
 name = "thin-vec"
 version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6477,6 +6606,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "yaml-rust"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
 name = "yansi-term"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 7a45d909d07..910fbb87697 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2501,6 +2501,8 @@ pub enum IsAuto {
 pub enum Safety {
     /// `unsafe` an item is explicitly marked as `unsafe`.
     Unsafe(Span),
+    /// `safe` an item is explicitly marked as `safe`.
+    Safe(Span),
     /// Default means no value was provided, it will take a default value given the context in
     /// which is used.
     Default,
@@ -3162,6 +3164,7 @@ pub struct DelegationMac {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct StaticItem {
     pub ty: P<Ty>,
+    pub safety: Safety,
     pub mutability: Mutability,
     pub expr: Option<P<Expr>>,
 }
@@ -3171,6 +3174,7 @@ pub struct StaticItem {
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct StaticForeignItem {
     pub ty: P<Ty>,
+    pub safety: Safety,
     pub mutability: Mutability,
     pub expr: Option<P<Expr>>,
 }
@@ -3179,6 +3183,7 @@ impl From<StaticItem> for StaticForeignItem {
     fn from(static_item: StaticItem) -> StaticForeignItem {
         StaticForeignItem {
             ty: static_item.ty,
+            safety: static_item.safety,
             mutability: static_item.mutability,
             expr: static_item.expr,
         }
@@ -3189,6 +3194,7 @@ impl From<StaticForeignItem> for StaticItem {
     fn from(static_item: StaticForeignItem) -> StaticItem {
         StaticItem {
             ty: static_item.ty,
+            safety: static_item.safety,
             mutability: static_item.mutability,
             expr: static_item.expr,
         }
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 5c581c270e4..a04c648ac73 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -862,6 +862,7 @@ fn visit_defaultness<T: MutVisitor>(defaultness: &mut Defaultness, vis: &mut T)
 fn visit_safety<T: MutVisitor>(safety: &mut Safety, vis: &mut T) {
     match safety {
         Safety::Unsafe(span) => vis.visit_span(span),
+        Safety::Safe(span) => vis.visit_span(span),
         Safety::Default => {}
     }
 }
@@ -1079,7 +1080,7 @@ impl NoopVisitItemKind for ItemKind {
         match self {
             ItemKind::ExternCrate(_orig_name) => {}
             ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
-            ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
+            ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
                 vis.visit_ty(ty);
                 visit_opt(expr, |expr| vis.visit_expr(expr));
             }
@@ -1289,7 +1290,12 @@ pub fn noop_flat_map_item<K: NoopVisitItemKind>(
 impl NoopVisitItemKind for ForeignItemKind {
     fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
         match self {
-            ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
+            ForeignItemKind::Static(box StaticForeignItem {
+                ty,
+                mutability: _,
+                expr,
+                safety: _,
+            }) => {
                 visitor.visit_ty(ty);
                 visit_opt(expr, |expr| visitor.visit_expr(expr));
             }
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 099a6096d0b..109c401bb6a 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -210,6 +210,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: IdentIsRaw) -> boo
             kw::Unsafe,
             kw::While,
             kw::Yield,
+            kw::Safe,
             kw::Static,
         ]
         .contains(&name)
@@ -577,6 +578,7 @@ impl Token {
                 kw::Impl,
                 kw::Unsafe,
                 kw::Const,
+                kw::Safe,
                 kw::Static,
                 kw::Union,
                 kw::Macro,
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index b2f3b27c77e..de285aed165 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -334,7 +334,7 @@ impl WalkItemKind for ItemKind {
         match self {
             ItemKind::ExternCrate(_) => {}
             ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
-            ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
+            ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
             }
@@ -658,7 +658,12 @@ impl WalkItemKind for ForeignItemKind {
     ) -> V::Result {
         let &Item { id, span, ident, ref vis, .. } = item;
         match self {
-            ForeignItemKind::Static(box StaticForeignItem { ty, mutability: _, expr }) => {
+            ForeignItemKind::Static(box StaticForeignItem {
+                ty,
+                mutability: _,
+                expr,
+                safety: _,
+            }) => {
                 try_visit!(visitor.visit_ty(ty));
                 visit_opt!(visitor, visit_expr, expr);
             }
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index a15449409df..8c963e9f890 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -181,7 +181,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
                 self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
             }
-            ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => {
+            ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
                 let (ty, body_id) =
                     self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
                 hir::ItemKind::Static(ty, *m, body_id)
@@ -388,7 +388,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)),
                 };
                 hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
-                    safety: self.lower_safety(*safety),
+                    safety: self.lower_safety(*safety, hir::Safety::Safe),
                     polarity,
                     defaultness,
                     defaultness_span,
@@ -418,7 +418,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         let items = this.arena.alloc_from_iter(
                             items.iter().map(|item| this.lower_trait_item_ref(item)),
                         );
-                        let safety = this.lower_safety(*safety);
+                        let safety = this.lower_safety(*safety, hir::Safety::Safe);
                         (safety, items, bounds)
                     },
                 );
@@ -660,13 +660,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
                                 this.lower_fn_params_to_names(fdec),
                             )
                         });
+                    let safety = self.lower_safety(sig.header.safety, hir::Safety::Unsafe);
 
-                    hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
+                    hir::ForeignItemKind::Fn(fn_dec, fn_args, generics, safety)
                 }
-                ForeignItemKind::Static(box StaticForeignItem { ty, mutability, expr: _ }) => {
+                ForeignItemKind::Static(box StaticForeignItem {
+                    ty,
+                    mutability,
+                    expr: _,
+                    safety,
+                }) => {
                     let ty = self
                         .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
-                    hir::ForeignItemKind::Static(ty, *mutability)
+                    let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
+
+                    hir::ForeignItemKind::Static(ty, *mutability, safety)
                 }
                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
                 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
@@ -1360,7 +1368,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             hir::IsAsync::NotAsync
         };
         hir::FnHeader {
-            safety: self.lower_safety(h.safety),
+            safety: self.lower_safety(h.safety, hir::Safety::Safe),
             asyncness: asyncness,
             constness: self.lower_constness(h.constness),
             abi: self.lower_extern(h.ext),
@@ -1410,10 +1418,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    pub(super) fn lower_safety(&mut self, s: Safety) -> hir::Safety {
+    pub(super) fn lower_safety(&mut self, s: Safety, default: hir::Safety) -> hir::Safety {
         match s {
             Safety::Unsafe(_) => hir::Safety::Unsafe,
-            Safety::Default => hir::Safety::Safe,
+            Safety::Default => default,
+            Safety::Safe(_) => hir::Safety::Safe,
         }
     }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5a80fa803f8..023dc6d52c3 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1321,7 +1321,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
                 hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
                     generic_params,
-                    safety: self.lower_safety(f.safety),
+                    safety: self.lower_safety(f.safety, hir::Safety::Safe),
                     abi: self.lower_extern(f.ext),
                     decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),
                     param_names: self.lower_fn_params_to_names(&f.decl),
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 3a4c95b250c..9a8689e27c0 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -67,6 +67,9 @@ ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have quali
     .label = in this `extern` block
     .suggestion = remove this qualifier
 
+ast_passes_extern_invalid_safety = items in unadorned `extern` blocks cannot have safety qualifiers
+    .suggestion = add unsafe to this `extern` block
+
 ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
     .label = in this `extern` block
     .note = this limitation may be lifted in the future; see issue #83942 <https://github.com/rust-lang/rust/issues/83942> for more information
@@ -174,6 +177,8 @@ ast_passes_match_arm_with_no_body =
     `match` arm with no body
     .suggestion = add a body after the pattern
 
+ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe
+
 ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name
     .help = consider using the `#[path]` attribute to specify filesystem path
 
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 435b0b6a956..0fbb288cc96 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -15,7 +15,8 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_feature::Features;
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::{
-    DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
+    DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN,
+    PATTERNS_IN_FNS_WITHOUT_BODY,
 };
 use rustc_session::lint::{BuiltinLintDiag, LintBuffer};
 use rustc_session::Session;
@@ -86,6 +87,9 @@ struct AstValidator<'a> {
     /// or `Foo::Bar<impl Trait>`
     is_impl_trait_banned: bool,
 
+    /// Used to ban explicit safety on foreign items when the extern block is not marked as unsafe.
+    extern_mod_safety: Option<Safety>,
+
     lint_buffer: &'a mut LintBuffer,
 }
 
@@ -116,6 +120,12 @@ impl<'a> AstValidator<'a> {
         self.outer_trait_or_trait_impl = old;
     }
 
+    fn with_in_extern_mod(&mut self, extern_mod_safety: Safety, f: impl FnOnce(&mut Self)) {
+        let old = mem::replace(&mut self.extern_mod_safety, Some(extern_mod_safety));
+        f(self);
+        self.extern_mod_safety = old;
+    }
+
     fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
         let old = mem::replace(&mut self.is_impl_trait_banned, true);
         f(self);
@@ -429,6 +439,18 @@ impl<'a> AstValidator<'a> {
         }
     }
 
+    fn check_foreign_item_safety(&self, item_span: Span, safety: Safety) {
+        if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_))
+            && (self.extern_mod_safety == Some(Safety::Default)
+                || !self.features.unsafe_extern_blocks)
+        {
+            self.dcx().emit_err(errors::InvalidSafetyOnExtern {
+                item_span,
+                block: self.current_extern_span(),
+            });
+        }
+    }
+
     fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
         if let Defaultness::Default(def_span) = defaultness {
             let span = self.session.source_map().guess_head_span(span);
@@ -518,7 +540,7 @@ impl<'a> AstValidator<'a> {
     fn check_foreign_fn_headerless(
         &self,
         // Deconstruct to ensure exhaustiveness
-        FnHeader { safety, coroutine_kind, constness, ext }: FnHeader,
+        FnHeader { safety: _, coroutine_kind, constness, ext }: FnHeader,
     ) {
         let report_err = |span| {
             self.dcx().emit_err(errors::FnQualifierInExtern {
@@ -526,10 +548,6 @@ impl<'a> AstValidator<'a> {
                 block: self.current_extern_span(),
             });
         };
-        match safety {
-            Safety::Unsafe(span) => report_err(span),
-            Safety::Default => (),
-        }
         match coroutine_kind {
             Some(knd) => report_err(knd.span()),
             None => (),
@@ -1017,19 +1035,39 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 return; // Avoid visiting again.
             }
             ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
-                let old_item = mem::replace(&mut self.extern_mod, Some(item));
-                self.visibility_not_permitted(
-                    &item.vis,
-                    errors::VisibilityNotPermittedNote::IndividualForeignItems,
-                );
-                if let &Safety::Unsafe(span) = safety {
-                    self.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
-                }
-                if abi.is_none() {
-                    self.maybe_lint_missing_abi(item.span, item.id);
-                }
-                visit::walk_item(self, item);
-                self.extern_mod = old_item;
+                self.with_in_extern_mod(*safety, |this| {
+                    let old_item = mem::replace(&mut this.extern_mod, Some(item));
+                    this.visibility_not_permitted(
+                        &item.vis,
+                        errors::VisibilityNotPermittedNote::IndividualForeignItems,
+                    );
+
+                    if this.features.unsafe_extern_blocks {
+                        if &Safety::Default == safety {
+                            if item.span.at_least_rust_2024() {
+                                this.dcx()
+                                    .emit_err(errors::MissingUnsafeOnExtern { span: item.span });
+                            } else {
+                                this.lint_buffer.buffer_lint(
+                                    MISSING_UNSAFE_ON_EXTERN,
+                                    item.id,
+                                    item.span,
+                                    BuiltinLintDiag::MissingUnsafeOnExtern {
+                                        suggestion: item.span.shrink_to_lo(),
+                                    },
+                                );
+                            }
+                        }
+                    } else if let &Safety::Unsafe(span) = safety {
+                        this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" });
+                    }
+
+                    if abi.is_none() {
+                        this.maybe_lint_missing_abi(item.span, item.id);
+                    }
+                    visit::walk_item(this, item);
+                    this.extern_mod = old_item;
+                });
                 return; // Avoid visiting again.
             }
             ItemKind::Enum(def, _) => {
@@ -1161,6 +1199,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
         match &fi.kind {
             ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
+                self.check_foreign_item_safety(fi.span, sig.header.safety);
                 self.check_defaultness(fi.span, *defaultness);
                 self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
                 self.check_foreign_fn_headerless(sig.header);
@@ -1180,7 +1219,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self.check_foreign_ty_genericless(generics, where_clauses);
                 self.check_foreign_item_ascii_only(fi.ident);
             }
-            ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability: _, expr }) => {
+            ForeignItemKind::Static(box StaticForeignItem { expr, safety, .. }) => {
+                self.check_foreign_item_safety(fi.span, *safety);
                 self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span));
                 self.check_foreign_item_ascii_only(fi.ident);
             }
@@ -1736,6 +1776,7 @@ pub fn check_crate(
         outer_impl_trait: None,
         disallow_tilde_const: Some(DisallowTildeConstContext::Item),
         is_impl_trait_banned: false,
+        extern_mod_safety: None,
         lint_buffer: lints,
     };
     visit::walk_crate(&mut validator, krate);
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index c07fbe5b016..260c182bd9e 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -217,6 +217,15 @@ pub enum ExternBlockSuggestion {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_passes_extern_invalid_safety)]
+pub struct InvalidSafetyOnExtern {
+    #[primary_span]
+    pub item_span: Span,
+    #[suggestion(code = "", applicability = "maybe-incorrect")]
+    pub block: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_passes_bound_in_context)]
 pub struct BoundInContext<'a> {
     #[primary_span]
@@ -486,6 +495,13 @@ pub struct UnsafeItem {
 }
 
 #[derive(Diagnostic)]
+#[diag(ast_passes_missing_unsafe_on_extern)]
+pub struct MissingUnsafeOnExtern {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(ast_passes_fieldless_union)]
 pub struct FieldlessUnion {
     #[primary_span]
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 4c29ca0ca46..ca26b436b82 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1973,6 +1973,7 @@ impl<'a> State<'a> {
     fn print_safety(&mut self, s: ast::Safety) {
         match s {
             ast::Safety::Default => {}
+            ast::Safety::Safe(_) => self.word_nbsp("safe"),
             ast::Safety::Unsafe(_) => self.word_nbsp("unsafe"),
         }
     }
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 59d9b0c1a8e..474741fb067 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -31,7 +31,13 @@ impl<'a> State<'a> {
             ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
                 self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
             }
-            ast::ForeignItemKind::Static(box ast::StaticForeignItem { ty, mutability, expr }) => {
+            ast::ForeignItemKind::Static(box ast::StaticForeignItem {
+                ty,
+                mutability,
+                expr,
+                safety,
+            }) => {
+                self.print_safety(*safety);
                 self.print_item_const(
                     ident,
                     Some(*mutability),
@@ -165,7 +171,8 @@ impl<'a> State<'a> {
                 self.print_use_tree(tree);
                 self.word(";");
             }
-            ast::ItemKind::Static(box StaticItem { ty, mutability: mutbl, expr: body }) => {
+            ast::ItemKind::Static(box StaticItem { ty, safety, mutability: mutbl, expr: body }) => {
+                self.print_safety(*safety);
                 self.print_item_const(
                     item.ident,
                     Some(*mutbl),
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 291d2782c32..fcfb297d50a 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -346,7 +346,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
         } else {
             let tcx = self.tcx();
             let maybe_uneval = match constant.const_ {
-                Const::Ty(ct) => match ct.kind() {
+                Const::Ty(_, ct) => match ct.kind() {
                     ty::ConstKind::Unevaluated(_) => {
                         bug!("should not encounter unevaluated Const::Ty here, got {:?}", ct)
                     }
@@ -1856,7 +1856,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
         if let Operand::Constant(constant) = op {
             let maybe_uneval = match constant.const_ {
-                Const::Val(..) | Const::Ty(_) => None,
+                Const::Val(..) | Const::Ty(_, _) => None,
                 Const::Unevaluated(uv, _) => Some(uv),
             };
 
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index cbd8a4125cd..9863c4a3883 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -193,7 +193,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
                 types: &mut |_bound_ty: ty::BoundTy| {
                     unreachable!("we only replace regions in nll_relate, not types")
                 },
-                consts: &mut |_bound_var: ty::BoundVar, _ty| {
+                consts: &mut |_bound_var: ty::BoundVar| {
                     unreachable!("we only replace regions in nll_relate, not consts")
                 },
             };
@@ -231,7 +231,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
             types: &mut |_bound_ty: ty::BoundTy| {
                 unreachable!("we only replace regions in nll_relate, not types")
             },
-            consts: &mut |_bound_var: ty::BoundVar, _ty| {
+            consts: &mut |_bound_var: ty::BoundVar| {
                 unreachable!("we only replace regions in nll_relate, not consts")
             },
         };
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 78144226114..a98cb6f0f76 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -57,7 +57,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
     /// Builds the whole `assert!` expression. For example, `let elem = 1; assert!(elem == 1);` expands to:
     ///
     /// ```rust
-    /// #![feature(generic_assert_internals)]
     /// let elem = 1;
     /// {
     ///   #[allow(unused_imports)]
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 5f63a8ae0a8..03aff6f9633 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -196,7 +196,7 @@ impl CfgEval<'_, '_> {
         // Re-parse the tokens, setting the `capture_cfg` flag to save extra information
         // to the captured `AttrTokenStream` (specifically, we capture
         // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
-        let mut parser = rustc_parse::stream_to_parser(&self.cfg.sess.psess, orig_tokens, None);
+        let mut parser = Parser::new(&self.cfg.sess.psess, orig_tokens, None);
         parser.capture_cfg = true;
         match parse_annotatable_with(&mut parser) {
             Ok(a) => annotatable = a,
diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index ada82e45712..e9b63b4abeb 100644
--- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
@@ -4,16 +4,17 @@ use crate::errors;
 use rustc_ast::attr::mk_attr;
 use rustc_ast::token;
 use rustc_ast::{self as ast, AttrItem, AttrStyle};
+use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::FileName;
 
 pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
     for raw_attr in attrs {
-        let mut parser = rustc_parse::new_parser_from_source_str(
+        let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str(
             psess,
             FileName::cli_crate_attr_source_code(raw_attr),
             raw_attr.clone(),
-        );
+        ));
 
         let start_span = parser.token.span;
         let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) {
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 217fa5ff9f1..ba289f9552e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -412,6 +412,15 @@ fn find_type_parameters(
 
     impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
         fn visit_ty(&mut self, ty: &'a ast::Ty) {
+            let stack_len = self.bound_generic_params_stack.len();
+            if let ast::TyKind::BareFn(bare_fn) = &ty.kind
+                && !bare_fn.generic_params.is_empty()
+            {
+                // Given a field `x: for<'a> fn(T::SomeType<'a>)`, we wan't to account for `'a` so
+                // that we generate `where for<'a> T::SomeType<'a>: ::core::clone::Clone`. #122622
+                self.bound_generic_params_stack.extend(bare_fn.generic_params.iter().cloned());
+            }
+
             if let ast::TyKind::Path(_, path) = &ty.kind
                 && let Some(segment) = path.segments.first()
                 && self.ty_param_names.contains(&segment.ident.name)
@@ -422,7 +431,8 @@ fn find_type_parameters(
                 });
             }
 
-            visit::walk_ty(self, ty)
+            visit::walk_ty(self, ty);
+            self.bound_generic_params_stack.truncate(stack_len);
         }
 
         // Place bound generic params on a stack, to extract them when a type is encountered.
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 29e991525a9..dc1d82df0c3 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -12,8 +12,8 @@ use rustc_expand::base::{
 };
 use rustc_expand::module::DirOwnership;
 use rustc_lint_defs::BuiltinLintDiag;
-use rustc_parse::new_parser_from_file;
 use rustc_parse::parser::{ForceCollect, Parser};
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Symbol;
@@ -126,7 +126,7 @@ pub(crate) fn expand_include<'cx>(
             return ExpandResult::Ready(DummyResult::any(sp, guar));
         }
     };
-    let p = new_parser_from_file(cx.psess(), &file, Some(sp));
+    let p = unwrap_or_emit_fatal(new_parser_from_file(cx.psess(), &file, Some(sp)));
 
     // If in the included file we have e.g., `mod bar;`,
     // then the path of `bar.rs` should be relative to the directory of `file`.
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index b17f191ce26..65eeaf156d8 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
                 .expect_const()
                 .eval(fx.tcx, ty::ParamEnv::reveal_all(), span)
                 .unwrap()
+                .1
                 .unwrap_branch();
 
             assert_eq!(x.layout(), y.layout());
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index fa7e7e5377a..a354f3d3536 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -128,11 +128,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
         is_direct_dependency: bool,
     ) -> PathBuf {
         let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
-        let output_path = {
-            let mut output_path: PathBuf = tmpdir.to_path_buf();
-            output_path.push(format!("{lib_name}{name_suffix}"));
-            output_path.with_extension("lib")
-        };
+        let output_path = tmpdir.join(format!("{lib_name}{name_suffix}.lib"));
 
         let target = &sess.target;
         let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(target);
@@ -157,8 +153,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
             // that loaded but crashed with an AV upon calling one of the imported
             // functions. Therefore, use binutils to create the import library instead,
             // by writing a .DEF file to the temp dir and calling binutils's dlltool.
-            let def_file_path =
-                tmpdir.join(format!("{lib_name}{name_suffix}")).with_extension("def");
+            let def_file_path = tmpdir.join(format!("{lib_name}{name_suffix}.def"));
 
             let def_file_content = format!(
                 "EXPORTS\n{}",
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 39bbf87bea7..7b1038d5617 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1201,6 +1201,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
             .expect_const()
             .eval(tcx, ty::ParamEnv::reveal_all(), span)
             .unwrap()
+            .1
             .unwrap_branch();
         let n = idx.len() as u64;
 
diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs
index 3114f1c38ae..f499bbcf853 100644
--- a/compiler/rustc_codegen_ssa/src/back/rpath.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs
@@ -85,6 +85,11 @@ fn get_rpath_relative_to_output(config: &RPathConfig<'_>, lib: &Path) -> OsStrin
     // Strip filenames
     let lib = lib.parent().unwrap();
     let output = config.out_filename.parent().unwrap();
+
+    // If output or lib is empty, just assume it locates in current path
+    let lib = if lib == Path::new("") { Path::new(".") } else { lib };
+    let output = if output == Path::new("") { Path::new(".") } else { output };
+
     let lib = try_canonicalize(lib).unwrap();
     let output = try_canonicalize(output).unwrap();
     let relative = path_relative_from(&lib, &output)
diff --git a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
index ac2e54072c4..0de90a1036e 100644
--- a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs
@@ -58,6 +58,22 @@ fn test_rpath_relative() {
 }
 
 #[test]
+fn test_rpath_relative_issue_119571() {
+    let config = &mut RPathConfig {
+        libs: &[],
+        out_filename: PathBuf::from("rustc"),
+        has_rpath: true,
+        is_like_osx: false,
+        linker_is_gnu: true,
+    };
+    // Should not panic when out_filename only contains filename.
+    // Issue 119571
+    let _ = get_rpath_relative_to_output(config, Path::new("lib/libstd.so"));
+    // Should not panic when lib only contains filename.
+    let _ = get_rpath_relative_to_output(config, Path::new("libstd.so"));
+}
+
+#[test]
 fn test_xlinker() {
     let args = rpaths_to_flags(vec!["a/normal/path".into(), "a,comma,path".into()]);
 
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 79d6641a0da..a6df8950b35 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -400,7 +400,7 @@ fn upstream_monomorphizations_provider(
     tcx: TyCtxt<'_>,
     (): (),
 ) -> DefIdMap<UnordMap<GenericArgsRef<'_>, CrateNum>> {
-    let cnums = tcx.used_crates(());
+    let cnums = tcx.crates(());
 
     let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index f372d3a0522..0b450c43924 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -541,7 +541,7 @@ pub fn collect_debugger_visualizers_transitive(
     tcx.debugger_visualizers(LOCAL_CRATE)
         .iter()
         .chain(
-            tcx.used_crates(())
+            tcx.crates(())
                 .iter()
                 .filter(|&cnum| {
                     let used_crate_source = tcx.used_crate_source(*cnum);
@@ -851,7 +851,7 @@ impl CrateInfo {
         // `compiler_builtins` are always placed last to ensure that they're linked correctly.
         used_crates.extend(compiler_builtins);
 
-        let crates = tcx.used_crates(());
+        let crates = tcx.crates(());
         let n_crates = crates.len();
         let mut info = CrateInfo {
             target_cpu,
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 5d7257b15c4..15955170e87 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -324,21 +324,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     let linkage = Some(linkage_by_name(tcx, did, val.as_str()));
                     if tcx.is_foreign_item(did) {
                         codegen_fn_attrs.import_linkage = linkage;
+
+                        if tcx.is_mutable_static(did.into()) {
+                            let mut diag = tcx.dcx().struct_span_err(
+                                attr.span,
+                                "extern mutable statics are not allowed with `#[linkage]`",
+                            );
+                            diag.note(
+                                "marking the extern static mutable would allow changing which symbol \
+                                 the static references rather than make the target of the symbol \
+                                 mutable",
+                            );
+                            diag.emit();
+                        }
                     } else {
                         codegen_fn_attrs.linkage = linkage;
                     }
-                    if tcx.is_mutable_static(did.into()) {
-                        let mut diag = tcx.dcx().struct_span_err(
-                            attr.span,
-                            "mutable statics are not allowed with `#[linkage]`",
-                        );
-                        diag.note(
-                            "making the static mutable would allow changing which symbol the \
-                             static references rather than make the target of the symbol \
-                             mutable",
-                        );
-                        diag.emit();
-                    }
                 }
             }
             sym::link_section => {
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 2360cce55a9..c4e5c858240 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -693,41 +693,46 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
         ty::ConstKind::Param(param) => {
             write!(output, "{}", param.name)
         }
-        _ => match ct.ty().kind() {
-            ty::Int(ity) => {
-                let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
-                let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
-                write!(output, "{val}")
-            }
-            ty::Uint(_) => {
-                let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
-                write!(output, "{val}")
-            }
-            ty::Bool => {
-                let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
-                write!(output, "{val}")
-            }
-            _ => {
-                // If we cannot evaluate the constant to a known type, we fall back
-                // to emitting a stable hash value of the constant. This isn't very pretty
-                // but we get a deterministic, virtually unique value for the constant.
-                //
-                // Let's only emit 64 bits of the hash value. That should be plenty for
-                // avoiding collisions and will make the emitted type names shorter.
-                let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
-                    let mut hasher = StableHasher::new();
-                    let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
-                    hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
-                    hasher.finish::<Hash64>()
-                });
-
-                if cpp_like_debuginfo(tcx) {
-                    write!(output, "CONST${hash_short:x}")
-                } else {
-                    write!(output, "{{CONST#{hash_short:x}}}")
+        ty::ConstKind::Value(ty, _) => {
+            match ty.kind() {
+                ty::Int(ity) => {
+                    // FIXME: directly extract the bits from a valtree instead of evaluating an
+                    // alreay evaluated `Const` in order to get the bits.
+                    let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
+                    let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
+                    write!(output, "{val}")
+                }
+                ty::Uint(_) => {
+                    let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all());
+                    write!(output, "{val}")
+                }
+                ty::Bool => {
+                    let val = ct.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
+                    write!(output, "{val}")
+                }
+                _ => {
+                    // If we cannot evaluate the constant to a known type, we fall back
+                    // to emitting a stable hash value of the constant. This isn't very pretty
+                    // but we get a deterministic, virtually unique value for the constant.
+                    //
+                    // Let's only emit 64 bits of the hash value. That should be plenty for
+                    // avoiding collisions and will make the emitted type names shorter.
+                    let hash_short = tcx.with_stable_hashing_context(|mut hcx| {
+                        let mut hasher = StableHasher::new();
+                        let ct = ct.eval(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP).unwrap();
+                        hcx.while_hashing_spans(false, |hcx| ct.hash_stable(hcx, &mut hasher));
+                        hasher.finish::<Hash64>()
+                    });
+
+                    if cpp_like_debuginfo(tcx) {
+                        write!(output, "CONST${hash_short:x}")
+                    } else {
+                        write!(output, "{{CONST#{hash_short:x}}}")
+                    }
                 }
             }
-        },
+        }
+        _ => bug!("Invalid `Const` during codegen: {:?}", ct),
     }
     .unwrap();
 }
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index dba5fbefd8a..822f5c2c44a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -40,10 +40,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     ) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> {
         let uv = match self.monomorphize(constant.const_) {
             mir::Const::Unevaluated(uv, _) => uv.shrink(),
-            mir::Const::Ty(c) => match c.kind() {
+            mir::Const::Ty(_, c) => match c.kind() {
                 // A constant that came from a const generic but was then used as an argument to old-style
                 // simd_shuffle (passing as argument instead of as a generic param).
-                rustc_type_ir::ConstKind::Value(valtree) => return Ok(Some(valtree)),
+                rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Some(valtree)),
                 other => span_bug!(constant.span, "{other:#?}"),
             },
             // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index 5949444e599..9fd7219499b 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -357,15 +357,15 @@ where
 
     // Check the qualifs of the value of `const` items.
     let uneval = match constant.const_ {
-        Const::Ty(ct)
+        Const::Ty(_, ct)
             if matches!(
                 ct.kind(),
-                ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_)
+                ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_, _)
             ) =>
         {
             None
         }
-        Const::Ty(c) => {
+        Const::Ty(_, c) => {
             bug!("expected ConstKind::Param or ConstKind::Value here, found {:?}", c)
         }
         Const::Unevaluated(uv, _) => Some(uv),
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 8d0b267e1a9..3066e0933d9 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -102,7 +102,7 @@ fn intern_as_new_static<'tcx>(
     let feed = tcx.create_def(
         static_id,
         sym::nested,
-        DefKind::Static { mutability: alloc.0.mutability, nested: true },
+        DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true },
     );
     tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
 
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 0649bb5617c..cbfe25ca8df 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -294,17 +294,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Unwrap types that are guaranteed a null-pointer-optimization
     fn unfold_npo(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
-        // Check if this is `Option` wrapping some type.
-        let inner = match layout.ty.kind() {
-            ty::Adt(def, args) if self.tcx.is_diagnostic_item(sym::Option, def.did()) => {
-                args[0].as_type().unwrap()
-            }
-            _ => {
-                // Not an `Option`.
-                return Ok(layout);
+        // Check if this is `Option` wrapping some type or if this is `Result` wrapping a 1-ZST and
+        // another type.
+        let ty::Adt(def, args) = layout.ty.kind() else {
+            // Not an ADT, so definitely no NPO.
+            return Ok(layout);
+        };
+        let inner = if self.tcx.is_diagnostic_item(sym::Option, def.did()) {
+            // The wrapped type is the only arg.
+            self.layout_of(args[0].as_type().unwrap())?
+        } else if self.tcx.is_diagnostic_item(sym::Result, def.did()) {
+            // We want to extract which (if any) of the args is not a 1-ZST.
+            let lhs = self.layout_of(args[0].as_type().unwrap())?;
+            let rhs = self.layout_of(args[1].as_type().unwrap())?;
+            if lhs.is_1zst() {
+                rhs
+            } else if rhs.is_1zst() {
+                lhs
+            } else {
+                return Ok(layout); // no NPO
             }
+        } else {
+            return Ok(layout); // no NPO
         };
-        let inner = self.layout_of(inner)?;
+
         // Check if the inner type is one of the NPO-guaranteed ones.
         // For that we first unpeel transparent *structs* (but not unions).
         let is_npo = |def: AdtDef<'tcx>| {
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index e35ce9ef28d..3407c7b8c79 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -711,7 +711,9 @@ fn mutability<'tcx>(ecx: &InterpCx<'tcx, impl Machine<'tcx>>, alloc_id: AllocId)
     // We're not using `try_global_alloc` since dangling pointers have already been handled.
     match ecx.tcx.global_alloc(alloc_id) {
         GlobalAlloc::Static(did) => {
-            let DefKind::Static { mutability, nested } = ecx.tcx.def_kind(did) else { bug!() };
+            let DefKind::Static { safety: _, mutability, nested } = ecx.tcx.def_kind(did) else {
+                bug!()
+            };
             if nested {
                 assert!(
                     ecx.memory.alloc_map.get(alloc_id).is_none(),
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 627fd74c8d7..93a65290602 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -32,6 +32,7 @@ use rustc_interface::{interface, Queries};
 use rustc_lint::unerased_lint_store;
 use rustc_metadata::creader::MetadataLoader;
 use rustc_metadata::locator;
+use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
 use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType};
 use rustc_session::getopts::{self, Matches};
@@ -1264,12 +1265,13 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
 }
 
 fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
-    match &sess.io.input {
-        Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.psess),
+    let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
+        Input::File(file) => new_parser_from_file(&sess.psess, file, None),
         Input::Str { name, input } => {
-            rustc_parse::parse_crate_attrs_from_source_str(name.clone(), input.clone(), &sess.psess)
+            new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
         }
-    }
+    });
+    parser.parse_inner_attributes()
 }
 
 /// Runs a closure and catches unwinds triggered by fatal errors.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0582.md b/compiler/rustc_error_codes/src/error_codes/E0582.md
index e50cc60ea33..b2cdb509c95 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0582.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0582.md
@@ -27,6 +27,40 @@ fn bar<F, G>(t: F, u: G)
 fn main() { }
 ```
 
+This error also includes the use of associated types with lifetime parameters.
+```compile_fail,E0582
+trait Foo {
+    type Assoc<'a>;
+}
+
+struct Bar<X, F>
+where
+    X: Foo,
+    F: for<'a> Fn(X::Assoc<'a>) -> &'a i32
+{
+    x: X,
+    f: F
+}
+```
+The latter scenario encounters this error because `Foo::Assoc<'a>` could be
+implemented by a type that does not use the `'a` parameter, so there is no
+guarentee that `X::Assoc<'a>` actually uses `'a`.
+
+To fix this we can pass a dummy parameter:
+```
+# trait Foo {
+#     type Assoc<'a>;
+# }
+struct Bar<X, F>
+where
+    X: Foo,
+    F: for<'a> Fn(X::Assoc<'a>, /* dummy */ &'a ()) -> &'a i32
+{
+    x: X,
+    f: F
+}
+```
+
 Note: The examples above used to be (erroneously) accepted by the
 compiler, but this was since corrected. See [issue #33685] for more
 details.
diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl
index 530b37aadb1..718129c5b6e 100644
--- a/compiler/rustc_expand/messages.ftl
+++ b/compiler/rustc_expand/messages.ftl
@@ -124,6 +124,9 @@ expand_not_a_meta_item =
 expand_only_one_word =
     must only be one word
 
+expand_proc_macro_back_compat = using an old version of `{$crate_name}`
+    .note = older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives
+
 expand_proc_macro_derive_panicked =
     proc-macro derive panicked
     .help = message: {$message}
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 91af8758e51..b3f6a35f3a4 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -14,9 +14,8 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::{self, Lrc};
 use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
 use rustc_feature::Features;
-use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
-use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, RegisteredTools};
-use rustc_parse::{parser, MACRO_ARGUMENTS};
+use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools};
+use rustc_parse::{parser::Parser, MACRO_ARGUMENTS};
 use rustc_session::config::CollapseMacroDebuginfo;
 use rustc_session::{parse::ParseSess, Limit, Session};
 use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
@@ -1150,8 +1149,8 @@ impl<'a> ExtCtxt<'a> {
     pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
         expand::MacroExpander::new(self, true)
     }
-    pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
-        rustc_parse::stream_to_parser(&self.sess.psess, stream, MACRO_ARGUMENTS)
+    pub fn new_parser_from_tts(&self, stream: TokenStream) -> Parser<'a> {
+        Parser::new(&self.sess.psess, stream, MACRO_ARGUMENTS)
     }
     pub fn source_map(&self) -> &'a SourceMap {
         self.sess.psess.source_map()
@@ -1330,80 +1329,63 @@ pub fn parse_macro_name_and_helper_attrs(
     Some((trait_ident.name, proc_attrs))
 }
 
-/// This nonterminal looks like some specific enums from
-/// `proc-macro-hack` and `procedural-masquerade` crates.
-/// We need to maintain some special pretty-printing behavior for them due to incorrect
-/// asserts in old versions of those crates and their wide use in the ecosystem.
-/// See issue #73345 for more details.
+/// If this item looks like a specific enums from `rental`, emit a fatal error.
+/// See #73345 and #83125 for more details.
 /// FIXME(#73933): Remove this eventually.
-fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) -> bool {
+fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) {
     let name = item.ident.name;
-    if name == sym::ProceduralMasqueradeDummyType {
-        if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
-            if let [variant] = &*enum_def.variants {
-                if variant.ident.name == sym::Input {
-                    let filename = sess.source_map().span_to_filename(item.ident.span);
-                    if let FileName::Real(real) = filename {
-                        if let Some(c) = real
-                            .local_path()
-                            .unwrap_or(Path::new(""))
-                            .components()
-                            .flat_map(|c| c.as_os_str().to_str())
-                            .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental"))
-                        {
-                            let crate_matches = if c.starts_with("allsorts-rental") {
-                                true
-                            } else {
-                                let mut version = c.trim_start_matches("rental-").split('.');
-                                version.next() == Some("0")
-                                    && version.next() == Some("5")
-                                    && version
-                                        .next()
-                                        .and_then(|c| c.parse::<u32>().ok())
-                                        .is_some_and(|v| v < 6)
-                            };
-
-                            if crate_matches {
-                                sess.psess.buffer_lint(
-                                    PROC_MACRO_BACK_COMPAT,
-                                    item.ident.span,
-                                    ast::CRATE_NODE_ID,
-                                    BuiltinLintDiag::ProcMacroBackCompat {
-                                        crate_name: "rental".to_string(),
-                                        fixed_version: "0.5.6".to_string(),
-                                    },
-                                );
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
+    if name == sym::ProceduralMasqueradeDummyType
+        && let ast::ItemKind::Enum(enum_def, _) = &item.kind
+        && let [variant] = &*enum_def.variants
+        && variant.ident.name == sym::Input
+        && let FileName::Real(real) = sess.source_map().span_to_filename(item.ident.span)
+        && let Some(c) = real
+            .local_path()
+            .unwrap_or(Path::new(""))
+            .components()
+            .flat_map(|c| c.as_os_str().to_str())
+            .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental"))
+    {
+        let crate_matches = if c.starts_with("allsorts-rental") {
+            true
+        } else {
+            let mut version = c.trim_start_matches("rental-").split('.');
+            version.next() == Some("0")
+                && version.next() == Some("5")
+                && version.next().and_then(|c| c.parse::<u32>().ok()).is_some_and(|v| v < 6)
+        };
+
+        if crate_matches {
+            // FIXME: make this translatable
+            #[allow(rustc::untranslatable_diagnostic)]
+            sess.psess.dcx.emit_fatal(errors::ProcMacroBackCompat {
+                crate_name: "rental".to_string(),
+                fixed_version: "0.5.6".to_string(),
+            });
         }
     }
-    false
 }
 
-pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &Session) -> bool {
+pub(crate) fn ann_pretty_printing_compatibility_hack(ann: &Annotatable, sess: &Session) {
     let item = match ann {
         Annotatable::Item(item) => item,
         Annotatable::Stmt(stmt) => match &stmt.kind {
             ast::StmtKind::Item(item) => item,
-            _ => return false,
+            _ => return,
         },
-        _ => return false,
+        _ => return,
     };
     pretty_printing_compatibility_hack(item, sess)
 }
 
-pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &Session) -> bool {
+pub(crate) fn nt_pretty_printing_compatibility_hack(nt: &Nonterminal, sess: &Session) {
     let item = match nt {
         Nonterminal::NtItem(item) => item,
         Nonterminal::NtStmt(stmt) => match &stmt.kind {
             ast::StmtKind::Item(item) => item,
-            _ => return false,
+            _ => return,
         },
-        _ => return false,
+        _ => return,
     };
     pretty_printing_compatibility_hack(item, sess)
 }
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 1b6e191c2eb..b3d41908260 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -631,7 +631,10 @@ impl<'a> ExtCtxt<'a> {
             span,
             name,
             AttrVec::new(),
-            ast::ItemKind::Static(ast::StaticItem { ty, mutability, expr: Some(expr) }.into()),
+            ast::ItemKind::Static(
+                ast::StaticItem { ty, safety: ast::Safety::Default, mutability, expr: Some(expr) }
+                    .into(),
+            ),
         )
     }
 
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index a5fc9e9d89c..3f8b4661e5f 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -440,3 +440,13 @@ pub(crate) struct EmptyDelegationList {
     #[primary_span]
     pub span: Span,
 }
+
+// This used to be the `proc_macro_back_compat` lint (#83125). It was later
+// turned into a hard error.
+#[derive(Diagnostic)]
+#[diag(expand_proc_macro_back_compat)]
+#[note]
+pub struct ProcMacroBackCompat {
+    pub crate_name: String,
+    pub fixed_version: String,
+}
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index e1f50876b05..3196b826085 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -267,7 +267,6 @@ pub(super) fn transcribe<'a>(
                 // some of the unnecessary whitespace.
                 let ident = MacroRulesNormalizedIdent::new(original_ident);
                 if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
-                    // njn: explain the use of alone here
                     let tt = match cur_matched {
                         MatchedSingle(ParseNtResult::Tt(tt)) => {
                             // `tt`s are emitted into the output stream directly as "raw tokens",
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index c8983619e70..506bd445be3 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -5,8 +5,8 @@ use crate::errors::{
 use rustc_ast::ptr::P;
 use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans};
 use rustc_errors::{Diag, ErrorGuaranteed};
-use rustc_parse::new_parser_from_file;
 use rustc_parse::validate_attr;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
@@ -66,7 +66,8 @@ pub(crate) fn parse_external_mod(
         }
 
         // Actually parse the external file as a module.
-        let mut parser = new_parser_from_file(&sess.psess, &mp.file_path, Some(span));
+        let mut parser =
+            unwrap_or_emit_fatal(new_parser_from_file(&sess.psess, &mp.file_path, Some(span)));
         let (inner_attrs, items, inner_span) =
             parser.parse_mod(&token::Eof).map_err(|err| ModError::ParserError(err))?;
         attrs.extend(inner_attrs);
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 530059e53c2..96145affe0a 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -4,14 +4,12 @@ use crate::proc_macro_server;
 
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
-use rustc_ast::token;
 use rustc_ast::tokenstream::TokenStream;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::ErrorGuaranteed;
-use rustc_parse::parser::ForceCollect;
+use rustc_parse::parser::{ForceCollect, Parser};
 use rustc_session::config::ProcMacroExecutionStrategy;
 use rustc_span::profiling::SpannedEventArgRecorder;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::Span;
 
 struct MessagePipe<T> {
     tx: std::sync::mpsc::SyncSender<T>,
@@ -120,18 +118,13 @@ impl MultiItemModifier for DeriveProcMacro {
         // We need special handling for statement items
         // (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
         let is_stmt = matches!(item, Annotatable::Stmt(..));
-        let hack = crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess);
-        let input = if hack {
-            let nt = match item {
-                Annotatable::Item(item) => token::NtItem(item),
-                Annotatable::Stmt(stmt) => token::NtStmt(stmt),
-                _ => unreachable!(),
-            };
-            TokenStream::token_alone(token::Interpolated(Lrc::new(nt)), DUMMY_SP)
-        } else {
-            item.to_tokens()
-        };
 
+        // We used to have an alternative behaviour for crates that needed it.
+        // We had a lint for a long time, but now we just emit a hard error.
+        // Eventually we might remove the special case hard error check
+        // altogether. See #73345.
+        crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess);
+        let input = item.to_tokens();
         let stream = {
             let _timer =
                 ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
@@ -161,8 +154,7 @@ impl MultiItemModifier for DeriveProcMacro {
         };
 
         let error_count_before = ecx.dcx().err_count();
-        let mut parser =
-            rustc_parse::stream_to_parser(&ecx.sess.psess, stream, Some("proc-macro derive"));
+        let mut parser = Parser::new(&ecx.sess.psess, stream, Some("proc-macro derive"));
         let mut items = vec![];
 
         loop {
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index ec7e4416b91..93f8682090d 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -13,7 +13,8 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
 use rustc_parse::lexer::nfc_normalize;
-use rustc_parse::parse_stream_from_source_str;
+use rustc_parse::parser::Parser;
+use rustc_parse::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::def_id::CrateNum;
 use rustc_span::symbol::{self, sym, Symbol};
@@ -276,21 +277,20 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
 
                 Interpolated(nt) => {
                     let stream = TokenStream::from_nonterminal_ast(&nt);
-                    // A hack used to pass AST fragments to attribute and derive
-                    // macros as a single nonterminal token instead of a token
-                    // stream. Such token needs to be "unwrapped" and not
-                    // represented as a delimited group.
-                    // FIXME: It needs to be removed, but there are some
-                    // compatibility issues (see #73345).
-                    if crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.ecx.sess) {
-                        trees.extend(Self::from_internal((stream, rustc)));
-                    } else {
-                        trees.push(TokenTree::Group(Group {
-                            delimiter: pm::Delimiter::None,
-                            stream: Some(stream),
-                            span: DelimSpan::from_single(span),
-                        }))
-                    }
+                    // We used to have an alternative behaviour for crates that
+                    // needed it: a hack used to pass AST fragments to
+                    // attribute and derive macros as a single nonterminal
+                    // token instead of a token stream. Such token needs to be
+                    // "unwrapped" and not represented as a delimited group. We
+                    // had a lint for a long time, but now we just emit a hard
+                    // error. Eventually we might remove the special case hard
+                    // error check altogether. See #73345.
+                    crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.ecx.sess);
+                    trees.push(TokenTree::Group(Group {
+                        delimiter: pm::Delimiter::None,
+                        stream: Some(stream),
+                        span: DelimSpan::from_single(span),
+                    }))
                 }
 
                 OpenDelim(..) | CloseDelim(..) => unreachable!(),
@@ -467,7 +467,8 @@ impl server::FreeFunctions for Rustc<'_, '_> {
 
     fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
         let name = FileName::proc_macro_source_code(s);
-        let mut parser = rustc_parse::new_parser_from_source_str(self.psess(), name, s.to_owned());
+        let mut parser =
+            unwrap_or_emit_fatal(new_parser_from_source_str(self.psess(), name, s.to_owned()));
 
         let first_span = parser.token.span.data();
         let minus_present = parser.eat(&token::BinOp(token::Minus));
@@ -539,12 +540,12 @@ impl server::TokenStream for Rustc<'_, '_> {
     }
 
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        parse_stream_from_source_str(
+        unwrap_or_emit_fatal(source_str_to_stream(
+            self.psess(),
             FileName::proc_macro_source_code(src),
             src.to_string(),
-            self.psess(),
             Some(self.call_site),
-        )
+        ))
     }
 
     fn to_string(&mut self, stream: &Self::TokenStream) -> String {
@@ -554,11 +555,7 @@ impl server::TokenStream for Rustc<'_, '_> {
     fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
         // Parse the expression from our tokenstream.
         let expr: PResult<'_, _> = try {
-            let mut p = rustc_parse::stream_to_parser(
-                self.psess(),
-                stream.clone(),
-                Some("proc_macro expand expr"),
-            );
+            let mut p = Parser::new(self.psess(), stream.clone(), Some("proc_macro expand expr"));
             let expr = p.parse_expr()?;
             if p.token != token::Eof {
                 p.unexpected()?;
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index eaaf7ca34e0..aea447b2aff 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -128,6 +128,8 @@ declare_features! (
     /// Allows the use of type alias impl trait in function return positions
     (removed, min_type_alias_impl_trait, "1.56.0", Some(63063),
      Some("removed in favor of full type_alias_impl_trait")),
+    /// Make `mut` not reset the binding mode on edition >= 2024.
+    (removed, mut_preserve_binding_mode_2024, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024`")),
     (removed, needs_allocator, "1.4.0", Some(27389),
      Some("subsumed by `#![feature(allocator_internals)]`")),
     /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
@@ -181,6 +183,7 @@ declare_features! (
     (removed, pushpop_unsafe, "1.2.0", None, None),
     (removed, quad_precision_float, "1.0.0", None, None),
     (removed, quote, "1.33.0", Some(29601), None),
+    (removed, ref_pat_everywhere, "1.79.0", Some(123076), Some("superseded by `ref_pat_eat_one_layer_2024")),
     (removed, reflect, "1.0.0", Some(27749), None),
     /// Allows using the `#[register_attr]` attribute.
     (removed, register_attr, "1.65.0", Some(66080),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 8de2cdefa81..8add2b92761 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -529,8 +529,6 @@ declare_features! (
     (unstable, more_qualified_paths, "1.54.0", Some(86935)),
     /// Allows the `#[must_not_suspend]` attribute.
     (unstable, must_not_suspend, "1.57.0", Some(83310)),
-    /// Make `mut` not reset the binding mode on edition >= 2024.
-    (incomplete, mut_preserve_binding_mode_2024, "1.79.0", Some(123076)),
     /// Allows `mut ref` and `mut ref mut` identifier patterns.
     (incomplete, mut_ref, "1.79.0", Some(123076)),
     /// Allows using `#[naked]` on functions.
@@ -573,8 +571,6 @@ declare_features! (
     (unstable, raw_ref_op, "1.41.0", Some(64490)),
     /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
     (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
-    /// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
-    (incomplete, ref_pat_everywhere, "1.79.0", Some(123076)),
     /// Allows using the `#[register_tool]` attribute.
     (unstable, register_tool, "1.41.0", Some(66079)),
     /// Allows the `#[repr(i128)]` attribute for enums.
@@ -624,6 +620,8 @@ declare_features! (
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
     /// Allows unnamed fields of struct and union type
     (incomplete, unnamed_fields, "1.74.0", Some(49804)),
+    /// Allows unsafe on extern declarations and safety qualifiers over internal items.
+    (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
     /// Allows unsized fn parameters.
     (unstable, unsized_fn_params, "1.49.0", Some(48055)),
     /// Allows unsized rvalues at arguments and parameters.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 649a08b6972..b1854923247 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -76,6 +76,8 @@ pub enum DefKind {
     /// Constant generic parameter: `struct Foo<const N: usize> { ... }`
     ConstParam,
     Static {
+        /// Whether it's a `unsafe static`, `safe static` (inside extern only) or just a `static`.
+        safety: hir::Safety,
         /// Whether it's a `static mut` or just a `static`.
         mutability: ast::Mutability,
         /// Whether it's an anonymous static generated for nested allocations.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e971d0e3c14..770dfcb98c9 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3475,9 +3475,9 @@ impl ForeignItem<'_> {
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum ForeignItemKind<'hir> {
     /// A foreign function.
-    Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>),
+    Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>, Safety),
     /// A foreign static item (`static ext: u8`).
-    Static(&'hir Ty<'hir>, Mutability),
+    Static(&'hir Ty<'hir>, Mutability, Safety),
     /// A foreign type.
     Type,
 }
@@ -3545,7 +3545,7 @@ impl<'hir> OwnerNode<'hir> {
             | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
             | OwnerNode::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
             OwnerNode::ForeignItem(ForeignItem {
-                kind: ForeignItemKind::Fn(fn_decl, _, _),
+                kind: ForeignItemKind::Fn(fn_decl, _, _, _),
                 ..
             }) => Some(fn_decl),
             _ => None,
@@ -3728,9 +3728,9 @@ impl<'hir> Node<'hir> {
             | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. })
             | Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
             Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl, .. }), .. })
-            | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
-                Some(fn_decl)
-            }
+            | Node::ForeignItem(ForeignItem {
+                kind: ForeignItemKind::Fn(fn_decl, _, _, _), ..
+            }) => Some(fn_decl),
             _ => None,
         }
     }
@@ -3813,7 +3813,7 @@ impl<'hir> Node<'hir> {
     pub fn generics(self) -> Option<&'hir Generics<'hir>> {
         match self {
             Node::ForeignItem(ForeignItem {
-                kind: ForeignItemKind::Fn(_, _, generics), ..
+                kind: ForeignItemKind::Fn(_, _, generics, _), ..
             })
             | Node::TraitItem(TraitItem { generics, .. })
             | Node::ImplItem(ImplItem { generics, .. }) => Some(generics),
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9bc2bbe0c64..e37473df956 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -608,12 +608,14 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
     try_visit!(visitor.visit_ident(foreign_item.ident));
 
     match foreign_item.kind {
-        ForeignItemKind::Fn(ref function_declaration, param_names, ref generics) => {
+        ForeignItemKind::Fn(ref function_declaration, param_names, ref generics, _) => {
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_fn_decl(function_declaration));
             walk_list!(visitor, visit_ident, param_names.iter().copied());
         }
-        ForeignItemKind::Static(ref typ, _) => try_visit!(visitor.visit_ty(typ)),
+        ForeignItemKind::Static(ref typ, _, _) => {
+            try_visit!(visitor.visit_ty(typ));
+        }
         ForeignItemKind::Type => (),
     }
     V::Result::output()
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 76b6cbd6e53..8a0623ef93e 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -801,7 +801,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
                         let item = tcx.hir().foreign_item(item.id);
                         match &item.kind {
-                            hir::ForeignItemKind::Fn(fn_decl, _, _) => {
+                            hir::ForeignItemKind::Fn(fn_decl, _, _, _) => {
                                 require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
                             }
                             hir::ForeignItemKind::Static(..) => {
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 74dcd672578..82b57cdd106 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2198,9 +2198,6 @@ fn param_env_with_gat_bounds<'tcx>(
                         tcx,
                         ty::INNERMOST,
                         ty::BoundVar::from_usize(bound_vars.len() - 1),
-                        tcx.type_of(param.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic"),
                     )
                     .into()
                 }
diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs
index a49626eed35..2cdcc06f53c 100644
--- a/compiler/rustc_hir_analysis/src/check/errs.rs
+++ b/compiler/rustc_hir_analysis/src/check/errs.rs
@@ -41,7 +41,8 @@ fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option<String> {
     if let hir::ExprKind::Path(qpath) = expr.kind
         && let hir::QPath::Resolved(_, path) = qpath
         && let hir::def::Res::Def(def_kind, _) = path.res
-        && let hir::def::DefKind::Static { mutability: Mutability::Mut, nested: false } = def_kind
+        && let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } =
+            def_kind
     {
         return Some(qpath_to_string(&tcx, &qpath));
     }
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index f7989aeab41..13180fa2673 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -29,7 +29,7 @@ fn equate_intrinsic_type<'tcx>(
     let (own_counts, span) = match tcx.hir_node_by_def_id(def_id) {
         hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })
         | hir::Node::ForeignItem(hir::ForeignItem {
-            kind: hir::ForeignItemKind::Fn(.., generics),
+            kind: hir::ForeignItemKind::Fn(.., generics, _),
             ..
         }) => {
             let own_counts = tcx.generics_of(def_id).own_counts();
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 7e746006148..c6e8759327f 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -18,11 +18,11 @@ use rustc_ast::Recovered;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::unord::UnordMap;
-use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
-use rustc_hir as hir;
+use rustc_errors::{struct_span_code_err, Applicability, Diag, ErrorGuaranteed, StashKey, E0228};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::intravisit::{self, walk_generics, Visitor};
+use rustc_hir::{self as hir};
 use rustc_hir::{GenericParamKind, Node};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCause;
@@ -44,7 +44,7 @@ use std::ops::Bound;
 
 use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::errors;
-use crate::hir_ty_lowering::HirTyLowerer;
+use crate::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
 pub use type_of::test_opaque_hidden_types;
 
 mod generics_of;
@@ -370,32 +370,34 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
         self.tcx
     }
 
-    fn item_def_id(&self) -> DefId {
-        self.item_def_id.to_def_id()
+    fn item_def_id(&self) -> LocalDefId {
+        self.item_def_id
     }
 
-    fn allow_infer(&self) -> bool {
-        false
-    }
-
-    fn re_infer(&self, _: Option<&ty::GenericParamDef>, _: Span) -> Option<ty::Region<'tcx>> {
-        None
+    fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
+        if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
+            let e = struct_span_code_err!(
+                self.tcx().dcx(),
+                span,
+                E0228,
+                "the lifetime bound for this object type cannot be deduced \
+                from context; please supply an explicit bound"
+            )
+            .emit();
+            self.set_tainted_by_errors(e);
+            ty::Region::new_error(self.tcx(), e)
+        } else {
+            // This indicates an illegal lifetime in a non-assoc-trait position
+            ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")
+        }
     }
 
     fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
         Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
     }
 
-    fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
-        let ty = self.tcx.fold_regions(ty, |r, _| match *r {
-            rustc_type_ir::RegionKind::ReStatic => r,
-
-            // This is never reached in practice. If it ever is reached,
-            // `ReErased` should be changed to `ReStatic`, and any other region
-            // left alone.
-            r => bug!("unexpected region: {r:?}"),
-        });
-        ty::Const::new_error_with_message(self.tcx(), ty, span, "bad placeholder constant")
+    fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
+        ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
     }
 
     fn probe_ty_param_bounds(
@@ -510,6 +512,89 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
     fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
         self.tainted_by_errors.set(Some(err));
     }
+
+    fn lower_fn_sig(
+        &self,
+        decl: &hir::FnDecl<'tcx>,
+        generics: Option<&hir::Generics<'_>>,
+        hir_id: rustc_hir::HirId,
+        hir_ty: Option<&hir::Ty<'_>>,
+    ) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
+        let tcx = self.tcx();
+        // We proactively collect all the inferred type params to emit a single error per fn def.
+        let mut visitor = HirPlaceholderCollector::default();
+        let mut infer_replacements = vec![];
+
+        if let Some(generics) = generics {
+            walk_generics(&mut visitor, generics);
+        }
+
+        let input_tys = decl
+            .inputs
+            .iter()
+            .enumerate()
+            .map(|(i, a)| {
+                if let hir::TyKind::Infer = a.kind {
+                    if let Some(suggested_ty) =
+                        self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
+                    {
+                        infer_replacements.push((a.span, suggested_ty.to_string()));
+                        return Ty::new_error_with_message(tcx, a.span, suggested_ty.to_string());
+                    }
+                }
+
+                // Only visit the type looking for `_` if we didn't fix the type above
+                visitor.visit_ty(a);
+                self.lowerer().lower_arg_ty(a, None)
+            })
+            .collect();
+
+        let output_ty = match decl.output {
+            hir::FnRetTy::Return(output) => {
+                if let hir::TyKind::Infer = output.kind
+                    && let Some(suggested_ty) =
+                        self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
+                {
+                    infer_replacements.push((output.span, suggested_ty.to_string()));
+                    Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string())
+                } else {
+                    visitor.visit_ty(output);
+                    self.lower_ty(output)
+                }
+            }
+            hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
+        };
+
+        if !(visitor.0.is_empty() && infer_replacements.is_empty()) {
+            // We check for the presence of
+            // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
+
+            let mut diag = crate::collect::placeholder_type_error_diag(
+                tcx,
+                generics,
+                visitor.0,
+                infer_replacements.iter().map(|(s, _)| *s).collect(),
+                true,
+                hir_ty,
+                "function",
+            );
+
+            if !infer_replacements.is_empty() {
+                diag.multipart_suggestion(
+                    format!(
+                    "try replacing `_` with the type{} in the corresponding trait method signature",
+                    rustc_errors::pluralize!(infer_replacements.len()),
+                ),
+                    infer_replacements,
+                    Applicability::MachineApplicable,
+                );
+            }
+
+            self.set_tainted_by_errors(diag.emit());
+        }
+
+        (input_tys, output_ty)
+    }
 }
 
 /// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
@@ -1321,9 +1406,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
             icx.lowerer().lower_fn_ty(hir_id, header.safety, header.abi, decl, Some(generics), None)
         }
 
-        ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
+        ForeignItem(&hir::ForeignItem {
+            kind: ForeignItemKind::Fn(fn_decl, _, _, safety), ..
+        }) => {
             let abi = tcx.hir().get_foreign_abi(hir_id);
-            compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
+            compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi, safety)
         }
 
         Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
@@ -1695,11 +1782,12 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     def_id: LocalDefId,
     decl: &'tcx hir::FnDecl<'tcx>,
     abi: abi::Abi,
+    safety: hir::Safety,
 ) -> ty::PolyFnSig<'tcx> {
     let safety = if abi == abi::Abi::RustIntrinsic {
         intrinsic_operation_unsafety(tcx, def_id)
     } else {
-        hir::Safety::Unsafe
+        safety
     };
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
     let fty =
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 072bb727901..40204961e9c 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -1,7 +1,7 @@
 use crate::bounds::Bounds;
 use crate::collect::ItemCtxt;
 use crate::constrained_generic_params as cgp;
-use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
+use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
 use hir::{HirId, Node};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
@@ -117,7 +117,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     let mut is_trait = None;
     let mut is_default_impl_trait = None;
 
-    // FIXME: Should ItemCtxt take a LocalDefId?
     let icx = ItemCtxt::new(tcx, def_id);
 
     const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
@@ -197,7 +196,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
                     .type_of(param.def_id.to_def_id())
                     .no_bound_vars()
                     .expect("const parameters cannot be generic");
-                let ct = icx.lowerer().lower_const_param(param.hir_id, ct_ty);
+                let ct = icx.lowerer().lower_const_param(param.hir_id);
                 predicates
                     .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));
             }
@@ -244,12 +243,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
             }
 
             hir::WherePredicate::RegionPredicate(region_pred) => {
-                let r1 = icx.lowerer().lower_lifetime(region_pred.lifetime, None);
+                let r1 = icx
+                    .lowerer()
+                    .lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
                 predicates.extend(region_pred.bounds.iter().map(|bound| {
                     let (r2, span) = match bound {
-                        hir::GenericBound::Outlives(lt) => {
-                            (icx.lowerer().lower_lifetime(lt, None), lt.ident.span)
-                        }
+                        hir::GenericBound::Outlives(lt) => (
+                            icx.lowerer().lower_lifetime(lt, RegionInferReason::RegionPredicate),
+                            lt.ident.span,
+                        ),
                         bound => {
                             span_bug!(
                                 bound.span(),
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index c1850f78f2f..abc3bb838db 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -603,7 +603,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
         match item.kind {
-            hir::ForeignItemKind::Fn(_, _, generics) => {
+            hir::ForeignItemKind::Fn(_, _, generics, _) => {
                 self.visit_early_late(item.hir_id(), generics, |this| {
                     intravisit::walk_foreign_item(this, item);
                 })
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 71b08e29376..6811f62de07 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -464,7 +464,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
                 let args = ty::GenericArgs::identity_for_item(tcx, def_id);
                 Ty::new_fn_def(tcx, def_id.to_def_id(), args)
             }
-            ForeignItemKind::Static(t, _) => icx.lower_ty(t),
+            ForeignItemKind::Static(t, _, _) => icx.lower_ty(t),
             ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()),
         },
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index b6a1799c03f..7f6f57907c2 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -18,6 +18,8 @@ use crate::bounds::Bounds;
 use crate::errors;
 use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
 
+use super::RegionInferReason;
+
 impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// Add a `Sized` bound to the `bounds` if appropriate.
     ///
@@ -166,7 +168,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     );
                 }
                 hir::GenericBound::Outlives(lifetime) => {
-                    let region = self.lower_lifetime(lifetime, None);
+                    let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
                     bounds.push_region_bound(
                         self.tcx(),
                         ty::Binder::bind_with_vars(
@@ -366,11 +368,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                     },
                                 )
                             });
-                            let ty = tcx
-                                .type_of(param.def_id)
-                                .no_bound_vars()
-                                .expect("ct params cannot have early bound vars");
-                            ty::Const::new_error(tcx, guar, ty).into()
+                            ty::Const::new_error(tcx, guar).into()
                         }
                     };
                     num_bound_vars += 1;
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 2f54349d267..7ec64f1feda 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -20,7 +20,6 @@ mod lint;
 mod object_safety;
 
 use crate::bounds::Bounds;
-use crate::collect::HirPlaceholderCollector;
 use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
 use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
 use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
@@ -34,7 +33,6 @@ use rustc_errors::{
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit::{walk_generics, Visitor as _};
 use rustc_hir::{GenericArg, GenericArgs, HirId};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCause;
@@ -82,6 +80,20 @@ pub enum PredicateFilter {
     SelfAndAssociatedTypeBounds,
 }
 
+#[derive(Debug)]
+pub enum RegionInferReason<'a> {
+    /// Lifetime on a trait object behind a reference.
+    /// This allows inferring information from the reference.
+    BorrowedObjectLifetimeDefault,
+    /// A trait object's lifetime.
+    ObjectLifetimeDefault,
+    /// Generic lifetime parameter
+    Param(&'a ty::GenericParamDef),
+    RegionPredicate,
+    Reference,
+    OutlivesBound,
+}
+
 /// A context which can lower type-system entities from the [HIR][hir] to
 /// the [`rustc_middle::ty`] representation.
 ///
@@ -89,26 +101,17 @@ pub enum PredicateFilter {
 pub trait HirTyLowerer<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx>;
 
-    /// Returns the [`DefId`] of the overarching item whose constituents get lowered.
-    fn item_def_id(&self) -> DefId;
-
-    /// Returns `true` if the current context allows the use of inference variables.
-    fn allow_infer(&self) -> bool;
+    /// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered.
+    fn item_def_id(&self) -> LocalDefId;
 
     /// Returns the region to use when a lifetime is omitted (and not elided).
-    fn re_infer(&self, param: Option<&ty::GenericParamDef>, span: Span)
-    -> Option<ty::Region<'tcx>>;
+    fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
 
     /// Returns the type to use when a type is omitted.
     fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
 
     /// Returns the const to use when a const is omitted.
-    fn ct_infer(
-        &self,
-        ty: Ty<'tcx>,
-        param: Option<&ty::GenericParamDef>,
-        span: Span,
-    ) -> Const<'tcx>;
+    fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
 
     /// Probe bounds in scope where the bounded type coincides with the given type parameter.
     ///
@@ -151,6 +154,14 @@ pub trait HirTyLowerer<'tcx> {
         poly_trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Ty<'tcx>;
 
+    fn lower_fn_sig(
+        &self,
+        decl: &hir::FnDecl<'tcx>,
+        generics: Option<&hir::Generics<'_>>,
+        hir_id: HirId,
+        hir_ty: Option<&hir::Ty<'_>>,
+    ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
+
     /// Returns `AdtDef` if `ty` is an ADT.
     ///
     /// Note that `ty` might be a alias type that needs normalization.
@@ -258,7 +269,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     pub fn lower_lifetime(
         &self,
         lifetime: &hir::Lifetime,
-        def: Option<&ty::GenericParamDef>,
+        reason: RegionInferReason<'_>,
     ) -> ty::Region<'tcx> {
         let tcx = self.tcx();
         let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id));
@@ -292,21 +303,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar),
 
-            None => {
-                self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
-                    debug!(?lifetime, "unelided lifetime in signature");
-
-                    // This indicates an illegal lifetime
-                    // elision. `resolve_lifetime` should have
-                    // reported an error in this case -- but if
-                    // not, let's error out.
-                    ty::Region::new_error_with_message(
-                        tcx,
-                        lifetime.ident.span,
-                        "unelided lifetime in signature",
-                    )
-                })
-            }
+            None => self.re_infer(lifetime.ident.span, reason),
         }
     }
 
@@ -421,7 +418,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             def_id: DefId,
             generic_args: &'a GenericArgs<'tcx>,
             span: Span,
-            inferred_params: Vec<Span>,
             infer_args: bool,
             incorrect_args: &'a Result<(), GenericArgCountMismatch>,
         }
@@ -438,7 +434,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             fn provided_kind(
                 &mut self,
-                preceding_args: &[ty::GenericArg<'tcx>],
+                _preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
@@ -446,11 +442,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
                 if let Err(incorrect) = self.incorrect_args {
                     if incorrect.invalid_args.contains(&(param.index as usize)) {
-                        return param.to_error(tcx, preceding_args);
+                        return param.to_error(tcx);
                     }
                 }
 
-                let mut handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
+                let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
                     if has_default {
                         tcx.check_optional_stability(
                             param.def_id,
@@ -467,17 +463,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             },
                         );
                     }
-                    if let (hir::TyKind::Infer, false) = (&ty.kind, self.lowerer.allow_infer()) {
-                        self.inferred_params.push(ty.span);
-                        Ty::new_misc_error(tcx).into()
-                    } else {
-                        self.lowerer.lower_ty(ty).into()
-                    }
+                    self.lowerer.lower_ty(ty).into()
                 };
 
                 match (&param.kind, arg) {
                     (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
-                        self.lowerer.lower_lifetime(lt, Some(param)).into()
+                        self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
                     }
                     (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
                         handle_ty_args(has_default, ty)
@@ -491,17 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         ty::Const::from_anon_const(tcx, did).into()
                     }
                     (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
-                        let ty = tcx
-                            .at(self.span)
-                            .type_of(param.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic");
-                        if self.lowerer.allow_infer() {
-                            self.lowerer.ct_infer(ty, Some(param), inf.span).into()
-                        } else {
-                            self.inferred_params.push(inf.span);
-                            ty::Const::new_misc_error(tcx, ty).into()
-                        }
+                        self.lowerer.ct_infer(Some(param), inf.span).into()
                     }
                     (kind, arg) => span_bug!(
                         self.span,
@@ -520,24 +501,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
                 if let Err(incorrect) = self.incorrect_args {
                     if incorrect.invalid_args.contains(&(param.index as usize)) {
-                        return param.to_error(tcx, preceding_args);
+                        return param.to_error(tcx);
                     }
                 }
                 match param.kind {
-                    GenericParamDefKind::Lifetime => self
-                        .lowerer
-                        .re_infer(Some(param), self.span)
-                        .unwrap_or_else(|| {
-                            debug!(?param, "unelided lifetime in signature");
-
-                            // This indicates an illegal lifetime in a non-assoc-trait position
-                            ty::Region::new_error_with_message(
-                                tcx,
-                                self.span,
-                                "unelided lifetime in signature",
-                            )
-                        })
-                        .into(),
+                    GenericParamDefKind::Lifetime => {
+                        self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
+                    }
                     GenericParamDefKind::Type { has_default, .. } => {
                         if !infer_args && has_default {
                             // No type parameter provided, but a default exists.
@@ -568,7 +538,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             .no_bound_vars()
                             .expect("const parameter types cannot be generic");
                         if let Err(guar) = ty.error_reported() {
-                            return ty::Const::new_error(tcx, guar, ty).into();
+                            return ty::Const::new_error(tcx, guar).into();
                         }
                         // FIXME(effects) see if we should special case effect params here
                         if !infer_args && has_default {
@@ -577,10 +547,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                 .into()
                         } else {
                             if infer_args {
-                                self.lowerer.ct_infer(ty, Some(param), self.span).into()
+                                self.lowerer.ct_infer(Some(param), self.span).into()
                             } else {
                                 // We've already errored above about the mismatch.
-                                ty::Const::new_misc_error(tcx, ty).into()
+                                ty::Const::new_misc_error(tcx).into()
                             }
                         }
                     }
@@ -604,7 +574,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             def_id,
             span,
             generic_args: segment.args(),
-            inferred_params: vec![],
             infer_args: segment.infer_args,
             incorrect_args: &arg_count.correct,
         };
@@ -1493,16 +1462,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             let def_id = self.item_def_id();
             debug!(item_def_id = ?def_id);
 
-            let parent_def_id = def_id
-                .as_local()
-                .map(|def_id| tcx.local_def_id_to_hir_id(def_id))
-                .map(|hir_id| tcx.hir().get_parent_item(hir_id).to_def_id());
+            // FIXME: document why/how this is different from `tcx.local_parent(def_id)`
+            let parent_def_id =
+                tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id();
             debug!(?parent_def_id);
 
             // If the trait in segment is the same as the trait defining the item,
             // use the `<Self as ..>` syntax in the error.
-            let is_part_of_self_trait_constraints = def_id == trait_def_id;
-            let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id);
+            let is_part_of_self_trait_constraints = def_id.to_def_id() == trait_def_id;
+            let is_part_of_fn_in_self_trait = parent_def_id == trait_def_id;
 
             let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
                 vec!["Self".to_string()]
@@ -1930,7 +1898,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// Early-bound const parameters get lowered to [`ty::ConstKind::Param`]
     /// and late-bound ones to [`ty::ConstKind::Bound`].
-    pub(crate) fn lower_const_param(&self, hir_id: HirId, param_ty: Ty<'tcx>) -> Const<'tcx> {
+    pub(crate) fn lower_const_param(&self, hir_id: HirId) -> Const<'tcx> {
         let tcx = self.tcx();
         match tcx.named_bound_var(hir_id) {
             Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
@@ -1940,12 +1908,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let generics = tcx.generics_of(item_def_id);
                 let index = generics.param_def_id_to_index[&def_id];
                 let name = tcx.item_name(def_id);
-                ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty)
+                ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
             }
             Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
-                ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index), param_ty)
+                ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
             }
-            Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar, param_ty),
+            Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
             arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id),
         }
     }
@@ -1983,7 +1951,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
 
         let sig_generics = self.tcx().generics_of(sig_id);
-        let parent = self.tcx().parent(self.item_def_id());
+        let parent = self.tcx().local_parent(self.item_def_id());
         let parent_generics = self.tcx().generics_of(parent);
 
         let parent_is_trait = (self.tcx().def_kind(parent) == DefKind::Trait) as usize;
@@ -2022,7 +1990,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let sig = self.tcx().fn_sig(sig_id);
         let sig_generics = self.tcx().generics_of(sig_id);
 
-        let parent = self.tcx().parent(self.item_def_id());
+        let parent = self.tcx().local_parent(self.item_def_id());
         let parent_def_kind = self.tcx().def_kind(parent);
 
         let sig = if let DefKind::Impl { .. } = parent_def_kind
@@ -2070,7 +2038,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
             hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
             hir::TyKind::Ref(region, mt) => {
-                let r = self.lower_lifetime(region, None);
+                let r = self.lower_lifetime(region, RegionInferReason::Reference);
                 debug!(?r);
                 let t = self.lower_ty_common(mt.ty, true, false);
                 Ty::new_ref(tcx, r, t, mt.mutbl)
@@ -2161,7 +2129,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
             hir::TyKind::Array(ty, length) => {
                 let length = match length {
-                    hir::ArrayLen::Infer(inf) => self.ct_infer(tcx.types.usize, None, inf.span),
+                    hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
                     hir::ArrayLen::Body(constant) => {
                         ty::Const::from_anon_const(tcx, constant.def_id)
                     }
@@ -2192,17 +2160,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                 }
                                 _ => (expr, None),
                             };
-                            let c = match &expr.kind {
+                            let (c, c_ty) = match &expr.kind {
                                 hir::ExprKind::Lit(lit) => {
                                     let lit_input =
                                         LitToConstInput { lit: &lit.node, ty, neg: neg.is_some() };
-                                    match tcx.lit_to_const(lit_input) {
+                                    let ct = match tcx.lit_to_const(lit_input) {
                                         Ok(c) => c,
                                         Err(LitToConstError::Reported(err)) => {
-                                            ty::Const::new_error(tcx, err, ty)
+                                            ty::Const::new_error(tcx, err)
                                         }
                                         Err(LitToConstError::TypeError) => todo!(),
-                                    }
+                                    };
+                                    (ct, ty)
                                 }
 
                                 hir::ExprKind::Path(hir::QPath::Resolved(
@@ -2220,19 +2189,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                                         .type_of(def_id)
                                         .no_bound_vars()
                                         .expect("const parameter types cannot be generic");
-                                    self.lower_const_param(expr.hir_id, ty)
+                                    let ct = self.lower_const_param(expr.hir_id);
+                                    (ct, ty)
                                 }
 
                                 _ => {
                                     let err = tcx
                                         .dcx()
                                         .emit_err(crate::errors::NonConstRange { span: expr.span });
-                                    ty::Const::new_error(tcx, err, ty)
+                                    (ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
                                 }
                             };
-                            self.record_ty(expr.hir_id, c.ty(), expr.span);
+                            self.record_ty(expr.hir_id, c_ty, expr.span);
                             if let Some((id, span)) = neg {
-                                self.record_ty(id, c.ty(), span);
+                                self.record_ty(id, c_ty, span);
                             }
                             c
                         };
@@ -2299,7 +2269,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         &lifetimes[i]
                     )
                 };
-                self.lower_lifetime(lifetime, None).into()
+                self.lower_lifetime(lifetime, RegionInferReason::Param(&param)).into()
             } else {
                 tcx.mk_param_from_def(param)
             }
@@ -2338,92 +2308,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let bound_vars = tcx.late_bound_vars(hir_id);
         debug!(?bound_vars);
 
-        // We proactively collect all the inferred type params to emit a single error per fn def.
-        let mut visitor = HirPlaceholderCollector::default();
-        let mut infer_replacements = vec![];
-
-        if let Some(generics) = generics {
-            walk_generics(&mut visitor, generics);
-        }
-
-        let input_tys: Vec<_> = decl
-            .inputs
-            .iter()
-            .enumerate()
-            .map(|(i, a)| {
-                if let hir::TyKind::Infer = a.kind
-                    && !self.allow_infer()
-                {
-                    if let Some(suggested_ty) =
-                        self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
-                    {
-                        infer_replacements.push((a.span, suggested_ty.to_string()));
-                        return Ty::new_error_with_message(
-                            self.tcx(),
-                            a.span,
-                            suggested_ty.to_string(),
-                        );
-                    }
-                }
-
-                // Only visit the type looking for `_` if we didn't fix the type above
-                visitor.visit_ty(a);
-                self.lower_arg_ty(a, None)
-            })
-            .collect();
-
-        let output_ty = match decl.output {
-            hir::FnRetTy::Return(output) => {
-                if let hir::TyKind::Infer = output.kind
-                    && !self.allow_infer()
-                    && let Some(suggested_ty) =
-                        self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
-                {
-                    infer_replacements.push((output.span, suggested_ty.to_string()));
-                    Ty::new_error_with_message(self.tcx(), output.span, suggested_ty.to_string())
-                } else {
-                    visitor.visit_ty(output);
-                    self.lower_ty(output)
-                }
-            }
-            hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
-        };
+        let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
 
         debug!(?output_ty);
 
         let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
         let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
 
-        if !self.allow_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) {
-            // We always collect the spans for placeholder types when evaluating `fn`s, but we
-            // only want to emit an error complaining about them if infer types (`_`) are not
-            // allowed. `allow_infer` gates this behavior. We check for the presence of
-            // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
-
-            let mut diag = crate::collect::placeholder_type_error_diag(
-                tcx,
-                generics,
-                visitor.0,
-                infer_replacements.iter().map(|(s, _)| *s).collect(),
-                true,
-                hir_ty,
-                "function",
-            );
-
-            if !infer_replacements.is_empty() {
-                diag.multipart_suggestion(
-                    format!(
-                    "try replacing `_` with the type{} in the corresponding trait method signature",
-                    rustc_errors::pluralize!(infer_replacements.len()),
-                ),
-                    infer_replacements,
-                    Applicability::MachineApplicable,
-                );
-            }
-
-            self.set_tainted_by_errors(diag.emit());
-        }
-
         // Find any late-bound regions declared in return type that do
         // not appear in the arguments. These are not well-formed.
         //
@@ -2453,7 +2344,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     /// corresponding function in the trait that the impl implements, if it exists.
     /// If arg_idx is Some, then it corresponds to an input type index, otherwise it
     /// corresponds to the return type.
-    fn suggest_trait_fn_ty_for_impl_fn_infer(
+    pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
         &self,
         fn_hir_id: HirId,
         arg_idx: Option<usize>,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
index 4f7a39d0250..34924f09d09 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
@@ -1,5 +1,7 @@
 use crate::bounds::Bounds;
-use crate::hir_ty_lowering::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds};
+use crate::hir_ty_lowering::{
+    GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds, RegionInferReason,
+};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
@@ -141,9 +143,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         // `trait_object_dummy_self`, so check for that.
                         let references_self = match pred.skip_binder().term.unpack() {
                             ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),
-                            ty::TermKind::Const(c) => {
-                                c.ty().walk().any(|arg| arg == dummy_self.into())
-                            }
+                            // FIXME(associated_const_equality): We should walk the const instead of not doing anything
+                            ty::TermKind::Const(_) => false,
                         };
 
                         // If the projection output contains `Self`, force the user to
@@ -321,30 +322,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         // Use explicitly-specified region bound.
         let region_bound = if !lifetime.is_elided() {
-            self.lower_lifetime(lifetime, None)
+            self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
         } else {
             self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
                 if tcx.named_bound_var(lifetime.hir_id).is_some() {
-                    self.lower_lifetime(lifetime, None)
+                    self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
                 } else {
-                    self.re_infer(None, span).unwrap_or_else(|| {
-                        let err = struct_span_code_err!(
-                            tcx.dcx(),
-                            span,
-                            E0228,
-                            "the lifetime bound for this object type cannot be deduced \
-                             from context; please supply an explicit bound"
-                        );
-                        let e = if borrowed {
-                            // We will have already emitted an error E0106 complaining about a
-                            // missing named lifetime in `&dyn Trait`, so we elide this one.
-                            err.delay_as_bug()
+                    self.re_infer(
+                        span,
+                        if borrowed {
+                            RegionInferReason::ObjectLifetimeDefault
                         } else {
-                            err.emit()
-                        };
-                        self.set_tainted_by_errors(e);
-                        ty::Region::new_error(tcx, e)
-                    })
+                            RegionInferReason::BorrowedObjectLifetimeDefault
+                        },
+                    )
                 }
             })
         };
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index 3e15fddf559..13993a1992b 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -158,7 +158,7 @@ fn diagnostic_hir_wf_check<'tcx>(
             },
             hir::Node::Field(field) => vec![field.ty],
             hir::Node::ForeignItem(ForeignItem {
-                kind: ForeignItemKind::Static(ty, _), ..
+                kind: ForeignItemKind::Static(ty, _, _), ..
             }) => vec![*ty],
             hir::Node::GenericParam(hir::GenericParam {
                 kind: hir::GenericParamKind::Type { default: Some(ty), .. },
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index a8e0b3fc079..6983bbcb052 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -345,12 +345,12 @@ impl<'a> State<'a> {
         self.maybe_print_comment(item.span.lo());
         self.print_outer_attributes(self.attrs(item.hir_id()));
         match item.kind {
-            hir::ForeignItemKind::Fn(decl, arg_names, generics) => {
+            hir::ForeignItemKind::Fn(decl, arg_names, generics, safety) => {
                 self.head("");
                 self.print_fn(
                     decl,
                     hir::FnHeader {
-                        safety: hir::Safety::Safe,
+                        safety,
                         constness: hir::Constness::NotConst,
                         abi: Abi::Rust,
                         asyncness: hir::IsAsync::NotAsync,
@@ -364,7 +364,8 @@ impl<'a> State<'a> {
                 self.word(";");
                 self.end() // end the outer fn box
             }
-            hir::ForeignItemKind::Static(t, m) => {
+            hir::ForeignItemKind::Static(t, m, safety) => {
+                self.print_safety(safety);
                 self.head("static");
                 if m.is_mut() {
                     self.word_space("mut");
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index fa147f9bfcf..5d30b2a71e0 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -350,7 +350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             lt_op: |_| self.tcx.lifetimes.re_erased,
             ct_op: |ct| {
                 if let ty::ConstKind::Infer(_) = ct.kind() {
-                    self.next_const_var(ct.ty(), DUMMY_SP)
+                    self.next_const_var(DUMMY_SP)
                 } else {
                     ct
                 }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3d88c425524..7dd7b3ff055 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -13,7 +13,6 @@ use crate::errors::{
     YieldExprOutsideOfCoroutine,
 };
 use crate::fatally_break_rust;
-use crate::method::SelfSource;
 use crate::type_error_struct;
 use crate::CoroutineTypes;
 use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
@@ -223,7 +222,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ty = ensure_sufficient_stack(|| match &expr.kind {
             hir::ExprKind::Path(
                 qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
-            ) => self.check_expr_path(qpath, expr, args, call),
+            ) => self.check_expr_path(qpath, expr, Some(args), call),
             _ => self.check_expr_kind(expr, expected),
         });
         let ty = self.resolve_vars_if_possible(ty);
@@ -290,7 +289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ExprKind::Path(QPath::LangItem(lang_item, _)) => {
                 self.check_lang_item_path(lang_item, expr)
             }
-            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[], None),
+            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None, None),
             ExprKind::InlineAsm(asm) => {
                 // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
                 self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
@@ -502,12 +501,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         qpath: &'tcx hir::QPath<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
-        args: &'tcx [hir::Expr<'tcx>],
+        args: Option<&'tcx [hir::Expr<'tcx>]>,
         call: Option<&'tcx hir::Expr<'tcx>>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let (res, opt_ty, segs) =
-            self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span, Some(args));
+            self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
         let ty = match res {
             Res::Err => {
                 self.suggest_assoc_method_call(segs);
@@ -564,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We just want to check sizedness, so instead of introducing
                     // placeholder lifetimes with probing, we just replace higher lifetimes
                     // with fresh vars.
-                    let span = args.get(i).map(|a| a.span).unwrap_or(expr.span);
+                    let span = args.and_then(|args| args.get(i)).map_or(expr.span, |arg| arg.span);
                     let input = self.instantiate_binder_with_fresh_vars(
                         span,
                         infer::BoundRegionConversionTime::FnCall,
@@ -1331,9 +1330,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let rcvr_t = self.check_expr(rcvr);
         // no need to check for bot/err -- callee does that
         let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
-        let span = segment.ident.span;
 
-        let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) {
+        let method = match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args)
+        {
             Ok(method) => {
                 // We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
                 // trigger this codepath causing `structurally_resolve_type` to emit an error.
@@ -1342,18 +1341,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Err(error) => {
                 if segment.ident.name != kw::Empty {
-                    if let Some(err) = self.report_method_error(
-                        span,
-                        Some(rcvr),
-                        rcvr_t,
-                        segment.ident,
-                        expr.hir_id,
-                        SelfSource::MethodCall(rcvr),
-                        error,
-                        Some(args),
-                        expected,
-                        false,
-                    ) {
+                    if let Some(err) =
+                        self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)
+                    {
                         err.emit();
                     }
                 }
@@ -1362,7 +1352,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         // Call the generic checker.
-        self.check_method_argument_types(span, expr, method, args, DontTupleArguments, expected)
+        self.check_method_argument_types(
+            segment.ident.span,
+            expr,
+            method,
+            args,
+            DontTupleArguments,
+            expected,
+        )
     }
 
     fn check_expr_cast(
@@ -1674,6 +1671,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let mut error_happened = false;
 
+        if variant.fields.len() != remaining_fields.len() {
+            // Some field is defined more than once. Make sure we don't try to
+            // instantiate this struct in static/const context.
+            let guar =
+                self.dcx().span_delayed_bug(expr.span, "struct fields have non-unique names");
+            self.set_tainted_by_errors(guar);
+            error_happened = true;
+        }
+
         // Type-check each field.
         for (idx, field) in hir_fields.iter().enumerate() {
             let ident = tcx.adjust_ident(field.ident, variant.def_id);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 58eb0c28179..85c6d4dc12c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1,6 +1,6 @@
 use crate::callee::{self, DeferredCallResolution};
 use crate::errors::{self, CtorIsPrivate};
-use crate::method::{self, MethodCallee, SelfSource};
+use crate::method::{self, MethodCallee};
 use crate::rvalue_scopes;
 use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
 use rustc_data_structures::fx::FxHashSet;
@@ -16,7 +16,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{
 };
 use rustc_hir_analysis::hir_ty_lowering::{
     ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
-    GenericPathSegment, HirTyLowerer, IsMethodCall,
+    GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
 };
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
@@ -436,7 +436,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> {
         match length {
-            hir::ArrayLen::Infer(inf) => self.ct_infer(self.tcx.types.usize, None, inf.span),
+            hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span),
             hir::ArrayLen::Body(anon_const) => {
                 let span = self.tcx.def_span(anon_const.def_id);
                 let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id);
@@ -735,7 +735,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         qpath: &'tcx QPath<'tcx>,
         hir_id: HirId,
         span: Span,
-        args: Option<&'tcx [hir::Expr<'tcx>]>,
     ) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
         debug!(
             "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
@@ -828,14 +827,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 if item_name.name != kw::Empty {
                     if let Some(e) = self.report_method_error(
-                        span,
-                        None,
-                        ty.normalized,
-                        item_name,
                         hir_id,
-                        SelfSource::QPath(qself),
+                        ty.normalized,
                         error,
-                        args,
                         Expectation::NoExpectation,
                         trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021
                     ) {
@@ -1072,7 +1066,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ty::ImplContainer => {
                         if segments.len() == 1 {
                             // `<T>::assoc` will end up here, and so
-                            // can `T::assoc`. It this came from an
+                            // can `T::assoc`. If this came from an
                             // inherent impl, we need to record the
                             // `T` for posterity (see `UserSelfTy` for
                             // details).
@@ -1280,9 +1274,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
                 match (&param.kind, arg) {
-                    (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
-                        self.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
-                    }
+                    (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => self
+                        .fcx
+                        .lowerer()
+                        .lower_lifetime(lt, RegionInferReason::Param(param))
+                        .into(),
                     (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
                         self.fcx.lower_ty(ty).raw.into()
                     }
@@ -1296,20 +1292,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         &GenericParamDefKind::Const { has_default, is_host_effect },
                         GenericArg::Infer(inf),
                     ) => {
-                        let tcx = self.fcx.tcx();
-
                         if has_default && is_host_effect {
                             self.fcx.var_for_effect(param)
                         } else {
-                            self.fcx
-                                .ct_infer(
-                                    tcx.type_of(param.def_id)
-                                        .no_bound_vars()
-                                        .expect("const parameter types cannot be generic"),
-                                    Some(param),
-                                    inf.span,
-                                )
-                                .into()
+                            self.fcx.ct_infer(Some(param), inf.span).into()
                         }
                     }
                     _ => unreachable!(),
@@ -1324,9 +1310,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ) -> ty::GenericArg<'tcx> {
                 let tcx = self.fcx.tcx();
                 match param.kind {
-                    GenericParamDefKind::Lifetime => {
-                        self.fcx.re_infer(Some(param), self.span).unwrap().into()
-                    }
+                    GenericParamDefKind::Lifetime => self
+                        .fcx
+                        .re_infer(
+                            self.span,
+                            rustc_hir_analysis::hir_ty_lowering::RegionInferReason::Param(param),
+                        )
+                        .into(),
                     GenericParamDefKind::Type { has_default, .. } => {
                         if !infer_args && has_default {
                             // If we have a default, then it doesn't matter that we're not
@@ -1416,11 +1406,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ) {
                 Ok(ok) => self.register_infer_ok_obligations(ok),
                 Err(_) => {
-                    self.dcx().span_delayed_bug(
+                    self.dcx().span_bug(
                         span,
                         format!(
-                        "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
-                    ),
+                            "instantiate_value_path: (UFCS) {self_ty:?} was a subtype of {impl_ty:?} but now is not?",
+                        ),
                     );
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index afba812a8e7..f02b0f95390 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -15,7 +15,7 @@ use hir::def_id::CRATE_DEF_ID;
 use rustc_errors::DiagCtxt;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
+use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
 use rustc_infer::infer;
 use rustc_infer::infer::error_reporting::sub_relations::SubRelations;
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
@@ -213,25 +213,21 @@ impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
-    fn item_def_id(&self) -> DefId {
-        self.body_id.to_def_id()
+    fn item_def_id(&self) -> LocalDefId {
+        self.body_id
     }
 
-    fn allow_infer(&self) -> bool {
-        true
-    }
-
-    fn re_infer(&self, def: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>> {
-        let v = match def {
-            Some(def) => infer::RegionParameterDefinition(span, def.name),
-            None => infer::MiscVariable(span),
+    fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
+        let v = match reason {
+            RegionInferReason::Param(def) => infer::RegionParameterDefinition(span, def.name),
+            _ => infer::MiscVariable(span),
         };
-        Some(self.next_region_var(v))
+        self.next_region_var(v)
     }
 
     fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
@@ -241,12 +237,7 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn ct_infer(
-        &self,
-        ty: Ty<'tcx>,
-        param: Option<&ty::GenericParamDef>,
-        span: Span,
-    ) -> Const<'tcx> {
+    fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
         // FIXME ideally this shouldn't use unwrap
         match param {
             Some(
@@ -256,7 +247,7 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
                 },
             ) => self.var_for_effect(param).as_const().unwrap(),
             Some(param) => self.var_for_def(span, param).as_const().unwrap(),
-            None => self.next_const_var(ty, span),
+            None => self.next_const_var(span),
         }
     }
 
@@ -350,6 +341,22 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> {
     fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
         self.infcx.set_tainted_by_errors(e)
     }
+
+    fn lower_fn_sig(
+        &self,
+        decl: &rustc_hir::FnDecl<'tcx>,
+        _generics: Option<&rustc_hir::Generics<'_>>,
+        _hir_id: rustc_hir::HirId,
+        _hir_ty: Option<&hir::Ty<'_>>,
+    ) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
+        let input_tys = decl.inputs.iter().map(|a| self.lowerer().lower_arg_ty(a, None)).collect();
+
+        let output_ty = match decl.output {
+            hir::FnRetTy::Return(output) => self.lowerer().lower_ty(output),
+            hir::FnRetTy::DefaultReturn(..) => self.tcx().types.unit,
+        };
+        (input_tys, output_ty)
+    }
 }
 
 /// The `ty` representation of a user-provided type. Depending on the use-site
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 0825e661373..3c9a49e91a3 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -7,7 +7,9 @@ use rustc_hir::GenericArg;
 use rustc_hir_analysis::hir_ty_lowering::generics::{
     check_generic_arg_count_for_call, lower_generic_args,
 };
-use rustc_hir_analysis::hir_ty_lowering::{GenericArgsLowerer, HirTyLowerer, IsMethodCall};
+use rustc_hir_analysis::hir_ty_lowering::{
+    GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason,
+};
 use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
 use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@@ -388,9 +390,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
                 match (&param.kind, arg) {
-                    (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
-                        self.cfcx.fcx.lowerer().lower_lifetime(lt, Some(param)).into()
-                    }
+                    (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => self
+                        .cfcx
+                        .fcx
+                        .lowerer()
+                        .lower_lifetime(lt, RegionInferReason::Param(param))
+                        .into(),
                     (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
                         self.cfcx.lower_ty(ty).raw.into()
                     }
@@ -401,16 +406,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                         self.cfcx.ty_infer(Some(param), inf.span).into()
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
-                        let tcx = self.cfcx.tcx();
-                        self.cfcx
-                            .ct_infer(
-                                tcx.type_of(param.def_id)
-                                    .no_bound_vars()
-                                    .expect("const parameter types cannot be generic"),
-                                Some(param),
-                                inf.span,
-                            )
-                            .into()
+                        self.cfcx.ct_infer(Some(param), inf.span).into()
                     }
                     (kind, arg) => {
                         bug!("mismatched method arg kind {kind:?} in turbofish: {arg:?}")
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 4165ccb1b80..1f90d5e4c88 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -7,7 +7,6 @@ mod prelude_edition_lints;
 pub mod probe;
 mod suggest;
 
-pub use self::suggest::SelfSource;
 pub use self::MethodError::*;
 
 use crate::FnCtxt;
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 12ced49f92f..ab0f16bd87d 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -41,6 +41,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{
 use rustc_trait_selection::traits::query::CanonicalTyGoal;
 use rustc_trait_selection::traits::ObligationCtxt;
 use rustc_trait_selection::traits::{self, ObligationCause};
+use std::cell::Cell;
 use std::cell::RefCell;
 use std::cmp::max;
 use std::iter;
@@ -76,8 +77,12 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
     /// requested name (by edit distance)
     allow_similar_names: bool,
 
+    /// List of potential private candidates. Will be trimmed to ones that
+    /// actually apply and then the result inserted into `private_candidate`
+    private_candidates: Vec<Candidate<'tcx>>,
+
     /// Some(candidate) if there is a private candidate
-    private_candidate: Option<(DefKind, DefId)>,
+    private_candidate: Cell<Option<(DefKind, DefId)>>,
 
     /// Collects near misses when the candidate functions are missing a `self` keyword and is only
     /// used for error reporting
@@ -581,7 +586,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             orig_steps_var_values,
             steps,
             allow_similar_names: false,
-            private_candidate: None,
+            private_candidates: Vec::new(),
+            private_candidate: Cell::new(None),
             static_candidates: RefCell::new(Vec::new()),
             unsatisfied_predicates: RefCell::new(Vec::new()),
             scope_expr_id,
@@ -593,7 +599,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.inherent_candidates.clear();
         self.extension_candidates.clear();
         self.impl_dups.clear();
-        self.private_candidate = None;
+        self.private_candidates.clear();
+        self.private_candidate.set(None);
         self.static_candidates.borrow_mut().clear();
         self.unsatisfied_predicates.borrow_mut().clear();
     }
@@ -617,9 +624,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             } else {
                 self.extension_candidates.push(candidate);
             }
-        } else if self.private_candidate.is_none() {
-            self.private_candidate =
-                Some((candidate.item.kind.as_def_kind(), candidate.item.def_id));
+        } else {
+            self.private_candidates.push(candidate);
         }
     }
 
@@ -1171,7 +1177,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         let mut possibly_unsatisfied_predicates = Vec::new();
 
         for (kind, candidates) in
-            &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
+            [("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
         {
             debug!("searching {} candidates", kind);
             let res = self.consider_candidates(
@@ -1185,6 +1191,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             }
         }
 
+        if self.private_candidate.get().is_none() {
+            if let Some(Ok(pick)) =
+                self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], None)
+            {
+                self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id)));
+            }
+        }
+
         // `pick_method` may be called twice for the same self_ty if no stable methods
         // match. Only extend once.
         if unstable_candidates.is_some() {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index daaaf630f2c..c1e14f7fb75 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -16,11 +16,11 @@ use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{
     codes::*, pluralize, struct_span_code_err, Applicability, Diag, MultiSpan, StashKey,
 };
-use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::PathSegment;
+use rustc_hir::{self as hir, HirId};
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::{self, RegionVariableOrigin};
 use rustc_middle::bug;
@@ -187,37 +187,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     pub fn report_method_error(
         &self,
-        span: Span,
-        rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
+        call_id: HirId,
         rcvr_ty: Ty<'tcx>,
-        item_name: Ident,
-        expr_id: hir::HirId,
-        source: SelfSource<'tcx>,
         error: MethodError<'tcx>,
-        args: Option<&'tcx [hir::Expr<'tcx>]>,
         expected: Expectation<'tcx>,
         trait_missing_method: bool,
     ) -> Option<Diag<'_>> {
+        let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
+            hir::Node::Expr(&hir::Expr {
+                kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
+                span,
+                ..
+            }) => {
+                (segment.ident.span, span, SelfSource::MethodCall(rcvr), segment.ident, Some(args))
+            }
+            hir::Node::Expr(&hir::Expr {
+                kind: hir::ExprKind::Path(QPath::TypeRelative(rcvr, segment)),
+                span,
+                ..
+            })
+            | hir::Node::Pat(&hir::Pat {
+                kind:
+                    hir::PatKind::Path(QPath::TypeRelative(rcvr, segment))
+                    | hir::PatKind::Struct(QPath::TypeRelative(rcvr, segment), ..)
+                    | hir::PatKind::TupleStruct(QPath::TypeRelative(rcvr, segment), ..),
+                span,
+                ..
+            }) => {
+                let args = match self.tcx.parent_hir_node(call_id) {
+                    hir::Node::Expr(&hir::Expr {
+                        kind: hir::ExprKind::Call(callee, args), ..
+                    }) if callee.hir_id == call_id => Some(args),
+                    _ => None,
+                };
+                (segment.ident.span, span, SelfSource::QPath(rcvr), segment.ident, args)
+            }
+            node => unreachable!("{node:?}"),
+        };
+
         // Avoid suggestions when we don't know what's going on.
         if rcvr_ty.references_error() {
             return None;
         }
 
-        let sugg_span = if let SelfSource::MethodCall(expr) = source {
-            // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
-            self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)).span
-        } else {
-            span
-        };
-
         match error {
             MethodError::NoMatch(mut no_match_data) => {
                 return self.report_no_match_method_error(
                     span,
-                    rcvr_opt,
                     rcvr_ty,
                     item_name,
-                    expr_id,
+                    call_id,
                     source,
                     args,
                     sugg_span,
@@ -362,7 +381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn suggest_use_shadowed_binding_with_method(
         &self,
-        rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
+        self_source: SelfSource<'tcx>,
         method_name: Ident,
         ty_str_reported: &str,
         err: &mut Diag<'_>,
@@ -502,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        if let Some(rcvr) = rcvr_opt
+        if let SelfSource::MethodCall(rcvr) = self_source
             && let hir::ExprKind::Path(QPath::Resolved(_, path)) = rcvr.kind
             && let hir::def::Res::Local(recv_id) = path.res
             && let Some(segment) = path.segments.first()
@@ -548,7 +567,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn report_no_match_method_error(
         &self,
         mut span: Span,
-        rcvr_opt: Option<&'tcx hir::Expr<'tcx>>,
         rcvr_ty: Ty<'tcx>,
         item_name: Ident,
         expr_id: hir::HirId,
@@ -658,7 +676,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             if is_method {
                 self.suggest_use_shadowed_binding_with_method(
-                    rcvr_opt,
+                    source,
                     item_name,
                     &ty_str_reported,
                     &mut err,
@@ -2078,9 +2096,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 .next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
                                 .into(),
                             GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(),
-                            GenericArgKind::Const(arg) => {
-                                self.next_const_var(arg.ty(), DUMMY_SP).into()
-                            }
+                            GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
                         }
                     } else {
                         arg
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index b37aba38619..be91e7d45b6 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -12,7 +12,7 @@ use rustc_infer::infer;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_middle::{bug, span_bug};
-use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
+use rustc_session::{lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS, parse::feature_err};
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::Spanned;
@@ -223,9 +223,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info;
 
         let path_res = match &pat.kind {
-            PatKind::Path(qpath) => Some(
-                self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None),
-            ),
+            PatKind::Path(qpath) => {
+                Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
+            }
             _ => None,
         };
         let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
@@ -335,9 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         match adjust_mode {
             AdjustMode::Pass => (expected, def_br, max_ref_mutbl),
             AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut),
-            AdjustMode::Peel => {
-                self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl)
-            }
+            AdjustMode::Peel => self.peel_off_references(pat, expected, def_br, max_ref_mutbl),
         }
     }
 
@@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat: &'tcx Pat<'tcx>,
         expected: Ty<'tcx>,
         mut def_br: ByRef,
-        max_peelable_mutability: Mutability,
-        mut max_ref_mutability: MutblCap,
+        mut max_ref_mutbl: MutblCap,
     ) -> (Ty<'tcx>, ByRef, MutblCap) {
         let mut expected = self.try_structurally_resolve_type(pat.span, expected);
         // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
@@ -421,9 +418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         //
         // See the examples in `ui/match-defbm*.rs`.
         let mut pat_adjustments = vec![];
-        while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind()
-            && inner_mutability <= max_peelable_mutability
-        {
+        while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() {
             debug!("inspecting {:?}", expected);
 
             debug!("current discriminant is Ref, inserting implicit deref");
@@ -443,10 +438,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             });
         }
 
-        if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
-            def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl());
+        if self.tcx.features().ref_pat_eat_one_layer_2024 {
+            def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
             if def_br == ByRef::Yes(Mutability::Not) {
-                max_ref_mutability = MutblCap::Not;
+                max_ref_mutbl = MutblCap::Not;
             }
         }
 
@@ -458,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .insert(pat.hir_id, pat_adjustments);
         }
 
-        (expected, def_br, max_ref_mutability)
+        (expected, def_br, max_ref_mutbl)
     }
 
     fn check_pat_lit(
@@ -674,17 +669,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Determine the binding mode...
         let bm = match user_bind_annot {
-            // `mut` resets binding mode on edition <= 2021
-            BindingMode(ByRef::No, Mutability::Mut)
-                if !(pat.span.at_least_rust_2024()
-                    && self.tcx.features().mut_preserve_binding_mode_2024)
-                    && matches!(def_br, ByRef::Yes(_)) =>
-            {
-                self.typeck_results
-                    .borrow_mut()
-                    .rust_2024_migration_desugared_pats_mut()
-                    .insert(pat_info.top_info.hir_id);
-                BindingMode(ByRef::No, Mutability::Mut)
+            BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
+                if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
+                    if !self.tcx.features().mut_ref {
+                        feature_err(
+                            &self.tcx.sess,
+                            sym::mut_ref,
+                            pat.span.until(ident.span),
+                            "binding cannot be both mutable and by-reference",
+                        )
+                        .emit();
+                    }
+
+                    BindingMode(def_br, Mutability::Mut)
+                } else {
+                    // `mut` resets binding mode on edition <= 2021
+                    self.typeck_results
+                        .borrow_mut()
+                        .rust_2024_migration_desugared_pats_mut()
+                        .insert(pat_info.top_info.hir_id);
+                    BindingMode(ByRef::No, Mutability::Mut)
+                }
             }
             BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
             BindingMode(ByRef::Yes(_), _) => user_bind_annot,
@@ -1184,7 +1189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Resolve the path and check the definition for errors.
         let (res, opt_ty, segments) =
-            self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span, None);
+            self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
         if res == Res::Err {
             let e = tcx.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted");
             self.set_tainted_by_errors(e);
@@ -2126,57 +2131,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         mut expected: Ty<'tcx>,
         mut pat_info: PatInfo<'tcx, '_>,
     ) -> Ty<'tcx> {
-        // FIXME: repace with `bool` once final decision on 1 vs 2 layers is made
-        #[derive(Clone, Copy, Debug, PartialEq, Eq)]
-        enum MatchErgonomicsMode {
-            EatOneLayer,
-            EatTwoLayers,
-            Legacy,
-        }
+        let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024;
+        let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and;
 
-        let match_ergonomics_mode =
-            if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 {
-                MatchErgonomicsMode::EatOneLayer
-            } else if self.tcx.features().ref_pat_everywhere {
-                MatchErgonomicsMode::EatTwoLayers
-            } else {
-                MatchErgonomicsMode::Legacy
-            };
+        let pat_prefix_span =
+            inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end));
 
-        let mut inherited_ref_mutbl_match = false;
-        if match_ergonomics_mode != MatchErgonomicsMode::Legacy {
+        if no_ref_mut_behind_and {
             if pat_mutbl == Mutability::Not {
                 // Prevent the inner pattern from binding with `ref mut`.
-                pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(
-                    inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)),
-                );
+                pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not(pat_prefix_span);
             }
+        } else {
+            pat_info.max_ref_mutbl = MutblCap::Mut;
+        }
 
+        if new_match_ergonomics {
             if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
-                inherited_ref_mutbl_match = pat_mutbl <= inh_mut;
-            }
+                // ref pattern consumes inherited reference
+
+                if pat_mutbl > inh_mut {
+                    // Tried to match inherited `ref` with `&mut`, which is an error
+                    let err_msg = "cannot match inherited `&` with `&mut` pattern";
+                    let err = if let Some(span) = pat_prefix_span {
+                        let mut err = self.dcx().struct_span_err(span, err_msg);
+                        err.span_suggestion_verbose(
+                            span,
+                            "replace this `&mut` pattern with `&`",
+                            "&",
+                            Applicability::MachineApplicable,
+                        );
+                        err
+                    } else {
+                        self.dcx().struct_span_err(pat.span, err_msg)
+                    };
+                    err.emit();
+                }
 
-            if inherited_ref_mutbl_match {
                 pat_info.binding_mode = ByRef::No;
-                if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer {
-                    self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
-                    self.check_pat(inner, expected, pat_info);
-                    return expected;
-                }
-            } else if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer
-                && pat_mutbl == Mutability::Mut
-            {
-                // `&mut` patterns pell off `&` references
-                let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references(
-                    pat,
-                    expected,
-                    pat_info.binding_mode,
-                    Mutability::Not,
-                    pat_info.max_ref_mutbl,
-                );
-                expected = new_expected;
-                pat_info.binding_mode = new_bm;
-                pat_info.max_ref_mutbl = max_ref_mutbl;
+                self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
+                self.check_pat(inner, expected, pat_info);
+                return expected;
             }
         } else {
             // Reset binding mode on old editions
@@ -2189,8 +2184,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .rust_2024_migration_desugared_pats_mut()
                     .insert(pat_info.top_info.hir_id);
             }
-
-            pat_info.max_ref_mutbl = MutblCap::Mut;
         }
 
         let tcx = self.tcx;
@@ -2205,34 +2198,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // the bad interactions of the given hack detailed in (note_1).
                 debug!("check_pat_ref: expected={:?}", expected);
                 match *expected.kind() {
-                    ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => {
-                        if r_mutbl == Mutability::Not
-                            && match_ergonomics_mode != MatchErgonomicsMode::Legacy
-                        {
+                    ty::Ref(_, r_ty, r_mutbl)
+                        if (new_match_ergonomics && r_mutbl >= pat_mutbl)
+                            || r_mutbl == pat_mutbl =>
+                    {
+                        if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
                             pat_info.max_ref_mutbl = MutblCap::Not;
                         }
 
                         (expected, r_ty)
                     }
 
-                    // `&` pattern eats `&mut` reference
-                    ty::Ref(_, r_ty, Mutability::Mut)
-                        if pat_mutbl == Mutability::Not
-                            && match_ergonomics_mode != MatchErgonomicsMode::Legacy =>
-                    {
-                        (expected, r_ty)
-                    }
-
-                    _ if inherited_ref_mutbl_match
-                        && match_ergonomics_mode == MatchErgonomicsMode::EatTwoLayers =>
-                    {
-                        // We already matched against a match-ergonmics inserted reference,
-                        // so we don't need to match against a reference from the original type.
-                        // Save this info for use in lowering later
-                        self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id);
-                        (expected, expected)
-                    }
-
                     _ => {
                         let inner_ty = self.next_ty_var(inner.span);
                         let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty);
@@ -2409,7 +2385,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         min_len: u64,
     ) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
         let len = match len.eval(self.tcx, self.param_env, span) {
-            Ok(val) => val
+            // FIXME(BoxyUwU): Assert the `Ty` is a `usize`?
+            Ok((_, val)) => val
                 .try_to_scalar()
                 .and_then(|scalar| scalar.try_to_int().ok())
                 .and_then(|int| int.try_to_target_usize(self.tcx).ok()),
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index e337105f011..8727c0f87dc 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -863,7 +863,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
 
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
         self.handle_term(ct, ty::Const::outer_exclusive_binder, |tcx, guar| {
-            ty::Const::new_error(tcx, guar, ct.ty())
+            ty::Const::new_error(tcx, guar)
         })
         .super_fold_with(self)
     }
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 27b06c4b73e..bc2592b43f3 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -462,7 +462,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                 // any equated inference vars correctly!
                 let root_vid = self.infcx.unwrap().root_const_var(vid);
                 if root_vid != vid {
-                    ct = ty::Const::new_var(self.tcx, root_vid, ct.ty());
+                    ct = ty::Const::new_var(self.tcx, root_vid);
                     vid = root_vid;
                 }
 
@@ -481,7 +481,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
                             ui = ty::UniverseIndex::ROOT;
                         }
                         return self.canonicalize_const_var(
-                            CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty()) },
+                            CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
                             ct,
                         );
                     }
@@ -510,9 +510,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
             }
             ty::ConstKind::Placeholder(placeholder) => {
                 return self.canonicalize_const_var(
-                    CanonicalVarInfo {
-                        kind: CanonicalVarKind::PlaceholderConst(placeholder, ct.ty()),
-                    },
+                    CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
                     ct,
                 );
             }
@@ -719,9 +717,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
                     CanonicalVarKind::Region(u) => {
                         CanonicalVarKind::Region(reverse_universe_map[&u])
                     }
-                    CanonicalVarKind::Const(u, t) => {
-                        CanonicalVarKind::Const(reverse_universe_map[&u], t)
-                    }
+                    CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
                     CanonicalVarKind::PlaceholderTy(placeholder) => {
                         CanonicalVarKind::PlaceholderTy(ty::Placeholder {
                             universe: reverse_universe_map[&placeholder.universe],
@@ -734,14 +730,11 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
                             ..placeholder
                         })
                     }
-                    CanonicalVarKind::PlaceholderConst(placeholder, t) => {
-                        CanonicalVarKind::PlaceholderConst(
-                            ty::Placeholder {
-                                universe: reverse_universe_map[&placeholder.universe],
-                                ..placeholder
-                            },
-                            t,
-                        )
+                    CanonicalVarKind::PlaceholderConst(placeholder) => {
+                        CanonicalVarKind::PlaceholderConst(ty::Placeholder {
+                            universe: reverse_universe_map[&placeholder.universe],
+                            ..placeholder
+                        })
                     }
                 },
             })
@@ -806,6 +799,6 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
             !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve_const(const_var))
         );
         let var = self.canonical_var(info, const_var.into());
-        ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty()))
+        ty::Const::new_bound(self.tcx, self.binder_index, var)
     }
 }
diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
index de0e15ef3de..153de3d4c09 100644
--- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs
+++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs
@@ -70,7 +70,7 @@ where
                 GenericArgKind::Type(ty) => ty,
                 r => bug!("{:?} is a type but value is {:?}", bound_ty, r),
             },
-            consts: &mut |bound_ct: ty::BoundVar, _| match var_values[bound_ct].unpack() {
+            consts: &mut |bound_ct: ty::BoundVar| match var_values[bound_ct].unpack() {
                 GenericArgKind::Const(ct) => ct,
                 c => bug!("{:?} is a const but value is {:?}", bound_ct, c),
             },
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 1abb8086d41..8ad4f7926ca 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -143,8 +143,8 @@ impl<'tcx> InferCtxt<'tcx> {
                 ty::Region::new_placeholder(self.tcx, placeholder_mapped).into()
             }
 
-            CanonicalVarKind::Const(ui, ty) => {
-                self.next_const_var_in_universe(ty, span, universe_map(ui)).into()
+            CanonicalVarKind::Const(ui) => {
+                self.next_const_var_in_universe(span, universe_map(ui)).into()
             }
             CanonicalVarKind::Effect => {
                 let vid = self
@@ -153,13 +153,12 @@ impl<'tcx> InferCtxt<'tcx> {
                     .effect_unification_table()
                     .new_key(EffectVarValue::Unknown)
                     .vid;
-                ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool)
-                    .into()
+                ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid)).into()
             }
-            CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }, ty) => {
+            CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => {
                 let universe_mapped = universe_map(universe);
                 let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound };
-                ty::Const::new_placeholder(self.tcx, placeholder_mapped, ty).into()
+                ty::Const::new_placeholder(self.tcx, placeholder_mapped).into()
             }
         }
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index fb8c843f309..cb0e13652e8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -543,9 +543,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             match arg.unpack() {
                                 GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
                                 GenericArgKind::Type(_) => self.next_ty_var(DUMMY_SP).into(),
-                                GenericArgKind::Const(arg) => {
-                                    self.next_const_var(arg.ty(), DUMMY_SP).into()
-                                }
+                                GenericArgKind::Const(_) => self.next_const_var(DUMMY_SP).into(),
                             }
                         }))
                         .unwrap();
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index a3c8d5f4251..4bb59bd9037 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -79,7 +79,6 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
         &mut self,
         input: Result<ty::Const<'tcx>, ty::InferConst>,
         freshener: F,
-        ty: Ty<'tcx>,
     ) -> ty::Const<'tcx>
     where
         F: FnOnce(u32) -> ty::InferConst,
@@ -91,7 +90,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
                 Entry::Vacant(entry) => {
                     let index = self.const_freshen_count;
                     self.const_freshen_count += 1;
-                    let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty);
+                    let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index));
                     entry.insert(ct);
                     ct
                 }
@@ -149,7 +148,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
                         ty::InferConst::Var(inner.const_unification_table().find(v).vid)
                     });
                 drop(inner);
-                self.freshen_const(input, ty::InferConst::Fresh, ct.ty())
+                self.freshen_const(input, ty::InferConst::Fresh)
             }
             ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => {
                 let mut inner = self.infcx.inner.borrow_mut();
@@ -158,7 +157,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
                         ty::InferConst::EffectVar(inner.effect_unification_table().find(v).vid)
                     });
                 drop(inner);
-                self.freshen_const(input, ty::InferConst::Fresh, ct.ty())
+                self.freshen_const(input, ty::InferConst::Fresh)
             }
             ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
                 if i >= self.const_freshen_count {
@@ -177,7 +176,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
             }
 
             ty::ConstKind::Param(_)
-            | ty::ConstKind::Value(_)
+            | ty::ConstKind::Value(_, _)
             | ty::ConstKind::Unevaluated(..)
             | ty::ConstKind::Expr(..)
             | ty::ConstKind::Error(_) => ct.super_fold_with(self),
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index e9a4cc3e04b..4476611d9c8 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -392,18 +392,18 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
         self.opportunistic_resolve_float_var(vid)
     }
 
-    fn opportunistic_resolve_ct_var(&self, vid: ConstVid, ty: Ty<'tcx>) -> ty::Const<'tcx> {
+    fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> ty::Const<'tcx> {
         match self.probe_const_var(vid) {
             Ok(ct) => ct,
-            Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid), ty),
+            Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)),
         }
     }
 
-    fn opportunistic_resolve_effect_var(&self, vid: EffectVid, ty: Ty<'tcx>) -> ty::Const<'tcx> {
+    fn opportunistic_resolve_effect_var(&self, vid: EffectVid) -> ty::Const<'tcx> {
         match self.probe_effect_var(vid) {
             Some(ct) => ct,
             None => {
-                ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid)), ty)
+                ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid)))
             }
         }
     }
@@ -832,9 +832,7 @@ impl<'tcx> InferCtxt<'tcx> {
         (0..table.len())
             .map(|i| ty::EffectVid::from_usize(i))
             .filter(|&vid| table.probe_value(vid).is_unknown())
-            .map(|v| {
-                ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
-            })
+            .map(|v| ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v)))
             .collect()
     }
 
@@ -993,27 +991,22 @@ impl<'tcx> InferCtxt<'tcx> {
         Ty::new_var(self.tcx, vid)
     }
 
-    pub fn next_const_var(&self, ty: Ty<'tcx>, span: Span) -> ty::Const<'tcx> {
-        self.next_const_var_with_origin(ty, ConstVariableOrigin { span, param_def_id: None })
+    pub fn next_const_var(&self, span: Span) -> ty::Const<'tcx> {
+        self.next_const_var_with_origin(ConstVariableOrigin { span, param_def_id: None })
     }
 
-    pub fn next_const_var_with_origin(
-        &self,
-        ty: Ty<'tcx>,
-        origin: ConstVariableOrigin,
-    ) -> ty::Const<'tcx> {
+    pub fn next_const_var_with_origin(&self, origin: ConstVariableOrigin) -> ty::Const<'tcx> {
         let vid = self
             .inner
             .borrow_mut()
             .const_unification_table()
             .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
             .vid;
-        ty::Const::new_var(self.tcx, vid, ty)
+        ty::Const::new_var(self.tcx, vid)
     }
 
     pub fn next_const_var_in_universe(
         &self,
-        ty: Ty<'tcx>,
         span: Span,
         universe: ty::UniverseIndex,
     ) -> ty::Const<'tcx> {
@@ -1024,7 +1017,7 @@ impl<'tcx> InferCtxt<'tcx> {
             .const_unification_table()
             .new_key(ConstVariableValue::Unknown { origin, universe })
             .vid;
-        ty::Const::new_var(self.tcx, vid, ty)
+        ty::Const::new_var(self.tcx, vid)
     }
 
     pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid {
@@ -1135,15 +1128,7 @@ impl<'tcx> InferCtxt<'tcx> {
                     .const_unification_table()
                     .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
                     .vid;
-                ty::Const::new_var(
-                    self.tcx,
-                    const_var_id,
-                    self.tcx
-                        .type_of(param.def_id)
-                        .no_bound_vars()
-                        .expect("const parameter types cannot be generic"),
-                )
-                .into()
+                ty::Const::new_var(self.tcx, const_var_id).into()
             }
         }
     }
@@ -1157,7 +1142,7 @@ impl<'tcx> InferCtxt<'tcx> {
             .no_bound_vars()
             .expect("const parameter types cannot be generic");
         debug_assert_eq!(self.tcx.types.bool, ty);
-        ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid), ty).into()
+        ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid)).into()
     }
 
     /// Given a set of generics defined on a type or impl, returns the generic parameters mapping each
@@ -1314,7 +1299,7 @@ impl<'tcx> InferCtxt<'tcx> {
             | ty::ConstKind::Bound(_, _)
             | ty::ConstKind::Placeholder(_)
             | ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Value(_)
+            | ty::ConstKind::Value(_, _)
             | ty::ConstKind::Error(_)
             | ty::ConstKind::Expr(_) => ct,
         }
@@ -1469,10 +1454,10 @@ impl<'tcx> InferCtxt<'tcx> {
                     .or_insert_with(|| self.infcx.next_ty_var(self.span).into())
                     .expect_ty()
             }
-            fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> {
+            fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
                 self.map
                     .entry(bv)
-                    .or_insert_with(|| self.infcx.next_const_var(ty, self.span).into())
+                    .or_insert_with(|| self.infcx.next_const_var(self.span).into())
                     .expect_const()
             }
         }
@@ -1526,11 +1511,14 @@ impl<'tcx> InferCtxt<'tcx> {
         &self,
         param_env: ty::ParamEnv<'tcx>,
         unevaluated: ty::UnevaluatedConst<'tcx>,
-        ty: Ty<'tcx>,
         span: Span,
     ) -> Result<ty::Const<'tcx>, ErrorHandled> {
         match self.const_eval_resolve(param_env, unevaluated, span) {
-            Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, ty)),
+            Ok(Some(val)) => Ok(ty::Const::new_value(
+                self.tcx,
+                val,
+                self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args),
+            )),
             Ok(None) => {
                 let tcx = self.tcx;
                 let def_id = unevaluated.def;
@@ -1964,11 +1952,6 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
 
         fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
             if let ty::ConstKind::Infer(_) = c.kind() {
-                let ty = c.ty();
-                // If the type references param or infer then ICE ICE ICE
-                if ty.has_non_region_param() || ty.has_non_region_infer() {
-                    bug!("const `{c}`'s type should not reference params or types");
-                }
                 ty::Const::new_placeholder(
                     self.tcx,
                     ty::PlaceholderConst {
@@ -1979,7 +1962,6 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
                             idx
                         }),
                     },
-                    ty,
                 )
             } else {
                 c.super_fold_with(self)
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index d4c7d752c95..225c126fcf8 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -329,6 +329,14 @@ impl<'tcx> Generalizer<'_, 'tcx> {
         }
     }
 
+    /// Create a new type variable in the universe of the target when
+    /// generalizing an alias. This has to set `has_unconstrained_ty_var`
+    /// if we're currently in a bivariant context.
+    fn next_ty_var_for_alias(&mut self) -> Ty<'tcx> {
+        self.has_unconstrained_ty_var |= self.ambient_variance == ty::Bivariant;
+        self.infcx.next_ty_var_in_universe(self.span, self.for_universe)
+    }
+
     /// An occurs check failure inside of an alias does not mean
     /// that the types definitely don't unify. We may be able
     /// to normalize the alias after all.
@@ -358,7 +366,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
         //
         // cc trait-system-refactor-initiative#110
         if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias {
-            return Ok(self.infcx.next_ty_var_in_universe(self.span, self.for_universe));
+            return Ok(self.next_ty_var_for_alias());
         }
 
         let is_nested_alias = mem::replace(&mut self.in_alias, true);
@@ -378,7 +386,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
                     }
 
                     debug!("generalization failure in alias");
-                    Ok(self.infcx.next_ty_var_in_universe(self.span, self.for_universe))
+                    Ok(self.next_ty_var_for_alias())
                 }
             }
         };
@@ -645,7 +653,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
                             {
                                 variable_table.union(vid, new_var_id);
                             }
-                            Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
+                            Ok(ty::Const::new_var(self.tcx(), new_var_id))
                         }
                     }
                 }
@@ -663,11 +671,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
                     args,
                     args,
                 )?;
-                Ok(ty::Const::new_unevaluated(
-                    self.tcx(),
-                    ty::UnevaluatedConst { def, args },
-                    c.ty(),
-                ))
+                Ok(ty::Const::new_unevaluated(self.tcx(), ty::UnevaluatedConst { def, args }))
             }
             ty::ConstKind::Placeholder(placeholder) => {
                 if self.for_universe.can_name(placeholder.universe) {
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index 70ed7cf9af1..d3001eb5838 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -43,11 +43,10 @@ impl<'tcx> InferCtxt<'tcx> {
                     ty::PlaceholderType { universe: next_universe, bound: bound_ty },
                 )
             },
-            consts: &mut |bound_var: ty::BoundVar, ty| {
+            consts: &mut |bound_var: ty::BoundVar| {
                 ty::Const::new_placeholder(
                     self.tcx,
                     ty::PlaceholderConst { universe: next_universe, bound: bound_var },
-                    ty,
                 )
             },
         };
diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
index 4408251c99d..a086c82c92e 100644
--- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -244,7 +244,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> {
                 // Recreate it with a fresh variable here.
                 let idx = vid.index() - self.const_vars.0.start.index();
                 let origin = self.const_vars.1[idx];
-                self.infcx.next_const_var_with_origin(ct.ty(), origin)
+                self.infcx.next_const_var_with_origin(origin)
             } else {
                 ct
             }
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 5254a6576f9..c95a10f4e8d 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -14,7 +14,7 @@ use rustc_lint::LintStore;
 use rustc_middle::ty;
 use rustc_middle::ty::CurrentGcx;
 use rustc_middle::util::Providers;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
 use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
@@ -67,7 +67,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
                 };
             }
 
-            match maybe_new_parser_from_source_str(&psess, filename, s.to_string()) {
+            match new_parser_from_source_str(&psess, filename, s.to_string()) {
                 Ok(mut parser) => match parser.parse_meta_item() {
                     Ok(meta_item) if parser.token == token::Eof => {
                         if meta_item.path.segments.len() != 1 {
@@ -166,7 +166,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
             error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
         };
 
-        let mut parser = match maybe_new_parser_from_source_str(&psess, filename, s.to_string()) {
+        let mut parser = match new_parser_from_source_str(&psess, filename, s.to_string()) {
             Ok(parser) => parser,
             Err(errs) => {
                 errs.into_iter().for_each(|err| err.cancel());
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index b678582766d..d52286d5887 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -19,7 +19,9 @@ use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
-use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_attr};
+use rustc_parse::{
+    new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr,
+};
 use rustc_passes::{abi_test, hir_stats, layout_test};
 use rustc_resolve::Resolver;
 use rustc_session::code_stats::VTableSizeInfo;
@@ -42,11 +44,14 @@ use std::{env, fs, iter};
 use tracing::{info, instrument};
 
 pub fn parse<'a>(sess: &'a Session) -> PResult<'a, ast::Crate> {
-    let krate = sess.time("parse_crate", || match &sess.io.input {
-        Input::File(file) => parse_crate_from_file(file, &sess.psess),
-        Input::Str { input, name } => {
-            parse_crate_from_source_str(name.clone(), input.clone(), &sess.psess)
-        }
+    let krate = sess.time("parse_crate", || {
+        let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
+            Input::File(file) => new_parser_from_file(&sess.psess, file, None),
+            Input::Str { input, name } => {
+                new_parser_from_source_str(&sess.psess, name.clone(), input.clone())
+            }
+        });
+        parser.parse_crate_mod()
     })?;
 
     if sess.opts.unstable_opts.input_stats {
@@ -459,7 +464,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
                 }
             }
 
-            for &cnum in tcx.crates_including_speculative(()) {
+            for &cnum in tcx.crates(()) {
                 let source = tcx.used_crate_source(cnum);
                 if let Some((path, _)) = &source.dylib {
                     files.push(escape_dep_filename(&path.display().to_string()));
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index fb71cb60140..0c236a4ed11 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -462,6 +462,9 @@ lint_metavariable_wrong_operator = meta-variable repeats with different Kleene o
 
 lint_missing_fragment_specifier = missing fragment specifier
 
+lint_missing_unsafe_on_extern = extern blocks should be unsafe
+    .suggestion = needs `unsafe` before the extern keyword
+
 lint_mixed_script_confusables =
     the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
     .includes_note = the usage includes {$includes}
@@ -635,9 +638,6 @@ lint_pattern_in_foreign = patterns aren't allowed in foreign function declaratio
 lint_private_extern_crate_reexport =
     extern crate `{$ident}` is private, and cannot be re-exported, consider declaring with `pub`
 
-lint_proc_macro_back_compat = using an old version of `{$crate_name}`
-    .note = older versions of the `{$crate_name}` crate will stop compiling in future versions of Rust; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives
-
 lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` in this scope
     .label = names from parent modules are not accessible without an explicit import
 
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 26f34486a3d..1dfbe1e9382 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -159,9 +159,6 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
         BuiltinLintDiag::LegacyDeriveHelpers(label_span) => {
             lints::LegacyDeriveHelpers { span: label_span }.decorate_lint(diag);
         }
-        BuiltinLintDiag::ProcMacroBackCompat { crate_name, fixed_version } => {
-            lints::ProcMacroBackCompat { crate_name, fixed_version }.decorate_lint(diag);
-        }
         BuiltinLintDiag::OrPatternsBackCompat(suggestion_span, suggestion) => {
             lints::OrPatternsBackCompat { span: suggestion_span, suggestion }.decorate_lint(diag);
         }
@@ -205,6 +202,9 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
             };
             lints::DeprecatedWhereClauseLocation { suggestion }.decorate_lint(diag);
         }
+        BuiltinLintDiag::MissingUnsafeOnExtern { suggestion } => {
+            lints::MissingUnsafeOnExtern { suggestion }.decorate_lint(diag);
+        }
         BuiltinLintDiag::SingleUseLifetime {
             param_span,
             use_span: Some((use_span, elide)),
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 84d46ef3b65..c493a989d91 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2650,14 +2650,6 @@ pub struct LegacyDeriveHelpers {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_proc_macro_back_compat)]
-#[note]
-pub struct ProcMacroBackCompat {
-    pub crate_name: String,
-    pub fixed_version: String,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(lint_or_patterns_back_compat)]
 pub struct OrPatternsBackCompat {
     #[suggestion(code = "{suggestion}", applicability = "machine-applicable")]
@@ -2739,6 +2731,13 @@ pub enum DeprecatedWhereClauseLocationSugg {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_missing_unsafe_on_extern)]
+pub struct MissingUnsafeOnExtern {
+    #[suggestion(code = "unsafe ", applicability = "machine-applicable")]
+    pub suggestion: Span,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(lint_single_use_lifetime)]
 pub struct SingleUseLifetime {
     #[label(lint_label_param)]
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 9d3a838666a..f3a904022e9 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1741,13 +1741,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
         let abi = cx.tcx.hir().get_foreign_abi(it.hir_id());
 
         match it.kind {
-            hir::ForeignItemKind::Fn(decl, _, _) if !vis.is_internal_abi(abi) => {
+            hir::ForeignItemKind::Fn(decl, _, _, _) if !vis.is_internal_abi(abi) => {
                 vis.check_foreign_fn(it.owner_id.def_id, decl);
             }
-            hir::ForeignItemKind::Static(ty, _) if !vis.is_internal_abi(abi) => {
+            hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => {
                 vis.check_foreign_static(it.owner_id, ty.span);
             }
-            hir::ForeignItemKind::Fn(decl, _, _) => vis.check_fn(it.owner_id.def_id, decl),
+            hir::ForeignItemKind::Fn(decl, _, _, _) => vis.check_fn(it.owner_id.def_id, decl),
             hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (),
         }
     }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index a3044489fdc..d0d570db04f 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -66,6 +66,7 @@ declare_lint_pass! {
         META_VARIABLE_MISUSE,
         MISSING_ABI,
         MISSING_FRAGMENT_SPECIFIER,
+        MISSING_UNSAFE_ON_EXTERN,
         MUST_NOT_SUSPEND,
         NAMED_ARGUMENTS_USED_POSITIONALLY,
         NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
@@ -76,7 +77,6 @@ declare_lint_pass! {
         PATTERNS_IN_FNS_WITHOUT_BODY,
         PRIVATE_BOUNDS,
         PRIVATE_INTERFACES,
-        PROC_MACRO_BACK_COMPAT,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
         PUB_USE_OF_PRIVATE_EXTERN_CRATE,
         REDUNDANT_LIFETIMES,
@@ -3665,53 +3665,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `proc_macro_back_compat` lint detects uses of old versions of certain
-    /// proc-macro crates, which have hardcoded workarounds in the compiler.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,ignore (needs-dependency)
-    ///
-    /// use time_macros_impl::impl_macros;
-    /// struct Foo;
-    /// impl_macros!(Foo);
-    /// ```
-    ///
-    /// This will produce:
-    ///
-    /// ```text
-    /// warning: using an old version of `time-macros-impl`
-    ///   ::: $DIR/group-compat-hack.rs:27:5
-    ///    |
-    /// LL |     impl_macros!(Foo);
-    ///    |     ------------------ in this macro invocation
-    ///    |
-    ///    = note: `#[warn(proc_macro_back_compat)]` on by default
-    ///    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-    ///    = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-    ///    = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage
-    ///    = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-    /// ```
-    ///
-    /// ### Explanation
-    ///
-    /// Eventually, the backwards-compatibility hacks present in the compiler will be removed,
-    /// causing older versions of certain crates to stop compiling.
-    /// This is a [future-incompatible] lint to ease the transition to an error.
-    /// See [issue #83125] for more details.
-    ///
-    /// [issue #83125]: https://github.com/rust-lang/rust/issues/83125
-    /// [future-incompatible]: ../index.md#future-incompatible-lints
-    pub PROC_MACRO_BACK_COMPAT,
-    Deny,
-    "detects usage of old versions of certain proc-macro crates",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>",
-    };
-}
-
-declare_lint! {
     /// The `rust_2021_incompatible_or_patterns` lint detects usage of old versions of or-patterns.
     ///
     /// ### Example
@@ -4851,3 +4804,40 @@ declare_lint! {
         reference: "issue #27970 <https://github.com/rust-lang/rust/issues/27970>",
     };
 }
+
+declare_lint! {
+    /// The `missing_unsafe_on_extern` lint detects missing unsafe keyword on extern declarations.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![feature(unsafe_extern_blocks)]
+    /// #![warn(missing_unsafe_on_extern)]
+    /// #![allow(dead_code)]
+    ///
+    /// extern "C" {
+    ///     fn foo(_: i32);
+    /// }
+    ///
+    /// fn main() {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Declaring extern items, even without ever using them, can cause Undefined Behavior. We
+    /// should consider all sources of Undefined Behavior to be unsafe.
+    ///
+    /// This is a [future-incompatible] lint to transition this to a
+    /// hard error in the future.
+    ///
+    /// [future-incompatible]: ../index.md#future-incompatible-lints
+    pub MISSING_UNSAFE_ON_EXTERN,
+    Allow,
+    "detects missing unsafe keyword on extern declarations",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
+        reference: "issue #123743 <https://github.com/rust-lang/rust/issues/123743>",
+    };
+}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index c8a9fb02bf2..a2970884af4 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -618,10 +618,6 @@ pub enum BuiltinLintDiag {
         is_foreign: bool,
     },
     LegacyDeriveHelpers(Span),
-    ProcMacroBackCompat {
-        crate_name: String,
-        fixed_version: String,
-    },
     OrPatternsBackCompat(Span, String),
     ReservedPrefix(Span, String),
     TrailingMacro(bool, Ident),
@@ -630,6 +626,9 @@ pub enum BuiltinLintDiag {
     UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>),
     UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
     DeprecatedWhereclauseLocation(Span, Option<(Span, String)>),
+    MissingUnsafeOnExtern {
+        suggestion: Span,
+    },
     SingleUseLifetime {
         /// Span of the parameter which declares this lifetime.
         param_span: Span,
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index 25675e06e38..ceff1da9763 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -314,6 +314,17 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
     let mut query_description_stream = quote! {};
     let mut query_cached_stream = quote! {};
     let mut feedable_queries = quote! {};
+    let mut errors = quote! {};
+
+    macro_rules! assert {
+        ( $cond:expr, $span:expr, $( $tt:tt )+ ) => {
+            if !$cond {
+                errors.extend(
+                    Error::new($span, format!($($tt)+)).into_compile_error(),
+                );
+            }
+        }
+    }
 
     for query in queries.0 {
         let Query { name, arg, modifiers, .. } = &query;
@@ -369,10 +380,15 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             [#attribute_stream] fn #name(#arg) #result,
         });
 
-        if modifiers.feedable.is_some() {
-            assert!(modifiers.anon.is_none(), "Query {name} cannot be both `feedable` and `anon`.");
+        if let Some(feedable) = &modifiers.feedable {
+            assert!(
+                modifiers.anon.is_none(),
+                feedable.span(),
+                "Query {name} cannot be both `feedable` and `anon`."
+            );
             assert!(
                 modifiers.eval_always.is_none(),
+                feedable.span(),
                 "Query {name} cannot be both `feedable` and `eval_always`."
             );
             feedable_queries.extend(quote! {
@@ -407,5 +423,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             use super::*;
             #query_cached_stream
         }
+        #errors
     })
 }
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index bf9bbfb8cfa..9c69ab2344e 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -144,7 +144,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
                     && sess.crt_static(Some(ty))
                     && !sess.target.crt_static_allows_dylibs)
             {
-                for &cnum in tcx.used_crates(()).iter() {
+                for &cnum in tcx.crates(()).iter() {
                     if tcx.dep_kind(cnum).macros_only() {
                         continue;
                     }
@@ -165,7 +165,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
     // Sweep all crates for found dylibs. Add all dylibs, as well as their
     // dependencies, ensuring there are no conflicts. The only valid case for a
     // dependency to be relied upon twice is for both cases to rely on a dylib.
-    for &cnum in tcx.used_crates(()).iter() {
+    for &cnum in tcx.crates(()).iter() {
         if tcx.dep_kind(cnum).macros_only() {
             continue;
         }
@@ -183,7 +183,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
     }
 
     // Collect what we've got so far in the return vector.
-    let last_crate = tcx.used_crates(()).len();
+    let last_crate = tcx.crates(()).len();
     let mut ret = (1..last_crate + 1)
         .map(|cnum| match formats.get(&CrateNum::new(cnum)) {
             Some(&RequireDynamic) => Linkage::Dynamic,
@@ -197,7 +197,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
     //
     // If the crate hasn't been included yet and it's not actually required
     // (e.g., it's an allocator) then we skip it here as well.
-    for &cnum in tcx.used_crates(()).iter() {
+    for &cnum in tcx.crates(()).iter() {
         let src = tcx.used_crate_source(cnum);
         if src.dylib.is_none()
             && !formats.contains_key(&cnum)
@@ -285,7 +285,7 @@ fn add_library(
 
 fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<DependencyList> {
     let all_crates_available_as_rlib = tcx
-        .used_crates(())
+        .crates(())
         .iter()
         .copied()
         .filter_map(|cnum| {
@@ -306,7 +306,7 @@ fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<De
     // All crates are available in an rlib format, so we're just going to link
     // everything in explicitly so long as it's actually required.
     let mut ret = tcx
-        .used_crates(())
+        .crates(())
         .iter()
         .map(|&cnum| match tcx.dep_kind(cnum) {
             CrateDepKind::Explicit => Linkage::Static,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index f6b9c7ed992..afee8d5646c 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -439,7 +439,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
             // traversal, but not globally minimal across all crates.
             let bfs_queue = &mut VecDeque::new();
 
-            for &cnum in tcx.crates_including_speculative(()) {
+            for &cnum in tcx.crates(()) {
                 // Ignore crates without a corresponding local `extern crate` item.
                 if tcx.missing_extern_crate_item(cnum) {
                     continue;
@@ -509,7 +509,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
             tcx.arena
                 .alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
         },
-        crates_including_speculative: |tcx, ()| {
+        crates: |tcx, ()| {
             // The list of loaded crates is now frozen in query cache,
             // so make sure cstore is not mutably accessed from here on.
             tcx.untracked().cstore.freeze();
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 4f186981a76..67c5bc8c786 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1899,7 +1899,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let deps = self
             .tcx
-            .crates_including_speculative(())
+            .crates(())
             .iter()
             .map(|&cnum| {
                 let dep = CrateDep {
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 23a6ceb4d3e..dcbddad2dbc 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -156,10 +156,14 @@ fixed_size_enum! {
         ( Impl { of_trait: false }                 )
         ( Impl { of_trait: true }                  )
         ( Closure                                  )
-        ( Static { mutability: ast::Mutability::Not, nested: false } )
-        ( Static { mutability: ast::Mutability::Mut, nested: false } )
-        ( Static { mutability: ast::Mutability::Not, nested: true } )
-        ( Static { mutability: ast::Mutability::Mut, nested: true } )
+        ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: false } )
+        ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: false } )
+        ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: false } )
+        ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: false } )
+        ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: true } )
+        ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: true } )
+        ( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: true } )
+        ( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: true } )
         ( Ctor(CtorOf::Struct, CtorKind::Fn)       )
         ( Ctor(CtorOf::Struct, CtorKind::Const)    )
         ( Ctor(CtorOf::Variant, CtorKind::Fn)      )
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 639c98155e7..8a3bbf71eb6 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -305,7 +305,9 @@ impl<'hir> Map<'hir> {
             DefKind::InlineConst => BodyOwnerKind::Const { inline: true },
             DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn,
             DefKind::Closure => BodyOwnerKind::Closure,
-            DefKind::Static { mutability, nested: false } => BodyOwnerKind::Static(mutability),
+            DefKind::Static { safety: _, mutability, nested: false } => {
+                BodyOwnerKind::Static(mutability)
+            }
             dk => bug!("{:?} is not a body node: {:?}", def_id, dk),
         }
     }
@@ -886,7 +888,7 @@ impl<'hir> Map<'hir> {
             Node::Variant(variant) => named_span(variant.span, variant.ident, None),
             Node::ImplItem(item) => named_span(item.span, item.ident, Some(item.generics)),
             Node::ForeignItem(item) => match item.kind {
-                ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
+                ForeignItemKind::Fn(decl, _, _, _) => until_within(item.span, decl.output.span()),
                 _ => named_span(item.span, item.ident, None),
             },
             Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)),
@@ -1040,7 +1042,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
     let krate = tcx.hir_crate(());
     let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash");
 
-    let upstream_crates = upstream_crates_for_hashing(tcx);
+    let upstream_crates = upstream_crates(tcx);
 
     let resolutions = tcx.resolutions(());
 
@@ -1109,9 +1111,9 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
     Svh::new(crate_hash)
 }
 
-fn upstream_crates_for_hashing(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
+fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
     let mut upstream_crates: Vec<_> = tcx
-        .crates_including_speculative(())
+        .crates(())
         .iter()
         .map(|&cnum| {
             let stable_crate_id = tcx.stable_crate_id(cnum);
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index b0c14cdfec9..57c8ba96a20 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -201,7 +201,7 @@ pub fn provide(providers: &mut Providers) {
             ..
         })
         | Node::ForeignItem(&ForeignItem {
-            kind: ForeignItemKind::Fn(_, idents, _),
+            kind: ForeignItemKind::Fn(_, idents, _, _),
             ..
         }) = tcx.hir_node(tcx.local_def_id_to_hir_id(def_id))
         {
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index d47e393c912..b499604df87 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -4,15 +4,16 @@
 //! has their own README with further details).
 //!
 //! - **HIR.** The "high-level (H) intermediate representation (IR)" is
-//!   defined in the `hir` module.
+//!   defined in the [`hir`] module.
 //! - **MIR.** The "mid-level (M) intermediate representation (IR)" is
-//!   defined in the `mir` module. This module contains only the
+//!   defined in the [`mir`] module. This module contains only the
 //!   *definition* of the MIR; the passes that transform and operate
 //!   on MIR are found in `rustc_const_eval` crate.
 //! - **Types.** The internal representation of types used in rustc is
-//!   defined in the `ty` module. This includes the **type context**
-//!   (or `tcx`), which is the central context during most of
-//!   compilation, containing the interners and other things.
+//!   defined in the [`ty`] module. This includes the
+//!   [**type context**][ty::TyCtxt] (or `tcx`), which is the central
+//!   context during most of compilation, containing the interners and
+//!   other things.
 //!
 //! For more information about how rustc works, see the [rustc dev guide].
 //!
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index e107c2c12bd..cc8979dd990 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -204,7 +204,9 @@ pub enum Const<'tcx> {
     /// Any way of turning `ty::Const` into `ConstValue` should go through `valtree_to_const_val`;
     /// this ensures that we consistently produce "clean" values without data in the padding or
     /// anything like that.
-    Ty(ty::Const<'tcx>),
+    ///
+    /// FIXME(BoxyUwU): We should remove this `Ty` and look up the type for params via `ParamEnv`
+    Ty(Ty<'tcx>, ty::Const<'tcx>),
 
     /// An unevaluated mir constant which is not part of the type system.
     ///
@@ -237,7 +239,15 @@ impl<'tcx> Const<'tcx> {
     #[inline(always)]
     pub fn ty(&self) -> Ty<'tcx> {
         match self {
-            Const::Ty(c) => c.ty(),
+            Const::Ty(ty, ct) => {
+                match ct.kind() {
+                    // Dont use the outter ty as on invalid code we can wind up with them not being the same.
+                    // this then results in allowing const eval to add `1_i64 + 1_usize` in cases where the mir
+                    // was originally `({N: usize} + 1_usize)` under `generic_const_exprs`.
+                    ty::ConstKind::Value(ty, _) => ty,
+                    _ => *ty,
+                }
+            }
             Const::Val(_, ty) | Const::Unevaluated(_, ty) => *ty,
         }
     }
@@ -247,8 +257,8 @@ impl<'tcx> Const<'tcx> {
     #[inline]
     pub fn is_required_const(&self) -> bool {
         match self {
-            Const::Ty(c) => match c.kind() {
-                ty::ConstKind::Value(_) => false, // already a value, cannot error
+            Const::Ty(_, c) => match c.kind() {
+                ty::ConstKind::Value(_, _) => false, // already a value, cannot error
                 _ => true,
             },
             Const::Val(..) => false, // already a value, cannot error
@@ -259,8 +269,8 @@ impl<'tcx> Const<'tcx> {
     #[inline]
     pub fn try_to_scalar(self) -> Option<Scalar> {
         match self {
-            Const::Ty(c) => match c.kind() {
-                ty::ConstKind::Value(valtree) if c.ty().is_primitive() => {
+            Const::Ty(_, c) => match c.kind() {
+                ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
                     // A valtree of a type where leaves directly represent the scalar const value.
                     // Just checking whether it is a leaf is insufficient as e.g. references are leafs
                     // but the leaf value is the value they point to, not the reference itself!
@@ -278,8 +288,8 @@ impl<'tcx> Const<'tcx> {
         // This is equivalent to `self.try_to_scalar()?.try_to_int().ok()`, but measurably faster.
         match self {
             Const::Val(ConstValue::Scalar(Scalar::Int(x)), _) => Some(x),
-            Const::Ty(c) => match c.kind() {
-                ty::ConstKind::Value(valtree) if c.ty().is_primitive() => {
+            Const::Ty(_, c) => match c.kind() {
+                ty::ConstKind::Value(ty, valtree) if ty.is_primitive() => {
                     Some(valtree.unwrap_leaf())
                 }
                 _ => None,
@@ -306,11 +316,11 @@ impl<'tcx> Const<'tcx> {
         span: Span,
     ) -> Result<ConstValue<'tcx>, ErrorHandled> {
         match self {
-            Const::Ty(c) => {
+            Const::Ty(_, c) => {
                 // We want to consistently have a "clean" value for type system constants (i.e., no
                 // data hidden in the padding), so we always go through a valtree here.
-                let val = c.eval(tcx, param_env, span)?;
-                Ok(tcx.valtree_to_const_val((self.ty(), val)))
+                let (ty, val) = c.eval(tcx, param_env, span)?;
+                Ok(tcx.valtree_to_const_val((ty, val)))
             }
             Const::Unevaluated(uneval, _) => {
                 // FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
@@ -326,7 +336,7 @@ impl<'tcx> Const<'tcx> {
         match self.eval(tcx, param_env, DUMMY_SP) {
             Ok(val) => Self::Val(val, self.ty()),
             Err(ErrorHandled::Reported(guar, _span)) => {
-                Self::Ty(ty::Const::new_error(tcx, guar.into(), self.ty()))
+                Self::Ty(Ty::new_error(tcx, guar.into()), ty::Const::new_error(tcx, guar.into()))
             }
             Err(ErrorHandled::TooGeneric(_span)) => self,
         }
@@ -338,15 +348,16 @@ impl<'tcx> Const<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Option<Scalar> {
-        match self {
-            Const::Ty(c) if c.ty().is_primitive() => {
-                // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
-                // are valtree leaves, and *not* on references. (References should return the
-                // pointer here, which valtrees don't represent.)
-                let val = c.eval(tcx, param_env, DUMMY_SP).ok()?;
-                Some(val.unwrap_leaf().into())
-            }
-            _ => self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar(),
+        if let Const::Ty(_, c) = self
+            && let ty::ConstKind::Value(ty, val) = c.kind()
+            && ty.is_primitive()
+        {
+            // Avoid the `valtree_to_const_val` query. Can only be done on primitive types that
+            // are valtree leaves, and *not* on references. (References should return the
+            // pointer here, which valtrees don't represent.)
+            Some(val.unwrap_leaf().into())
+        } else {
+            self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
         }
     }
 
@@ -439,14 +450,14 @@ impl<'tcx> Const<'tcx> {
         Self::Val(val, ty)
     }
 
-    pub fn from_ty_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
+    pub fn from_ty_const(c: ty::Const<'tcx>, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
         match c.kind() {
-            ty::ConstKind::Value(valtree) => {
+            ty::ConstKind::Value(ty, valtree) => {
                 // Make sure that if `c` is normalized, then the return value is normalized.
-                let const_val = tcx.valtree_to_const_val((c.ty(), valtree));
-                Self::Val(const_val, c.ty())
+                let const_val = tcx.valtree_to_const_val((ty, valtree));
+                Self::Val(const_val, ty)
             }
-            _ => Self::Ty(c),
+            _ => Self::Ty(ty, c),
         }
     }
 
@@ -458,12 +469,12 @@ impl<'tcx> Const<'tcx> {
         // - valtrees purposefully generate new allocations
         // - ConstValue::Slice also generate new allocations
         match self {
-            Const::Ty(c) => match c.kind() {
+            Const::Ty(_, c) => match c.kind() {
                 ty::ConstKind::Param(..) => true,
                 // A valtree may be a reference. Valtree references correspond to a
                 // different allocation each time they are evaluated. Valtrees for primitive
                 // types are fine though.
-                ty::ConstKind::Value(_) => c.ty().is_primitive(),
+                ty::ConstKind::Value(ty, _) => ty.is_primitive(),
                 ty::ConstKind::Unevaluated(..) | ty::ConstKind::Expr(..) => false,
                 // This can happen if evaluation of a constant failed. The result does not matter
                 // much since compilation is doomed.
@@ -517,7 +528,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
 impl<'tcx> Display for Const<'tcx> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         match *self {
-            Const::Ty(c) => pretty_print_const(c, fmt, true),
+            Const::Ty(_, c) => pretty_print_const(c, fmt, true),
             Const::Val(val, ty) => pretty_print_const_value(val, ty, fmt),
             // FIXME(valtrees): Correctly print mir constants.
             Const::Unevaluated(c, _ty) => {
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index fe743fa4aac..95857e8579d 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -1,4 +1,6 @@
-use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId};
+use super::{
+    ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, GlobalId,
+};
 
 use crate::mir;
 use crate::query::TyCtxtEnsure;
@@ -13,7 +15,7 @@ use tracing::{debug, instrument};
 
 impl<'tcx> TyCtxt<'tcx> {
     /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
-    /// that can't take any generic arguments like statics, const items or enum discriminants. If a
+    /// that can't take any generic arguments like const items or enum discriminants. If a
     /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
     #[instrument(skip(self), level = "debug")]
     pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> {
@@ -27,6 +29,24 @@ impl<'tcx> TyCtxt<'tcx> {
         let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
         self.const_eval_global_id(param_env, cid, DUMMY_SP)
     }
+
+    /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
+    /// that can't take any generic arguments like const items or enum discriminants. If a
+    /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
+    #[instrument(skip(self), level = "debug")]
+    pub fn const_eval_poly_to_alloc(self, def_id: DefId) -> EvalToAllocationRawResult<'tcx> {
+        // In some situations def_id will have generic parameters within scope, but they aren't allowed
+        // to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
+        // into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
+        // encountered.
+        let args = GenericArgs::identity_for_item(self, def_id);
+        let instance = ty::Instance::new(def_id, args);
+        let cid = GlobalId { instance, promoted: None };
+        let param_env = self.param_env(def_id).with_reveal_all_normalized(self);
+        let inputs = self.erase_regions(param_env.and(cid));
+        self.eval_to_allocation_raw(inputs)
+    }
+
     /// Resolves and evaluates a constant.
     ///
     /// The constant can be located on a trait like `<A as B>::C`, in which case the given
@@ -177,7 +197,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
 impl<'tcx> TyCtxtEnsure<'tcx> {
     /// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
-    /// that can't take any generic arguments like statics, const items or enum discriminants. If a
+    /// that can't take any generic arguments like const items or enum discriminants. If a
     /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
     #[instrument(skip(self), level = "debug")]
     pub fn const_eval_poly(self, def_id: DefId) {
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index f1c79c0b039..b64b7e2b1dc 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -559,10 +559,10 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io:
     match (kind, body.source.promoted) {
         (_, Some(_)) => write!(w, "const ")?, // promoteds are the closest to consts
         (DefKind::Const | DefKind::AssocConst, _) => write!(w, "const ")?,
-        (DefKind::Static { mutability: hir::Mutability::Not, nested: false }, _) => {
+        (DefKind::Static { safety: _, mutability: hir::Mutability::Not, nested: false }, _) => {
             write!(w, "static ")?
         }
-        (DefKind::Static { mutability: hir::Mutability::Mut, nested: false }, _) => {
+        (DefKind::Static { safety: _, mutability: hir::Mutability::Mut, nested: false }, _) => {
             write!(w, "static mut ")?
         }
         (_, _) if is_function => write!(w, "fn ")?,
@@ -1313,12 +1313,12 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
             };
 
             let val = match const_ {
-                Const::Ty(ct) => match ct.kind() {
+                Const::Ty(_, ct) => match ct.kind() {
                     ty::ConstKind::Param(p) => format!("ty::Param({p})"),
                     ty::ConstKind::Unevaluated(uv) => {
                         format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
                     }
-                    ty::ConstKind::Value(val) => format!("ty::Valtree({})", fmt_valtree(&val)),
+                    ty::ConstKind::Value(_, val) => format!("ty::Valtree({})", fmt_valtree(&val)),
                     // No `ty::` prefix since we also use this to represent errors from `mir::Unevaluated`.
                     ty::ConstKind::Error(_) => "Error".to_string(),
                     // These variants shouldn't exist in the MIR.
@@ -1417,7 +1417,7 @@ pub fn write_allocations<'tcx>(
     impl<'tcx> Visitor<'tcx> for CollectAllocIds {
         fn visit_constant(&mut self, c: &ConstOperand<'tcx>, _: Location) {
             match c.const_ {
-                Const::Ty(_) | Const::Unevaluated(..) => {}
+                Const::Ty(_, _) | Const::Unevaluated(..) => {}
                 Const::Val(val, _) => {
                     self.0.extend(alloc_ids_from_const_val(val));
                 }
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 8901fd42d93..f553b417294 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -895,7 +895,7 @@ macro_rules! make_mir_visitor {
 
                 self.visit_span($(& $mutability)? *span);
                 match const_ {
-                    Const::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
+                    Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location),
                     Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
                     Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
                 }
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index f98dbf8a0bd..b29a86d58ed 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -4,7 +4,7 @@ use crate::traits;
 use crate::ty::adjustment::CoerceUnsizedInfo;
 use crate::ty::{self, Ty};
 use std::intrinsics::transmute_unchecked;
-use std::mem::{size_of, MaybeUninit};
+use std::mem::MaybeUninit;
 
 #[derive(Copy, Clone)]
 pub struct Erased<T: Copy> {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 3c4aae73bc4..0af32a6a857 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1861,22 +1861,13 @@ rustc_queries! {
         eval_always
         desc { "calculating the stability index for the local crate" }
     }
-    /// All loaded crates, including those loaded purely for doc links or diagnostics.
-    /// (Diagnostics include lints, so speculatively loaded crates may occur in successful
-    /// compilation even without doc links.)
-    /// Should be used when encoding crate metadata (and therefore when generating crate hash,
-    /// depinfo and similar things), to avoid dangling crate references in other encoded data,
-    /// like source maps.
-    /// May also be used for diagnostics - if we are loading a crate anyway we can suggest some
-    /// items from it as well.
-    /// But otherwise, `used_crates` should generally be used.
-    query crates_including_speculative(_: ()) -> &'tcx [CrateNum] {
+    query crates(_: ()) -> &'tcx [CrateNum] {
         eval_always
         desc { "fetching all foreign CrateNum instances" }
     }
-    /// Crates that are loaded non-speculatively (not for diagnostics or doc links).
-    /// Should be used to maintain observable language behavior, for example when collecting lang
-    /// items or impls from all crates, or collecting libraries to link.
+    // Crates that are loaded non-speculatively (not for diagnostics or doc links).
+    // FIXME: This is currently only used for collecting lang items, but should be used instead of
+    // `crates` in most other cases too.
     query used_crates(_: ()) -> &'tcx [CrateNum] {
         eval_always
         desc { "fetching `CrateNum`s for all crates loaded non-speculatively" }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 62e71c4db11..63678ab659d 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -616,6 +616,8 @@ pub enum SelectionError<'tcx> {
     /// We can thus not know whether the hidden type implements an auto trait, so
     /// we should not presume anything about it.
     OpaqueTypeAutoTraitLeakageUnknown(DefId),
+    /// Error for a `ConstArgHasType` goal
+    ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
 }
 
 #[derive(Clone, Debug, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs
index 7fb5e9aadae..254e1b54481 100644
--- a/compiler/rustc_middle/src/ty/abstract_const.rs
+++ b/compiler/rustc_middle/src/ty/abstract_const.rs
@@ -53,7 +53,7 @@ impl<'tcx> TyCtxt<'tcx> {
             fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
                 let ct = match c.kind() {
                     ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
-                        Err(e) => ty::Const::new_error(self.tcx, e, c.ty()),
+                        Err(e) => ty::Const::new_error(self.tcx, e),
                         Ok(Some(bac)) => {
                             let args = self.tcx.erase_regions(uv.args);
                             let bac = bac.instantiate(self.tcx, args);
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 07652b47929..33f564e9b59 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -350,8 +350,8 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
 
 impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Const<'tcx> {
     fn decode(decoder: &mut D) -> Self {
-        let consts: ty::ConstData<'tcx> = Decodable::decode(decoder);
-        decoder.interner().mk_ct_from_kind(consts.kind, consts.ty)
+        let kind: ty::ConstKind<'tcx> = Decodable::decode(decoder);
+        decoder.interner().mk_ct_from_kind(kind)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 384a4e7009d..dc13cc5437d 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -6,7 +6,7 @@ use rustc_error_messages::MultiSpan;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
-use rustc_macros::{HashStable, TyDecodable, TyEncodable};
+use rustc_macros::HashStable;
 use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
 use tracing::{debug, instrument};
 
@@ -24,12 +24,11 @@ pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
 pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
 
 #[cfg(target_pointer_width = "64")]
-rustc_data_structures::static_assert_size!(ConstKind<'_>, 24);
+rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
 
-/// Use this rather than `ConstData`, whenever possible.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
 #[rustc_pass_by_value]
-pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>);
+pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstKind<'tcx>>>);
 
 impl<'tcx> rustc_type_ir::inherent::IntoKind for Const<'tcx> {
     type Kind = ConstKind<'tcx>;
@@ -49,26 +48,11 @@ impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
     }
 }
 
-/// Typed constant value.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-#[derive(HashStable, TyEncodable, TyDecodable)]
-pub struct ConstData<'tcx> {
-    pub ty: Ty<'tcx>,
-    pub kind: ConstKind<'tcx>,
-}
-
-#[cfg(target_pointer_width = "64")]
-rustc_data_structures::static_assert_size!(ConstData<'_>, 32);
-
 impl<'tcx> Const<'tcx> {
     #[inline]
-    pub fn ty(self) -> Ty<'tcx> {
-        self.0.ty
-    }
-
-    #[inline]
     pub fn kind(self) -> ConstKind<'tcx> {
-        self.0.kind
+        let a: &ConstKind<'tcx> = self.0.0;
+        *a
     }
 
     // FIXME(compiler-errors): Think about removing this.
@@ -84,28 +68,28 @@ impl<'tcx> Const<'tcx> {
     }
 
     #[inline]
-    pub fn new(tcx: TyCtxt<'tcx>, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
-        tcx.mk_ct_from_kind(kind, ty)
+    pub fn new(tcx: TyCtxt<'tcx>, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
+        tcx.mk_ct_from_kind(kind)
     }
 
     #[inline]
-    pub fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamConst, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Param(param), ty)
+    pub fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamConst) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Param(param))
     }
 
     #[inline]
-    pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Var(infer)), ty)
+    pub fn new_var(tcx: TyCtxt<'tcx>, infer: ty::ConstVid) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Var(infer)))
     }
 
     #[inline]
-    pub fn new_fresh(tcx: TyCtxt<'tcx>, fresh: u32, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Fresh(fresh)), ty)
+    pub fn new_fresh(tcx: TyCtxt<'tcx>, fresh: u32) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Infer(ty::InferConst::Fresh(fresh)))
     }
 
     #[inline]
-    pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Infer(infer), ty)
+    pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Infer(infer))
     }
 
     #[inline]
@@ -113,50 +97,40 @@ impl<'tcx> Const<'tcx> {
         tcx: TyCtxt<'tcx>,
         debruijn: ty::DebruijnIndex,
         var: ty::BoundVar,
-        ty: Ty<'tcx>,
     ) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Bound(debruijn, var), ty)
+        Const::new(tcx, ty::ConstKind::Bound(debruijn, var))
     }
 
     #[inline]
-    pub fn new_placeholder(
-        tcx: TyCtxt<'tcx>,
-        placeholder: ty::PlaceholderConst,
-        ty: Ty<'tcx>,
-    ) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Placeholder(placeholder), ty)
+    pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Placeholder(placeholder))
     }
 
     #[inline]
-    pub fn new_unevaluated(
-        tcx: TyCtxt<'tcx>,
-        uv: ty::UnevaluatedConst<'tcx>,
-        ty: Ty<'tcx>,
-    ) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Unevaluated(uv), ty)
+    pub fn new_unevaluated(tcx: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Unevaluated(uv))
     }
 
     #[inline]
     pub fn new_value(tcx: TyCtxt<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Value(val), ty)
+        Const::new(tcx, ty::ConstKind::Value(ty, val))
     }
 
     #[inline]
-    pub fn new_expr(tcx: TyCtxt<'tcx>, expr: ty::Expr<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Expr(expr), ty)
+    pub fn new_expr(tcx: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Expr(expr))
     }
 
     #[inline]
-    pub fn new_error(tcx: TyCtxt<'tcx>, e: ty::ErrorGuaranteed, ty: Ty<'tcx>) -> Const<'tcx> {
-        Const::new(tcx, ty::ConstKind::Error(e), ty)
+    pub fn new_error(tcx: TyCtxt<'tcx>, e: ty::ErrorGuaranteed) -> Const<'tcx> {
+        Const::new(tcx, ty::ConstKind::Error(e))
     }
 
     /// Like [Ty::new_error] but for constants.
     #[track_caller]
-    pub fn new_misc_error(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
+    pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Const<'tcx> {
         Const::new_error_with_message(
             tcx,
-            ty,
             DUMMY_SP,
             "ty::ConstKind::Error constructed but no error reported",
         )
@@ -166,52 +140,33 @@ impl<'tcx> Const<'tcx> {
     #[track_caller]
     pub fn new_error_with_message<S: Into<MultiSpan>>(
         tcx: TyCtxt<'tcx>,
-        ty: Ty<'tcx>,
         span: S,
         msg: &'static str,
     ) -> Const<'tcx> {
         let reported = tcx.dcx().span_delayed_bug(span, msg);
-        Const::new_error(tcx, reported, ty)
+        Const::new_error(tcx, reported)
     }
 }
 
 impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
-    fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Self {
-        Const::new_infer(tcx, infer, ty)
+    fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self {
+        Const::new_infer(tcx, infer)
     }
 
-    fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid, ty: Ty<'tcx>) -> Self {
-        Const::new_var(tcx, vid, ty)
+    fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid) -> Self {
+        Const::new_var(tcx, vid)
     }
 
-    fn new_bound(
-        interner: TyCtxt<'tcx>,
-        debruijn: ty::DebruijnIndex,
-        var: ty::BoundVar,
-        ty: Ty<'tcx>,
-    ) -> Self {
-        Const::new_bound(interner, debruijn, var, ty)
+    fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
+        Const::new_bound(interner, debruijn, var)
     }
 
-    fn new_anon_bound(
-        tcx: TyCtxt<'tcx>,
-        debruijn: ty::DebruijnIndex,
-        var: ty::BoundVar,
-        ty: Ty<'tcx>,
-    ) -> Self {
-        Const::new_bound(tcx, debruijn, var, ty)
-    }
-
-    fn new_unevaluated(
-        interner: TyCtxt<'tcx>,
-        uv: ty::UnevaluatedConst<'tcx>,
-        ty: Ty<'tcx>,
-    ) -> Self {
-        Const::new_unevaluated(interner, uv, ty)
+    fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
+        Const::new_bound(tcx, debruijn, var)
     }
 
-    fn ty(self) -> Ty<'tcx> {
-        self.ty()
+    fn new_unevaluated(interner: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Self {
+        Const::new_unevaluated(interner, uv)
     }
 }
 
@@ -241,7 +196,6 @@ impl<'tcx> Const<'tcx> {
                     def: def.to_def_id(),
                     args: GenericArgs::identity_for_item(tcx, def.to_def_id()),
                 },
-                ty,
             ),
         }
     }
@@ -293,9 +247,6 @@ impl<'tcx> Const<'tcx> {
                 _,
                 &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. },
             )) => {
-                // Use the type from the param's definition, since we can resolve it,
-                // not the expected parameter type from WithOptConstParam.
-                let param_ty = tcx.type_of(def_id).instantiate_identity();
                 match tcx.named_bound_var(expr.hir_id) {
                     Some(rbv::ResolvedArg::EarlyBound(_)) => {
                         // Find the name and index of the const parameter by indexing the generics of
@@ -304,19 +255,12 @@ impl<'tcx> Const<'tcx> {
                         let generics = tcx.generics_of(item_def_id);
                         let index = generics.param_def_id_to_index[&def_id];
                         let name = tcx.item_name(def_id);
-                        Some(ty::Const::new_param(tcx, ty::ParamConst::new(index, name), param_ty))
+                        Some(ty::Const::new_param(tcx, ty::ParamConst::new(index, name)))
                     }
                     Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
-                        Some(ty::Const::new_bound(
-                            tcx,
-                            debruijn,
-                            ty::BoundVar::from_u32(index),
-                            param_ty,
-                        ))
-                    }
-                    Some(rbv::ResolvedArg::Error(guar)) => {
-                        Some(ty::Const::new_error(tcx, guar, param_ty))
+                        Some(ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index)))
                     }
+                    Some(rbv::ResolvedArg::Error(guar)) => Some(ty::Const::new_error(tcx, guar)),
                     arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id),
                 }
             }
@@ -363,7 +307,7 @@ impl<'tcx> Const<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ParamEnv<'tcx>,
         span: Span,
-    ) -> Result<ValTree<'tcx>, ErrorHandled> {
+    ) -> Result<(Ty<'tcx>, ValTree<'tcx>), ErrorHandled> {
         assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
         match self.kind() {
             ConstKind::Unevaluated(unevaluated) => {
@@ -381,9 +325,9 @@ impl<'tcx> Const<'tcx> {
                     );
                     return Err(e.into());
                 };
-                Ok(c)
+                Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c))
             }
-            ConstKind::Value(val) => Ok(val),
+            ConstKind::Value(ty, val) => Ok((ty, val)),
             ConstKind::Error(g) => Err(g.into()),
             ConstKind::Param(_)
             | ConstKind::Infer(_)
@@ -397,8 +341,8 @@ impl<'tcx> Const<'tcx> {
     #[inline]
     pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
         match self.eval(tcx, param_env, DUMMY_SP) {
-            Ok(val) => Self::new_value(tcx, val, self.ty()),
-            Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into(), self.ty()),
+            Ok((ty, val)) => Self::new_value(tcx, val, ty),
+            Err(ErrorHandled::Reported(r, _span)) => Self::new_error(tcx, r.into()),
             Err(ErrorHandled::TooGeneric(_span)) => self,
         }
     }
@@ -408,8 +352,10 @@ impl<'tcx> Const<'tcx> {
         self,
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> Option<Scalar> {
-        self.eval(tcx, param_env, DUMMY_SP).ok()?.try_to_scalar()
+    ) -> Option<(Ty<'tcx>, Scalar)> {
+        let (ty, val) = self.eval(tcx, param_env, DUMMY_SP).ok()?;
+        let val = val.try_to_scalar()?;
+        Some((ty, val))
     }
 
     #[inline]
@@ -420,8 +366,10 @@ impl<'tcx> Const<'tcx> {
         self,
         tcx: TyCtxt<'tcx>,
         param_env: ParamEnv<'tcx>,
-    ) -> Option<ScalarInt> {
-        self.try_eval_scalar(tcx, param_env)?.try_to_int().ok()
+    ) -> Option<(Ty<'tcx>, ScalarInt)> {
+        let (ty, scalar) = self.try_eval_scalar(tcx, param_env)?;
+        let val = scalar.try_to_int().ok()?;
+        Some((ty, val))
     }
 
     #[inline]
@@ -429,18 +377,17 @@ impl<'tcx> Const<'tcx> {
     /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
     /// contains const generic parameters or pointers).
     pub fn try_eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u128> {
-        let int = self.try_eval_scalar_int(tcx, param_env)?;
-        let size =
-            tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size;
+        let (ty, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
+        let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
         // if `ty` does not depend on generic parameters, use an empty param_env
-        int.try_to_bits(size).ok()
+        scalar.try_to_bits(size).ok()
     }
 
     #[inline]
     /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
     pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u128 {
         self.try_eval_bits(tcx, param_env)
-            .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", self.ty(), self))
+            .unwrap_or_else(|| bug!("failed to evalate {:#?} to bits", self))
     }
 
     #[inline]
@@ -449,12 +396,14 @@ impl<'tcx> Const<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ParamEnv<'tcx>,
     ) -> Option<u64> {
-        self.try_eval_scalar_int(tcx, param_env)?.try_to_target_usize(tcx).ok()
+        let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
+        scalar.try_to_target_usize(tcx).ok()
     }
 
     #[inline]
     pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
-        self.try_eval_scalar_int(tcx, param_env)?.try_into().ok()
+        let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?;
+        scalar.try_into().ok()
     }
 
     #[inline]
@@ -467,7 +416,7 @@ impl<'tcx> Const<'tcx> {
     /// Panics if self.kind != ty::ConstKind::Value
     pub fn to_valtree(self) -> ty::ValTree<'tcx> {
         match self.kind() {
-            ty::ConstKind::Value(valtree) => valtree,
+            ty::ConstKind::Value(_, valtree) => valtree,
             _ => bug!("expected ConstKind::Value, got {:?}", self.kind()),
         }
     }
@@ -475,7 +424,7 @@ impl<'tcx> Const<'tcx> {
     /// Attempts to convert to a `ValTree`
     pub fn try_to_valtree(self) -> Option<ty::ValTree<'tcx>> {
         match self.kind() {
-            ty::ConstKind::Value(valtree) => Some(valtree),
+            ty::ConstKind::Value(_, valtree) => Some(valtree),
             _ => None,
         }
     }
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 5f29acf5ed2..bf834ef7607 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -104,10 +104,12 @@ impl<'tcx> Expr<'tcx> {
         tcx: TyCtxt<'tcx>,
         func_ty: Ty<'tcx>,
         func_expr: Const<'tcx>,
-        arguments: impl Iterator<Item = Const<'tcx>>,
+        arguments: impl IntoIterator<Item = Const<'tcx>>,
     ) -> Self {
         let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>(
-            [func_ty.into(), func_expr.into()].into_iter().chain(arguments.map(|ct| ct.into())),
+            [func_ty.into(), func_expr.into()]
+                .into_iter()
+                .chain(arguments.into_iter().map(|ct| ct.into())),
         );
 
         Self { kind: ExprKind::FunctionCall, args }
@@ -155,7 +157,7 @@ impl<'tcx> Expr<'tcx> {
         Self { kind, args }
     }
 
-    pub fn args(&self) -> ty::GenericArgsRef<'tcx> {
+    pub fn args(self) -> ty::GenericArgsRef<'tcx> {
         self.args
     }
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 47f66c64406..6b35b1f2d13 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -28,10 +28,10 @@ use crate::traits::solve::{
 };
 use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
 use crate::ty::{
-    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData,
-    GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern,
-    PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
-    Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, Visibility,
+    self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericParamDefKind,
+    ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, PatternKind,
+    PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity, Region,
+    RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, Visibility,
 };
 use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use rustc_ast::{self as ast, attr};
@@ -268,7 +268,7 @@ pub struct CtxtInterners<'tcx> {
     clauses: InternedSet<'tcx, ListWithCachedTypeInfo<Clause<'tcx>>>,
     projs: InternedSet<'tcx, List<ProjectionKind>>,
     place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
-    const_: InternedSet<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>,
+    const_: InternedSet<'tcx, WithCachedTypeInfo<ty::ConstKind<'tcx>>>,
     pat: InternedSet<'tcx, PatternKind<'tcx>>,
     const_allocation: InternedSet<'tcx, Allocation>,
     bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
@@ -338,18 +338,18 @@ impl<'tcx> CtxtInterners<'tcx> {
     #[inline(never)]
     fn intern_const(
         &self,
-        data: ty::ConstData<'tcx>,
+        kind: ty::ConstKind<'tcx>,
         sess: &Session,
         untracked: &Untracked,
     ) -> Const<'tcx> {
         Const(Interned::new_unchecked(
             self.const_
-                .intern(data, |data: ConstData<'_>| {
-                    let flags = super::flags::FlagComputation::for_const(&data.kind, data.ty);
-                    let stable_hash = self.stable_hash(&flags, sess, untracked, &data);
+                .intern(kind, |kind: ty::ConstKind<'_>| {
+                    let flags = super::flags::FlagComputation::for_const_kind(&kind);
+                    let stable_hash = self.stable_hash(&flags, sess, untracked, &kind);
 
                     InternedInSet(self.arena.alloc(WithCachedTypeInfo {
-                        internee: data,
+                        internee: kind,
                         stable_hash,
                         flags: flags.flags,
                         outer_exclusive_binder: flags.outer_exclusive_binder,
@@ -601,18 +601,15 @@ impl<'tcx> CommonConsts<'tcx> {
         };
 
         CommonConsts {
-            unit: mk_const(ty::ConstData {
-                kind: ty::ConstKind::Value(ty::ValTree::zst()),
-                ty: types.unit,
-            }),
-            true_: mk_const(ty::ConstData {
-                kind: ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::TRUE)),
-                ty: types.bool,
-            }),
-            false_: mk_const(ty::ConstData {
-                kind: ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::FALSE)),
-                ty: types.bool,
-            }),
+            unit: mk_const(ty::ConstKind::Value(types.unit, ty::ValTree::zst())),
+            true_: mk_const(ty::ConstKind::Value(
+                types.bool,
+                ty::ValTree::Leaf(ty::ScalarInt::TRUE),
+            )),
+            false_: mk_const(ty::ConstKind::Value(
+                types.bool,
+                ty::ValTree::Leaf(ty::ScalarInt::FALSE),
+            )),
         }
     }
 }
@@ -1619,7 +1616,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
         iter::once(LOCAL_CRATE)
-            .chain(self.used_crates(()).iter().copied())
+            .chain(self.crates(()).iter().copied())
             .flat_map(move |cnum| self.traits(cnum).iter().copied())
     }
 
@@ -2225,9 +2222,9 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     #[inline]
-    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
+    pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>) -> Const<'tcx> {
         self.interners.intern_const(
-            ty::ConstData { kind, ty },
+            kind,
             self.sess,
             // This is only used to create a stable hashing context.
             &self.untracked,
@@ -2252,14 +2249,10 @@ impl<'tcx> TyCtxt<'tcx> {
                 ty::Region::new_early_param(self, param.to_early_bound_region_data()).into()
             }
             GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(),
-            GenericParamDefKind::Const { .. } => ty::Const::new_param(
-                self,
-                ParamConst { index: param.index, name: param.name },
-                self.type_of(param.def_id)
-                    .no_bound_vars()
-                    .expect("const parameter types cannot be generic"),
-            )
-            .into(),
+            GenericParamDefKind::Const { .. } => {
+                ty::Const::new_param(self, ParamConst { index: param.index, name: param.name })
+                    .into()
+            }
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 7508f0080cc..923667e609b 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -337,7 +337,7 @@ impl DeepRejectCtxt {
             | ty::ConstKind::Error(_) => {
                 return true;
             }
-            ty::ConstKind::Value(impl_val) => impl_val,
+            ty::ConstKind::Value(_, impl_val) => impl_val,
             ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
                 bug!("unexpected impl arg: {:?}", impl_ct)
             }
@@ -357,7 +357,7 @@ impl DeepRejectCtxt {
             ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
                 true
             }
-            ty::ConstKind::Value(obl_val) => obl_val == impl_val,
+            ty::ConstKind::Value(_, obl_val) => obl_val == impl_val,
 
             ty::ConstKind::Infer(_) => true,
 
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 93a51d3a334..21c115c2c96 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -28,10 +28,9 @@ impl FlagComputation {
         result
     }
 
-    pub fn for_const(c: &ty::ConstKind<'_>, t: Ty<'_>) -> FlagComputation {
+    pub fn for_const_kind(kind: &ty::ConstKind<'_>) -> FlagComputation {
         let mut result = FlagComputation::new();
-        result.add_const_kind(c);
-        result.add_ty(t);
+        result.add_const_kind(kind);
         result
     }
 
@@ -373,7 +372,7 @@ impl FlagComputation {
                 self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
                 self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
-            ty::ConstKind::Value(_) => {}
+            ty::ConstKind::Value(ty, _) => self.add_ty(ty),
             ty::ConstKind::Expr(e) => self.add_args(e.args()),
             ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR),
         }
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index b5b36cbd1ba..9b5b1430c27 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -134,13 +134,13 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
 pub trait BoundVarReplacerDelegate<'tcx> {
     fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx>;
     fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx>;
-    fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx>;
+    fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx>;
 }
 
 pub struct FnMutDelegate<'a, 'tcx> {
     pub regions: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
     pub types: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
-    pub consts: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> ty::Const<'tcx> + 'a),
+    pub consts: &'a mut (dyn FnMut(ty::BoundVar) -> ty::Const<'tcx> + 'a),
 }
 
 impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
@@ -150,8 +150,8 @@ impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
     fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
         (self.types)(bt)
     }
-    fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> {
-        (self.consts)(bv, ty)
+    fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
+        (self.consts)(bv)
     }
 }
 
@@ -224,7 +224,7 @@ where
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
         match ct.kind() {
             ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
-                let ct = self.delegate.replace_const(bound_const, ct.ty());
+                let ct = self.delegate.replace_const(bound_const);
                 debug_assert!(!ct.has_vars_bound_above(ty::INNERMOST));
                 ty::fold::shift_vars(self.tcx, ct, self.current_index.as_u32())
             }
@@ -282,7 +282,7 @@ impl<'tcx> TyCtxt<'tcx> {
             let delegate = FnMutDelegate {
                 regions: &mut replace_regions,
                 types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"),
-                consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
+                consts: &mut |b| bug!("unexpected bound ct in binder: {b:?}"),
             };
             let mut replacer = BoundVarReplacer::new(self, delegate);
             value.fold_with(&mut replacer)
@@ -353,9 +353,7 @@ impl<'tcx> TyCtxt<'tcx> {
                         ty::BoundTy { var: shift_bv(t.var), kind: t.kind },
                     )
                 },
-                consts: &mut |c, ty: Ty<'tcx>| {
-                    ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c), ty)
-                },
+                consts: &mut |c| ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c)),
             },
         )
     }
@@ -398,12 +396,12 @@ impl<'tcx> TyCtxt<'tcx> {
                     .expect_ty();
                 Ty::new_bound(self.tcx, ty::INNERMOST, BoundTy { var, kind })
             }
-            fn replace_const(&mut self, bv: ty::BoundVar, ty: Ty<'tcx>) -> ty::Const<'tcx> {
+            fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
                 let entry = self.map.entry(bv);
                 let index = entry.index();
                 let var = ty::BoundVar::from_usize(index);
                 let () = entry.or_insert_with(|| ty::BoundVariableKind::Const).expect_const();
-                ty::Const::new_bound(self.tcx, ty::INNERMOST, var, ty)
+                ty::Const::new_bound(self.tcx, ty::INNERMOST, var)
             }
         }
 
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index c3ab755175d..7fff3d01324 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -228,7 +228,7 @@ impl<'tcx> GenericArg<'tcx> {
                     ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
                 ))),
                 CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
-                    ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
+                    ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
                 ))),
                 _ => intrinsics::unreachable(),
             }
@@ -454,11 +454,11 @@ impl<'tcx> GenericArgs<'tcx> {
         def_id: DefId,
         original_args: &[GenericArg<'tcx>],
     ) -> GenericArgsRef<'tcx> {
-        ty::GenericArgs::for_item(tcx, def_id, |def, args| {
+        ty::GenericArgs::for_item(tcx, def_id, |def, _| {
             if let Some(arg) = original_args.get(def.index as usize) {
                 *arg
             } else {
-                def.to_error(tcx, args)
+                def.to_error(tcx)
             }
         })
     }
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 89ba8cd2ad4..185dbe44735 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -100,19 +100,11 @@ impl GenericParamDef {
         }
     }
 
-    pub fn to_error<'tcx>(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        preceding_args: &[ty::GenericArg<'tcx>],
-    ) -> ty::GenericArg<'tcx> {
+    pub fn to_error<'tcx>(&self, tcx: TyCtxt<'tcx>) -> ty::GenericArg<'tcx> {
         match &self.kind {
             ty::GenericParamDefKind::Lifetime => ty::Region::new_error_misc(tcx).into(),
             ty::GenericParamDefKind::Type { .. } => Ty::new_misc_error(tcx).into(),
-            ty::GenericParamDefKind::Const { .. } => ty::Const::new_misc_error(
-                tcx,
-                tcx.type_of(self.def_id).instantiate(tcx, preceding_args),
-            )
-            .into(),
+            ty::GenericParamDefKind::Const { .. } => ty::Const::new_misc_error(tcx).into(),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index a2df90b2c0f..142872009bf 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -385,9 +385,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
                     ),
                 }
             }
-            ty::Array(inner, len)
-                if len.ty() == tcx.types.usize && tcx.features().transmute_generic_consts =>
-            {
+            ty::Array(inner, len) if tcx.features().transmute_generic_consts => {
                 let len_eval = len.try_eval_target_usize(tcx, param_env);
                 if len_eval == Some(0) {
                     return Ok(SizeSkeleton::Known(Size::from_bytes(0)));
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index c6028ef74a9..e0fbf127e70 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -87,7 +87,7 @@ pub use self::closure::{
     CAPTURE_STRUCT_LOCAL,
 };
 pub use self::consts::{
-    Const, ConstData, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree,
+    Const, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree,
 };
 pub use self::context::{
     tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift,
@@ -617,7 +617,7 @@ impl<'tcx> Term<'tcx> {
                     ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
                 ))),
                 CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
-                    ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
+                    ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
                 ))),
                 _ => core::intrinsics::unreachable(),
             }
@@ -934,6 +934,30 @@ pub struct Placeholder<T> {
     pub universe: UniverseIndex,
     pub bound: T,
 }
+impl Placeholder<BoundVar> {
+    pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
+        let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
+            // `ConstArgHasType` are never desugared to be higher ranked.
+            match clause.kind().skip_binder() {
+                ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => {
+                    assert!(!(placeholder_ct, ty).has_escaping_bound_vars());
+
+                    match placeholder_ct.kind() {
+                        ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => {
+                            Some(ty)
+                        }
+                        _ => None,
+                    }
+                }
+                _ => None,
+            }
+        });
+
+        let ty = candidates.next().unwrap();
+        assert!(candidates.next().is_none());
+        ty
+    }
+}
 
 pub type PlaceholderRegion = Placeholder<BoundRegion>;
 
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index bbcbcdce1b2..52902aadd7c 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -216,7 +216,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                             })
                             .emit_unless(self.ignore_errors);
 
-                        ty::Const::new_error(self.tcx, guar, ct.ty())
+                        ty::Const::new_error(self.tcx, guar)
                     }
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 1b37078e703..49d46eb3c4b 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1459,23 +1459,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             return Ok(());
         }
 
-        macro_rules! print_underscore {
-            () => {{
-                if print_ty {
-                    self.typed_value(
-                        |this| {
-                            write!(this, "_")?;
-                            Ok(())
-                        },
-                        |this| this.print_type(ct.ty()),
-                        ": ",
-                    )?;
-                } else {
-                    write!(self, "_")?;
-                }
-            }};
-        }
-
         match ct.kind() {
             ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
                 match self.tcx().def_kind(def) {
@@ -1508,11 +1491,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 ty::InferConst::Var(ct_vid) if let Some(name) = self.const_infer_name(ct_vid) => {
                     p!(write("{}", name))
                 }
-                _ => print_underscore!(),
+                _ => write!(self, "_")?,
             },
             ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
-            ty::ConstKind::Value(value) => {
-                return self.pretty_print_const_valtree(value, ct.ty(), print_ty);
+            ty::ConstKind::Value(ty, value) => {
+                return self.pretty_print_const_valtree(value, ty, print_ty);
             }
 
             ty::ConstKind::Bound(debruijn, bound_var) => {
@@ -1666,7 +1649,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             ty::Ref(_, inner, _) => {
                 if let ty::Array(elem, len) = inner.kind() {
                     if let ty::Uint(ty::UintTy::U8) = elem.kind() {
-                        if let ty::ConstKind::Value(ty::ValTree::Leaf(int)) = len.kind() {
+                        if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() {
                             match self.tcx().try_get_global_alloc(prov.alloc_id()) {
                                 Some(GlobalAlloc::Memory(alloc)) => {
                                     let len = int.assert_bits(self.tcx().data_layout.pointer_size);
@@ -3249,7 +3232,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
     let queue = &mut Vec::new();
     let mut seen_defs: DefIdSet = Default::default();
 
-    for &cnum in tcx.crates_including_speculative(()).iter() {
+    for &cnum in tcx.crates(()).iter() {
         let def_id = cnum.as_def_id();
 
         // Ignore crates that are not direct dependencies.
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index a621d255a03..e24e64b2301 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -646,24 +646,25 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
             true
         }
         (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
-        (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val,
+        (ty::ConstKind::Value(_, a_val), ty::ConstKind::Value(_, b_val)) => a_val == b_val,
 
         // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
         // and is the better alternative to waiting until `generic_const_exprs` can
         // be stabilized.
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => {
-            assert_eq!(a.ty(), b.ty());
+            if cfg!(debug_assertions) {
+                let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args);
+                let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args);
+                assert_eq!(a_ty, b_ty);
+            }
+
             let args = relation.relate_with_variance(
                 ty::Variance::Invariant,
                 ty::VarianceDiagInfo::default(),
                 au.args,
                 bu.args,
             )?;
-            return Ok(ty::Const::new_unevaluated(
-                tcx,
-                ty::UnevaluatedConst { def: au.def, args },
-                a.ty(),
-            ));
+            return Ok(ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { def: au.def, args }));
         }
         (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => {
             match (ae.kind, be.kind) {
@@ -676,7 +677,7 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
             }
 
             let args = relation.relate(ae.args(), be.args())?;
-            return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args), a.ty()));
+            return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args)));
         }
         _ => false,
     };
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 7a291b4dbff..cf4854d1364 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -201,26 +201,21 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::Const<'tcx> {
         f: &mut core::fmt::Formatter<'_>,
     ) -> core::fmt::Result {
         // If this is a value, we spend some effort to make it look nice.
-        if let ConstKind::Value(_) = this.data.kind() {
+        if let ConstKind::Value(_, _) = this.data.kind() {
             return ty::tls::with(move |tcx| {
                 // Somehow trying to lift the valtree results in lifetime errors, so we lift the
                 // entire constant.
                 let lifted = tcx.lift(*this.data).unwrap();
-                let ConstKind::Value(valtree) = lifted.kind() else {
+                let ConstKind::Value(ty, valtree) = lifted.kind() else {
                     bug!("we checked that this is a valtree")
                 };
                 let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
-                cx.pretty_print_const_valtree(valtree, lifted.ty(), /*print_ty*/ true)?;
+                cx.pretty_print_const_valtree(valtree, ty, /*print_ty*/ true)?;
                 f.write_str(&cx.into_buffer())
             });
         }
         // Fall back to something verbose.
-        write!(
-            f,
-            "{kind:?}: {ty:?}",
-            ty = &this.map(|data| data.ty()),
-            kind = &this.map(|data| data.kind())
-        )
+        write!(f, "{kind:?}", kind = &this.map(|data| data.kind()))
     }
 }
 
@@ -647,7 +642,6 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
         self,
         folder: &mut F,
     ) -> Result<Self, F::Error> {
-        let ty = self.ty().try_fold_with(folder)?;
         let kind = match self.kind() {
             ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?),
             ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?),
@@ -656,21 +650,18 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
             }
             ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
             ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
-            ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
+            ConstKind::Value(t, v) => {
+                ConstKind::Value(t.try_fold_with(folder)?, v.try_fold_with(folder)?)
+            }
             ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
             ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
         };
-        if ty != self.ty() || kind != self.kind() {
-            Ok(folder.interner().mk_ct_from_kind(kind, ty))
-        } else {
-            Ok(self)
-        }
+        if kind != self.kind() { Ok(folder.interner().mk_ct_from_kind(kind)) } else { Ok(self) }
     }
 }
 
 impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
     fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
-        try_visit!(self.ty().visit_with(visitor));
         match self.kind() {
             ConstKind::Param(p) => p.visit_with(visitor),
             ConstKind::Infer(i) => i.visit_with(visitor),
@@ -680,7 +671,10 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
             }
             ConstKind::Placeholder(p) => p.visit_with(visitor),
             ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
-            ConstKind::Value(v) => v.visit_with(visitor),
+            ConstKind::Value(t, v) => {
+                try_visit!(t.visit_with(visitor));
+                v.visit_with(visitor)
+            }
             ConstKind::Error(e) => e.visit_with(visitor),
             ConstKind::Expr(e) => e.visit_with(visitor),
         }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 879396b0678..c83f6b0b9ec 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -21,6 +21,7 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
 use rustc_target::spec::abi;
+use rustc_type_ir::visit::TypeVisitableExt;
 use std::assert_matches::debug_assert_matches;
 use std::borrow::Cow;
 use std::iter;
@@ -339,6 +340,27 @@ impl ParamConst {
     pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
         ParamConst::new(def.index, def.name)
     }
+
+    pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
+        let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
+            // `ConstArgHasType` are never desugared to be higher ranked.
+            match clause.kind().skip_binder() {
+                ty::ClauseKind::ConstArgHasType(param_ct, ty) => {
+                    assert!(!(param_ct, ty).has_escaping_bound_vars());
+
+                    match param_ct.kind() {
+                        ty::ConstKind::Param(param_ct) if param_ct.index == self.index => Some(ty),
+                        _ => None,
+                    }
+                }
+                _ => None,
+            }
+        });
+
+        let ty = candidates.next().unwrap();
+        assert!(candidates.next().is_none());
+        ty
+    }
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 37a34f28338..4dba97c3b5b 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -206,7 +206,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
     // Traits defined in the current crate can't have impls in upstream
     // crates, so we don't bother querying the cstore.
     if !trait_id.is_local() {
-        for &cnum in tcx.used_crates(()).iter() {
+        for &cnum in tcx.crates(()).iter() {
             for &(impl_def_id, simplified_self_ty) in
                 tcx.implementations_of_trait((cnum, trait_id)).iter()
             {
@@ -248,7 +248,7 @@ pub(super) fn incoherent_impls_provider(
     let mut impls = Vec::new();
 
     let mut res = Ok(());
-    for cnum in iter::once(LOCAL_CRATE).chain(tcx.used_crates(()).iter().copied()) {
+    for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) {
         let incoherent_impls = match tcx.crate_incoherent_impls((cnum, simp)) {
             Ok(impls) => impls,
             Err(e) => {
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 58f69d772ec..e0f204a687f 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -212,21 +212,19 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
             }
         },
         GenericArgKind::Lifetime(_) => {}
-        GenericArgKind::Const(parent_ct) => {
-            stack.push(parent_ct.ty().into());
-            match parent_ct.kind() {
-                ty::ConstKind::Infer(_)
-                | ty::ConstKind::Param(_)
-                | ty::ConstKind::Placeholder(_)
-                | ty::ConstKind::Bound(..)
-                | ty::ConstKind::Value(_)
-                | ty::ConstKind::Error(_) => {}
-
-                ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
-                ty::ConstKind::Unevaluated(ct) => {
-                    stack.extend(ct.args.iter().rev());
-                }
+        GenericArgKind::Const(parent_ct) => match parent_ct.kind() {
+            ty::ConstKind::Infer(_)
+            | ty::ConstKind::Param(_)
+            | ty::ConstKind::Placeholder(_)
+            | ty::ConstKind::Bound(..)
+            | ty::ConstKind::Error(_) => {}
+
+            ty::ConstKind::Value(ty, _) => stack.push(ty.into()),
+
+            ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()),
+            ty::ConstKind::Unevaluated(ct) => {
+                stack.extend(ct.args.iter().rev());
             }
-        }
+        },
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index f7229326c54..b783eba8c4e 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -7,7 +7,7 @@ use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput,
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{
-    self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex,
+    self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_target::abi::Size;
@@ -51,7 +51,7 @@ pub(crate) fn as_constant_inner<'tcx>(
             {
                 Ok(c) => c,
                 Err(LitToConstError::Reported(guar)) => {
-                    Const::Ty(ty::Const::new_error(tcx, guar, ty))
+                    Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar))
                 }
                 Err(LitToConstError::TypeError) => {
                     bug!("encountered type error in `lit_to_mir_constant`")
@@ -83,8 +83,8 @@ pub(crate) fn as_constant_inner<'tcx>(
             ConstOperand { user_ty, span, const_ }
         }
         ExprKind::ConstParam { param, def_id: _ } => {
-            let const_param = ty::Const::new_param(tcx, param, expr.ty);
-            let const_ = Const::Ty(const_param);
+            let const_param = ty::Const::new_param(tcx, param);
+            let const_ = Const::Ty(expr.ty, const_param);
 
             ConstOperand { user_ty: None, span, const_ }
         }
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 659ae172460..d781fb1c297 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -2,6 +2,7 @@ use crate::build::ExprCategory;
 use crate::errors::*;
 
 use rustc_errors::DiagArgValue;
+use rustc_hir::def::DefKind;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
 use rustc_middle::mir::BorrowKind;
 use rustc_middle::span_bug;
@@ -88,6 +89,33 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
         }
     }
 
+    fn emit_deprecated_safe_fn_call(&self, span: Span, kind: &UnsafeOpKind) -> bool {
+        match kind {
+            // Allow calls to deprecated-safe unsafe functions if the caller is
+            // from an edition before 2024.
+            &UnsafeOpKind::CallToUnsafeFunction(Some(id))
+                if !span.at_least_rust_2024()
+                    && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
+            {
+                self.tcx.emit_node_span_lint(
+                    DEPRECATED_SAFE,
+                    self.hir_context,
+                    span,
+                    CallToDeprecatedSafeFnRequiresUnsafe {
+                        span,
+                        function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
+                        sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
+                            left: span.shrink_to_lo(),
+                            right: span.shrink_to_hi(),
+                        },
+                    },
+                );
+                true
+            }
+            _ => false,
+        }
+    }
+
     fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
         let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
         match self.safety_context {
@@ -101,43 +129,29 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
             }
             SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
             SafetyContext::UnsafeFn => {
-                // unsafe_op_in_unsafe_fn is disallowed
-                kind.emit_unsafe_op_in_unsafe_fn_lint(
-                    self.tcx,
-                    self.hir_context,
-                    span,
-                    self.suggest_unsafe_block,
-                );
-                self.suggest_unsafe_block = false;
-            }
-            SafetyContext::Safe => match kind {
-                // Allow calls to deprecated-safe unsafe functions if the
-                // caller is from an edition before 2024.
-                UnsafeOpKind::CallToUnsafeFunction(Some(id))
-                    if !span.at_least_rust_2024()
-                        && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
-                {
-                    self.tcx.emit_node_span_lint(
-                        DEPRECATED_SAFE,
+                let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
+                if !deprecated_safe_fn {
+                    // unsafe_op_in_unsafe_fn is disallowed
+                    kind.emit_unsafe_op_in_unsafe_fn_lint(
+                        self.tcx,
                         self.hir_context,
                         span,
-                        CallToDeprecatedSafeFnRequiresUnsafe {
-                            span,
-                            function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
-                            sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
-                                left: span.shrink_to_lo(),
-                                right: span.shrink_to_hi(),
-                            },
-                        },
-                    )
+                        self.suggest_unsafe_block,
+                    );
+                    self.suggest_unsafe_block = false;
                 }
-                _ => kind.emit_requires_unsafe_err(
-                    self.tcx,
-                    span,
-                    self.hir_context,
-                    unsafe_op_in_unsafe_fn_allowed,
-                ),
-            },
+            }
+            SafetyContext::Safe => {
+                let deprecated_safe_fn = self.emit_deprecated_safe_fn_call(span, &kind);
+                if !deprecated_safe_fn {
+                    kind.emit_requires_unsafe_err(
+                        self.tcx,
+                        span,
+                        self.hir_context,
+                        unsafe_op_in_unsafe_fn_allowed,
+                    );
+                }
+            }
         }
     }
 
@@ -456,7 +470,10 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     if self.tcx.is_mutable_static(def_id) {
                         self.requires_unsafe(expr.span, UseOfMutableStatic);
                     } else if self.tcx.is_foreign_item(def_id) {
-                        self.requires_unsafe(expr.span, UseOfExternStatic);
+                        match self.tcx.def_kind(def_id) {
+                            DefKind::Static { safety: hir::Safety::Safe, .. } => {}
+                            _ => self.requires_unsafe(expr.span, UseOfExternStatic),
+                        }
                     }
                 } else if self.thir[arg].ty.is_unsafe_ptr() {
                     self.requires_unsafe(expr.span, DerefOfRawPointer);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 8d881713eeb..36495101d3f 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -101,9 +101,9 @@ impl<'tcx> ConstToPat<'tcx> {
         // level of indirection can be eliminated
 
         let have_valtree =
-            matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_)));
+            matches!(cv, mir::Const::Ty(_, c) if matches!(c.kind(), ty::ConstKind::Value(_, _)));
         let inlined_const_as_pat = match cv {
-            mir::Const::Ty(c) => match c.kind() {
+            mir::Const::Ty(_, c) => match c.kind() {
                 ty::ConstKind::Param(_)
                 | ty::ConstKind::Infer(_)
                 | ty::ConstKind::Bound(_, _)
@@ -113,8 +113,8 @@ impl<'tcx> ConstToPat<'tcx> {
                 | ty::ConstKind::Expr(_) => {
                     span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind())
                 }
-                ty::ConstKind::Value(valtree) => {
-                    self.recur(valtree, cv.ty()).unwrap_or_else(|_: FallbackToOpaqueConst| {
+                ty::ConstKind::Value(ty, valtree) => {
+                    self.recur(valtree, ty).unwrap_or_else(|_: FallbackToOpaqueConst| {
                         Box::new(Pat {
                             span: self.span,
                             ty: cv.ty(),
@@ -336,9 +336,9 @@ impl<'tcx> ConstToPat<'tcx> {
             ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
                 // `&str` is represented as a valtree, let's keep using this
                 // optimization for now.
-                ty::Str => {
-                    PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
-                }
+                ty::Str => PatKind::Constant {
+                    value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
+                },
                 // All other references are converted into deref patterns and then recursively
                 // convert the dereferenced constant to a pattern that is the sub-pattern of the
                 // deref pattern.
@@ -382,13 +382,15 @@ impl<'tcx> ConstToPat<'tcx> {
                     self.saw_const_match_error.set(Some(e));
                     return Err(FallbackToOpaqueConst);
                 } else {
-                    PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
+                    PatKind::Constant {
+                        value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
+                    }
                 }
             }
             ty::Pat(..) | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => {
                 // The raw pointers we see here have been "vetted" by valtree construction to be
                 // just integers, so we simply allow them.
-                PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) }
+                PatKind::Constant { value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)) }
             }
             ty::FnPtr(..) => {
                 unreachable!(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 33401cad631..145a40ca3cd 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -580,7 +580,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             .tcx
             .const_eval_global_id_for_typeck(param_env_reveal_all, cid, span)
             .map(|val| match val {
-                Some(valtree) => mir::Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)),
+                Some(valtree) => mir::Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)),
                 None => mir::Const::Val(
                     self.tcx
                         .const_eval_global_id(param_env_reveal_all, cid, span)
@@ -659,7 +659,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         };
         if let Some(lit_input) = lit_input {
             match tcx.at(expr.span).lit_to_const(lit_input) {
-                Ok(c) => return self.const_to_pat(Const::Ty(c), id, span).kind,
+                Ok(c) => return self.const_to_pat(Const::Ty(ty, c), id, span).kind,
                 // If an error occurred, ignore that it's a literal
                 // and leave reporting the error up to const eval of
                 // the unevaluated constant below.
@@ -681,8 +681,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         // but something more principled, like a trait query checking whether this can be turned into a valtree.
         if let Ok(Some(valtree)) = self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, span)
         {
-            let subpattern =
-                self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span);
+            let subpattern = self.const_to_pat(
+                Const::Ty(ty, ty::Const::new_value(self.tcx, valtree, ty)),
+                id,
+                span,
+            );
             PatKind::InlineConstant { subpattern, def: def_id }
         } else {
             // If that fails, convert it to an opaque constant pattern.
@@ -720,10 +723,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             _ => span_bug!(expr.span, "not a literal: {:?}", expr),
         };
 
-        let lit_input =
-            LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
+        let ct_ty = self.typeck_results.expr_ty(expr);
+        let lit_input = LitToConstInput { lit: &lit.node, ty: ct_ty, neg };
         match self.tcx.at(expr.span).lit_to_const(lit_input) {
-            Ok(constant) => self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span).kind,
+            Ok(constant) => {
+                self.const_to_pat(Const::Ty(ct_ty, constant), expr.hir_id, lit.span).kind
+            }
             Err(LitToConstError::Reported(e)) => PatKind::Error(e),
             Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
         }
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index f2f76ac70c2..743f1cc24be 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -20,37 +20,31 @@ pub(super) fn extract_refined_covspans(
     basic_coverage_blocks: &CoverageGraph,
     code_mappings: &mut impl Extend<mappings::CodeMapping>,
 ) {
-    let sorted_spans =
+    let sorted_span_buckets =
         from_mir::mir_to_initial_sorted_coverage_spans(mir_body, hir_info, basic_coverage_blocks);
-    let coverage_spans = SpansRefiner::refine_sorted_spans(sorted_spans);
-    code_mappings.extend(coverage_spans.into_iter().map(|RefinedCovspan { bcb, span, .. }| {
-        // Each span produced by the generator represents an ordinary code region.
-        mappings::CodeMapping { span, bcb }
-    }));
+    for bucket in sorted_span_buckets {
+        let refined_spans = SpansRefiner::refine_sorted_spans(bucket);
+        code_mappings.extend(refined_spans.into_iter().map(|RefinedCovspan { span, bcb }| {
+            // Each span produced by the refiner represents an ordinary code region.
+            mappings::CodeMapping { span, bcb }
+        }));
+    }
 }
 
 #[derive(Debug)]
 struct CurrCovspan {
     span: Span,
     bcb: BasicCoverageBlock,
-    is_hole: bool,
 }
 
 impl CurrCovspan {
-    fn new(span: Span, bcb: BasicCoverageBlock, is_hole: bool) -> Self {
-        Self { span, bcb, is_hole }
+    fn new(span: Span, bcb: BasicCoverageBlock) -> Self {
+        Self { span, bcb }
     }
 
     fn into_prev(self) -> PrevCovspan {
-        let Self { span, bcb, is_hole } = self;
-        PrevCovspan { span, bcb, merged_spans: vec![span], is_hole }
-    }
-
-    fn into_refined(self) -> RefinedCovspan {
-        // This is only called in cases where `curr` is a hole span that has
-        // been carved out of `prev`.
-        debug_assert!(self.is_hole);
-        self.into_prev().into_refined()
+        let Self { span, bcb } = self;
+        PrevCovspan { span, bcb, merged_spans: vec![span] }
     }
 }
 
@@ -61,12 +55,11 @@ struct PrevCovspan {
     /// List of all the original spans from MIR that have been merged into this
     /// span. Mainly used to precisely skip over gaps when truncating a span.
     merged_spans: Vec<Span>,
-    is_hole: bool,
 }
 
 impl PrevCovspan {
     fn is_mergeable(&self, other: &CurrCovspan) -> bool {
-        self.bcb == other.bcb && !self.is_hole && !other.is_hole
+        self.bcb == other.bcb
     }
 
     fn merge_from(&mut self, other: &CurrCovspan) {
@@ -84,14 +77,9 @@ impl PrevCovspan {
         if self.merged_spans.is_empty() { None } else { Some(self.into_refined()) }
     }
 
-    fn refined_copy(&self) -> RefinedCovspan {
-        let &Self { span, bcb, merged_spans: _, is_hole } = self;
-        RefinedCovspan { span, bcb, is_hole }
-    }
-
     fn into_refined(self) -> RefinedCovspan {
-        // Even though we consume self, we can just reuse the copying impl.
-        self.refined_copy()
+        let Self { span, bcb, merged_spans: _ } = self;
+        RefinedCovspan { span, bcb }
     }
 }
 
@@ -99,12 +87,11 @@ impl PrevCovspan {
 struct RefinedCovspan {
     span: Span,
     bcb: BasicCoverageBlock,
-    is_hole: bool,
 }
 
 impl RefinedCovspan {
     fn is_mergeable(&self, other: &Self) -> bool {
-        self.bcb == other.bcb && !self.is_hole && !other.is_hole
+        self.bcb == other.bcb
     }
 
     fn merge_from(&mut self, other: &Self) {
@@ -119,8 +106,6 @@ impl RefinedCovspan {
 ///  * Remove duplicate source code coverage regions
 ///  * Merge spans that represent continuous (both in source code and control flow), non-branching
 ///    execution
-///  * Carve out (leave uncovered) any "hole" spans that need to be left blank
-///    (e.g. closures that will be counted by their own MIR body)
 struct SpansRefiner {
     /// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative
     /// dominance between the `BasicCoverageBlock`s of equal `Span`s.
@@ -181,13 +166,6 @@ impl SpansRefiner {
                 );
                 let prev = self.take_prev().into_refined();
                 self.refined_spans.push(prev);
-            } else if prev.is_hole {
-                // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the
-                // next iter
-                debug!(?prev, "prev (a hole) overlaps curr, so discarding curr");
-                self.take_curr(); // Discards curr.
-            } else if curr.is_hole {
-                self.carve_out_span_for_hole();
             } else {
                 self.cutoff_prev_at_overlapping_curr();
             }
@@ -211,9 +189,6 @@ impl SpansRefiner {
             }
         });
 
-        // Discard hole spans, since their purpose was to carve out chunks from
-        // other spans, but we don't want the holes themselves in the final mappings.
-        self.refined_spans.retain(|covspan| !covspan.is_hole);
         self.refined_spans
     }
 
@@ -249,50 +224,17 @@ impl SpansRefiner {
         if let Some(curr) = self.some_curr.take() {
             self.some_prev = Some(curr.into_prev());
         }
-        while let Some(curr) = self.sorted_spans_iter.next() {
-            debug!("FOR curr={:?}", curr);
-            if let Some(prev) = &self.some_prev
-                && prev.span.lo() > curr.span.lo()
-            {
-                // Skip curr because prev has already advanced beyond the end of curr.
-                // This can only happen if a prior iteration updated `prev` to skip past
-                // a region of code, such as skipping past a hole.
-                debug!(?prev, "prev.span starts after curr.span, so curr will be dropped");
-            } else {
-                self.some_curr = Some(CurrCovspan::new(curr.span, curr.bcb, curr.is_hole));
-                return true;
+        if let Some(SpanFromMir { span, bcb, .. }) = self.sorted_spans_iter.next() {
+            // This code only sees sorted spans after hole-carving, so there should
+            // be no way for `curr` to start before `prev`.
+            if let Some(prev) = &self.some_prev {
+                debug_assert!(prev.span.lo() <= span.lo());
             }
-        }
-        false
-    }
-
-    /// If `prev`s span extends left of the hole (`curr`), carve out the hole's span from
-    /// `prev`'s span. Add the portion of the span to the left of the hole; and if the span
-    /// extends to the right of the hole, update `prev` to that portion of the span.
-    fn carve_out_span_for_hole(&mut self) {
-        let prev = self.prev();
-        let curr = self.curr();
-
-        let left_cutoff = curr.span.lo();
-        let right_cutoff = curr.span.hi();
-        let has_pre_hole_span = prev.span.lo() < right_cutoff;
-        let has_post_hole_span = prev.span.hi() > right_cutoff;
-
-        if has_pre_hole_span {
-            let mut pre_hole = prev.refined_copy();
-            pre_hole.span = pre_hole.span.with_hi(left_cutoff);
-            debug!(?pre_hole, "prev overlaps a hole; adding pre-hole span");
-            self.refined_spans.push(pre_hole);
-        }
-
-        if has_post_hole_span {
-            // Mutate `prev.span` to start after the hole (and discard curr).
-            self.prev_mut().span = self.prev().span.with_lo(right_cutoff);
-            debug!(prev=?self.prev(), "mutated prev to start after the hole");
-
-            // Prevent this curr from becoming prev.
-            let hole_covspan = self.take_curr().into_refined();
-            self.refined_spans.push(hole_covspan); // since self.prev() was already updated
+            self.some_curr = Some(CurrCovspan::new(span, bcb));
+            debug!(?self.some_prev, ?self.some_curr, "next_coverage_span");
+            true
+        } else {
+            false
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index d1727a94a35..b1f71035dde 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -1,3 +1,5 @@
+use std::collections::VecDeque;
+
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::bug;
@@ -17,23 +19,34 @@ use crate::coverage::ExtractedHirInfo;
 /// spans, each associated with a node in the coverage graph (BCB) and possibly
 /// other metadata.
 ///
-/// The returned spans are sorted in a specific order that is expected by the
-/// subsequent span-refinement step.
+/// The returned spans are divided into one or more buckets, such that:
+/// - The spans in each bucket are strictly after all spans in previous buckets,
+///   and strictly before all spans in subsequent buckets.
+/// - The contents of each bucket are also sorted, in a specific order that is
+///   expected by the subsequent span-refinement step.
 pub(super) fn mir_to_initial_sorted_coverage_spans(
     mir_body: &mir::Body<'_>,
     hir_info: &ExtractedHirInfo,
     basic_coverage_blocks: &CoverageGraph,
-) -> Vec<SpanFromMir> {
+) -> Vec<Vec<SpanFromMir>> {
     let &ExtractedHirInfo { body_span, .. } = hir_info;
 
     let mut initial_spans = vec![];
+    let mut holes = vec![];
 
     for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() {
-        initial_spans.extend(bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data));
+        bcb_to_initial_coverage_spans(
+            mir_body,
+            body_span,
+            bcb,
+            bcb_data,
+            &mut initial_spans,
+            &mut holes,
+        );
     }
 
     // Only add the signature span if we found at least one span in the body.
-    if !initial_spans.is_empty() {
+    if !initial_spans.is_empty() || !holes.is_empty() {
         // If there is no usable signature span, add a fake one (before refinement)
         // to avoid an ugly gap between the body start and the first real span.
         // FIXME: Find a more principled way to solve this problem.
@@ -45,29 +58,82 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
     remove_unwanted_macro_spans(&mut initial_spans);
     split_visible_macro_spans(&mut initial_spans);
 
-    initial_spans.sort_by(|a, b| {
-        // First sort by span start.
-        Ord::cmp(&a.span.lo(), &b.span.lo())
-            // If span starts are the same, sort by span end in reverse order.
-            // This ensures that if spans A and B are adjacent in the list,
-            // and they overlap but are not equal, then either:
-            // - Span A extends further left, or
-            // - Both have the same start and span A extends further right
-            .then_with(|| Ord::cmp(&a.span.hi(), &b.span.hi()).reverse())
-            // If two spans have the same lo & hi, put hole spans first,
-            // as they take precedence over non-hole spans.
-            .then_with(|| Ord::cmp(&a.is_hole, &b.is_hole).reverse())
+    let compare_covspans = |a: &SpanFromMir, b: &SpanFromMir| {
+        compare_spans(a.span, b.span)
             // After deduplication, we want to keep only the most-dominated BCB.
             .then_with(|| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb).reverse())
-    });
+    };
+    initial_spans.sort_by(compare_covspans);
 
-    // Among covspans with the same span, keep only one. Hole spans take
-    // precedence, otherwise keep the one with the most-dominated BCB.
+    // Among covspans with the same span, keep only one,
+    // preferring the one with the most-dominated BCB.
     // (Ideally we should try to preserve _all_ non-dominating BCBs, but that
     // requires a lot more complexity in the span refiner, for little benefit.)
     initial_spans.dedup_by(|b, a| a.span.source_equal(b.span));
 
-    initial_spans
+    // Sort the holes, and merge overlapping/adjacent holes.
+    holes.sort_by(|a, b| compare_spans(a.span, b.span));
+    holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b));
+
+    // Now we're ready to start carving holes out of the initial coverage spans,
+    // and grouping them in buckets separated by the holes.
+
+    let mut initial_spans = VecDeque::from(initial_spans);
+    let mut fragments: Vec<SpanFromMir> = vec![];
+
+    // For each hole:
+    // - Identify the spans that are entirely or partly before the hole.
+    // - Put those spans in a corresponding bucket, truncated to the start of the hole.
+    // - If one of those spans also extends after the hole, put the rest of it
+    //   in a "fragments" vector that is processed by the next hole.
+    let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
+    for (hole, bucket) in holes.iter().zip(&mut buckets) {
+        let fragments_from_prev = std::mem::take(&mut fragments);
+
+        // Only inspect spans that precede or overlap this hole,
+        // leaving the rest to be inspected by later holes.
+        // (This relies on the spans and holes both being sorted.)
+        let relevant_initial_spans =
+            drain_front_while(&mut initial_spans, |c| c.span.lo() < hole.span.hi());
+
+        for covspan in fragments_from_prev.into_iter().chain(relevant_initial_spans) {
+            let (before, after) = covspan.split_around_hole_span(hole.span);
+            bucket.extend(before);
+            fragments.extend(after);
+        }
+    }
+
+    // After finding the spans before each hole, any remaining fragments/spans
+    // form their own final bucket, after the final hole.
+    // (If there were no holes, this will just be all of the initial spans.)
+    fragments.extend(initial_spans);
+    buckets.push(fragments);
+
+    // Make sure each individual bucket is still internally sorted.
+    for bucket in &mut buckets {
+        bucket.sort_by(compare_covspans);
+    }
+    buckets
+}
+
+fn compare_spans(a: Span, b: Span) -> std::cmp::Ordering {
+    // First sort by span start.
+    Ord::cmp(&a.lo(), &b.lo())
+        // If span starts are the same, sort by span end in reverse order.
+        // This ensures that if spans A and B are adjacent in the list,
+        // and they overlap but are not equal, then either:
+        // - Span A extends further left, or
+        // - Both have the same start and span A extends further right
+        .then_with(|| Ord::cmp(&a.hi(), &b.hi()).reverse())
+}
+
+/// Similar to `.drain(..)`, but stops just before it would remove an item not
+/// satisfying the predicate.
+fn drain_front_while<'a, T>(
+    queue: &'a mut VecDeque<T>,
+    mut pred_fn: impl FnMut(&T) -> bool,
+) -> impl Iterator<Item = T> + Captures<'a> {
+    std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None })
 }
 
 /// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
@@ -80,8 +146,8 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
 fn remove_unwanted_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
     let mut seen_macro_spans = FxHashSet::default();
     initial_spans.retain(|covspan| {
-        // Ignore (retain) hole spans and non-macro-expansion spans.
-        if covspan.is_hole || covspan.visible_macro.is_none() {
+        // Ignore (retain) non-macro-expansion spans.
+        if covspan.visible_macro.is_none() {
             return true;
         }
 
@@ -98,10 +164,6 @@ fn split_visible_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
     let mut extra_spans = vec![];
 
     initial_spans.retain(|covspan| {
-        if covspan.is_hole {
-            return true;
-        }
-
         let Some(visible_macro) = covspan.visible_macro else { return true };
 
         let split_len = visible_macro.as_str().len() as u32 + 1;
@@ -114,9 +176,8 @@ fn split_visible_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
             return true;
         }
 
-        assert!(!covspan.is_hole);
-        extra_spans.push(SpanFromMir::new(before, covspan.visible_macro, covspan.bcb, false));
-        extra_spans.push(SpanFromMir::new(after, covspan.visible_macro, covspan.bcb, false));
+        extra_spans.push(SpanFromMir::new(before, covspan.visible_macro, covspan.bcb));
+        extra_spans.push(SpanFromMir::new(after, covspan.visible_macro, covspan.bcb));
         false // Discard the original covspan that we just split.
     });
 
@@ -135,8 +196,10 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
     body_span: Span,
     bcb: BasicCoverageBlock,
     bcb_data: &'a BasicCoverageBlockData,
-) -> impl Iterator<Item = SpanFromMir> + Captures<'a> + Captures<'tcx> {
-    bcb_data.basic_blocks.iter().flat_map(move |&bb| {
+    initial_covspans: &mut Vec<SpanFromMir>,
+    holes: &mut Vec<Hole>,
+) {
+    for &bb in &bcb_data.basic_blocks {
         let data = &mir_body[bb];
 
         let unexpand = move |expn_span| {
@@ -146,24 +209,32 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
                 .filter(|(span, _)| !span.source_equal(body_span))
         };
 
-        let statement_spans = data.statements.iter().filter_map(move |statement| {
+        let mut extract_statement_span = |statement| {
             let expn_span = filtered_statement_span(statement)?;
             let (span, visible_macro) = unexpand(expn_span)?;
 
             // A statement that looks like the assignment of a closure expression
             // is treated as a "hole" span, to be carved out of other spans.
-            Some(SpanFromMir::new(span, visible_macro, bcb, is_closure_like(statement)))
-        });
+            if is_closure_like(statement) {
+                holes.push(Hole { span });
+            } else {
+                initial_covspans.push(SpanFromMir::new(span, visible_macro, bcb));
+            }
+            Some(())
+        };
+        for statement in data.statements.iter() {
+            extract_statement_span(statement);
+        }
 
-        let terminator_span = Some(data.terminator()).into_iter().filter_map(move |terminator| {
+        let mut extract_terminator_span = |terminator| {
             let expn_span = filtered_terminator_span(terminator)?;
             let (span, visible_macro) = unexpand(expn_span)?;
 
-            Some(SpanFromMir::new(span, visible_macro, bcb, false))
-        });
-
-        statement_spans.chain(terminator_span)
-    })
+            initial_covspans.push(SpanFromMir::new(span, visible_macro, bcb));
+            Some(())
+        };
+        extract_terminator_span(data.terminator());
+    }
 }
 
 fn is_closure_like(statement: &Statement<'_>) -> bool {
@@ -331,6 +402,22 @@ fn unexpand_into_body_span_with_prev(
 }
 
 #[derive(Debug)]
+struct Hole {
+    span: Span,
+}
+
+impl Hole {
+    fn merge_if_overlapping_or_adjacent(&mut self, other: &mut Self) -> bool {
+        if !self.span.overlaps_or_adjacent(other.span) {
+            return false;
+        }
+
+        self.span = self.span.to(other.span);
+        true
+    }
+}
+
+#[derive(Debug)]
 pub(super) struct SpanFromMir {
     /// A span that has been extracted from MIR and then "un-expanded" back to
     /// within the current function's `body_span`. After various intermediate
@@ -342,23 +429,30 @@ pub(super) struct SpanFromMir {
     pub(super) span: Span,
     visible_macro: Option<Symbol>,
     pub(super) bcb: BasicCoverageBlock,
-    /// If true, this covspan represents a "hole" that should be carved out
-    /// from other spans, e.g. because it represents a closure expression that
-    /// will be instrumented separately as its own function.
-    pub(super) is_hole: bool,
 }
 
 impl SpanFromMir {
     fn for_fn_sig(fn_sig_span: Span) -> Self {
-        Self::new(fn_sig_span, None, START_BCB, false)
+        Self::new(fn_sig_span, None, START_BCB)
+    }
+
+    fn new(span: Span, visible_macro: Option<Symbol>, bcb: BasicCoverageBlock) -> Self {
+        Self { span, visible_macro, bcb }
     }
 
-    fn new(
-        span: Span,
-        visible_macro: Option<Symbol>,
-        bcb: BasicCoverageBlock,
-        is_hole: bool,
-    ) -> Self {
-        Self { span, visible_macro, bcb, is_hole }
+    /// Splits this span into 0-2 parts:
+    /// - The part that is strictly before the hole span, if any.
+    /// - The part that is strictly after the hole span, if any.
+    fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) {
+        let before = try {
+            let span = self.span.trim_end(hole_span)?;
+            Self { span, ..*self }
+        };
+        let after = try {
+            let span = self.span.trim_start(hole_span)?;
+            Self { span, ..*self }
+        };
+
+        (before, after)
     }
 }
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index e88b727a21e..a8caead46f2 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -203,7 +203,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
                     && let operand_ty = operand.ty(self.local_decls, self.tcx)
                     && let Some(operand_ty) = operand_ty.builtin_deref(true)
                     && let ty::Array(_, len) = operand_ty.kind()
-                    && let Some(len) = Const::Ty(*len).try_eval_scalar_int(self.tcx, self.param_env)
+                    && let Some(len) = Const::Ty(self.tcx.types.usize, *len)
+                        .try_eval_scalar_int(self.tcx, self.param_env)
                 {
                     state.insert_value_idx(target_len, FlatSet::Elem(len.into()), self.map());
                 }
@@ -221,7 +222,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
             Rvalue::Len(place) => {
                 let place_ty = place.ty(self.local_decls, self.tcx);
                 if let ty::Array(_, len) = place_ty.ty.kind() {
-                    Const::Ty(*len)
+                    Const::Ty(self.tcx.types.usize, *len)
                         .try_eval_scalar(self.tcx, self.param_env)
                         .map_or(FlatSet::Top, FlatSet::Elem)
                 } else if let [ProjectionElem::Deref] = place.projection[..] {
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index fadb5edefdf..acde16fcb75 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -223,7 +223,6 @@ enum Value<'tcx> {
     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
     UnaryOp(UnOp, VnIndex),
     BinaryOp(BinOp, VnIndex, VnIndex),
-    CheckedBinaryOp(BinOp, VnIndex, VnIndex), // FIXME get rid of this, work like MIR instead
     Cast {
         kind: CastKind,
         value: VnIndex,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 let val = self.ecx.binary_op(bin_op, &lhs, &rhs).ok()?;
                 val.into()
             }
-            CheckedBinaryOp(bin_op, lhs, rhs) => {
-                let lhs = self.evaluated[lhs].as_ref()?;
-                let lhs = self.ecx.read_immediate(lhs).ok()?;
-                let rhs = self.evaluated[rhs].as_ref()?;
-                let rhs = self.ecx.read_immediate(rhs).ok()?;
-                let val = self
-                    .ecx
-                    .binary_op(bin_op.wrapping_to_overflowing().unwrap(), &lhs, &rhs)
-                    .ok()?;
-                val.into()
-            }
             Cast { kind, value, from: _, to } => match kind {
                 CastKind::IntToInt | CastKind::IntToFloat => {
                     let value = self.evaluated[value].as_ref()?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 let lhs = lhs?;
                 let rhs = rhs?;
 
-                if let Some(op) = op.overflowing_to_wrapping() {
-                    if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
-                        return Some(value);
-                    }
-                    Value::CheckedBinaryOp(op, lhs, rhs)
-                } else {
-                    if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
-                        return Some(value);
-                    }
-                    Value::BinaryOp(op, lhs, rhs)
+                if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
+                    return Some(value);
                 }
+                Value::BinaryOp(op, lhs, rhs)
             }
             Rvalue::UnaryOp(op, ref mut arg) => {
                 let arg = self.simplify_operand(arg, location)?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
     fn simplify_binary(
         &mut self,
         op: BinOp,
-        checked: bool,
         lhs_ty: Ty<'tcx>,
         lhs: VnIndex,
         rhs: VnIndex,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         use Either::{Left, Right};
         let a = as_bits(lhs).map_or(Right(lhs), Left);
         let b = as_bits(rhs).map_or(Right(rhs), Left);
+
         let result = match (op, a, b) {
             // Neutral elements.
-            (BinOp::Add | BinOp::BitOr | BinOp::BitXor, Left(0), Right(p))
+            (
+                BinOp::Add
+                | BinOp::AddWithOverflow
+                | BinOp::AddUnchecked
+                | BinOp::BitOr
+                | BinOp::BitXor,
+                Left(0),
+                Right(p),
+            )
             | (
                 BinOp::Add
+                | BinOp::AddWithOverflow
+                | BinOp::AddUnchecked
                 | BinOp::BitOr
                 | BinOp::BitXor
                 | BinOp::Sub
+                | BinOp::SubWithOverflow
+                | BinOp::SubUnchecked
                 | BinOp::Offset
                 | BinOp::Shl
                 | BinOp::Shr,
                 Right(p),
                 Left(0),
             )
-            | (BinOp::Mul, Left(1), Right(p))
-            | (BinOp::Mul | BinOp::Div, Right(p), Left(1)) => p,
+            | (BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked, Left(1), Right(p))
+            | (
+                BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::Div,
+                Right(p),
+                Left(1),
+            ) => p,
             // Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
             (BinOp::BitAnd, Right(p), Left(ones)) | (BinOp::BitAnd, Left(ones), Right(p))
                 if ones == layout.size.truncate(u128::MAX)
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 p
             }
             // Absorbing elements.
-            (BinOp::Mul | BinOp::BitAnd, _, Left(0))
+            (
+                BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::BitAnd,
+                _,
+                Left(0),
+            )
             | (BinOp::Rem, _, Left(1))
             | (
-                BinOp::Mul | BinOp::Div | BinOp::Rem | BinOp::BitAnd | BinOp::Shl | BinOp::Shr,
+                BinOp::Mul
+                | BinOp::MulWithOverflow
+                | BinOp::MulUnchecked
+                | BinOp::Div
+                | BinOp::Rem
+                | BinOp::BitAnd
+                | BinOp::Shl
+                | BinOp::Shr,
                 Left(0),
                 _,
             ) => self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty),
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 self.insert_scalar(Scalar::from_uint(ones, layout.size), lhs_ty)
             }
             // Sub/Xor with itself.
-            (BinOp::Sub | BinOp::BitXor, a, b) if a == b => {
+            (BinOp::Sub | BinOp::SubWithOverflow | BinOp::SubUnchecked | BinOp::BitXor, a, b)
+                if a == b =>
+            {
                 self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty)
             }
             // Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             _ => return None,
         };
 
-        if checked {
+        if op.is_overflowing() {
             let false_val = self.insert_bool(false);
             Some(self.insert_tuple(vec![result, false_val]))
         } else {
@@ -1108,7 +1118,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         // Trivial case: we are fetching a statically known length.
         let place_ty = place.ty(self.local_decls, self.tcx).ty;
         if let ty::Array(_, len) = place_ty.kind() {
-            return self.insert_constant(Const::from_ty_const(*len, self.tcx));
+            return self.insert_constant(Const::from_ty_const(
+                *len,
+                self.tcx.types.usize,
+                self.tcx,
+            ));
         }
 
         let mut inner = self.simplify_place_value(place, location)?;
@@ -1130,7 +1144,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             && let Some(to) = to.builtin_deref(true)
             && let ty::Slice(..) = to.kind()
         {
-            return self.insert_constant(Const::from_ty_const(*len, self.tcx));
+            return self.insert_constant(Const::from_ty_const(
+                *len,
+                self.tcx.types.usize,
+                self.tcx,
+            ));
         }
 
         // Fallback: a symbolic `Len`.
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 40db3e38fd3..6806c517c17 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -150,7 +150,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
                     return;
                 }
 
-                let const_ = Const::from_ty_const(len, self.tcx);
+                let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
                 let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
                 *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
             }
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index 2070895c900..d5e72706661 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -95,7 +95,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
             *rvalue = Rvalue::Use(Operand::Constant(Box::new(ConstOperand {
                 span: rustc_span::DUMMY_SP,
                 user_ty: None,
-                const_: Const::from_ty_const(len, self.tcx),
+                const_: Const::from_ty_const(len, self.tcx.types.usize, self.tcx),
             })));
         }
         self.super_rvalue(rvalue, loc);
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index dc13766d145..a3ca9e9f9cf 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -263,7 +263,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> {
 
     fn visit_constant(&mut self, ct: &mir::ConstOperand<'tcx>, location: Location) {
         match ct.const_ {
-            mir::Const::Ty(c) => {
+            mir::Const::Ty(_, c) => {
                 c.visit_with(self);
             }
             mir::Const::Unevaluated(mir::UnevaluatedConst { def, args: _, promoted }, ty) => {
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 127ebde5fec..f22e24ef654 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -386,23 +386,15 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
     }
 
     fn fold_const(&mut self, c: I::Const) -> I::Const {
-        // We could canonicalize all consts with static types, but the only ones we
-        // *really* need to worry about are the ones that we end up putting into `CanonicalVarKind`
-        // since canonical vars can't reference other canonical vars.
-        let ty = c
-            .ty()
-            .fold_with(&mut RegionsToStatic { interner: self.interner(), binder: ty::INNERMOST });
         let kind = match c.kind() {
             ty::ConstKind::Infer(i) => match i {
                 ty::InferConst::Var(vid) => {
-                    // We compare `kind`s here because we've folded the `ty` with `RegionsToStatic`
-                    // so we'll get a mismatch in types if it actually changed any regions.
                     assert_eq!(
-                        self.infcx.opportunistic_resolve_ct_var(vid, ty).kind(),
-                        c.kind(),
-                        "region vid should have been resolved fully before canonicalization"
+                        self.infcx.opportunistic_resolve_ct_var(vid),
+                        c,
+                        "const vid should have been resolved fully before canonicalization"
                     );
-                    CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
+                    CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap())
                 }
                 ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
                 ty::InferConst::Fresh(_) => todo!(),
@@ -410,23 +402,21 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
             ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
                 CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
                     PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
-                    ty,
                 ),
                 CanonicalizeMode::Response { .. } => {
-                    CanonicalVarKind::PlaceholderConst(placeholder, ty)
+                    CanonicalVarKind::PlaceholderConst(placeholder)
                 }
             },
             ty::ConstKind::Param(_) => match self.canonicalize_mode {
                 CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
                     PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
-                    ty,
                 ),
                 CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
             },
             // FIXME: See comment above -- we could fold the region separately or something.
             ty::ConstKind::Bound(_, _)
             | ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Value(_)
+            | ty::ConstKind::Value(_, _)
             | ty::ConstKind::Error(_)
             | ty::ConstKind::Expr(_) => return c.super_fold_with(self),
         };
@@ -440,34 +430,6 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
             }),
         );
 
-        Const::new_anon_bound(self.interner(), self.binder_index, var, ty)
-    }
-}
-
-struct RegionsToStatic<I> {
-    interner: I,
-    binder: ty::DebruijnIndex,
-}
-
-impl<I: Interner> TypeFolder<I> for RegionsToStatic<I> {
-    fn interner(&self) -> I {
-        self.interner
-    }
-
-    fn fold_binder<T>(&mut self, t: ty::Binder<I, T>) -> ty::Binder<I, T>
-    where
-        T: TypeFoldable<I>,
-    {
-        self.binder.shift_in(1);
-        let t = t.super_fold_with(self);
-        self.binder.shift_out(1);
-        t
-    }
-
-    fn fold_region(&mut self, r: I::Region) -> I::Region {
-        match r.kind() {
-            ty::ReBound(db, _) if self.binder > db => r,
-            _ => Region::new_static(self.interner()),
-        }
+        Const::new_anon_bound(self.interner(), self.binder_index, var)
     }
 }
diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs
index 1333b4aa7d8..92e05cc4901 100644
--- a/compiler/rustc_next_trait_solver/src/resolve.rs
+++ b/compiler/rustc_next_trait_solver/src/resolve.rs
@@ -58,8 +58,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerRes
     fn fold_const(&mut self, c: I::Const) -> I::Const {
         match c.kind() {
             ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
-                let ty = c.ty().fold_with(self);
-                let resolved = self.infcx.opportunistic_resolve_ct_var(vid, ty);
+                let resolved = self.infcx.opportunistic_resolve_ct_var(vid);
                 if c != resolved && resolved.has_infer() {
                     resolved.fold_with(self)
                 } else {
@@ -67,9 +66,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerRes
                 }
             }
             ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
-                let bool = Ty::new_bool(self.infcx.interner());
-                debug_assert_eq!(c.ty(), bool);
-                self.infcx.opportunistic_resolve_effect_var(vid, bool)
+                self.infcx.opportunistic_resolve_effect_var(vid)
             }
             _ => {
                 if c.has_infer() {
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index d3a6a033978..43f4963b27a 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -42,7 +42,7 @@ pub(crate) struct UnmatchedDelim {
     pub candidate_span: Option<Span>,
 }
 
-pub(crate) fn parse_token_trees<'psess, 'src>(
+pub(crate) fn lex_token_trees<'psess, 'src>(
     psess: &'psess ParseSess,
     mut src: &'src str,
     mut start_pos: BytePos,
@@ -66,7 +66,7 @@ pub(crate) fn parse_token_trees<'psess, 'src>(
         last_lifetime: None,
     };
     let (stream, res, unmatched_delims) =
-        tokentrees::TokenTreesReader::parse_all_token_trees(string_reader);
+        tokentrees::TokenTreesReader::lex_all_token_trees(string_reader);
     match res {
         Ok(()) if unmatched_delims.is_empty() => Ok(stream),
         _ => {
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index eabe0226b2f..f7645446081 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -2,6 +2,7 @@ use super::diagnostics::report_suspicious_mismatch_block;
 use super::diagnostics::same_indentation_level;
 use super::diagnostics::TokenTreeDiagInfo;
 use super::{StringReader, UnmatchedDelim};
+use crate::Parser;
 use rustc_ast::token::{self, Delimiter, Token};
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
 use rustc_ast_pretty::pprust::token_to_string;
@@ -17,7 +18,7 @@ pub(super) struct TokenTreesReader<'psess, 'src> {
 }
 
 impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
-    pub(super) fn parse_all_token_trees(
+    pub(super) fn lex_all_token_trees(
         string_reader: StringReader<'psess, 'src>,
     ) -> (TokenStream, Result<(), Vec<PErr<'psess>>>, Vec<UnmatchedDelim>) {
         let mut tt_reader = TokenTreesReader {
@@ -25,14 +26,13 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
             token: Token::dummy(),
             diag_info: TokenTreeDiagInfo::default(),
         };
-        let (_open_spacing, stream, res) =
-            tt_reader.parse_token_trees(/* is_delimited */ false);
+        let (_open_spacing, stream, res) = tt_reader.lex_token_trees(/* is_delimited */ false);
         (stream, res, tt_reader.diag_info.unmatched_delims)
     }
 
-    // Parse a stream of tokens into a list of `TokenTree`s. The `Spacing` in
-    // the result is that of the opening delimiter.
-    fn parse_token_trees(
+    // Lex into a token stream. The `Spacing` in the result is that of the
+    // opening delimiter.
+    fn lex_token_trees(
         &mut self,
         is_delimited: bool,
     ) -> (Spacing, TokenStream, Result<(), Vec<PErr<'psess>>>) {
@@ -42,12 +42,10 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
         let mut buf = Vec::new();
         loop {
             match self.token.kind {
-                token::OpenDelim(delim) => {
-                    buf.push(match self.parse_token_tree_open_delim(delim) {
-                        Ok(val) => val,
-                        Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
-                    })
-                }
+                token::OpenDelim(delim) => buf.push(match self.lex_token_tree_open_delim(delim) {
+                    Ok(val) => val,
+                    Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
+                }),
                 token::CloseDelim(delim) => {
                     return (
                         open_spacing,
@@ -95,24 +93,24 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
         err
     }
 
-    fn parse_token_tree_open_delim(
+    fn lex_token_tree_open_delim(
         &mut self,
         open_delim: Delimiter,
     ) -> Result<TokenTree, Vec<PErr<'psess>>> {
-        // The span for beginning of the delimited section
+        // The span for beginning of the delimited section.
         let pre_span = self.token.span;
 
         self.diag_info.open_braces.push((open_delim, self.token.span));
 
-        // Parse the token trees within the delimiters.
+        // Lex the token trees within the delimiters.
         // We stop at any delimiter so we can try to recover if the user
         // uses an incorrect delimiter.
-        let (open_spacing, tts, res) = self.parse_token_trees(/* is_delimited */ true);
+        let (open_spacing, tts, res) = self.lex_token_trees(/* is_delimited */ true);
         if let Err(errs) = res {
             return Err(self.unclosed_delim_err(tts, errs));
         }
 
-        // Expand to cover the entire delimited token tree
+        // Expand to cover the entire delimited token tree.
         let delim_span = DelimSpan::from_pair(pre_span, self.token.span);
         let sm = self.string_reader.psess.source_map();
 
@@ -150,7 +148,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                     self.diag_info.last_unclosed_found_span = Some(self.token.span);
                     // This is a conservative error: only report the last unclosed
                     // delimiter. The previous unclosed delimiters could actually be
-                    // closed! The parser just hasn't gotten to them yet.
+                    // closed! The lexer just hasn't gotten to them yet.
                     if let Some(&(_, sp)) = self.diag_info.open_braces.last() {
                         unclosed_delimiter = Some(sp);
                     };
@@ -234,11 +232,11 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
     ) -> Vec<PErr<'psess>> {
         // If there are unclosed delims, see if there are diff markers and if so, point them
         // out instead of complaining about the unclosed delims.
-        let mut parser = crate::stream_to_parser(self.string_reader.psess, tts, None);
+        let mut parser = Parser::new(self.string_reader.psess, tts, None);
         let mut diff_errs = vec![];
-        // Suggest removing a `{` we think appears in an `if`/`while` condition
-        // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition, but
-        // we have no way of tracking this in the lexer itself, so we piggyback on the parser
+        // Suggest removing a `{` we think appears in an `if`/`while` condition.
+        // We want to suggest removing a `{` only if we think we're in an `if`/`while` condition,
+        // but we have no way of tracking this in the lexer itself, so we piggyback on the parser.
         let mut in_cond = false;
         while parser.token != token::Eof {
             if let Err(diff_err) = parser.err_vcs_conflict_marker() {
@@ -249,14 +247,15 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
                 parser.token.kind,
                 token::CloseDelim(Delimiter::Brace) | token::FatArrow
             ) {
-                // end of the `if`/`while` body, or the end of a `match` guard
+                // End of the `if`/`while` body, or the end of a `match` guard.
                 in_cond = false;
             } else if in_cond && parser.token == token::OpenDelim(Delimiter::Brace) {
                 // Store the `&&` and `let` to use their spans later when creating the diagnostic
                 let maybe_andand = parser.look_ahead(1, |t| t.clone());
                 let maybe_let = parser.look_ahead(2, |t| t.clone());
                 if maybe_andand == token::OpenDelim(Delimiter::Brace) {
-                    // This might be the beginning of the `if`/`while` body (i.e., the end of the condition)
+                    // This might be the beginning of the `if`/`while` body (i.e., the end of the
+                    // condition).
                     in_cond = false;
                 } else if maybe_andand == token::AndAnd && maybe_let.is_keyword(kw::Let) {
                     let mut err = parser.dcx().struct_span_err(
@@ -288,8 +287,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
     }
 
     fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'psess> {
-        // An unexpected closing delimiter (i.e., there is no
-        // matching opening delimiter).
+        // An unexpected closing delimiter (i.e., there is no matching opening delimiter).
         let token_str = token_to_string(&self.token);
         let msg = format!("unexpected closing delimiter: `{token_str}`");
         let mut err = self.string_reader.psess.dcx.struct_span_err(self.token.span, msg);
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index c9470151a7b..8eb299108d1 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -129,42 +129,42 @@ pub(super) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
     ('。', "Ideographic Full Stop", "."),
     ('︒', "Presentation Form For Vertical Ideographic Full Stop", "."),
 
-    ('՝', "Armenian Comma", "\'"),
-    (''', "Fullwidth Apostrophe", "\'"),
-    ('‘', "Left Single Quotation Mark", "\'"),
-    ('’', "Right Single Quotation Mark", "\'"),
-    ('‛', "Single High-Reversed-9 Quotation Mark", "\'"),
-    ('′', "Prime", "\'"),
-    ('‵', "Reversed Prime", "\'"),
-    ('՚', "Armenian Apostrophe", "\'"),
-    ('׳', "Hebrew Punctuation Geresh", "\'"),
-    ('`', "Grave Accent", "\'"),
-    ('`', "Greek Varia", "\'"),
-    ('`', "Fullwidth Grave Accent", "\'"),
-    ('´', "Acute Accent", "\'"),
-    ('΄', "Greek Tonos", "\'"),
-    ('´', "Greek Oxia", "\'"),
-    ('᾽', "Greek Koronis", "\'"),
-    ('᾿', "Greek Psili", "\'"),
-    ('῾', "Greek Dasia", "\'"),
-    ('ʹ', "Modifier Letter Prime", "\'"),
-    ('ʹ', "Greek Numeral Sign", "\'"),
-    ('ˈ', "Modifier Letter Vertical Line", "\'"),
-    ('ˊ', "Modifier Letter Acute Accent", "\'"),
-    ('ˋ', "Modifier Letter Grave Accent", "\'"),
-    ('˴', "Modifier Letter Middle Grave Accent", "\'"),
-    ('ʻ', "Modifier Letter Turned Comma", "\'"),
-    ('ʽ', "Modifier Letter Reversed Comma", "\'"),
-    ('ʼ', "Modifier Letter Apostrophe", "\'"),
-    ('ʾ', "Modifier Letter Right Half Ring", "\'"),
-    ('ꞌ', "Latin Small Letter Saltillo", "\'"),
-    ('י', "Hebrew Letter Yod", "\'"),
-    ('ߴ', "Nko High Tone Apostrophe", "\'"),
-    ('ߵ', "Nko Low Tone Apostrophe", "\'"),
-    ('ᑊ', "Canadian Syllabics West-Cree P", "\'"),
-    ('ᛌ', "Runic Letter Short-Twig-Sol S", "\'"),
-    ('𖽑', "Miao Sign Aspiration", "\'"),
-    ('𖽒', "Miao Sign Reformed Voicing", "\'"),
+    ('՝', "Armenian Comma", "'"),
+    (''', "Fullwidth Apostrophe", "'"),
+    ('‘', "Left Single Quotation Mark", "'"),
+    ('’', "Right Single Quotation Mark", "'"),
+    ('‛', "Single High-Reversed-9 Quotation Mark", "'"),
+    ('′', "Prime", "'"),
+    ('‵', "Reversed Prime", "'"),
+    ('՚', "Armenian Apostrophe", "'"),
+    ('׳', "Hebrew Punctuation Geresh", "'"),
+    ('`', "Grave Accent", "'"),
+    ('`', "Greek Varia", "'"),
+    ('`', "Fullwidth Grave Accent", "'"),
+    ('´', "Acute Accent", "'"),
+    ('΄', "Greek Tonos", "'"),
+    ('´', "Greek Oxia", "'"),
+    ('᾽', "Greek Koronis", "'"),
+    ('᾿', "Greek Psili", "'"),
+    ('῾', "Greek Dasia", "'"),
+    ('ʹ', "Modifier Letter Prime", "'"),
+    ('ʹ', "Greek Numeral Sign", "'"),
+    ('ˈ', "Modifier Letter Vertical Line", "'"),
+    ('ˊ', "Modifier Letter Acute Accent", "'"),
+    ('ˋ', "Modifier Letter Grave Accent", "'"),
+    ('˴', "Modifier Letter Middle Grave Accent", "'"),
+    ('ʻ', "Modifier Letter Turned Comma", "'"),
+    ('ʽ', "Modifier Letter Reversed Comma", "'"),
+    ('ʼ', "Modifier Letter Apostrophe", "'"),
+    ('ʾ', "Modifier Letter Right Half Ring", "'"),
+    ('ꞌ', "Latin Small Letter Saltillo", "'"),
+    ('י', "Hebrew Letter Yod", "'"),
+    ('ߴ', "Nko High Tone Apostrophe", "'"),
+    ('ߵ', "Nko Low Tone Apostrophe", "'"),
+    ('ᑊ', "Canadian Syllabics West-Cree P", "'"),
+    ('ᛌ', "Runic Letter Short-Twig-Sol S", "'"),
+    ('𖽑', "Miao Sign Aspiration", "'"),
+    ('𖽒', "Miao Sign Reformed Voicing", "'"),
 
     ('᳓', "Vedic Sign Nihshvasa", "\""),
     ('"', "Fullwidth Quotation Mark", "\""),
@@ -298,6 +298,7 @@ pub(super) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
     ('〉', "Right Angle Bracket", ">"),
     ('》', "Right Double Angle Bracket", ">"),
     ('>', "Fullwidth Greater-Than Sign", ">"),
+
     ('⩵', "Two Consecutive Equals Signs", "==")
 ];
 
@@ -332,7 +333,7 @@ const ASCII_ARRAY: &[(&str, &str, Option<token::TokenKind>)] = &[
     (">", "Greater-Than Sign", Some(token::Gt)),
     // FIXME: Literals are already lexed by this point, so we can't recover gracefully just by
     // spitting the correct token out.
-    ("\'", "Single Quote", None),
+    ("'", "Single Quote", None),
     ("\"", "Quotation Mark", None),
 ];
 
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 322739be3fb..b316327a262 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -34,84 +34,41 @@ mod errors;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
-// A bunch of utility functions of the form `parse_<thing>_from_<source>`
-// where <thing> includes crate, expr, item, stmt, tts, and one that
-// uses a HOF to parse anything, and <source> includes file and
-// `source_str`.
-
-/// A variant of 'panictry!' that works on a `Vec<Diag>` instead of a single `Diag`.
-macro_rules! panictry_buffer {
-    ($e:expr) => {{
-        use std::result::Result::{Err, Ok};
-        match $e {
-            Ok(e) => e,
-            Err(errs) => {
-                for e in errs {
-                    e.emit();
-                }
-                FatalError.raise()
+// Unwrap the result if `Ok`, otherwise emit the diagnostics and abort.
+pub fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
+    match expr {
+        Ok(expr) => expr,
+        Err(errs) => {
+            for err in errs {
+                err.emit();
             }
+            FatalError.raise()
         }
-    }};
-}
-
-pub fn parse_crate_from_file<'a>(input: &Path, psess: &'a ParseSess) -> PResult<'a, ast::Crate> {
-    let mut parser = new_parser_from_file(psess, input, None);
-    parser.parse_crate_mod()
-}
-
-pub fn parse_crate_attrs_from_file<'a>(
-    input: &Path,
-    psess: &'a ParseSess,
-) -> PResult<'a, ast::AttrVec> {
-    let mut parser = new_parser_from_file(psess, input, None);
-    parser.parse_inner_attributes()
-}
-
-pub fn parse_crate_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-) -> PResult<'_, ast::Crate> {
-    new_parser_from_source_str(psess, name, source).parse_crate_mod()
-}
-
-pub fn parse_crate_attrs_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-) -> PResult<'_, ast::AttrVec> {
-    new_parser_from_source_str(psess, name, source).parse_inner_attributes()
-}
-
-pub fn parse_stream_from_source_str(
-    name: FileName,
-    source: String,
-    psess: &ParseSess,
-    override_span: Option<Span>,
-) -> TokenStream {
-    source_file_to_stream(psess, psess.source_map().new_source_file(name, source), override_span)
-}
-
-/// Creates a new parser from a source string.
-pub fn new_parser_from_source_str(psess: &ParseSess, name: FileName, source: String) -> Parser<'_> {
-    panictry_buffer!(maybe_new_parser_from_source_str(psess, name, source))
+    }
 }
 
-/// Creates a new parser from a source string. Returns any buffered errors from lexing the initial
-/// token stream; these must be consumed via `emit`, `cancel`, etc., otherwise a panic will occur
-/// when they are dropped.
-pub fn maybe_new_parser_from_source_str(
+/// Creates a new parser from a source string. On failure, the errors must be consumed via
+/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
+/// dropped.
+pub fn new_parser_from_source_str(
     psess: &ParseSess,
     name: FileName,
     source: String,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
-    maybe_source_file_to_parser(psess, psess.source_map().new_source_file(name, source))
+    let source_file = psess.source_map().new_source_file(name, source);
+    new_parser_from_source_file(psess, source_file)
 }
 
-/// Creates a new parser, aborting if the file doesn't exist. If a span is given, that is used on
-/// an error as the source of the problem.
-pub fn new_parser_from_file<'a>(psess: &'a ParseSess, path: &Path, sp: Option<Span>) -> Parser<'a> {
+/// Creates a new parser from a filename. On failure, the errors must be consumed via
+/// `unwrap_or_emit_fatal`, `emit`, `cancel`, etc., otherwise a panic will occur when they are
+/// dropped.
+///
+/// If a span is given, that is used on an error as the source of the problem.
+pub fn new_parser_from_file<'a>(
+    psess: &'a ParseSess,
+    path: &Path,
+    sp: Option<Span>,
+) -> Result<Parser<'a>, Vec<Diag<'a>>> {
     let source_file = psess.source_map().load_file(path).unwrap_or_else(|e| {
         let msg = format!("couldn't read {}: {}", path.display(), e);
         let mut err = psess.dcx.struct_fatal(msg);
@@ -120,40 +77,37 @@ pub fn new_parser_from_file<'a>(psess: &'a ParseSess, path: &Path, sp: Option<Sp
         }
         err.emit();
     });
-
-    panictry_buffer!(maybe_source_file_to_parser(psess, source_file))
+    new_parser_from_source_file(psess, source_file)
 }
 
 /// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
 /// the initial token stream.
-fn maybe_source_file_to_parser(
+fn new_parser_from_source_file(
     psess: &ParseSess,
     source_file: Lrc<SourceFile>,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let end_pos = source_file.end_position();
-    let stream = maybe_file_to_stream(psess, source_file, None)?;
-    let mut parser = stream_to_parser(psess, stream, None);
+    let stream = source_file_to_stream(psess, source_file, None)?;
+    let mut parser = Parser::new(psess, stream, None);
     if parser.token == token::Eof {
         parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt(), None);
     }
-
     Ok(parser)
 }
 
-// Base abstractions
-
-/// Given a `source_file`, produces a sequence of token trees.
-pub fn source_file_to_stream(
+pub fn source_str_to_stream(
     psess: &ParseSess,
-    source_file: Lrc<SourceFile>,
+    name: FileName,
+    source: String,
     override_span: Option<Span>,
-) -> TokenStream {
-    panictry_buffer!(maybe_file_to_stream(psess, source_file, override_span))
+) -> Result<TokenStream, Vec<Diag<'_>>> {
+    let source_file = psess.source_map().new_source_file(name, source);
+    source_file_to_stream(psess, source_file, override_span)
 }
 
 /// Given a source file, produces a sequence of token trees. Returns any buffered errors from
 /// parsing the token stream.
-fn maybe_file_to_stream<'psess>(
+fn source_file_to_stream<'psess>(
     psess: &'psess ParseSess,
     source_file: Lrc<SourceFile>,
     override_span: Option<Span>,
@@ -165,16 +119,7 @@ fn maybe_file_to_stream<'psess>(
         ));
     });
 
-    lexer::parse_token_trees(psess, src.as_str(), source_file.start_pos, override_span)
-}
-
-/// Given a stream and the `ParseSess`, produces a parser.
-pub fn stream_to_parser<'a>(
-    psess: &'a ParseSess,
-    stream: TokenStream,
-    subparser_name: Option<&'static str>,
-) -> Parser<'a> {
-    Parser::new(psess, stream, subparser_name)
+    lexer::lex_token_trees(psess, src.as_str(), source_file.start_pos, override_span)
 }
 
 /// Runs the given subparser `f` on the tokens of the given `attr`'s item.
@@ -195,19 +140,28 @@ pub fn parse_in<'a, T>(
 pub fn fake_token_stream_for_item(psess: &ParseSess, item: &ast::Item) -> TokenStream {
     let source = pprust::item_to_string(item);
     let filename = FileName::macro_expansion_source_code(&source);
-    parse_stream_from_source_str(filename, source, psess, Some(item.span))
+    unwrap_or_emit_fatal(source_str_to_stream(psess, filename, source, Some(item.span)))
 }
 
 pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> TokenStream {
     let source = pprust::crate_to_string_for_macros(krate);
     let filename = FileName::macro_expansion_source_code(&source);
-    parse_stream_from_source_str(filename, source, psess, Some(krate.spans.inner_span))
+    unwrap_or_emit_fatal(source_str_to_stream(
+        psess,
+        filename,
+        source,
+        Some(krate.spans.inner_span),
+    ))
 }
 
 pub fn parse_cfg_attr(
     attr: &Attribute,
     psess: &ParseSess,
 ) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
+    const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
+    const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
+        <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
+
     match attr.get_normal_item().args {
         ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
             if !tokens.is_empty() =>
@@ -222,16 +176,12 @@ pub fn parse_cfg_attr(
                 }
             }
         }
-        _ => error_malformed_cfg_attr_missing(attr.span, psess),
+        _ => {
+            psess.dcx.emit_err(errors::MalformedCfgAttr {
+                span: attr.span,
+                sugg: CFG_ATTR_GRAMMAR_HELP,
+            });
+        }
     }
     None
 }
-
-const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
-const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
-    <https://doc.rust-lang.org/reference/conditional-compilation.html\
-    #the-cfg_attr-attribute>";
-
-fn error_malformed_cfg_attr_missing(span: Span, psess: &ParseSess) {
-    psess.dcx.emit_err(errors::MalformedCfgAttr { span, sugg: CFG_ATTR_GRAMMAR_HELP });
-}
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index a57eb70c705..4acc610d8c4 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -265,7 +265,7 @@ impl<'a> Parser<'a> {
     /// terminated by a semicolon.
     ///
     /// Matches `inner_attrs*`.
-    pub(crate) fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
+    pub fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> {
         let mut attrs = ast::AttrVec::new();
         loop {
             let start_pos: u32 = self.num_bump_calls.try_into().unwrap();
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 53757c38e8b..37c99958fc8 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -226,10 +226,11 @@ impl<'a> Parser<'a> {
             self.expect_keyword(kw::Extern)?;
             self.parse_item_foreign_mod(attrs, safety)?
         } else if self.is_static_global() {
+            let safety = self.parse_safety(Case::Sensitive);
             // STATIC ITEM
             self.bump(); // `static`
             let mutability = self.parse_mutability();
-            let (ident, item) = self.parse_static_item(mutability)?;
+            let (ident, item) = self.parse_static_item(safety, mutability)?;
             (ident, ItemKind::Static(Box::new(item)))
         } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
             // CONST ITEM
@@ -952,7 +953,7 @@ impl<'a> Parser<'a> {
                 let kind = match AssocItemKind::try_from(kind) {
                     Ok(kind) => kind,
                     Err(kind) => match kind {
-                        ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
+                        ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
                             self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
                             AssocItemKind::Const(Box::new(ConstItem {
                                 defaultness: Defaultness::Final,
@@ -1221,6 +1222,7 @@ impl<'a> Parser<'a> {
                                 ty,
                                 mutability: Mutability::Not,
                                 expr,
+                                safety: Safety::Default,
                             }))
                         }
                         _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
@@ -1258,7 +1260,10 @@ impl<'a> Parser<'a> {
                 matches!(token.kind, token::BinOp(token::Or) | token::OrOr)
             })
         } else {
-            false
+            let quals: &[Symbol] = &[kw::Unsafe, kw::Safe];
+            // `$qual static`
+            quals.iter().any(|&kw| self.check_keyword(kw))
+                && self.look_ahead(1, |t| t.is_keyword(kw::Static))
         }
     }
 
@@ -1319,7 +1324,11 @@ impl<'a> Parser<'a> {
     /// ```ebnf
     /// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
     /// ```
-    fn parse_static_item(&mut self, mutability: Mutability) -> PResult<'a, (Ident, StaticItem)> {
+    fn parse_static_item(
+        &mut self,
+        safety: Safety,
+        mutability: Mutability,
+    ) -> PResult<'a, (Ident, StaticItem)> {
         let ident = self.parse_ident()?;
 
         if self.token.kind == TokenKind::Lt && self.may_recover() {
@@ -1340,7 +1349,7 @@ impl<'a> Parser<'a> {
 
         self.expect_semi()?;
 
-        Ok((ident, StaticItem { ty, mutability, expr }))
+        Ok((ident, StaticItem { ty, safety, mutability, expr }))
     }
 
     /// Parse a constant item with the prefix `"const"` already parsed.
@@ -2400,9 +2409,9 @@ impl<'a> Parser<'a> {
         // `pub` is added in case users got confused with the ordering like `async pub fn`,
         // only if it wasn't preceded by `default` as `default pub` is invalid.
         let quals: &[Symbol] = if check_pub {
-            &[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
+            &[kw::Pub, kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
         } else {
-            &[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Extern]
+            &[kw::Gen, kw::Const, kw::Async, kw::Unsafe, kw::Safe, kw::Extern]
         };
         self.check_keyword_case(kw::Fn, case) // Definitely an `fn`.
             // `$qual fn` or `$qual $qual`:
@@ -2537,11 +2546,27 @@ impl<'a> Parser<'a> {
                     } else if self.check_keyword(kw::Unsafe) {
                         match safety {
                             Safety::Unsafe(sp) => Some(WrongKw::Duplicated(sp)),
+                            Safety::Safe(sp) => {
+                                recover_safety = Safety::Unsafe(self.token.span);
+                                Some(WrongKw::Misplaced(sp))
+                            }
                             Safety::Default => {
                                 recover_safety = Safety::Unsafe(self.token.span);
                                 Some(WrongKw::Misplaced(ext_start_sp))
                             }
                         }
+                    } else if self.check_keyword(kw::Safe) {
+                        match safety {
+                            Safety::Safe(sp) => Some(WrongKw::Duplicated(sp)),
+                            Safety::Unsafe(sp) => {
+                                recover_safety = Safety::Safe(self.token.span);
+                                Some(WrongKw::Misplaced(sp))
+                            }
+                            Safety::Default => {
+                                recover_safety = Safety::Safe(self.token.span);
+                                Some(WrongKw::Misplaced(ext_start_sp))
+                            }
+                        }
                     } else {
                         None
                     };
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index bab8b6c06eb..8f733b4fcbb 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1221,6 +1221,8 @@ impl<'a> Parser<'a> {
     fn parse_safety(&mut self, case: Case) -> Safety {
         if self.eat_keyword_case(kw::Unsafe, case) {
             Safety::Unsafe(self.prev_token.uninterpolated_span())
+        } else if self.eat_keyword_case(kw::Safe, case) {
+            Safety::Safe(self.prev_token.uninterpolated_span())
         } else {
             Safety::Default
         }
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index a31e350541a..79a6cf1b541 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -1,5 +1,7 @@
 use crate::parser::ForceCollect;
-use crate::{new_parser_from_source_str, parser::Parser, source_file_to_stream};
+use crate::{
+    new_parser_from_source_str, parser::Parser, source_str_to_stream, unwrap_or_emit_fatal,
+};
 use ast::token::IdentIsRaw;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter, Token};
@@ -29,7 +31,11 @@ fn psess() -> ParseSess {
 
 /// Map string to parser (via tts).
 fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
-    new_parser_from_source_str(psess, PathBuf::from("bogofile").into(), source_str)
+    unwrap_or_emit_fatal(new_parser_from_source_str(
+        psess,
+        PathBuf::from("bogofile").into(),
+        source_str,
+    ))
 }
 
 fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
@@ -82,11 +88,12 @@ where
 /// Maps a string to tts, using a made-up filename.
 pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
     let psess = psess();
-    source_file_to_stream(
+    unwrap_or_emit_fatal(source_str_to_stream(
         &psess,
-        psess.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str),
+        PathBuf::from("bogofile").into(),
+        source_str,
         None,
-    )
+    ))
 }
 
 /// Parses a string, returns a crate.
@@ -1068,7 +1075,8 @@ fn parse_item_from_source_str(
     source: String,
     psess: &ParseSess,
 ) -> PResult<'_, Option<P<ast::Item>>> {
-    new_parser_from_source_str(psess, name, source).parse_item(ForceCollect::No)
+    unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source))
+        .parse_item(ForceCollect::No)
 }
 
 // Produces a `rustc_span::span`.
@@ -1349,7 +1357,7 @@ fn ttdelim_span() {
         source: String,
         psess: &ParseSess,
     ) -> PResult<'_, P<ast::Expr>> {
-        new_parser_from_source_str(psess, name, source).parse_expr()
+        unwrap_or_emit_fatal(new_parser_from_source_str(psess, name, source)).parse_expr()
     }
 
     create_default_session_globals_then(|| {
diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs
index 78653e5f95a..906ecdfe5ab 100644
--- a/compiler/rustc_passes/src/diagnostic_items.rs
+++ b/compiler/rustc_passes/src/diagnostic_items.rs
@@ -82,7 +82,7 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
     let mut items = DiagnosticItems::default();
 
     // Collect diagnostic items in other crates.
-    for &cnum in tcx.crates_including_speculative(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
+    for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
         for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
             collect_item(tcx, &mut items, name, def_id);
         }
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index ab1dd248556..74b89546e6f 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -32,7 +32,7 @@ use rustc_hir::Node;
 use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::middle::privacy::{self, Level};
-use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc};
+use rustc_middle::mir::interpret::{ConstAllocation, ErrorHandled, GlobalAlloc};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ExistentialTraitRef, TyCtxt};
 use rustc_privacy::DefIdVisitor;
@@ -157,6 +157,7 @@ impl<'tcx> ReachableContext<'tcx> {
                 }
                 hir::ImplItemKind::Type(_) => false,
             },
+            Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => true,
             _ => false,
         }
     }
@@ -205,11 +206,21 @@ impl<'tcx> ReachableContext<'tcx> {
                         }
                     }
 
-                    // Reachable constants will be inlined into other crates
-                    // unconditionally, so we need to make sure that their
-                    // contents are also reachable.
                     hir::ItemKind::Const(_, _, init) => {
-                        self.visit_nested_body(init);
+                        // Only things actually ending up in the final constant need to be reachable.
+                        // Everything else is either already available as `mir_for_ctfe`, or can't be used
+                        // by codegen anyway.
+                        match self.tcx.const_eval_poly_to_alloc(item.owner_id.def_id.into()) {
+                            Ok(alloc) => {
+                                let alloc = self.tcx.global_alloc(alloc.alloc_id).unwrap_memory();
+                                self.propagate_from_alloc(alloc);
+                            }
+                            // Reachable generic constants will be inlined into other crates
+                            // unconditionally, so we need to make sure that their
+                            // contents are also reachable.
+                            Err(ErrorHandled::TooGeneric(_)) => self.visit_nested_body(init),
+                            Err(ErrorHandled::Reported(..)) => {}
+                        }
                     }
                     hir::ItemKind::Static(..) => {
                         if let Ok(alloc) = self.tcx.eval_static_initializer(item.owner_id.def_id) {
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 31c709f2eb6..6bdfaf0c908 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -1020,7 +1020,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
         // stabilization diagnostic, but it can be avoided when there are no
         // `remaining_lib_features`.
         let mut all_implications = remaining_implications.clone();
-        for &cnum in tcx.used_crates(()) {
+        for &cnum in tcx.crates(()) {
             all_implications
                 .extend_unord(tcx.stability_implications(cnum).items().map(|(k, v)| (*k, *v)));
         }
@@ -1033,7 +1033,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
             &all_implications,
         );
 
-        for &cnum in tcx.used_crates(()) {
+        for &cnum in tcx.crates(()) {
             if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
                 break;
             }
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index d80addf1236..90691ca1790 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -68,7 +68,7 @@ fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
     }
 
     let mut missing = FxHashSet::default();
-    for &cnum in tcx.used_crates(()).iter() {
+    for &cnum in tcx.crates(()).iter() {
         for &item in tcx.missing_lang_items(cnum).iter() {
             missing.insert(item);
         }
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index ff68dd81bea..81c5f355231 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -737,7 +737,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 // this). We show this to the user as `usize::MAX..` which is slightly incorrect but
                 // probably clear enough.
                 let c = ty.numeric_max_val(cx.tcx).unwrap();
-                let value = mir::Const::from_ty_const(c, cx.tcx);
+                let value = mir::Const::from_ty_const(c, ty.0, cx.tcx);
                 lo = PatRangeBoundary::Finite(value);
             }
             let hi = if let Some(hi) = range.hi.minus_one() {
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 76227a78c3d..66fb3136805 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -64,7 +64,6 @@ pub struct MarkFrame<'a> {
     parent: Option<&'a MarkFrame<'a>>,
 }
 
-#[derive(PartialEq)]
 enum DepNodeColor {
     Red,
     Green(DepNodeIndex),
@@ -925,7 +924,7 @@ impl<D: Deps> DepGraph<D> {
     /// Returns true if the given node has been marked as red during the
     /// current compilation session. Used in various assertions
     pub fn is_red(&self, dep_node: &DepNode) -> bool {
-        self.node_color(dep_node) == Some(DepNodeColor::Red)
+        matches!(self.node_color(dep_node), Some(DepNodeColor::Red))
     }
 
     /// Returns true if the given node has been marked as green during the
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index f824e4faf5d..358f25e2334 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -11,6 +11,10 @@ resolve_added_macro_use =
 resolve_ancestor_only =
     visibilities can only be restricted to ancestor modules
 
+resolve_anonymous_livetime_non_gat_report_error =
+    in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
+    .label = this lifetime must come from the implemented type
+
 resolve_arguments_macro_use_not_allowed = arguments to `macro_use` are not allowed here
 
 resolve_associated_const_with_similar_name_exists =
@@ -234,6 +238,10 @@ resolve_items_in_traits_are_not_importable =
 resolve_label_with_similar_name_reachable =
     a label with a similar name is reachable
 
+resolve_lending_iterator_report_error =
+    associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
+    .note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type.
+
 resolve_lifetime_param_in_enum_discriminant =
     lifetime parameters may not be used in enum discriminant values
 
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index cad10571afe..d7416ead325 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -2,6 +2,7 @@ use crate::{ImplTraitContext, Resolver};
 use rustc_ast::visit::FnKind;
 use rustc_ast::*;
 use rustc_expand::expand::AstFragment;
+use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind};
 use rustc_hir::def_id::LocalDefId;
 use rustc_span::hygiene::LocalExpnId;
@@ -128,7 +129,11 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
             ItemKind::Union(..) => DefKind::Union,
             ItemKind::ExternCrate(..) => DefKind::ExternCrate,
             ItemKind::TyAlias(..) => DefKind::TyAlias,
-            ItemKind::Static(s) => DefKind::Static { mutability: s.mutability, nested: false },
+            ItemKind::Static(s) => DefKind::Static {
+                safety: hir::Safety::Safe,
+                mutability: s.mutability,
+                nested: false,
+            },
             ItemKind::Const(..) => DefKind::Const,
             ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
             ItemKind::MacroDef(..) => {
@@ -211,8 +216,18 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
 
     fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
         let def_kind = match fi.kind {
-            ForeignItemKind::Static(box StaticForeignItem { ty: _, mutability, expr: _ }) => {
-                DefKind::Static { mutability, nested: false }
+            ForeignItemKind::Static(box StaticForeignItem {
+                ty: _,
+                mutability,
+                expr: _,
+                safety,
+            }) => {
+                let safety = match safety {
+                    ast::Safety::Unsafe(_) | ast::Safety::Default => hir::Safety::Unsafe,
+                    ast::Safety::Safe(_) => hir::Safety::Safe,
+                };
+
+                DefKind::Static { safety, mutability, nested: false }
             }
             ForeignItemKind::Fn(_) => DefKind::Fn,
             ForeignItemKind::TyAlias(_) => DefKind::ForeignTy,
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index edfeacec7e3..0620f3d709e 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -882,6 +882,23 @@ pub(crate) struct ElidedAnonymousLivetimeReportError {
     pub(crate) suggestion: Option<ElidedAnonymousLivetimeReportErrorSuggestion>,
 }
 
+#[derive(Diagnostic)]
+#[diag(resolve_lending_iterator_report_error)]
+pub(crate) struct LendingIteratorReportError {
+    #[primary_span]
+    pub(crate) lifetime: Span,
+    #[note]
+    pub(crate) ty: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(resolve_anonymous_livetime_non_gat_report_error)]
+pub(crate) struct AnonymousLivetimeNonGatReportError {
+    #[primary_span]
+    #[label]
+    pub(crate) lifetime: Span,
+}
+
 #[derive(Subdiagnostic)]
 #[multipart_suggestion(
     resolve_elided_anonymous_lifetime_report_error_suggestion,
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 57db765c07e..78bd3c4e49f 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -965,6 +965,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // if it can then our result is not determined and can be invalidated.
         for single_import in &resolution.single_imports {
             let Some(import_vis) = single_import.vis.get() else {
+                // This branch handles a cycle in single imports, which occurs
+                // when we've previously captured the `vis` value during an import
+                // process.
+                //
+                // For example:
+                // ```
+                // use a::b;
+                // use b as a;
+                // ```
+                // 1. Steal the `vis` in `use a::b` and attempt to locate `a` in the
+                //    current module.
+                // 2. Encounter the import `use b as a`, which is a `single_import` for `a`,
+                //    and try to find `b` in the current module.
+                // 3. Re-encounter the `use a::b` import since it's a `single_import` of `b`.
+                //    This leads to entering this branch.
                 continue;
             };
             if !self.is_accessible_from(import_vis, parent_scope.module) {
@@ -979,15 +994,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // named imports.
                 continue;
             }
+
             let Some(module) = single_import.imported_module.get() else {
                 return Err((Undetermined, Weak::No));
             };
-            let ImportKind::Single { source: ident, .. } = single_import.kind else {
+            let ImportKind::Single { source: ident, source_bindings, .. } = &single_import.kind
+            else {
                 unreachable!();
             };
+            if binding.map_or(false, |binding| binding.module().is_some())
+                && source_bindings.iter().all(|binding| matches!(binding.get(), Err(Undetermined)))
+            {
+                // This branch allows the binding to be defined or updated later,
+                // avoiding module inconsistency between the resolve process and the finalize process.
+                // See more details in #124840
+                return Err((Undetermined, Weak::No));
+            }
             match self.resolve_ident_in_module(
                 module,
-                ident,
+                *ident,
                 ns,
                 &single_import.parent_scope,
                 None,
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 6bbde26db34..27ea7760f58 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -352,9 +352,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     (old_glob @ true, false) | (old_glob @ false, true) => {
                         let (glob_binding, nonglob_binding) =
                             if old_glob { (old_binding, binding) } else { (binding, old_binding) };
-                        if glob_binding.res() != nonglob_binding.res()
-                            && key.ns == MacroNS
+                        if key.ns == MacroNS
                             && nonglob_binding.expansion != LocalExpnId::ROOT
+                            && glob_binding.res() != nonglob_binding.res()
                         {
                             resolution.binding = Some(this.ambiguity(
                                 AmbiguityKind::GlobVsExpanded,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index bcf2c9a9206..c7c95addf49 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -9,7 +9,7 @@
 use crate::{errors, path_names_to_string, rustdoc, BindingError, Finalize, LexicalScopeBinding};
 use crate::{BindingKey, Used};
 use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
-use crate::{ResolutionError, Resolver, Segment, UseError};
+use crate::{ResolutionError, Resolver, Segment, TyCtxt, UseError};
 
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{visit_opt, walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
@@ -629,6 +629,9 @@ struct DiagMetadata<'ast> {
     in_assignment: Option<&'ast Expr>,
     is_assign_rhs: bool,
 
+    /// If we are setting an associated type in trait impl, is it a non-GAT type?
+    in_non_gat_assoc_type: Option<bool>,
+
     /// Used to detect possible `.` -> `..` typo when calling methods.
     in_range: Option<(&'ast Expr, &'ast Expr)>,
 
@@ -1703,10 +1706,35 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                                 break;
                             }
                         }
-                        self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
-                            span: lifetime.ident.span,
-                            suggestion,
-                        });
+
+                        // are we trying to use an anonymous lifetime
+                        // on a non GAT associated trait type?
+                        if !self.in_func_body
+                            && let Some((module, _)) = &self.current_trait_ref
+                            && let Some(ty) = &self.diag_metadata.current_self_type
+                            && Some(true) == self.diag_metadata.in_non_gat_assoc_type
+                            && let crate::ModuleKind::Def(DefKind::Trait, trait_id, _) = module.kind
+                        {
+                            if def_id_matches_path(
+                                self.r.tcx,
+                                trait_id,
+                                &["core", "iter", "traits", "iterator", "Iterator"],
+                            ) {
+                                self.r.dcx().emit_err(errors::LendingIteratorReportError {
+                                    lifetime: lifetime.ident.span,
+                                    ty: ty.span(),
+                                });
+                            } else {
+                                self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError {
+                                    lifetime: lifetime.ident.span,
+                                });
+                            }
+                        } else {
+                            self.r.dcx().emit_err(errors::ElidedAnonymousLivetimeReportError {
+                                span: lifetime.ident.span,
+                                suggestion,
+                            });
+                        }
                     } else {
                         self.r.dcx().emit_err(errors::ExplicitAnonymousLivetimeReportError {
                             span: lifetime.ident.span,
@@ -3058,6 +3086,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 );
             }
             AssocItemKind::Type(box TyAlias { generics, .. }) => {
+                self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
                 debug!("resolve_implementation AssocItemKind::Type");
                 // We also need a new scope for the impl item type parameters.
                 self.with_generic_param_rib(
@@ -3086,6 +3115,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         });
                     },
                 );
+                self.diag_metadata.in_non_gat_assoc_type = None;
             }
             AssocItemKind::Delegation(box delegation) => {
                 debug!("resolve_implementation AssocItemKind::Delegation");
@@ -4829,3 +4859,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 }
+
+/// Check if definition matches a path
+fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str]) -> bool {
+    let mut path = expected_path.iter().rev();
+    while let (Some(parent), Some(next_step)) = (tcx.opt_parent(def_id), path.next()) {
+        if !tcx.opt_item_name(def_id).map_or(false, |n| n.as_str() == *next_step) {
+            return false;
+        }
+        def_id = parent;
+    }
+    return true;
+}
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index d67132d2dd4..0be8b5d5718 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -68,6 +68,8 @@ fn compress<'tcx>(
 fn encode_args<'tcx>(
     tcx: TyCtxt<'tcx>,
     args: GenericArgsRef<'tcx>,
+    for_def: DefId,
+    has_erased_self: bool,
     dict: &mut FxHashMap<DictKey<'tcx>, usize>,
     options: EncodeTyOptions,
 ) -> String {
@@ -76,7 +78,8 @@ fn encode_args<'tcx>(
     let args: Vec<GenericArg<'_>> = args.iter().collect();
     if !args.is_empty() {
         s.push('I');
-        for arg in args {
+        let def_generics = tcx.generics_of(for_def);
+        for (n, arg) in args.iter().enumerate() {
             match arg.unpack() {
                 GenericArgKind::Lifetime(region) => {
                     s.push_str(&encode_region(region, dict));
@@ -85,7 +88,10 @@ fn encode_args<'tcx>(
                     s.push_str(&encode_ty(tcx, ty, dict, options));
                 }
                 GenericArgKind::Const(c) => {
-                    s.push_str(&encode_const(tcx, c, dict, options));
+                    let n = n + (has_erased_self as usize);
+                    let ct_ty =
+                        tcx.type_of(def_generics.param_at(n, tcx).def_id).instantiate_identity();
+                    s.push_str(&encode_const(tcx, c, ct_ty, dict, options));
                 }
             }
         }
@@ -99,6 +105,7 @@ fn encode_args<'tcx>(
 fn encode_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     c: Const<'tcx>,
+    ct_ty: Ty<'tcx>,
     dict: &mut FxHashMap<DictKey<'tcx>, usize>,
     options: EncodeTyOptions,
 ) -> String {
@@ -111,20 +118,20 @@ fn encode_const<'tcx>(
             // L<element-type>E as literal argument
 
             // Element type
-            s.push_str(&encode_ty(tcx, c.ty(), dict, options));
+            s.push_str(&encode_ty(tcx, ct_ty, dict, options));
         }
 
         // Literal arguments
-        ty::ConstKind::Value(..) => {
+        ty::ConstKind::Value(ct_ty, ..) => {
             // L<element-type>[n]<element-value>E as literal argument
 
             // Element type
-            s.push_str(&encode_ty(tcx, c.ty(), dict, options));
+            s.push_str(&encode_ty(tcx, ct_ty, dict, options));
 
             // The only allowed types of const values are bool, u8, u16, u32,
             // u64, u128, usize i8, i16, i32, i64, i128, isize, and char. The
             // bool value false is encoded as 0 and true as 1.
-            match c.ty().kind() {
+            match ct_ty.kind() {
                 ty::Int(ity) => {
                     let bits = c.eval_bits(tcx, ty::ParamEnv::reveal_all());
                     let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
@@ -142,7 +149,7 @@ fn encode_const<'tcx>(
                     let _ = write!(s, "{val}");
                 }
                 _ => {
-                    bug!("encode_const: unexpected type `{:?}`", c.ty());
+                    bug!("encode_const: unexpected type `{:?}`", ct_ty);
                 }
             }
         }
@@ -231,15 +238,21 @@ fn encode_predicate<'tcx>(
         ty::ExistentialPredicate::Trait(trait_ref) => {
             let name = encode_ty_name(tcx, trait_ref.def_id);
             let _ = write!(s, "u{}{}", name.len(), &name);
-            s.push_str(&encode_args(tcx, trait_ref.args, dict, options));
+            s.push_str(&encode_args(tcx, trait_ref.args, trait_ref.def_id, true, dict, options));
         }
         ty::ExistentialPredicate::Projection(projection) => {
             let name = encode_ty_name(tcx, projection.def_id);
             let _ = write!(s, "u{}{}", name.len(), &name);
-            s.push_str(&encode_args(tcx, projection.args, dict, options));
+            s.push_str(&encode_args(tcx, projection.args, projection.def_id, true, dict, options));
             match projection.term.unpack() {
                 TermKind::Ty(ty) => s.push_str(&encode_ty(tcx, ty, dict, options)),
-                TermKind::Const(c) => s.push_str(&encode_const(tcx, c, dict, options)),
+                TermKind::Const(c) => s.push_str(&encode_const(
+                    tcx,
+                    c,
+                    tcx.type_of(projection.def_id).instantiate(tcx, projection.args),
+                    dict,
+                    options,
+                )),
             }
         }
         ty::ExistentialPredicate::AutoTrait(def_id) => {
@@ -485,7 +498,7 @@ pub fn encode_ty<'tcx>(
                 // <subst>, as vendor extended type.
                 let name = encode_ty_name(tcx, def_id);
                 let _ = write!(s, "u{}{}", name.len(), &name);
-                s.push_str(&encode_args(tcx, args, dict, options));
+                s.push_str(&encode_args(tcx, args, def_id, false, dict, options));
                 compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
             }
             typeid.push_str(&s);
@@ -529,7 +542,7 @@ pub fn encode_ty<'tcx>(
             let mut s = String::new();
             let name = encode_ty_name(tcx, *def_id);
             let _ = write!(s, "u{}{}", name.len(), &name);
-            s.push_str(&encode_args(tcx, args, dict, options));
+            s.push_str(&encode_args(tcx, args, *def_id, false, dict, options));
             compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
             typeid.push_str(&s);
         }
@@ -541,7 +554,7 @@ pub fn encode_ty<'tcx>(
             let name = encode_ty_name(tcx, *def_id);
             let _ = write!(s, "u{}{}", name.len(), &name);
             let parent_args = tcx.mk_args(args.as_coroutine_closure().parent_args());
-            s.push_str(&encode_args(tcx, parent_args, dict, options));
+            s.push_str(&encode_args(tcx, parent_args, *def_id, false, dict, options));
             compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
             typeid.push_str(&s);
         }
@@ -556,6 +569,8 @@ pub fn encode_ty<'tcx>(
             s.push_str(&encode_args(
                 tcx,
                 tcx.mk_args(args.as_coroutine().parent_args()),
+                *def_id,
+                false,
                 dict,
                 options,
             ));
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index edfd48ed43b..c33a52f4a7a 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -251,7 +251,9 @@ impl RustcInternal for MirConst {
     fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
         let constant = tables.mir_consts[self.id];
         match constant {
-            rustc_middle::mir::Const::Ty(ty) => rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap()),
+            rustc_middle::mir::Const::Ty(ty, ct) => {
+                rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap())
+            }
             rustc_middle::mir::Const::Unevaluated(uneval, ty) => {
                 rustc_middle::mir::Const::Unevaluated(
                     tcx.lift(uneval).unwrap(),
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 9822ed79e2b..a8688c88601 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -126,7 +126,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         let mut tables = self.0.borrow_mut();
         let tcx = tables.tcx;
         iter::once(LOCAL_CRATE)
-            .chain(tables.tcx.used_crates(()).iter().copied())
+            .chain(tables.tcx.crates(()).iter().copied())
             .flat_map(|cnum| tcx.trait_impls_in_crate(cnum).iter())
             .map(|impl_def_id| tables.impl_def(*impl_def_id))
             .collect()
@@ -201,19 +201,14 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
 
     fn external_crates(&self) -> Vec<stable_mir::Crate> {
         let tables = self.0.borrow();
-        tables
-            .tcx
-            .used_crates(())
-            .iter()
-            .map(|crate_num| smir_crate(tables.tcx, *crate_num))
-            .collect()
+        tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
     }
 
     fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
         let tables = self.0.borrow();
         let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
             .iter()
-            .chain(tables.tcx.used_crates(()).iter())
+            .chain(tables.tcx.crates(()).iter())
             .filter_map(|crate_num| {
                 let crate_name = tables.tcx.crate_name(*crate_num).to_string();
                 (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
@@ -398,7 +393,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
             )));
         }
 
-        Ok(mir::Const::Ty(ty::Const::zero_sized(tables.tcx, ty_internal)).stable(&mut *tables))
+        Ok(mir::Const::Ty(ty_internal, ty::Const::zero_sized(tables.tcx, ty_internal))
+            .stable(&mut *tables))
     }
 
     fn new_const_str(&self, value: &str) -> MirConst {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 1c87293209c..bcacf54baf3 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -729,9 +729,9 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap());
         match *self {
-            mir::Const::Ty(c) => MirConst::new(
+            mir::Const::Ty(ty, c) => MirConst::new(
                 stable_mir::ty::ConstantKind::Ty(c.stable(tables)),
-                c.ty().stable(tables),
+                ty.stable(tables),
                 id,
             ),
             mir::Const::Unevaluated(unev_const, ty) => {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 1f3356f579f..73bc87dc9ab 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -415,7 +415,7 @@ pub fn mir_const_from_ty_const<'tcx>(
     ty: Ty<'tcx>,
 ) -> stable_mir::ty::MirConst {
     let kind = match ty_const.kind() {
-        ty::Value(val) => {
+        ty::Value(ty, val) => {
             let val = match val {
                 ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
                 ty::ValTree::Branch(branch) => {
@@ -447,7 +447,7 @@ pub fn mir_const_from_ty_const<'tcx>(
         ty::ExprCt(_) => unimplemented!(),
     };
     let stable_ty = tables.intern_ty(ty);
-    let id = tables.intern_mir_const(mir::Const::Ty(ty_const));
+    let id = tables.intern_mir_const(mir::Const::Ty(ty, ty_const));
     stable_mir::ty::MirConst::new(kind, stable_ty, id)
 }
 
@@ -456,14 +456,15 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         let kind = match self.kind() {
-            ty::Value(val) => {
+            ty::Value(ty, val) => {
                 let val = match val {
                     ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar),
                     ty::ValTree::Branch(branch) => {
                         ty::ValTree::Branch(tables.tcx.lift(branch).unwrap())
                     }
                 };
-                let ty = tables.tcx.lift(self.ty()).unwrap();
+
+                let ty = tables.tcx.lift(ty).unwrap();
                 let const_val = tables.tcx.valtree_to_const_val((ty, val));
                 if matches!(const_val, mir::ConstValue::ZeroSized) {
                     stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables))
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index b2ca01fe3b9..82179a4a058 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -682,6 +682,13 @@ impl Span {
         if span.hi > other.hi { Some(span.with_lo(cmp::max(span.lo, other.hi))) } else { None }
     }
 
+    /// Returns `Some(span)`, where the end is trimmed by the start of `other`.
+    pub fn trim_end(self, other: Span) -> Option<Span> {
+        let span = self.data();
+        let other = other.data();
+        if span.lo < other.lo { Some(span.with_hi(cmp::min(span.hi, other.lo))) } else { None }
+    }
+
     /// Returns the source span -- this is either the supplied span, or the span for
     /// the macro callsite that expanded to it.
     pub fn source_callsite(self) -> Span {
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index 788a52faf56..6a028226631 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -216,6 +216,7 @@ impl Span {
 
     // Returns either syntactic context, if it can be retrieved without taking the interner lock,
     // or an index into the interner if it cannot.
+    #[inline]
     fn inline_ctxt(self) -> Result<SyntaxContext, usize> {
         Ok(if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER {
             if self.len_with_tag_or_marker & PARENT_TAG == 0 {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 61ca0d54ca4..f530d1dd1d4 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -103,6 +103,7 @@ symbols! {
         MacroRules:         "macro_rules",
         Raw:                "raw",
         Reuse:              "reuse",
+        Safe:               "safe",
         Union:              "union",
         Yeet:               "yeet",
     }
@@ -1964,6 +1965,7 @@ symbols! {
         unsafe_block_in_unsafe_fn,
         unsafe_cell,
         unsafe_cell_raw_get,
+        unsafe_extern_blocks,
         unsafe_no_drop_flag,
         unsafe_pin_internals,
         unsize,
@@ -2213,6 +2215,7 @@ impl fmt::Display for IdentPrinter {
 pub struct MacroRulesNormalizedIdent(Ident);
 
 impl MacroRulesNormalizedIdent {
+    #[inline]
     pub fn new(ident: Ident) -> Self {
         Self(ident.normalize_to_macro_rules())
     }
diff --git a/compiler/rustc_span/src/tests.rs b/compiler/rustc_span/src/tests.rs
index cb88fa89058..48fa786fb1c 100644
--- a/compiler/rustc_span/src/tests.rs
+++ b/compiler/rustc_span/src/tests.rs
@@ -42,3 +42,60 @@ fn test_normalize_newlines() {
     check("\r\r\n", "\r\n", &[2]);
     check("hello\rworld", "hello\rworld", &[]);
 }
+
+#[test]
+fn test_trim() {
+    let span = |lo: usize, hi: usize| {
+        Span::new(BytePos::from_usize(lo), BytePos::from_usize(hi), SyntaxContext::root(), None)
+    };
+
+    // Various positions, named for their relation to `start` and `end`.
+    let well_before = 1;
+    let before = 3;
+    let start = 5;
+    let mid = 7;
+    let end = 9;
+    let after = 11;
+    let well_after = 13;
+
+    // The resulting span's context should be that of `self`, not `other`.
+    let other = span(start, end).with_ctxt(SyntaxContext::from_u32(999));
+
+    // Test cases for `trim_end`.
+
+    assert_eq!(span(well_before, before).trim_end(other), Some(span(well_before, before)));
+    assert_eq!(span(well_before, start).trim_end(other), Some(span(well_before, start)));
+    assert_eq!(span(well_before, mid).trim_end(other), Some(span(well_before, start)));
+    assert_eq!(span(well_before, end).trim_end(other), Some(span(well_before, start)));
+    assert_eq!(span(well_before, after).trim_end(other), Some(span(well_before, start)));
+
+    assert_eq!(span(start, mid).trim_end(other), None);
+    assert_eq!(span(start, end).trim_end(other), None);
+    assert_eq!(span(start, after).trim_end(other), None);
+
+    assert_eq!(span(mid, end).trim_end(other), None);
+    assert_eq!(span(mid, after).trim_end(other), None);
+
+    assert_eq!(span(end, after).trim_end(other), None);
+
+    assert_eq!(span(after, well_after).trim_end(other), None);
+
+    // Test cases for `trim_start`.
+
+    assert_eq!(span(after, well_after).trim_start(other), Some(span(after, well_after)));
+    assert_eq!(span(end, well_after).trim_start(other), Some(span(end, well_after)));
+    assert_eq!(span(mid, well_after).trim_start(other), Some(span(end, well_after)));
+    assert_eq!(span(start, well_after).trim_start(other), Some(span(end, well_after)));
+    assert_eq!(span(before, well_after).trim_start(other), Some(span(end, well_after)));
+
+    assert_eq!(span(mid, end).trim_start(other), None);
+    assert_eq!(span(start, end).trim_start(other), None);
+    assert_eq!(span(before, end).trim_start(other), None);
+
+    assert_eq!(span(start, mid).trim_start(other), None);
+    assert_eq!(span(before, mid).trim_start(other), None);
+
+    assert_eq!(span(before, start).trim_start(other), None);
+
+    assert_eq!(span(well_before, before).trim_start(other), None);
+}
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 0ed1f67bb82..75cac6c7992 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -270,15 +270,15 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
 
     fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
         // only print integers
-        match (ct.kind(), ct.ty().kind()) {
-            (ty::ConstKind::Value(ty::ValTree::Leaf(scalar)), ty::Int(_) | ty::Uint(_)) => {
+        match ct.kind() {
+            ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar)) if ty.is_integral() => {
                 // The `pretty_print_const` formatting depends on -Zverbose-internals
                 // flag, so we cannot reuse it here.
-                let signed = matches!(ct.ty().kind(), ty::Int(_));
+                let signed = matches!(ty.kind(), ty::Int(_));
                 write!(
                     self,
                     "{:#?}",
-                    ty::ConstInt::new(scalar, signed, ct.ty().is_ptr_sized_integral())
+                    ty::ConstInt::new(scalar, signed, ty.is_ptr_sized_integral())
                 )?;
             }
             _ => self.write_str("_")?,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 57b1542ff5a..55479bce6fc 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -541,8 +541,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
     fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
         // We only mangle a typed value if the const can be evaluated.
         let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all());
-        match ct.kind() {
-            ty::ConstKind::Value(_) => {}
+        let (ct_ty, valtree) = match ct.kind() {
+            ty::ConstKind::Value(ty, val) => (ty, val),
 
             // Placeholders (should be demangled as `_`).
             // NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore
@@ -559,7 +559,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 self.push("p");
                 return Ok(());
             }
-        }
+        };
 
         if let Some(&i) = self.consts.get(&ct) {
             self.print_backref(i)?;
@@ -567,16 +567,15 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
         }
 
         let start = self.out.len();
-        let ty = ct.ty();
 
-        match ty.kind() {
+        match ct_ty.kind() {
             ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
-                ty.print(self)?;
+                ct_ty.print(self)?;
 
                 let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all());
 
                 // Negative integer values are mangled using `n` as a "sign prefix".
-                if let ty::Int(ity) = ty.kind() {
+                if let ty::Int(ity) = ct_ty.kind() {
                     let val =
                         Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128;
                     if val < 0 {
@@ -598,40 +597,32 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
 
                 match inner_ty.kind() {
                     ty::Str if mutbl.is_not() => {
-                        match ct.kind() {
-                            ty::ConstKind::Value(valtree) => {
-                                let slice =
-                                    valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| {
-                                        bug!(
-                                        "expected to get raw bytes from valtree {:?} for type {:}",
-                                        valtree, ty
-                                    )
-                                    });
-                                let s = std::str::from_utf8(slice)
-                                    .expect("non utf8 str from MIR interpreter");
-
-                                self.push("e");
-
-                                // FIXME(eddyb) use a specialized hex-encoding loop.
-                                for byte in s.bytes() {
-                                    let _ = write!(self.out, "{byte:02x}");
-                                }
-
-                                self.push("_");
-                            }
-
-                            _ => {
-                                bug!("symbol_names: unsupported `&str` constant: {:?}", ct);
-                            }
+                        let slice =
+                            valtree.try_to_raw_bytes(self.tcx(), ct_ty).unwrap_or_else(|| {
+                                bug!(
+                                    "expected to get raw bytes from valtree {:?} for type {:}",
+                                    valtree,
+                                    ct_ty
+                                )
+                            });
+                        let s =
+                            std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
+
+                        self.push("e");
+
+                        // FIXME(eddyb) use a specialized hex-encoding loop.
+                        for byte in s.bytes() {
+                            let _ = write!(self.out, "{byte:02x}");
                         }
+
+                        self.push("_");
                     }
                     _ => {
-                        let pointee_ty = ct
-                            .ty()
+                        let pointee_ty = ct_ty
                             .builtin_deref(true)
                             .expect("tried to dereference on non-ptr type");
-                        // FIXME(const_generics): add an assert that we only do this for valtrees.
-                        let dereferenced_const = self.tcx.mk_ct_from_kind(ct.kind(), pointee_ty);
+                        let dereferenced_const =
+                            ty::Const::new_value(self.tcx, valtree, pointee_ty);
                         dereferenced_const.print(self)?;
                     }
                 }
@@ -649,7 +640,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                     Ok(())
                 };
 
-                match *ct.ty().kind() {
+                match *ct_ty.kind() {
                     ty::Array(..) | ty::Slice(_) => {
                         self.push("A");
                         print_field_list(self)?;
@@ -698,7 +689,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 }
             }
             _ => {
-                bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty(), ct);
+                bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct_ty, ct);
             }
         }
 
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 690c1797f23..0e0b9e98339 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -444,7 +444,7 @@ pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable<TyCtxt
                 infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)).into()
             }
             ty::GenericArgKind::Type(_) => infcx.next_ty_var(span).into(),
-            ty::GenericArgKind::Const(ct) => infcx.next_const_var(ct.ty(), span).into(),
+            ty::GenericArgKind::Const(_) => infcx.next_const_var(span).into(),
         };
 
         orig_values.push(unconstrained);
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index f18f1f4f8f0..f90e4711037 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -609,8 +609,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         ty
     }
 
-    pub(super) fn next_const_infer(&mut self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
-        let ct = self.infcx.next_const_var(ty, DUMMY_SP);
+    pub(super) fn next_const_infer(&mut self) -> ty::Const<'tcx> {
+        let ct = self.infcx.next_const_var(DUMMY_SP);
         self.inspect.add_var_value(ct);
         ct
     }
@@ -620,7 +620,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
     pub(super) fn next_term_infer_of_kind(&mut self, kind: ty::Term<'tcx>) -> ty::Term<'tcx> {
         match kind.unpack() {
             ty::TermKind::Ty(_) => self.next_ty_infer().into(),
-            ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
+            ty::TermKind::Const(_) => self.next_const_infer().into(),
         }
     }
 
@@ -1037,14 +1037,19 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         &self,
         param_env: ty::ParamEnv<'tcx>,
         unevaluated: ty::UnevaluatedConst<'tcx>,
-        ty: Ty<'tcx>,
     ) -> Option<ty::Const<'tcx>> {
         use rustc_middle::mir::interpret::ErrorHandled;
         match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
-            Ok(Some(val)) => Some(ty::Const::new_value(self.interner(), val, ty)),
+            Ok(Some(val)) => Some(ty::Const::new_value(
+                self.interner(),
+                val,
+                self.interner()
+                    .type_of(unevaluated.def)
+                    .instantiate(self.interner(), unevaluated.args),
+            )),
             Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None,
             Err(ErrorHandled::Reported(e, _)) => {
-                Some(ty::Const::new_error(self.interner(), e.into(), ty))
+                Some(ty::Const::new_error(self.interner(), e.into()))
             }
         }
     }
@@ -1124,7 +1129,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceAliasWithInfer<'_, '_, 'tcx> {
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
         match ct.kind() {
             ty::ConstKind::Unevaluated(..) if !ct.has_escaping_bound_vars() => {
-                let infer_ct = self.ecx.next_const_infer(ct.ty());
+                let infer_ct = self.ecx.next_const_infer();
                 let normalizes_to = ty::PredicateKind::AliasRelate(
                     ct.into(),
                     infer_ct.into(),
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index 1f27978e5a6..19c95dad48c 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -208,7 +208,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
                 Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
                     let unconstrained_term = match term.unpack() {
                         ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
-                        ty::TermKind::Const(ct) => infcx.next_const_var(ct.ty(), span).into(),
+                        ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
                     };
                     let goal =
                         goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 68a4831c335..c47b0194964 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -169,7 +169,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
 
                 // FIXME(generic_const_exprs): Implement handling for generic
                 // const expressions here.
-                if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv, ct.ty()) {
+                if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv) {
                     self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
                 } else {
                     self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
@@ -178,7 +178,9 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
             ty::ConstKind::Infer(_) => {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
             }
-            ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {
+            ty::ConstKind::Placeholder(_)
+            | ty::ConstKind::Value(_, _)
+            | ty::ConstKind::Error(_) => {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
             // We can freely ICE here as:
@@ -198,29 +200,37 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
     ) -> QueryResult<'tcx> {
         let (ct, ty) = goal.predicate;
 
-        // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
-        // other than `ConstKind::Value`. Unfortunately this would require looking in the
-        // env for any `ConstArgHasType` assumptions for parameters and placeholders. I
-        // have not yet gotten around to implementing this though.
-        //
-        // We do still stall on infer vars though as otherwise a goal like:
-        // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
-        // get unified with some const that is not of type `usize`.
-        match ct.kind() {
+        let ct_ty = match ct.kind() {
             // FIXME: Ignore effect vars because canonicalization doesn't handle them correctly
             // and if we stall on the var then we wind up creating ambiguity errors in a probe
             // for this goal which contains an effect var. Which then ends up ICEing.
-            ty::ConstKind::Infer(ty::InferConst::Var(_)) => {
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+            ty::ConstKind::Infer(ty::InferConst::EffectVar(_)) => {
+                return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+            }
+            ty::ConstKind::Infer(_) => {
+                return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
             }
             ty::ConstKind::Error(_) => {
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
             }
-            _ => {
-                self.eq(goal.param_env, ct.ty(), ty)?;
-                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            ty::ConstKind::Unevaluated(uv) => {
+                self.interner().type_of(uv.def).instantiate(self.interner(), uv.args)
             }
-        }
+            ty::ConstKind::Expr(_) => unimplemented!(
+                "`feature(generic_const_exprs)` is not supported in the new trait solver"
+            ),
+            ty::ConstKind::Param(_) => {
+                unreachable!("`ConstKind::Param` should have been canonicalized to `Placeholder`")
+            }
+            ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
+            ty::ConstKind::Value(ty, _) => ty,
+            ty::ConstKind::Placeholder(placeholder) => {
+                placeholder.find_const_ty_from_env(goal.param_env)
+            }
+        };
+
+        self.eq(goal.param_env, ct_ty, ty)?;
+        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index c60d1aed415..f42edebfcc4 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -109,7 +109,6 @@ where
 
     fn normalize_unevaluated_const(
         &mut self,
-        ty: Ty<'tcx>,
         uv: ty::UnevaluatedConst<'tcx>,
     ) -> Result<ty::Const<'tcx>, Vec<E>> {
         let infcx = self.at.infcx;
@@ -126,7 +125,7 @@ where
 
         self.depth += 1;
 
-        let new_infer_ct = infcx.next_const_var(ty, self.at.cause.span);
+        let new_infer_ct = infcx.next_const_var(self.at.cause.span);
         let obligation = Obligation::new(
             tcx,
             self.at.cause.clone(),
@@ -143,7 +142,7 @@ where
             let ct = infcx.resolve_vars_if_possible(new_infer_ct);
             ct.try_fold_with(self)?
         } else {
-            ty::Const::new_unevaluated(tcx, uv, ty).try_super_fold_with(self)?
+            ty::Const::new_unevaluated(tcx, uv).try_super_fold_with(self)?
         };
 
         self.depth -= 1;
@@ -214,7 +213,7 @@ where
         if uv.has_escaping_bound_vars() {
             let (uv, mapped_regions, mapped_types, mapped_consts) =
                 BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, uv);
-            let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct.ty(), uv))?;
+            let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))?;
             Ok(PlaceholderReplacer::replace_placeholders(
                 infcx,
                 mapped_regions,
@@ -224,7 +223,7 @@ where
                 result,
             ))
         } else {
-            ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct.ty(), uv))
+            ensure_sufficient_stack(|| self.normalize_unevaluated_const(uv))
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs
index 362c4072278..a6e4b6ff4a8 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs
@@ -12,10 +12,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
         if let Some(normalized_const) = self.try_const_eval_resolve(
             goal.param_env,
             ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args),
-            self.interner()
-                .type_of(goal.predicate.alias.def_id)
-                .no_bound_vars()
-                .expect("const ty should not rely on other generics"),
         ) {
             self.instantiate_normalizes_to_term(goal, normalized_const.into());
             self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 8c63bd824bc..787f08a084e 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -201,13 +201,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             let error_response = |ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, reason| {
                 let guar = tcx.dcx().span_delayed_bug(tcx.def_span(assoc_def.item.def_id), reason);
                 let error_term = match assoc_def.item.kind {
-                    ty::AssocKind::Const => ty::Const::new_error(
-                        tcx,
-                        guar,
-                        tcx.type_of(goal.predicate.def_id())
-                            .instantiate(tcx, goal.predicate.alias.args),
-                    )
-                    .into(),
+                    ty::AssocKind::Const => ty::Const::new_error(tcx, guar).into(),
                     ty::AssocKind::Type => Ty::new_error(tcx, guar).into(),
                     // This makes no sense...
                     ty::AssocKind::Fn => span_bug!(
@@ -253,7 +247,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                         ty::EarlyBinder::bind(
                             ty::Const::new_error_with_message(
                                 tcx,
-                                tcx.type_of(assoc_def.item.def_id).instantiate_identity(),
                                 DUMMY_SP,
                                 "associated const projection is not supported yet",
                             )
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6623a86e69f..1d32ef2ccd9 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -765,7 +765,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                                 unevaluated,
                                 obligation.cause.span,
                             ) {
-                                Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, c.ty())),
+                                Ok(Some(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args))),
                                 Ok(None) => {
                                     let tcx = self.tcx;
                                     let reported =
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 7723f2229bf..1ef2f26cd09 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -529,7 +529,6 @@ fn plug_infer_with_placeholders<'tcx>(
                         ty::Const::new_placeholder(
                             self.infcx.tcx,
                             ty::Placeholder { universe: self.universe, bound: self.next_var() },
-                            ct.ty(),
                         ),
                     )
                 else {
@@ -924,11 +923,12 @@ where
                 }
             }
 
-            ty::Alias(kind @ (ty::Projection | ty::Inherent | ty::Weak), ..) => {
-                if ty.has_type_flags(ty::TypeFlags::HAS_TY_PARAM) {
-                    bug!("unexpected ty param in alias ty");
-                }
-
+            // A rigid alias may normalize to anything.
+            // * If it references an infer var, placeholder or bound ty, it may
+            //   normalize to that, so we have to treat it as an uncovered ty param.
+            // * Otherwise it may normalize to any non-type-generic type
+            //   be it local or non-local.
+            ty::Alias(kind, _) => {
                 if ty.has_type_flags(
                     ty::TypeFlags::HAS_TY_PLACEHOLDER
                         | ty::TypeFlags::HAS_TY_BOUND
@@ -948,7 +948,24 @@ where
                         }
                     }
                 } else {
-                    ControlFlow::Continue(())
+                    // Regarding *opaque types* specifically, we choose to treat them as non-local,
+                    // even those that appear within the same crate. This seems somewhat surprising
+                    // at first, but makes sense when you consider that opaque types are supposed
+                    // to hide the underlying type *within the same crate*. When an opaque type is
+                    // used from outside the module where it is declared, it should be impossible to
+                    // observe anything about it other than the traits that it implements.
+                    //
+                    // The alternative would be to look at the underlying type to determine whether
+                    // or not the opaque type itself should be considered local.
+                    //
+                    // However, this could make it a breaking change to switch the underlying hidden
+                    // type from a local type to a remote type. This would violate the rule that
+                    // opaque types should be completely opaque apart from the traits that they
+                    // implement, so we don't use this behavior.
+                    // Addendum: Moreover, revealing the underlying type is likely to cause cycle
+                    // errors as we rely on coherence / the specialization graph during typeck.
+
+                    self.found_non_local_ty(ty)
                 }
             }
 
@@ -990,35 +1007,6 @@ where
             // auto trait impl applies. There will never be multiple impls, so we can just
             // act as if it were a local type here.
             ty::CoroutineWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
-            ty::Alias(ty::Opaque, ..) => {
-                // This merits some explanation.
-                // Normally, opaque types are not involved when performing
-                // coherence checking, since it is illegal to directly
-                // implement a trait on an opaque type. However, we might
-                // end up looking at an opaque type during coherence checking
-                // if an opaque type gets used within another type (e.g. as
-                // the type of a field) when checking for auto trait or `Sized`
-                // impls. This requires us to decide whether or not an opaque
-                // type should be considered 'local' or not.
-                //
-                // We choose to treat all opaque types as non-local, even
-                // those that appear within the same crate. This seems
-                // somewhat surprising at first, but makes sense when
-                // you consider that opaque types are supposed to hide
-                // the underlying type *within the same crate*. When an
-                // opaque type is used from outside the module
-                // where it is declared, it should be impossible to observe
-                // anything about it other than the traits that it implements.
-                //
-                // The alternative would be to look at the underlying type
-                // to determine whether or not the opaque type itself should
-                // be considered local. However, this could make it a breaking change
-                // to switch the underlying ('defining') type from a local type
-                // to a remote type. This would violate the rule that opaque
-                // types should be completely opaque apart from the traits
-                // that they implement, so we don't use this behavior.
-                self.found_non_local_ty(ty)
-            }
         };
         // A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so
         // the first type we visit is always the self type.
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 8348482386f..f93bd0a396d 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -34,7 +34,7 @@ pub fn is_const_evaluatable<'tcx>(
         ty::ConstKind::Param(_)
         | ty::ConstKind::Bound(_, _)
         | ty::ConstKind::Placeholder(_)
-        | ty::ConstKind::Value(_)
+        | ty::ConstKind::Value(_, _)
         | ty::ConstKind::Error(_) => return Ok(()),
         ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
     };
@@ -173,8 +173,7 @@ fn satisfied_from_param_env<'tcx>(
             debug!("is_const_evaluatable: candidate={:?}", c);
             if self.infcx.probe(|_| {
                 let ocx = ObligationCtxt::new(self.infcx);
-                ocx.eq(&ObligationCause::dummy(), self.param_env, c.ty(), self.ct.ty()).is_ok()
-                    && ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok()
+                ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok()
                     && ocx.select_all_or_error().is_empty()
             }) {
                 self.single_match = match self.single_match {
@@ -215,7 +214,6 @@ fn satisfied_from_param_env<'tcx>(
 
     if let Some(Ok(c)) = single_match {
         let ocx = ObligationCtxt::new(infcx);
-        assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok());
         assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
         assert!(ocx.select_all_or_error().is_empty());
         return true;
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 9a0929baeaf..46b13788186 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -876,56 +876,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         }
                     }
 
-                    ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => {
-                        // Errors for `ConstEvaluatable` predicates show up as
-                        // `SelectionError::ConstEvalFailure`,
-                        // not `Unimplemented`.
+                    // Errors for `ConstEvaluatable` predicates show up as
+                    // `SelectionError::ConstEvalFailure`,
+                    // not `Unimplemented`.
+                    ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
+                    // Errors for `ConstEquate` predicates show up as
+                    // `SelectionError::ConstEvalFailure`,
+                    // not `Unimplemented`.
+                    | ty::PredicateKind::ConstEquate { .. }
+                    // Ambiguous predicates should never error
+                    | ty::PredicateKind::Ambiguous
+                    | ty::PredicateKind::NormalizesTo { .. }
+                    | ty::PredicateKind::AliasRelate { .. }
+                    | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {
                         span_bug!(
                             span,
-                            "const-evaluatable requirement gave wrong error: `{:?}`",
+                            "Unexpected `Predicate` for `SelectionError`: `{:?}`",
                             obligation
                         )
                     }
-
-                    ty::PredicateKind::ConstEquate(..) => {
-                        // Errors for `ConstEquate` predicates show up as
-                        // `SelectionError::ConstEvalFailure`,
-                        // not `Unimplemented`.
-                        span_bug!(
-                            span,
-                            "const-equate requirement gave wrong error: `{:?}`",
-                            obligation
-                        )
-                    }
-
-                    ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"),
-
-                    ty::PredicateKind::NormalizesTo(..) => span_bug!(
-                        span,
-                        "NormalizesTo predicate should never be the predicate cause of a SelectionError"
-                    ),
-
-                    ty::PredicateKind::AliasRelate(..) => span_bug!(
-                        span,
-                        "AliasRelate predicate should never be the predicate cause of a SelectionError"
-                    ),
-
-                    ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
-                        let mut diag = self.dcx().struct_span_err(
-                            span,
-                            format!("the constant `{ct}` is not of type `{ty}`"),
-                        );
-                        self.note_type_err(
-                            &mut diag,
-                            &obligation.cause,
-                            None,
-                            None,
-                            TypeError::Sorts(ty::error::ExpectedFound::new(true, ty, ct.ty())),
-                            false,
-                            false,
-                        );
-                        diag
-                    }
                 }
             }
 
@@ -988,6 +957,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             Overflow(_) => {
                 bug!("overflow should be handled before the `report_selection_error` path");
             }
+
+            SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty } => {
+                let mut diag = self.dcx().struct_span_err(
+                    span,
+                    format!("the constant `{ct}` is not of type `{expected_ty}`"),
+                );
+
+                self.note_type_err(
+                    &mut diag,
+                    &obligation.cause,
+                    None,
+                    None,
+                    TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)),
+                    false,
+                    false,
+                );
+                diag
+            }
         };
 
         self.note_obligation_cause(&mut err, &obligation);
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index a26288efc96..bce5c7101cc 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -439,37 +439,50 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                 // This is because this is not ever a useful obligation to report
                 // as the cause of an overflow.
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
-                    // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
-                    // other than `ConstKind::Value`. Unfortunately this would require looking in the
-                    // env for any `ConstArgHasType` assumptions for parameters and placeholders. I
-                    // don't really want to implement this in the old solver so I haven't.
-                    //
-                    // We do still stall on infer vars though as otherwise a goal like:
-                    // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
-                    // get unified with some const that is not of type `usize`.
-                    let ct = self.selcx.infcx.shallow_resolve_const(ct);
-                    match ct.kind() {
-                        ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
+                    let ct = infcx.shallow_resolve_const(ct);
+                    let ct_ty = match ct.kind() {
+                        ty::ConstKind::Infer(var) => {
+                            let var = match var {
+                                ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid),
+                                ty::InferConst::EffectVar(vid) => TyOrConstInferVar::Effect(vid),
+                                ty::InferConst::Fresh(_) => {
+                                    bug!("encountered fresh const in fulfill")
+                                }
+                            };
                             pending_obligation.stalled_on.clear();
-                            pending_obligation.stalled_on.extend([TyOrConstInferVar::Const(vid)]);
-                            ProcessResult::Unchanged
+                            pending_obligation.stalled_on.extend([var]);
+                            return ProcessResult::Unchanged;
                         }
                         ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]),
-                        _ => {
-                            match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
-                                // Only really excercised by generic_const_exprs
-                                DefineOpaqueTypes::Yes,
-                                ct.ty(),
-                                ty,
-                            ) {
-                                Ok(inf_ok) => {
-                                    ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
-                                }
-                                Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
-                                    SelectionError::Unimplemented,
-                                )),
-                            }
+                        ty::ConstKind::Value(ty, _) => ty,
+                        ty::ConstKind::Unevaluated(uv) => {
+                            infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
+                        }
+                        // FIXME(generic_const_exprs): we should construct an alias like
+                        // `<lhs_ty as Add<rhs_ty>>::Output` when this is an `Expr` representing
+                        // `lhs + rhs`.
+                        ty::ConstKind::Expr(_) => {
+                            return ProcessResult::Changed(mk_pending(vec![]));
+                        }
+                        ty::ConstKind::Placeholder(_) => {
+                            bug!("placeholder const {:?} in old solver", ct)
+                        }
+                        ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
+                        ty::ConstKind::Param(param_ct) => {
+                            param_ct.find_ty_from_env(obligation.param_env)
                         }
+                    };
+
+                    match infcx.at(&obligation.cause, obligation.param_env).eq(
+                        // Only really excercised by generic_const_exprs
+                        DefineOpaqueTypes::Yes,
+                        ct_ty,
+                        ty,
+                    ) {
+                        Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
+                        Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
+                            SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
+                        )),
                     }
                 }
 
@@ -633,7 +646,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                             match self.selcx.infcx.try_const_eval_resolve(
                                 obligation.param_env,
                                 unevaluated,
-                                c.ty(),
                                 obligation.cause.span,
                             ) {
                                 Ok(val) => Ok(val),
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index d918945dbed..7be2c4a85c5 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -359,7 +359,7 @@ pub fn normalize_param_env_or_error<'tcx>(
                     // `ty::Const::normalize` can only work with properly preserved binders.
 
                     if c.has_escaping_bound_vars() {
-                        return ty::Const::new_misc_error(self.0, c.ty());
+                        return ty::Const::new_misc_error(self.0);
                     }
                     // While it is pretty sus to be evaluating things with an empty param env, it
                     // should actually be okay since without `feature(generic_const_exprs)` the only
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 501d9c9266e..2c9cb79664b 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -523,16 +523,9 @@ fn normalize_to_error<'a, 'tcx>(
         | ty::AliasTermKind::InherentTy
         | ty::AliasTermKind::OpaqueTy
         | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(),
-        ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => selcx
-            .infcx
-            .next_const_var(
-                selcx
-                    .tcx()
-                    .type_of(projection_term.def_id)
-                    .instantiate(selcx.tcx(), projection_term.args),
-                cause.span,
-            )
-            .into(),
+        ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => {
+            selcx.infcx.next_const_var(cause.span).into()
+        }
     };
     let trait_obligation = Obligation {
         cause,
@@ -744,8 +737,6 @@ fn project<'cx, 'tcx>(
                         obligation.predicate.def_id,
                         obligation.predicate.args,
                     ),
-                    tcx.type_of(obligation.predicate.def_id)
-                        .instantiate(tcx, obligation.predicate.args),
                 )
                 .into(),
                 kind => {
@@ -2071,15 +2062,14 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     // * `args` ends up as `[u32, S]`
     let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args);
     let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node);
-    let ty = tcx.type_of(assoc_ty.item.def_id);
     let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
     let term: ty::EarlyBinder<'tcx, ty::Term<'tcx>> = if is_const {
         let did = assoc_ty.item.def_id;
         let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did);
         let uv = ty::UnevaluatedConst::new(did, identity_args);
-        ty.map_bound(|ty| ty::Const::new_unevaluated(tcx, uv, ty).into())
+        ty::EarlyBinder::bind(ty::Const::new_unevaluated(tcx, uv).into())
     } else {
-        ty.map_bound(|ty| ty.into())
+        tcx.type_of(assoc_ty.item.def_id).map_bound(|ty| ty.into())
     };
     if !tcx.check_args_compatible(assoc_ty.item.def_id, args) {
         let err = Ty::new_error_with_message(
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 4d3aa067c6c..6db5fa0e4e5 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -921,6 +921,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         cause: &ObligationCause<'tcx>,
     ) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
+        // Don't drop any candidates in intercrate mode, as it's incomplete.
+        // (Not that it matters, since `Unsize` is not a stable trait.)
+        if self.infcx.intercrate {
+            return None;
+        }
+
         let tcx = self.tcx();
         if tcx.features().trait_upcasting {
             return None;
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index ef0d8735d35..749081006f3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -665,9 +665,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 tcx,
                                 ty::INNERMOST,
                                 ty::BoundVar::from_usize(bound_vars.len() - 1),
-                                tcx.type_of(param.def_id)
-                                    .no_bound_vars()
-                                    .expect("const parameter types cannot be generic"),
                             )
                             .into()
                         }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 2489b8916d1..ce4fa5fa47c 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -947,7 +947,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             match self.infcx.try_const_eval_resolve(
                                 obligation.param_env,
                                 unevaluated,
-                                c.ty(),
                                 obligation.cause.span,
                             ) {
                                 Ok(val) => Ok(val),
@@ -995,21 +994,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
                 ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
-                    // FIXME(BoxyUwU): Really we should not be calling `ct.ty()` for any variant
-                    // other than `ConstKind::Value`. Unfortunately this would require looking in the
-                    // env for any `ConstArgHasType` assumptions for parameters and placeholders. I
-                    // don't really want to implement this in the old solver so I haven't.
-                    //
-                    // We do still stall on infer vars though as otherwise a goal like:
-                    // `ConstArgHasType(?x: usize, usize)` can succeed even though it might later
-                    // get unified with some const that is not of type `usize`.
                     let ct = self.infcx.shallow_resolve_const(ct);
                     let ct_ty = match ct.kind() {
-                        ty::ConstKind::Infer(ty::InferConst::Var(_)) => {
+                        ty::ConstKind::Infer(_) => {
                             return Ok(EvaluatedToAmbig);
                         }
                         ty::ConstKind::Error(_) => return Ok(EvaluatedToOk),
-                        _ => ct.ty(),
+                        ty::ConstKind::Value(ty, _) => ty,
+                        ty::ConstKind::Unevaluated(uv) => {
+                            self.tcx().type_of(uv.def).instantiate(self.tcx(), uv.args)
+                        }
+                        // FIXME(generic_const_exprs): See comment in `fulfill.rs`
+                        ty::ConstKind::Expr(_) => return Ok(EvaluatedToOk),
+                        ty::ConstKind::Placeholder(_) => {
+                            bug!("placeholder const {:?} in old solver", ct)
+                        }
+                        ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
+                        ty::ConstKind::Param(param_ct) => {
+                            param_ct.find_ty_from_env(obligation.param_env)
+                        }
                     };
 
                     match self.infcx.at(&obligation.cause, obligation.param_env).eq(
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 5d5a22e189c..960c27b636e 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -483,7 +483,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> {
                 let universe = self.universe_for(debruijn);
                 let p = ty::PlaceholderConst { universe, bound: bound_const };
                 self.mapped_consts.insert(p, bound_const);
-                ty::Const::new_placeholder(self.infcx.tcx, p, ct.ty())
+                ty::Const::new_placeholder(self.infcx.tcx, p)
             }
             _ => ct.super_fold_with(self),
         }
@@ -626,7 +626,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,
                     );
-                    ty::Const::new_bound(self.infcx.tcx, db, *replace_var, ct.ty())
+                    ty::Const::new_bound(self.infcx.tcx, db, *replace_var)
                 }
                 None => {
                     if ct.has_infer() {
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 8d7d81d8f73..ffebf7b0721 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -135,7 +135,7 @@ mod rustc {
             use rustc_middle::ty::ScalarInt;
             use rustc_span::symbol::sym;
 
-            let Ok(cv) = c.eval(tcx, param_env, DUMMY_SP) else {
+            let Ok((ty, cv)) = c.eval(tcx, param_env, DUMMY_SP) else {
                 return Some(Self {
                     alignment: true,
                     lifetimes: true,
@@ -144,7 +144,7 @@ mod rustc {
                 });
             };
 
-            let adt_def = c.ty().ty_adt_def()?;
+            let adt_def = ty.ty_adt_def()?;
 
             assert_eq!(
                 tcx.require_lang_item(LangItem::TransmuteOpts, None),
diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
index 8a42298f216..1aec40e95f6 100644
--- a/compiler/rustc_ty_utils/src/consts.rs
+++ b/compiler/rustc_ty_utils/src/consts.rs
@@ -23,7 +23,7 @@ fn destructure_const<'tcx>(
     tcx: TyCtxt<'tcx>,
     const_: ty::Const<'tcx>,
 ) -> ty::DestructuredConst<'tcx> {
-    let ty::ConstKind::Value(valtree) = const_.kind() else {
+    let ty::ConstKind::Value(ct_ty, valtree) = const_.kind() else {
         bug!("cannot destructure constant {:?}", const_)
     };
 
@@ -32,7 +32,7 @@ fn destructure_const<'tcx>(
         _ => bug!("cannot destructure constant {:?}", const_),
     };
 
-    let (fields, variant) = match const_.ty().kind() {
+    let (fields, variant) = match ct_ty.kind() {
         ty::Array(inner_ty, _) | ty::Slice(inner_ty) => {
             // construct the consts for the elements of the array/slice
             let field_consts = branches
@@ -121,7 +121,7 @@ fn recurse_build<'tcx>(
             let sp = node.span;
             match tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) {
                 Ok(c) => c,
-                Err(LitToConstError::Reported(guar)) => ty::Const::new_error(tcx, guar, node.ty),
+                Err(LitToConstError::Reported(guar)) => ty::Const::new_error(tcx, guar),
                 Err(LitToConstError::TypeError) => {
                     bug!("encountered type error in lit_to_const")
                 }
@@ -137,35 +137,31 @@ fn recurse_build<'tcx>(
         }
         &ExprKind::NamedConst { def_id, args, user_ty: _ } => {
             let uneval = ty::UnevaluatedConst::new(def_id, args);
-            ty::Const::new_unevaluated(tcx, uneval, node.ty)
+            ty::Const::new_unevaluated(tcx, uneval)
         }
-        ExprKind::ConstParam { param, .. } => ty::Const::new_param(tcx, *param, node.ty),
+        ExprKind::ConstParam { param, .. } => ty::Const::new_param(tcx, *param),
 
         ExprKind::Call { fun, args, .. } => {
+            let fun_ty = body.exprs[*fun].ty;
             let fun = recurse_build(tcx, body, *fun, root_span)?;
 
             let mut new_args = Vec::<ty::Const<'tcx>>::with_capacity(args.len());
             for &id in args.iter() {
                 new_args.push(recurse_build(tcx, body, id, root_span)?);
             }
-            ty::Const::new_expr(
-                tcx,
-                Expr::new_call(tcx, fun.ty(), fun, new_args.into_iter()),
-                node.ty,
-            )
+            ty::Const::new_expr(tcx, Expr::new_call(tcx, fun_ty, fun, new_args))
         }
         &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => {
+            let lhs_ty = body.exprs[lhs].ty;
             let lhs = recurse_build(tcx, body, lhs, root_span)?;
+            let rhs_ty = body.exprs[rhs].ty;
             let rhs = recurse_build(tcx, body, rhs, root_span)?;
-            ty::Const::new_expr(
-                tcx,
-                Expr::new_binop(tcx, op, lhs.ty(), rhs.ty(), lhs, rhs),
-                node.ty,
-            )
+            ty::Const::new_expr(tcx, Expr::new_binop(tcx, op, lhs_ty, rhs_ty, lhs, rhs))
         }
         &ExprKind::Unary { op, arg } if check_unop(op) => {
+            let arg_ty = body.exprs[arg].ty;
             let arg = recurse_build(tcx, body, arg, root_span)?;
-            ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg.ty(), arg), node.ty)
+            ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg_ty, arg))
         }
         // This is necessary so that the following compiles:
         //
@@ -187,20 +183,12 @@ fn recurse_build<'tcx>(
         &ExprKind::Use { source } => {
             let value_ty = body.exprs[source].ty;
             let value = recurse_build(tcx, body, source, root_span)?;
-            ty::Const::new_expr(
-                tcx,
-                Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty),
-                node.ty,
-            )
+            ty::Const::new_expr(tcx, Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty))
         }
         &ExprKind::Cast { source } => {
             let value_ty = body.exprs[source].ty;
             let value = recurse_build(tcx, body, source, root_span)?;
-            ty::Const::new_expr(
-                tcx,
-                Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty),
-                node.ty,
-            )
+            ty::Const::new_expr(tcx, Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty))
         }
         ExprKind::Borrow { arg, .. } => {
             let arg_node = &body.exprs[*arg];
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 1c30f03c693..61ae36265ec 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -115,8 +115,8 @@ impl<I: Interner> CanonicalVarInfo<I> {
             CanonicalVarKind::PlaceholderTy(_) => false,
             CanonicalVarKind::Region(_) => true,
             CanonicalVarKind::PlaceholderRegion(..) => false,
-            CanonicalVarKind::Const(..) => true,
-            CanonicalVarKind::PlaceholderConst(_, _) => false,
+            CanonicalVarKind::Const(_) => true,
+            CanonicalVarKind::PlaceholderConst(_) => false,
             CanonicalVarKind::Effect => true,
         }
     }
@@ -126,8 +126,8 @@ impl<I: Interner> CanonicalVarInfo<I> {
             CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
             CanonicalVarKind::Ty(_)
             | CanonicalVarKind::PlaceholderTy(_)
-            | CanonicalVarKind::Const(_, _)
-            | CanonicalVarKind::PlaceholderConst(_, _)
+            | CanonicalVarKind::Const(_)
+            | CanonicalVarKind::PlaceholderConst(_)
             | CanonicalVarKind::Effect => false,
         }
     }
@@ -136,12 +136,12 @@ impl<I: Interner> CanonicalVarInfo<I> {
         match self.kind {
             CanonicalVarKind::Ty(_)
             | CanonicalVarKind::Region(_)
-            | CanonicalVarKind::Const(_, _)
+            | CanonicalVarKind::Const(_)
             | CanonicalVarKind::Effect => panic!("expected placeholder: {self:?}"),
 
             CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
             CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
-            CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.var().as_usize(),
+            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
         }
     }
 }
@@ -169,13 +169,13 @@ pub enum CanonicalVarKind<I: Interner> {
     PlaceholderRegion(I::PlaceholderRegion),
 
     /// Some kind of const inference variable.
-    Const(UniverseIndex, I::Ty),
+    Const(UniverseIndex),
 
     /// Effect variable `'?E`.
     Effect,
 
     /// A "placeholder" that represents "any const".
-    PlaceholderConst(I::PlaceholderConst, I::Ty),
+    PlaceholderConst(I::PlaceholderConst),
 }
 
 impl<I: Interner> PartialEq for CanonicalVarKind<I> {
@@ -185,10 +185,8 @@ impl<I: Interner> PartialEq for CanonicalVarKind<I> {
             (Self::PlaceholderTy(l0), Self::PlaceholderTy(r0)) => l0 == r0,
             (Self::Region(l0), Self::Region(r0)) => l0 == r0,
             (Self::PlaceholderRegion(l0), Self::PlaceholderRegion(r0)) => l0 == r0,
-            (Self::Const(l0, l1), Self::Const(r0, r1)) => l0 == r0 && l1 == r1,
-            (Self::PlaceholderConst(l0, l1), Self::PlaceholderConst(r0, r1)) => {
-                l0 == r0 && l1 == r1
-            }
+            (Self::Const(l0), Self::Const(r0)) => l0 == r0,
+            (Self::PlaceholderConst(l0), Self::PlaceholderConst(r0)) => l0 == r0,
             _ => std::mem::discriminant(self) == std::mem::discriminant(other),
         }
     }
@@ -199,10 +197,10 @@ impl<I: Interner> CanonicalVarKind<I> {
         match self {
             CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
             CanonicalVarKind::Region(ui) => ui,
-            CanonicalVarKind::Const(ui, _) => ui,
+            CanonicalVarKind::Const(ui) => ui,
             CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
             CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
-            CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(),
+            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(),
             CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
                 UniverseIndex::ROOT
             }
@@ -220,7 +218,7 @@ impl<I: Interner> CanonicalVarKind<I> {
                 CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
             }
             CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
-            CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty),
+            CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui),
 
             CanonicalVarKind::PlaceholderTy(placeholder) => {
                 CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
@@ -228,8 +226,8 @@ impl<I: Interner> CanonicalVarKind<I> {
             CanonicalVarKind::PlaceholderRegion(placeholder) => {
                 CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
             }
-            CanonicalVarKind::PlaceholderConst(placeholder, ty) => {
-                CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui), ty)
+            CanonicalVarKind::PlaceholderConst(placeholder) => {
+                CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
             }
             CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
             | CanonicalVarKind::Effect => {
@@ -345,21 +343,14 @@ impl<I: Interner> CanonicalVarValues<I> {
                             Region::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i))
                                 .into()
                         }
-                        CanonicalVarKind::Effect => Const::new_anon_bound(
-                            tcx,
-                            ty::INNERMOST,
-                            ty::BoundVar::from_usize(i),
-                            Ty::new_bool(tcx),
-                        )
-                        .into(),
-                        CanonicalVarKind::Const(_, ty)
-                        | CanonicalVarKind::PlaceholderConst(_, ty) => Const::new_anon_bound(
-                            tcx,
-                            ty::INNERMOST,
-                            ty::BoundVar::from_usize(i),
-                            ty,
-                        )
-                        .into(),
+                        CanonicalVarKind::Effect => {
+                            Const::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i))
+                                .into()
+                        }
+                        CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => {
+                            Const::new_anon_bound(tcx, ty::INNERMOST, ty::BoundVar::from_usize(i))
+                                .into()
+                        }
                     }
                 },
             )),
diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs
index 7076df2893f..84d48e14c24 100644
--- a/compiler/rustc_type_ir/src/const_kind.rs
+++ b/compiler/rustc_type_ir/src/const_kind.rs
@@ -32,7 +32,7 @@ pub enum ConstKind<I: Interner> {
     Unevaluated(ty::UnevaluatedConst<I>),
 
     /// Used to hold computed value.
-    Value(I::ValueConst),
+    Value(I::Ty, I::ValueConst),
 
     /// A placeholder for a const which could not be computed; this is
     /// propagated to avoid useless error messages.
@@ -51,7 +51,7 @@ impl<I: Interner> PartialEq for ConstKind<I> {
             (Bound(l0, l1), Bound(r0, r1)) => l0 == r0 && l1 == r1,
             (Placeholder(l0), Placeholder(r0)) => l0 == r0,
             (Unevaluated(l0), Unevaluated(r0)) => l0 == r0,
-            (Value(l0), Value(r0)) => l0 == r0,
+            (Value(l0, l1), Value(r0, r1)) => l0 == r0 && l1 == r1,
             (Error(l0), Error(r0)) => l0 == r0,
             (Expr(l0), Expr(r0)) => l0 == r0,
             _ => false,
@@ -80,7 +80,7 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
             Unevaluated(uv) => {
                 write!(f, "{:?}", &this.wrap(uv))
             }
-            Value(valtree) => write!(f, "{valtree:?}"),
+            Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &this.wrap(ty)),
             Error(_) => write!(f, "{{const error}}"),
             Expr(expr) => write!(f, "{:?}", &this.wrap(expr)),
         }
diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs
index 4e8be1ee4c2..c206f3ccdb5 100644
--- a/compiler/rustc_type_ir/src/debug.rs
+++ b/compiler/rustc_type_ir/src/debug.rs
@@ -38,11 +38,11 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
         panic!("cannot resolve {vid:?}")
     }
 
-    fn opportunistic_resolve_ct_var(&self, vid: ConstVid, _: I::Ty) -> I::Const {
+    fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> I::Const {
         panic!("cannot resolve {vid:?}")
     }
 
-    fn opportunistic_resolve_effect_var(&self, vid: EffectVid, _: I::Ty) -> I::Const {
+    fn opportunistic_resolve_effect_var(&self, vid: EffectVid) -> I::Const {
         panic!("cannot resolve {vid:?}")
     }
 
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 501311ff72f..ee3e5ce66d0 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -387,7 +387,7 @@ impl<I: Interner> TypeFolder<I> for Shifter<I> {
         match ct.kind() {
             ty::ConstKind::Bound(debruijn, bound_ct) if debruijn >= self.current_index => {
                 let debruijn = debruijn.shifted_in(self.amount);
-                Const::new_bound(self.tcx, debruijn, bound_ct, ct.ty())
+                Const::new_bound(self.tcx, debruijn, bound_ct)
             }
             _ => ct.super_fold_with(self),
         }
diff --git a/compiler/rustc_type_ir/src/infcx.rs b/compiler/rustc_type_ir/src/infcx.rs
index bb5081fb335..24e10722448 100644
--- a/compiler/rustc_type_ir/src/infcx.rs
+++ b/compiler/rustc_type_ir/src/infcx.rs
@@ -12,15 +12,10 @@ pub trait InferCtxtLike {
     fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> <Self::Interner as Interner>::Ty;
     fn opportunistic_resolve_int_var(&self, vid: IntVid) -> <Self::Interner as Interner>::Ty;
     fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> <Self::Interner as Interner>::Ty;
-    fn opportunistic_resolve_ct_var(
-        &self,
-        vid: ConstVid,
-        ty: <Self::Interner as Interner>::Ty,
-    ) -> <Self::Interner as Interner>::Const;
+    fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> <Self::Interner as Interner>::Const;
     fn opportunistic_resolve_effect_var(
         &self,
         vid: EffectVid,
-        ty: <Self::Interner as Interner>::Ty,
     ) -> <Self::Interner as Interner>::Const;
     fn opportunistic_resolve_lt_var(&self, vid: RegionVid) -> <Self::Interner as Interner>::Region;
 
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index f305ed9b5d7..94874a6acfc 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -104,22 +104,15 @@ pub trait Const<I: Interner<Const = Self>>:
     + TypeSuperFoldable<I>
     + Flags
 {
-    fn new_infer(interner: I, var: ty::InferConst, ty: I::Ty) -> Self;
+    fn new_infer(interner: I, var: ty::InferConst) -> Self;
 
-    fn new_var(interner: I, var: ty::ConstVid, ty: I::Ty) -> Self;
+    fn new_var(interner: I, var: ty::ConstVid) -> Self;
 
-    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst, ty: I::Ty) -> Self;
+    fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst) -> Self;
 
-    fn new_anon_bound(
-        interner: I,
-        debruijn: ty::DebruijnIndex,
-        var: ty::BoundVar,
-        ty: I::Ty,
-    ) -> Self;
-
-    fn new_unevaluated(interner: I, uv: ty::UnevaluatedConst<I>, ty: I::Ty) -> Self;
+    fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;
 
-    fn ty(self) -> I::Ty;
+    fn new_unevaluated(interner: I, uv: ty::UnevaluatedConst<I>) -> Self;
 }
 
 pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index e7039583c91..9e0e52cfb4b 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -567,7 +567,6 @@ impl<I: Interner> AliasTerm<I> {
                 I::Const::new_unevaluated(
                     interner,
                     ty::UnevaluatedConst::new(self.def_id, self.args),
-                    interner.type_of(self.def_id).instantiate(interner, &self.args),
                 )
                 .into()
             }
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 1c90c171a15..01510a61405 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1705,7 +1705,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
         unsafe {
             self.current = unlinked_node.as_ref().next;
             self.list.unlink_node(unlinked_node);
-            let unlinked_node = Box::from_raw(unlinked_node.as_ptr());
+            let unlinked_node = Box::from_raw_in(unlinked_node.as_ptr(), &self.list.alloc);
             Some(unlinked_node.element)
         }
     }
@@ -1946,7 +1946,7 @@ where
                 if (self.pred)(&mut node.as_mut().element) {
                     // `unlink_node` is okay with aliasing `element` references.
                     self.list.unlink_node(node);
-                    return Some(Box::from_raw(node.as_ptr()).element);
+                    return Some(Box::from_raw_in(node.as_ptr(), &self.list.alloc).element);
                 }
             }
         }
diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs
index 8dcd59d12d9..d3744c5a9d0 100644
--- a/library/alloc/src/collections/linked_list/tests.rs
+++ b/library/alloc/src/collections/linked_list/tests.rs
@@ -1164,3 +1164,42 @@ fn test_drop_panic() {
 
     assert_eq!(unsafe { DROPS }, 8);
 }
+
+#[test]
+fn test_allocator() {
+    use core::alloc::AllocError;
+    use core::alloc::Allocator;
+    use core::alloc::Layout;
+    use core::cell::Cell;
+
+    struct A {
+        has_allocated: Cell<bool>,
+        has_deallocated: Cell<bool>,
+    }
+
+    unsafe impl Allocator for A {
+        fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+            assert!(!self.has_allocated.get());
+            self.has_allocated.set(true);
+
+            Global.allocate(layout)
+        }
+
+        unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
+            assert!(!self.has_deallocated.get());
+            self.has_deallocated.set(true);
+
+            unsafe { Global.deallocate(ptr, layout) }
+        }
+    }
+
+    let alloc = &A { has_allocated: Cell::new(false), has_deallocated: Cell::new(false) };
+    {
+        let mut list = LinkedList::new_in(alloc);
+        list.push_back(5u32);
+        list.remove(0);
+    }
+
+    assert!(alloc.has_allocated.get());
+    assert!(alloc.has_deallocated.get());
+}
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 875c24c28e4..f3a4803e0d4 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -257,8 +257,6 @@ use core::intrinsics::abort;
 #[cfg(not(no_global_oom_handling))]
 use core::iter;
 use core::marker::{PhantomData, Unsize};
-#[cfg(not(no_global_oom_handling))]
-use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw, forget, ManuallyDrop};
 use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver};
 use core::panic::{RefUnwindSafe, UnwindSafe};
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 7dcaa59dcd1..5a4f9df614e 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -18,8 +18,6 @@ use core::intrinsics::abort;
 #[cfg(not(no_global_oom_handling))]
 use core::iter;
 use core::marker::{PhantomData, Unsize};
-#[cfg(not(no_global_oom_handling))]
-use core::mem::size_of_val;
 use core::mem::{self, align_of_val_raw};
 use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver};
 use core::panic::{RefUnwindSafe, UnwindSafe};
diff --git a/library/alloc/tests/vec_deque_alloc_error.rs b/library/alloc/tests/vec_deque_alloc_error.rs
index c11f4556da9..8b516ddbc5c 100644
--- a/library/alloc/tests/vec_deque_alloc_error.rs
+++ b/library/alloc/tests/vec_deque_alloc_error.rs
@@ -8,6 +8,7 @@ use std::{
 };
 
 #[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_shrink_to_unwind() {
     // This tests that `shrink_to` leaves the deque in a consistent state when
     // the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index ac026de95da..efa0fd7b56c 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -82,6 +82,20 @@
 //!
 //! The corresponding [`Sync`] version of `OnceCell<T>` is [`OnceLock<T>`].
 //!
+//! ## `LazyCell<T, F>`
+//!
+//! A common pattern with OnceCell is, for a given OnceCell, to use the same function on every
+//! call to [`OnceCell::get_or_init`] with that cell. This is what is offered by [`LazyCell`],
+//! which pairs cells of `T` with functions of `F`, and always calls `F` before it yields `&T`.
+//! This happens implicitly by simply attempting to dereference the LazyCell to get its contents,
+//! so its use is much more transparent with a place which has been initialized by a constant.
+//!
+//! More complicated patterns that don't fit this description can be built on `OnceCell<T>` instead.
+//!
+//! `LazyCell` works by providing an implementation of `impl Deref` that calls the function,
+//! so you can just use it by dereference (e.g. `*lazy_cell` or `lazy_cell.deref()`).
+//!
+//! The corresponding [`Sync`] version of `LazyCell<T, F>` is [`LazyLock<T, F>`].
 //!
 //! # When to choose interior mutability
 //!
@@ -230,6 +244,7 @@
 //! [`RwLock<T>`]: ../../std/sync/struct.RwLock.html
 //! [`Mutex<T>`]: ../../std/sync/struct.Mutex.html
 //! [`OnceLock<T>`]: ../../std/sync/struct.OnceLock.html
+//! [`LazyLock<T, F>`]: ../../std/sync/struct.LazyLock.html
 //! [`Sync`]: ../../std/marker/trait.Sync.html
 //! [`atomic`]: crate::sync::atomic
 
@@ -238,7 +253,7 @@
 use crate::cmp::Ordering;
 use crate::fmt::{self, Debug, Display};
 use crate::marker::{PhantomData, Unsize};
-use crate::mem::{self, size_of};
+use crate::mem;
 use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
 use crate::ptr::{self, NonNull};
 
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 89e0b670995..28397fe4619 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -65,7 +65,6 @@
 
 use crate::marker::DiscriminantKind;
 use crate::marker::Tuple;
-use crate::mem::align_of;
 use crate::ptr;
 use crate::ub_checks;
 
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index bcaac2f42cf..dad3d79acb1 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -4,8 +4,8 @@ use crate::ops::Try;
 
 /// An iterator that links two iterators together, in a chain.
 ///
-/// This `struct` is created by [`Iterator::chain`]. See its documentation
-/// for more.
+/// This `struct` is created by [`chain`] or [`Iterator::chain`]. See their
+/// documentation for more.
 ///
 /// # Examples
 ///
@@ -38,6 +38,39 @@ impl<A, B> Chain<A, B> {
     }
 }
 
+/// Converts the arguments to iterators and links them together, in a chain.
+///
+/// See the documentation of [`Iterator::chain`] for more.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(iter_chain)]
+///
+/// use std::iter::chain;
+///
+/// let a = [1, 2, 3];
+/// let b = [4, 5, 6];
+///
+/// let mut iter = chain(a, b);
+///
+/// assert_eq!(iter.next(), Some(1));
+/// assert_eq!(iter.next(), Some(2));
+/// assert_eq!(iter.next(), Some(3));
+/// assert_eq!(iter.next(), Some(4));
+/// assert_eq!(iter.next(), Some(5));
+/// assert_eq!(iter.next(), Some(6));
+/// assert_eq!(iter.next(), None);
+/// ```
+#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
+pub fn chain<A, B>(a: A, b: B) -> Chain<A::IntoIter, B::IntoIter>
+where
+    A: IntoIterator,
+    B: IntoIterator<Item = A::Item>,
+{
+    Chain::new(a.into_iter(), b.into_iter())
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B> Iterator for Chain<A, B>
 where
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index cc514bd914f..05a5f268905 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -41,6 +41,9 @@ pub use self::array_chunks::ArrayChunks;
 #[unstable(feature = "std_internals", issue = "none")]
 pub use self::by_ref_sized::ByRefSized;
 
+#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
+pub use self::chain::chain;
+
 #[stable(feature = "iter_cloned", since = "1.1.0")]
 pub use self::cloned::Cloned;
 
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 44fef3e145b..921c75c85f1 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -428,6 +428,8 @@ pub use self::traits::{
     DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator, Product, Sum,
 };
 
+#[unstable(feature = "iter_chain", reason = "recently added", issue = "125964")]
+pub use self::adapters::chain;
 #[stable(feature = "iter_zip", since = "1.59.0")]
 pub use self::adapters::zip;
 #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 2ddedfa37fe..0d4ca4d5f01 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1569,7 +1569,12 @@ pub(crate) mod builtin {
     #[rustc_builtin_macro]
     #[macro_export]
     #[rustc_diagnostic_item = "assert_macro"]
-    #[allow_internal_unstable(panic_internals, edition_panic, generic_assert_internals)]
+    #[allow_internal_unstable(
+        core_intrinsics,
+        panic_internals,
+        edition_panic,
+        generic_assert_internals
+    )]
     macro_rules! assert {
         ($cond:expr $(,)?) => {{ /* compiler built-in */ }};
         ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 026e21586d4..4175d4a3329 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -120,12 +120,8 @@ use crate::slice;
 /// use std::mem::{self, MaybeUninit};
 ///
 /// let data = {
-///     // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
-///     // safe because the type we are claiming to have initialized here is a
-///     // bunch of `MaybeUninit`s, which do not require initialization.
-///     let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
-///         MaybeUninit::uninit().assume_init()
-///     };
+///     // Create an uninitialized array of `MaybeUninit`.
+///     let mut data: [MaybeUninit<Vec<u32>>; 1000] = [const { MaybeUninit::uninit() }; 1000];
 ///
 ///     // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
 ///     // we have a memory leak, but there is no memory safety issue.
@@ -147,10 +143,8 @@ use crate::slice;
 /// ```
 /// use std::mem::MaybeUninit;
 ///
-/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
-/// // safe because the type we are claiming to have initialized here is a
-/// // bunch of `MaybeUninit`s, which do not require initialization.
-/// let mut data: [MaybeUninit<String>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
+/// // Create an uninitialized array of `MaybeUninit`.
+/// let mut data: [MaybeUninit<String>; 1000] = [const { MaybeUninit::uninit() }; 1000];
 /// // Count the number of elements we have assigned.
 /// let mut data_len: usize = 0;
 ///
@@ -348,8 +342,7 @@ impl<T> MaybeUninit<T> {
     #[must_use]
     #[inline(always)]
     pub const fn uninit_array<const N: usize>() -> [Self; N] {
-        // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
-        unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
+        [const { MaybeUninit::uninit() }; N]
     }
 
     /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs
index afc6817aa1d..2a0331ef7b2 100644
--- a/library/core/src/prelude/common.rs
+++ b/library/core/src/prelude/common.rs
@@ -14,6 +14,9 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use crate::mem::drop;
+#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")]
+#[doc(no_inline)]
+pub use crate::mem::{align_of, align_of_val, size_of, size_of_val};
 
 // Re-exported types and traits
 #[stable(feature = "core_prelude", since = "1.4.0")]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 8e3447d0b1b..6661f6ee78b 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -415,7 +415,7 @@ use crate::intrinsics;
 use crate::marker::FnPtr;
 use crate::ub_checks;
 
-use crate::mem::{self, align_of, size_of, MaybeUninit};
+use crate::mem::{self, MaybeUninit};
 
 mod alignment;
 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 29a12f106c5..3f4305866e6 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -1,7 +1,6 @@
 //! Free functions to create `&[T]` and `&mut [T]`.
 
 use crate::array;
-use crate::mem::{align_of, size_of};
 use crate::ops::Range;
 use crate::ptr;
 use crate::ub_checks;
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 232ec589093..482bd19705c 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -1296,7 +1296,6 @@ impl<T> AtomicPtr<T> {
     #[cfg(target_has_atomic_equal_alignment = "ptr")]
     #[unstable(feature = "atomic_from_mut", issue = "76314")]
     pub fn from_mut(v: &mut *mut T) -> &mut Self {
-        use crate::mem::align_of;
         let [] = [(); align_of::<AtomicPtr<()>>() - align_of::<*mut ()>()];
         // SAFETY:
         //  - the mutable reference guarantees unique ownership.
@@ -2286,7 +2285,6 @@ macro_rules! atomic_int {
             #[$cfg_align]
             #[unstable(feature = "atomic_from_mut", issue = "76314")]
             pub fn from_mut(v: &mut $int_type) -> &mut Self {
-                use crate::mem::align_of;
                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
                 // SAFETY:
                 //  - the mutable reference guarantees unique ownership.
@@ -2354,7 +2352,6 @@ macro_rules! atomic_int {
             #[$cfg_align]
             #[unstable(feature = "atomic_from_mut", issue = "76314")]
             pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
-                use crate::mem::align_of;
                 let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
                 // SAFETY:
                 //  - the mutable reference guarantees unique ownership.
diff --git a/library/core/tests/iter/adapters/chain.rs b/library/core/tests/iter/adapters/chain.rs
index b2429588de1..c93510df524 100644
--- a/library/core/tests/iter/adapters/chain.rs
+++ b/library/core/tests/iter/adapters/chain.rs
@@ -3,6 +3,14 @@ use core::iter::*;
 use core::num::NonZero;
 
 #[test]
+fn test_chain() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
+    assert_eq!(Vec::from_iter(chain(xs, ys)), expected);
+}
+
+#[test]
 fn test_iterator_chain() {
     let xs = [0, 1, 2, 3, 4, 5];
     let ys = [30, 40, 50, 60];
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index e0f82c91663..20ff6fd7687 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -75,6 +75,7 @@
 #![feature(ip)]
 #![feature(iter_advance_by)]
 #![feature(iter_array_chunks)]
+#![feature(iter_chain)]
 #![feature(iter_collect_into)]
 #![feature(iter_partition_in_place)]
 #![feature(iter_intersperse)]
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
index 0f1719206c9..cbffbc564cf 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
@@ -96,7 +96,7 @@ where
     fn cast<U>(self) -> Self::CastPtr<U> {
         // SimdElement currently requires zero-sized metadata, so this should never fail.
         // If this ever changes, `simd_cast_ptr` should produce a post-mono error.
-        use core::{mem::size_of, ptr::Pointee};
+        use core::ptr::Pointee;
         assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0);
         assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0);
 
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
index 7ba996d149c..6bc6ca3ac42 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
@@ -93,7 +93,7 @@ where
     fn cast<U>(self) -> Self::CastPtr<U> {
         // SimdElement currently requires zero-sized metadata, so this should never fail.
         // If this ever changes, `simd_cast_ptr` should produce a post-mono error.
-        use core::{mem::size_of, ptr::Pointee};
+        use core::ptr::Pointee;
         assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0);
         assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0);
 
diff --git a/library/proc_macro/src/bridge/fxhash.rs b/library/proc_macro/src/bridge/fxhash.rs
index f9f74c63fc4..9fb79eabd05 100644
--- a/library/proc_macro/src/bridge/fxhash.rs
+++ b/library/proc_macro/src/bridge/fxhash.rs
@@ -7,7 +7,6 @@
 use std::collections::HashMap;
 use std::hash::BuildHasherDefault;
 use std::hash::Hasher;
-use std::mem::size_of;
 use std::ops::BitXor;
 
 /// Type alias for a hashmap using the `fx` hash algorithm.
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 5039f0b6bb2..fcd1c307b5a 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1218,7 +1218,7 @@ where
     /// will cause the map to produce seemingly random results. Higher-level and
     /// more foolproof APIs like `entry` should be preferred when possible.
     ///
-    /// In particular, the hash used to initialized the raw entry must still be
+    /// In particular, the hash used to initialize the raw entry must still be
     /// consistent with the hash of the key that is ultimately stored in the entry.
     /// This is because implementations of HashMap may need to recompute hashes
     /// when resizing, at which point only the keys are available.
diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs
index 6f8d5e37775..c9d3934ad70 100644
--- a/library/std/src/io/error/repr_bitpacked.rs
+++ b/library/std/src/io/error/repr_bitpacked.rs
@@ -104,7 +104,6 @@
 
 use super::{Custom, ErrorData, ErrorKind, RawOsError, SimpleMessage};
 use core::marker::PhantomData;
-use core::mem::{align_of, size_of};
 use core::ptr::{self, NonNull};
 
 // The 2 least-significant bits are used as tag.
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index c8968b74b12..9aee2bb5e1c 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -1190,9 +1190,8 @@ pub trait IsTerminal: crate::sealed::Sealed {
     ///
     /// - If you run this example by piping some text to it, e.g. `echo "foo" | path/to/executable`
     ///   it will print: `Hello foo`.
-    /// - If you instead run the example interactively by running the executable directly, it will
-    ///   panic with the message "Expected input to be piped to the process".
-    ///
+    /// - If you instead run the example interactively by running `path/to/executable` directly, it will
+    ///   prompt for input.
     ///
     /// [changes]: io#platform-specific-behavior
     /// [`Stdin`]: crate::io::Stdin
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 0597fdcbd72..fe8e2be9372 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -3,7 +3,7 @@
 use super::{sockaddr_un, SocketAddr};
 use crate::io::{self, IoSlice, IoSliceMut};
 use crate::marker::PhantomData;
-use crate::mem::{size_of, zeroed};
+use crate::mem::zeroed;
 use crate::os::unix::io::RawFd;
 use crate::path::Path;
 use crate::ptr::{eq, read_unaligned};
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index 01936734d75..ceee3e33c3e 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -14,6 +14,9 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
 pub use crate::mem::drop;
+#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")]
+#[doc(no_inline)]
+pub use crate::mem::{align_of, align_of_val, size_of, size_of_val};
 
 // Re-exported types and traits
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 0bdbab716ad..2d4639342bf 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -36,6 +36,10 @@
 //!   operations for both destructors and overloading `()`.
 //! * <code>[std::mem]::[drop]</code>, a convenience function for explicitly
 //!   dropping a value.
+//! * <code>[std::mem]::{[size_of], [size_of_val]}</code>, to get the size of
+//!   a type or value.
+//! * <code>[std::mem]::{[align_of], [align_of_val]}</code>, to get the
+//!   alignment of a type or value.
 //! * <code>[std::boxed]::[Box]</code>, a way to allocate values on the heap.
 //! * <code>[std::borrow]::[ToOwned]</code>, the conversion trait that defines
 //!   [`to_owned`], the generic method for creating an owned type from a
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index d3bb3bfdff9..7a2eed93dd4 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -29,34 +29,26 @@ union Data<T, F> {
 /// # Examples
 ///
 /// Initialize static variables with `LazyLock`.
-///
 /// ```
-/// use std::collections::HashMap;
-///
 /// use std::sync::LazyLock;
 ///
-/// static HASHMAP: LazyLock<HashMap<i32, String>> = LazyLock::new(|| {
-///     println!("initializing");
-///     let mut m = HashMap::new();
-///     m.insert(13, "Spica".to_string());
-///     m.insert(74, "Hoyten".to_string());
-///     m
+/// // n.b. static items do not call [`Drop`] on program termination, so this won't be deallocated.
+/// // this is fine, as the OS can deallocate the terminated program faster than we can free memory
+/// // but tools like valgrind might report "memory leaks" as it isn't obvious this is intentional.
+/// static DEEP_THOUGHT: LazyLock<String> = LazyLock::new(|| {
+/// # mod another_crate {
+/// #     pub fn great_question() -> String { "42".to_string() }
+/// # }
+///     // M3 Ultra takes about 16 million years in --release config
+///     another_crate::great_question()
 /// });
 ///
-/// fn main() {
-///     println!("ready");
-///     std::thread::spawn(|| {
-///         println!("{:?}", HASHMAP.get(&13));
-///     }).join().unwrap();
-///     println!("{:?}", HASHMAP.get(&74));
-///
-///     // Prints:
-///     //   ready
-///     //   initializing
-///     //   Some("Spica")
-///     //   Some("Hoyten")
-/// }
+/// // The `String` is built, stored in the `LazyLock`, and returned as `&String`.
+/// let _ = &*DEEP_THOUGHT;
+/// // The `String` is retrieved from the `LazyLock` and returned as `&String`.
+/// let _ = &*DEEP_THOUGHT;
 /// ```
+///
 /// Initialize fields with `LazyLock`.
 /// ```
 /// use std::sync::LazyLock;
diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs
index fb7d601b094..70e8f5f90c6 100644
--- a/library/std/src/sync/mod.rs
+++ b/library/std/src/sync/mod.rs
@@ -136,7 +136,10 @@
 //! - [`Once`]: Used for a thread-safe, one-time global initialization routine
 //!
 //! - [`OnceLock`]: Used for thread-safe, one-time initialization of a
-//!   global variable.
+//!   variable, with potentially different initializers based on the caller.
+//!
+//! - [`LazyLock`]: Used for thread-safe, one-time initialization of a
+//!   variable, using one nullary initializer function provided at creation.
 //!
 //! - [`RwLock`]: Provides a mutual exclusion mechanism which allows
 //!   multiple readers at the same time, while allowing only one
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 6b9f70da854..f52b9e52c54 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -8,47 +8,17 @@ use crate::sync::Once;
 /// A synchronization primitive which can nominally be written to only once.
 ///
 /// This type is a thread-safe [`OnceCell`], and can be used in statics.
+/// In many simple cases, you can use [`LazyLock<T, F>`] instead to get the benefits of this type
+/// with less effort: `LazyLock<T, F>` "looks like" `&T` because it initializes with `F` on deref!
+/// Where OnceLock shines is when LazyLock is too simple to support a given case, as LazyLock
+/// doesn't allow additional inputs to its function after you call [`LazyLock::new(|| ...)`].
 ///
 /// [`OnceCell`]: crate::cell::OnceCell
+/// [`LazyLock<T, F>`]: crate::sync::LazyLock
+/// [`LazyLock::new(|| ...)`]: crate::sync::LazyLock::new
 ///
 /// # Examples
 ///
-/// Using `OnceLock` to store a function’s previously computed value (a.k.a.
-/// ‘lazy static’ or ‘memoizing’):
-///
-/// ```
-/// use std::sync::OnceLock;
-///
-/// struct DeepThought {
-///     answer: String,
-/// }
-///
-/// impl DeepThought {
-/// #   fn great_question() -> String {
-/// #       "42".to_string()
-/// #   }
-/// #
-///     fn new() -> Self {
-///         Self {
-///             // M3 Ultra takes about 16 million years in --release config
-///             answer: Self::great_question(),
-///         }
-///     }
-/// }
-///
-/// fn computation() -> &'static DeepThought {
-///     // n.b. static items do not call [`Drop`] on program termination, so if
-///     // [`DeepThought`] impls Drop, that will not be used for this instance.
-///     static COMPUTATION: OnceLock<DeepThought> = OnceLock::new();
-///     COMPUTATION.get_or_init(|| DeepThought::new())
-/// }
-///
-/// // The `DeepThought` is built, stored in the `OnceLock`, and returned.
-/// let _ = computation().answer;
-/// // The `DeepThought` is retrieved from the `OnceLock` and returned.
-/// let _ = computation().answer;
-/// ```
-///
 /// Writing to a `OnceLock` from a separate thread:
 ///
 /// ```
@@ -73,6 +43,55 @@ use crate::sync::Once;
 ///     Some(&12345),
 /// );
 /// ```
+///
+/// You can use `OnceLock` to implement a type that requires "append-only" logic:
+///
+/// ```
+/// use std::sync::{OnceLock, atomic::{AtomicU32, Ordering}};
+/// use std::thread;
+///
+/// struct OnceList<T> {
+///     data: OnceLock<T>,
+///     next: OnceLock<Box<OnceList<T>>>,
+/// }
+/// impl<T> OnceList<T> {
+///     const fn new() -> OnceList<T> {
+///         OnceList { data: OnceLock::new(), next: OnceLock::new() }
+///     }
+///     fn push(&self, value: T) {
+///         // FIXME: this impl is concise, but is also slow for long lists or many threads.
+///         // as an exercise, consider how you might improve on it while preserving the behavior
+///         if let Err(value) = self.data.set(value) {
+///             let next = self.next.get_or_init(|| Box::new(OnceList::new()));
+///             next.push(value)
+///         };
+///     }
+///     fn contains(&self, example: &T) -> bool
+///     where
+///         T: PartialEq,
+///     {
+///         self.data.get().map(|item| item == example).filter(|v| *v).unwrap_or_else(|| {
+///             self.next.get().map(|next| next.contains(example)).unwrap_or(false)
+///         })
+///     }
+/// }
+///
+/// // Let's exercise this new Sync append-only list by doing a little counting
+/// static LIST: OnceList<u32> = OnceList::new();
+/// static COUNTER: AtomicU32 = AtomicU32::new(0);
+///
+/// let vec = (0..thread::available_parallelism().unwrap().get()).map(|_| thread::spawn(|| {
+///     while let i @ 0..=1000 = COUNTER.fetch_add(1, Ordering::Relaxed) {
+///         LIST.push(i);
+///     }
+/// })).collect::<Vec<thread::JoinHandle<_>>>();
+/// vec.into_iter().for_each(|handle| handle.join().unwrap());
+///
+/// for i in 0..=1000 {
+///     assert!(LIST.contains(&i));
+/// }
+///
+/// ```
 #[stable(feature = "once_cell", since = "1.70.0")]
 pub struct OnceLock<T> {
     once: Once,
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index 7d271e6d2b6..446cdd18b7e 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -15,7 +15,7 @@ pub use self::task_queue::JoinNotifier;
 
 mod task_queue {
     use super::wait_notify;
-    use crate::sync::{Mutex, MutexGuard, Once};
+    use crate::sync::{Mutex, MutexGuard};
 
     pub type JoinHandle = wait_notify::Waiter;
 
@@ -28,12 +28,12 @@ mod task_queue {
     }
 
     pub(super) struct Task {
-        p: Box<dyn FnOnce()>,
+        p: Box<dyn FnOnce() + Send>,
         done: JoinNotifier,
     }
 
     impl Task {
-        pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
+        pub(super) fn new(p: Box<dyn FnOnce() + Send>) -> (Task, JoinHandle) {
             let (done, recv) = wait_notify::new();
             let done = JoinNotifier(Some(done));
             (Task { p, done }, recv)
@@ -46,17 +46,11 @@ mod task_queue {
     }
 
     #[cfg_attr(test, linkage = "available_externally")]
-    #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"]
-    static TASK_QUEUE_INIT: Once = Once::new();
-    #[cfg_attr(test, linkage = "available_externally")]
     #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
-    static mut TASK_QUEUE: Option<Mutex<Vec<Task>>> = None;
+    static TASK_QUEUE: Mutex<Vec<Task>> = Mutex::new(Vec::new());
 
     pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
-        unsafe {
-            TASK_QUEUE_INIT.call_once(|| TASK_QUEUE = Some(Default::default()));
-            TASK_QUEUE.as_ref().unwrap().lock().unwrap()
-        }
+        TASK_QUEUE.lock().unwrap()
     }
 }
 
@@ -101,7 +95,7 @@ pub mod wait_notify {
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
+    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce() + Send>) -> io::Result<Thread> {
         let mut queue_lock = task_queue::lock();
         unsafe { usercalls::launch_thread()? };
         let (task, handle) = task_queue::Task::new(p);
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
index edc736978a1..7d4006ff4b2 100644
--- a/library/std/src/sys/pal/uefi/thread.rs
+++ b/library/std/src/sys/pal/uefi/thread.rs
@@ -7,7 +7,7 @@ use crate::time::Duration;
 
 pub struct Thread(!);
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index dbaf86d73a6..56a0f8e39c4 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1481,29 +1481,33 @@ impl FromRawFd for File {
 
 impl fmt::Debug for File {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        #[cfg(any(
-            target_os = "linux",
-            target_os = "netbsd",
-            target_os = "illumos",
-            target_os = "solaris"
-        ))]
+        #[cfg(any(target_os = "linux", target_os = "illumos", target_os = "solaris"))]
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let mut p = PathBuf::from("/proc/self/fd");
             p.push(&fd.to_string());
             readlink(&p).ok()
         }
 
-        #[cfg(target_vendor = "apple")]
+        #[cfg(any(target_vendor = "apple", target_os = "netbsd"))]
         fn get_path(fd: c_int) -> Option<PathBuf> {
             // FIXME: The use of PATH_MAX is generally not encouraged, but it
-            // is inevitable in this case because Apple targets define `fcntl`
+            // is inevitable in this case because Apple targets and NetBSD define `fcntl`
             // with `F_GETPATH` in terms of `MAXPATHLEN`, and there are no
             // alternatives. If a better method is invented, it should be used
             // instead.
             let mut buf = vec![0; libc::PATH_MAX as usize];
             let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_ptr()) };
             if n == -1 {
-                return None;
+                cfg_if::cfg_if! {
+                    if #[cfg(target_os = "netbsd")] {
+                        // fallback to procfs as last resort
+                        let mut p = PathBuf::from("/proc/self/fd");
+                        p.push(&fd.to_string());
+                        return readlink(&p).ok();
+                    } else {
+                        return None;
+                    }
+                }
             }
             let l = buf.iter().position(|&c| c == 0).unwrap();
             buf.truncate(l as usize);
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs
index ea939247199..89f8bad7026 100644
--- a/library/std/src/sys/pal/unsupported/thread.rs
+++ b/library/std/src/sys/pal/unsupported/thread.rs
@@ -6,7 +6,7 @@ use crate::time::Duration;
 
 pub struct Thread(!);
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index d45fb28b67e..975eef2451f 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -66,7 +66,7 @@ cfg_if::cfg_if! {
     }
 }
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
index 49f936f1449..484bd08495e 100644
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ b/library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -6,7 +6,7 @@ use crate::time::Duration;
 
 pub struct Thread(!);
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 22215873933..83e27dfb746 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -561,7 +561,8 @@ impl Builder {
         let main = Box::new(main);
         // SAFETY: dynamic size and alignment of the Box remain the same. See below for why the
         // lifetime change is justified.
-        let main = unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + 'static)) };
+        let main =
+            unsafe { Box::from_raw(Box::into_raw(main) as *mut (dyn FnOnce() + Send + 'static)) };
 
         Ok(JoinInner {
             // SAFETY:
@@ -1544,7 +1545,7 @@ struct Packet<'scope, T> {
 // The type `T` should already always be Send (otherwise the thread could not
 // have been created) and the Packet is Sync because all access to the
 // `UnsafeCell` synchronized (by the `join()` boundary), and `ScopeData` is Sync.
-unsafe impl<'scope, T: Sync> Sync for Packet<'scope, T> {}
+unsafe impl<'scope, T: Send> Sync for Packet<'scope, T> {}
 
 impl<'scope, T> Drop for Packet<'scope, T> {
     fn drop(&mut self) {
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index ca0d1fa5bd0..32dd3efa7a6 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -7,6 +7,7 @@ default-run = "bootstrap"
 
 [features]
 build-metrics = ["sysinfo"]
+bootstrap-self-test = [] # enabled in the bootstrap unit tests
 
 [lib]
 path = "src/lib.rs"
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index e60e8f0aa1f..9861121aac0 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -599,6 +599,12 @@ class RustBuild(object):
                 print('Choosing a pool size of', pool_size, 'for the unpacking of the tarballs')
             p = Pool(pool_size)
             try:
+                # FIXME: A cheap workaround for https://github.com/rust-lang/rust/issues/125578,
+                # remove this once the issue is closed.
+                bootstrap_out = self.bootstrap_out()
+                if os.path.exists(bootstrap_out):
+                    shutil.rmtree(bootstrap_out)
+
                 p.map(unpack_component, tarballs_download_info)
             finally:
                 p.close()
@@ -864,6 +870,16 @@ class RustBuild(object):
             return line[start + 1:end]
         return None
 
+    def bootstrap_out(self):
+        """Return the path of the bootstrap build artifacts
+
+        >>> rb = RustBuild()
+        >>> rb.build_dir = "build"
+        >>> rb.bootstrap_binary() == os.path.join("build", "bootstrap")
+        True
+        """
+        return os.path.join(self.build_dir, "bootstrap")
+
     def bootstrap_binary(self):
         """Return the path of the bootstrap binary
 
@@ -873,7 +889,7 @@ class RustBuild(object):
         ... "debug", "bootstrap")
         True
         """
-        return os.path.join(self.build_dir, "bootstrap", "debug", "bootstrap")
+        return os.path.join(self.bootstrap_out(), "debug", "bootstrap")
 
     def build_bootstrap(self):
         """Build bootstrap"""
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 30b3edfd3ae..b37b2b5bcef 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -29,7 +29,7 @@ macro_rules! submodule_helper {
 }
 
 macro_rules! book {
-    ($($name:ident, $path:expr, $book_name:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
+    ($($name:ident, $path:expr, $book_name:expr, $lang:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
         pub struct $name {
@@ -61,6 +61,7 @@ macro_rules! book {
                     name: $book_name.to_owned(),
                     src: builder.src.join($path),
                     parent: Some(self),
+                    languages: $lang.into(),
                 })
             }
         }
@@ -74,15 +75,15 @@ macro_rules! book {
 // FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules
 // and checking against it?).
 book!(
-    CargoBook, "src/tools/cargo/src/doc", "cargo", submodule = "src/tools/cargo";
-    ClippyBook, "src/tools/clippy/book", "clippy";
-    EditionGuide, "src/doc/edition-guide", "edition-guide", submodule;
-    EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule;
-    Nomicon, "src/doc/nomicon", "nomicon", submodule;
-    Reference, "src/doc/reference", "reference", submodule;
-    RustByExample, "src/doc/rust-by-example", "rust-by-example", submodule;
-    RustdocBook, "src/doc/rustdoc", "rustdoc";
-    StyleGuide, "src/doc/style-guide", "style-guide";
+    CargoBook, "src/tools/cargo/src/doc", "cargo", &[], submodule = "src/tools/cargo";
+    ClippyBook, "src/tools/clippy/book", "clippy", &[];
+    EditionGuide, "src/doc/edition-guide", "edition-guide", &[], submodule;
+    EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[], submodule;
+    Nomicon, "src/doc/nomicon", "nomicon", &[], submodule;
+    Reference, "src/doc/reference", "reference", &[], submodule;
+    RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja"], submodule;
+    RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
+    StyleGuide, "src/doc/style-guide", "style-guide", &[];
 );
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -110,6 +111,7 @@ impl Step for UnstableBook {
             name: "unstable-book".to_owned(),
             src: builder.md_doc_out(self.target).join("unstable-book"),
             parent: Some(self),
+            languages: vec![],
         })
     }
 }
@@ -120,6 +122,7 @@ struct RustbookSrc<P: Step> {
     name: String,
     src: PathBuf,
     parent: Option<P>,
+    languages: Vec<&'static str>,
 }
 
 impl<P: Step> Step for RustbookSrc<P> {
@@ -151,7 +154,19 @@ impl<P: Step> Step for RustbookSrc<P> {
             builder.info(&format!("Rustbook ({target}) - {name}"));
             let _ = fs::remove_dir_all(&out);
 
-            builder.run(rustbook_cmd.arg("build").arg(src).arg("-d").arg(out));
+            builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out));
+
+            for lang in &self.languages {
+                let out = out.join(lang);
+
+                builder.info(&format!("Rustbook ({target}) - {name} - {lang}"));
+                let _ = fs::remove_dir_all(&out);
+
+                let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
+                builder.run(
+                    rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).arg("-l").arg(lang),
+                );
+            }
         }
 
         if self.parent.is_some() {
@@ -214,6 +229,7 @@ impl Step for TheBook {
             name: "book".to_owned(),
             src: absolute_path.clone(),
             parent: Some(self),
+            languages: vec![],
         });
 
         // building older edition redirects
@@ -225,6 +241,7 @@ impl Step for TheBook {
                 // There should only be one book that is marked as the parent for each target, so
                 // treat the other editions as not having a parent.
                 parent: Option::<Self>::None,
+                languages: vec![],
             });
         }
 
@@ -1208,6 +1225,7 @@ impl Step for RustcBook {
             name: "rustc".to_owned(),
             src: out_base,
             parent: Some(self),
+            languages: vec![],
         });
     }
 }
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 601e4e55e09..0caa39d78ac 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -118,7 +118,9 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
 
 pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
     if !paths.is_empty() {
-        eprintln!("fmt error: path arguments are not accepted");
+        eprintln!(
+            "fmt error: path arguments are no longer accepted; use `--all` to format everything"
+        );
         crate::exit!(1);
     };
     if build.config.dry_run() {
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 29b3d1669b4..aaedee65ed7 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -3053,6 +3053,7 @@ impl Step for Bootstrap {
 
         let mut cmd = Command::new(&builder.initial_cargo);
         cmd.arg("test")
+            .args(["--features", "bootstrap-self-test"])
             .current_dir(builder.src.join("src/bootstrap"))
             .env("RUSTFLAGS", "-Cdebuginfo=2")
             .env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 2db3f8f7936..1b55fc85da4 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -10,6 +10,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
 use crate::core::config::TargetSelection;
 use crate::utils::channel::GitInfo;
 use crate::utils::exec::BootstrapCommand;
+use crate::utils::helpers::output;
 use crate::utils::helpers::{add_dylib_path, exe, t};
 use crate::Compiler;
 use crate::Mode;
@@ -804,6 +805,59 @@ impl Step for LlvmBitcodeLinker {
     }
 }
 
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub struct LibcxxVersionTool {
+    pub target: TargetSelection,
+}
+
+#[allow(dead_code)]
+#[derive(Debug, Clone)]
+pub enum LibcxxVersion {
+    Gnu(usize),
+    Llvm(usize),
+}
+
+impl Step for LibcxxVersionTool {
+    type Output = LibcxxVersion;
+    const DEFAULT: bool = false;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.never()
+    }
+
+    fn run(self, builder: &Builder<'_>) -> LibcxxVersion {
+        let out_dir = builder.out.join(self.target.to_string()).join("libcxx-version");
+        let _ = fs::remove_dir_all(&out_dir);
+        t!(fs::create_dir_all(&out_dir));
+
+        let compiler = builder.cxx(self.target).unwrap();
+        let mut cmd = Command::new(compiler);
+
+        let executable = out_dir.join(exe("libcxx-version", self.target));
+        cmd.arg("-o").arg(&executable).arg(builder.src.join("src/tools/libcxx-version/main.cpp"));
+
+        builder.run_cmd(&mut cmd);
+
+        if !executable.exists() {
+            panic!("Something went wrong. {} is not present", executable.display());
+        }
+
+        let version_output = output(&mut Command::new(executable));
+
+        let version_str = version_output.split_once("version:").unwrap().1;
+        let version = version_str.trim().parse::<usize>().unwrap();
+
+        if version_output.starts_with("libstdc++") {
+            LibcxxVersion::Gnu(version)
+        } else if version_output.starts_with("libc++") {
+            LibcxxVersion::Llvm(version)
+        } else {
+            panic!("Coudln't recognize the standard library version.");
+        }
+    }
+}
+
 macro_rules! tool_extended {
     (($sel:ident, $builder:ident),
        $($name:ident,
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 70d32f2f6d9..17e37c1ecd2 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -22,8 +22,6 @@ use crate::utils::cache::{Interned, INTERNER};
 use crate::utils::channel::{self, GitInfo};
 use crate::utils::helpers::{exe, output, t};
 use build_helper::exit;
-use build_helper::util::fail;
-use semver::Version;
 use serde::{Deserialize, Deserializer};
 use serde_derive::Deserialize;
 
@@ -2382,8 +2380,14 @@ impl Config {
         }
     }
 
-    // check rustc/cargo version is same or lower with 1 apart from the building one
+    #[cfg(feature = "bootstrap-self-test")]
+    pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {}
+
+    /// check rustc/cargo version is same or lower with 1 apart from the building one
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub fn check_stage0_version(&self, program_path: &Path, component_name: &'static str) {
+        use build_helper::util::fail;
+
         if self.dry_run() {
             return;
         }
@@ -2400,11 +2404,12 @@ impl Config {
         }
 
         let stage0_version =
-            Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
-                .unwrap();
-        let source_version =
-            Version::parse(fs::read_to_string(self.src.join("src/version")).unwrap().trim())
+            semver::Version::parse(stage0_output.next().unwrap().split('-').next().unwrap().trim())
                 .unwrap();
+        let source_version = semver::Version::parse(
+            fs::read_to_string(self.src.join("src/version")).unwrap().trim(),
+        )
+        .unwrap();
         if !(source_version == stage0_version
             || (source_version.major == stage0_version.major
                 && (source_version.minor == stage0_version.minor
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index c4073910623..bfb2c02860d 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -14,16 +14,9 @@ use std::{
 };
 
 fn parse(config: &str) -> Config {
-    Config::parse_inner(
-        &[
-            "check".to_string(),
-            "--set=build.rustc=/does/not/exist".to_string(),
-            "--set=build.cargo=/does/not/exist".to_string(),
-            "--config=/does/not/exist".to_string(),
-            "--skip-stage0-validation".to_string(),
-        ],
-        |&_| toml::from_str(&config).unwrap(),
-    )
+    Config::parse_inner(&["check".to_string(), "--config=/does/not/exist".to_string()], |&_| {
+        toml::from_str(&config).unwrap()
+    })
 }
 
 #[test]
@@ -212,10 +205,7 @@ fn override_toml_duplicate() {
     Config::parse_inner(
         &[
             "check".to_owned(),
-            "--set=build.rustc=/does/not/exist".to_string(),
-            "--set=build.cargo=/does/not/exist".to_string(),
-            "--config=/does/not/exist".to_owned(),
-            "--skip-stage0-validation".to_owned(),
+            "--config=/does/not/exist".to_string(),
             "--set=change-id=1".to_owned(),
             "--set=change-id=2".to_owned(),
         ],
@@ -238,15 +228,7 @@ fn profile_user_dist() {
             .and_then(|table: toml::Value| TomlConfig::deserialize(table))
             .unwrap()
     }
-    Config::parse_inner(
-        &[
-            "check".to_owned(),
-            "--set=build.rustc=/does/not/exist".to_string(),
-            "--set=build.cargo=/does/not/exist".to_string(),
-            "--skip-stage0-validation".to_string(),
-        ],
-        get_toml,
-    );
+    Config::parse_inner(&["check".to_owned()], get_toml);
 }
 
 #[test]
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 60f48c5923e..2b11b8c3d4f 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -9,11 +9,10 @@ use std::{
 };
 
 use build_helper::ci::CiEnv;
-use build_helper::stage0_parser::VersionMetadata;
 use xz2::bufread::XzDecoder;
 
+use crate::utils::helpers::hex_encode;
 use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date};
-use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
 use crate::{t, Config};
 
 static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
@@ -405,9 +404,17 @@ impl Config {
         cargo_clippy
     }
 
+    #[cfg(feature = "bootstrap-self-test")]
+    pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
+        None
+    }
+
     /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
     /// reuse target directories or artifacts
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
+        use build_helper::stage0_parser::VersionMetadata;
+
         let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
         let channel = format!("{version}-{date}");
 
@@ -487,6 +494,10 @@ impl Config {
         );
     }
 
+    #[cfg(feature = "bootstrap-self-test")]
+    pub(crate) fn download_beta_toolchain(&self) {}
+
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn download_beta_toolchain(&self) {
         self.verbose(|| println!("downloading stage0 beta artifacts"));
 
@@ -665,7 +676,13 @@ download-rustc = false
         self.unpack(&tarball, &bin_root, prefix);
     }
 
+    #[cfg(feature = "bootstrap-self-test")]
+    pub(crate) fn maybe_download_ci_llvm(&self) {}
+
+    #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn maybe_download_ci_llvm(&self) {
+        use crate::core::build_steps::llvm::detect_llvm_sha;
+
         if !self.llvm_from_ci {
             return;
         }
@@ -707,6 +724,7 @@ download-rustc = false
         }
     }
 
+    #[cfg(not(feature = "bootstrap-self-test"))]
     fn download_ci_llvm(&self, llvm_sha: &str) {
         let llvm_assertions = self.llvm_assertions;
 
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 8ffa97ab78b..e3556cb16b0 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -8,13 +8,19 @@
 //! In theory if we get past this phase it's a bug if a build fails, but in
 //! practice that's likely not true!
 
-use std::collections::{HashMap, HashSet};
+use std::collections::HashMap;
 use std::env;
 use std::ffi::{OsStr, OsString};
 use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
-use walkdir::WalkDir;
+
+#[cfg(not(feature = "bootstrap-self-test"))]
+use crate::builder::Builder;
+#[cfg(not(feature = "bootstrap-self-test"))]
+use crate::core::build_steps::tool;
+#[cfg(not(feature = "bootstrap-self-test"))]
+use std::collections::HashSet;
 
 use crate::builder::Kind;
 use crate::core::config::Target;
@@ -31,10 +37,16 @@ pub struct Finder {
 // it might not yet be included in stage0. In such cases, we handle the targets missing from stage0 in this list.
 //
 // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
+#[cfg(not(feature = "bootstrap-self-test"))]
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
 ];
 
+/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
+/// from CI (with`llvm.download-ci-llvm` option).
+#[cfg(not(feature = "bootstrap-self-test"))]
+const LIBSTDCXX_MIN_VERSION_THRESHOLD: usize = 8;
+
 impl Finder {
     pub fn new() -> Self {
         Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() }
@@ -99,6 +111,32 @@ pub fn check(build: &mut Build) {
         cmd_finder.must_have("git");
     }
 
+    // Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`.
+    #[cfg(not(feature = "bootstrap-self-test"))]
+    if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci {
+        let builder = Builder::new(build);
+        let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build });
+
+        match libcxx_version {
+            tool::LibcxxVersion::Gnu(version) => {
+                if LIBSTDCXX_MIN_VERSION_THRESHOLD > version {
+                    eprintln!(
+                        "\nYour system's libstdc++ version is too old for the `llvm.download-ci-llvm` option."
+                    );
+                    eprintln!("Current version detected: '{}'", version);
+                    eprintln!("Minimum required version: '{}'", LIBSTDCXX_MIN_VERSION_THRESHOLD);
+                    eprintln!(
+                        "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option."
+                    );
+                    crate::exit!(1);
+                }
+            }
+            tool::LibcxxVersion::Llvm(_) => {
+                // FIXME: Handle libc++ version check.
+            }
+        }
+    }
+
     // We need cmake, but only if we're actually building LLVM or sanitizers.
     let building_llvm = build
         .hosts
@@ -167,6 +205,7 @@ than building it.
         .map(|p| cmd_finder.must_have(p))
         .or_else(|| cmd_finder.maybe_have("reuse"));
 
+    #[cfg(not(feature = "bootstrap-self-test"))]
     let stage0_supported_target_list: HashSet<String> =
         output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"]))
             .lines()
@@ -193,11 +232,11 @@ than building it.
             continue;
         }
 
-        let target_str = target.to_string();
-
         // Ignore fake targets that are only used for unit tests in bootstrap.
-        if !["A-A", "B-B", "C-C"].contains(&target_str.as_str()) {
+        #[cfg(not(feature = "bootstrap-self-test"))]
+        {
             let mut has_target = false;
+            let target_str = target.to_string();
 
             let missing_targets_hashset: HashSet<_> =
                 STAGE0_MISSING_TARGETS.iter().map(|t| t.to_string()).collect();
@@ -226,7 +265,7 @@ than building it.
                     target_filename.push(".json");
 
                     // Recursively traverse through nested directories.
-                    let walker = WalkDir::new(custom_target_path).into_iter();
+                    let walker = walkdir::WalkDir::new(custom_target_path).into_iter();
                     for entry in walker.filter_map(|e| e.ok()) {
                         has_target |= entry.file_name() == target_filename;
                     }
diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh
index 3939b4b7c41..d046b539036 100755
--- a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh
@@ -54,7 +54,7 @@ apt-get clean
 # This makes all those symlinks.
 for lib in $(find -name '*.so.*'); do
   target=${lib%.so.*}.so
-  [ -e $target ] || ln -s ${lib##*/} $target
+  ln -s ${lib##*/} $target || echo "warning: silenced error symlinking $lib"
 done
 
 # Remove Solaris 11 functions that are optionally used by libbacktrace.
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index d4325862248..8c84e721f5d 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -58,6 +58,7 @@ envs:
     CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL
     ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55
     AWS_REGION: us-west-1
+    TOOLSTATE_PUBLISH: 1
 
   try:
     <<: *production
diff --git a/src/ci/publish_toolstate.sh b/src/ci/publish_toolstate.sh
index 691df04e754..e828365c416 100755
--- a/src/ci/publish_toolstate.sh
+++ b/src/ci/publish_toolstate.sh
@@ -24,8 +24,8 @@ cd rust-toolstate
 FAILURE=1
 for RETRY_COUNT in 1 2 3 4 5; do
     # The purpose of this is to publish the new "current" toolstate in the toolstate repo.
-    # This happens post-landing, on master.
-    # (Publishing the per-commit test results happens pre-landing in src/bootstrap/toolstate.rs).
+    # This happens at the end of auto builds.
+    # (Publishing the per-commit test results happens in src/bootstrap/toolstate.rs).
     "$(ciCheckoutPath)/src/tools/publish_toolstate.py" "$GIT_COMMIT" \
         "$GIT_COMMIT_MSG" \
         "$MESSAGE_FILE" \
diff --git a/src/doc/book b/src/doc/book
-Subproject 85442a608426d3667f1c9458ad457b241a36b56
+Subproject 5228bfac8267ad24659a81b92ec5417976b5edb
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 0c68e90acaae5a611f8f5098a3c2980de9845ab
+Subproject bbaabbe088e21a81a0d9ae6757705020d5d7b41
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject dd962bb82865a5284f2404e5234f1e3222b9c02
+Subproject b10c6acaf0f43481f6600e95d4b5013446e29f7
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 0d5f88475fe285affa6dbbc806e9e44d730797c
+Subproject 0ebdacadbda8ce2cd8fbf93985e15af61a7ab89
diff --git a/src/doc/reference b/src/doc/reference
-Subproject e356977fceaa8591c762312d8d446769166d4b3
+Subproject 6019b76f5b28938565b251bbba0bf5cc5c43d86
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 20482893d1a502df72f76762c97aed88854cdf8
+Subproject 4840dca06cadf48b305d3ce0aeafde7f80933f8
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject b6d4a4940bab85cc91eec70cc2e3096dd48da62
+Subproject 6a7374bd87cbac0f8be4fd4877d8186d9c31398
diff --git a/src/doc/rustc/src/check-cfg/cargo-specifics.md b/src/doc/rustc/src/check-cfg/cargo-specifics.md
index bfa60161926..bd4bebbc874 100644
--- a/src/doc/rustc/src/check-cfg/cargo-specifics.md
+++ b/src/doc/rustc/src/check-cfg/cargo-specifics.md
@@ -3,12 +3,12 @@
 <!--
 This page is currently (as of May 2024) the canonical place for describing the interaction
 between Cargo and --check-cfg. It is placed in the rustc book rather than the Cargo book
-since check-cfg is primarely a Rust/rustc feature and is therefor consider by T-cargo to
+since check-cfg is primarily a Rust/rustc feature and is therefore considered by T-cargo to
 be an implementation detail, at least --check-cfg and the unexpected_cfgs are owned by
 rustc, not Cargo.
 -->
 
-This document is intented to summarize the principal ways Cargo interacts with
+This document is intended to summarize the principal ways Cargo interacts with
 the `unexpected_cfgs` lint and `--check-cfg` flag. It is not intended to provide
 individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and
 to the [Cargo book](../../cargo/index.html).
@@ -17,7 +17,7 @@ to the [Cargo book](../../cargo/index.html).
 
 *See the [`[features]` section in the Cargo book][cargo-features] for more details.*
 
-With the `[features]` table Cargo provides a mechanism to express conditional compilation and
+With the `[features]` table, Cargo provides a mechanism to express conditional compilation and
 optional dependencies. Cargo *automatically* declares corresponding cfgs for every feature as
 expected.
 
@@ -32,16 +32,16 @@ my_feature = []
 
 ## `check-cfg` in `[lints.rust]` table
 
-<!-- Note that T-Cargo considers `[lints.rust.unexpected_cfgs.check-cfg]` to be an
-implementation detail and is therefor not documented in Cargo, we therefor do that ourself -->
+<!-- Note that T-Cargo considers `lints.rust.unexpected_cfgs.check-cfg` to be an
+implementation detail and is therefore documented here and not in Cargo. -->
 
 *See the [`[lints]` section in the Cargo book][cargo-lints-table] for more details.*
 
-When using a staticlly known custom config (ie. not dependant on a build-script), Cargo provides
+When using a statically known custom config (i.e., not dependent on a build-script), Cargo provides
 the custom lint config `check-cfg` under `[lints.rust.unexpected_cfgs]`.
 
 It can be used to set custom static [`--check-cfg`](../check-cfg.md) args, it is mainly useful when
-the list of expected cfgs is known is advance.
+the list of expected cfgs is known in advance.
 
 `Cargo.toml`:
 ```toml
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 77859956c95..633c26a4f56 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -33,12 +33,12 @@ All tier 1 targets with host tools support the full standard library.
 target | notes
 -------|-------
 `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+)
-`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+) [^x86_32-floats-return-ABI]
-`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+) [^x86_32-floats-return-ABI]
+`i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI]
+`i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI]
 `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI]
 [`x86_64-apple-darwin`](platform-support/apple-darwin.md) | 64-bit macOS (10.12+, Sierra+)
-`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+)
-`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+)
+`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 10+, Windows Server 2016+)
+`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 10+, Windows Server 2016+)
 `x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 3.2+, glibc 2.17+)
 
 [^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue].
diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
index ab8b4caaadf..0c5129d0efb 100644
--- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
@@ -12,6 +12,7 @@ overall performance.
 ## Target Maintainers
 
 * [@Lokathor](https://github.com/lokathor)
+* [@corwinkuiper](https://github.com/corwinkuiper)
 
 ## Testing
 
diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md
index 3e1db692f50..5643c6a0188 100644
--- a/src/doc/rustc/src/platform-support/fuchsia.md
+++ b/src/doc/rustc/src/platform-support/fuchsia.md
@@ -10,9 +10,9 @@ updatable, and performant.
 The [Fuchsia team]:
 
 - Tyler Mandry ([@tmandry](https://github.com/tmandry))
-- Dan Johnson ([@computerdruid](https://github.com/computerdruid))
 - David Koloski ([@djkoloski](https://github.com/djkoloski))
-- Joseph Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
+- Julia Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
+- Erick Tryzelaar ([@erickt](https://github.com/erickt))
 
 As the team evolves over time, the specific members listed here may differ from
 the members reported by the API. The API should be considered to be
diff --git a/src/doc/unstable-book/src/compiler-flags/codegen-backend.md b/src/doc/unstable-book/src/compiler-flags/codegen-backend.md
index 67634be6993..7e4be9841f4 100644
--- a/src/doc/unstable-book/src/compiler-flags/codegen-backend.md
+++ b/src/doc/unstable-book/src/compiler-flags/codegen-backend.md
@@ -12,8 +12,9 @@ backend. The library must be of crate type `dylib` and must contain a function
 named `__rustc_codegen_backend` with a signature of `fn() -> Box<dyn rustc_codegen_ssa::traits::CodegenBackend>`.
 
 ## Example
-See also the [`hotplug_codegen_backend`](https://github.com/rust-lang/rust/tree/master/tests/run-make-fulldeps/hotplug_codegen_backend) test
-for a full example.
+See also the [`codegen-backend/hotplug`] test for a working example.
+
+[`codegen-backend/hotplug`]: https://github.com/rust-lang/rust/tree/master/tests/ui-fulldeps/codegen-backend/hotplug.rs
 
 ```rust,ignore (partial-example)
 use rustc_codegen_ssa::traits::CodegenBackend;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index c7366ce1a68..0024e246ef0 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -130,7 +130,10 @@ pub(crate) fn try_inline(
         }
         Res::Def(DefKind::Const, did) => {
             record_extern_fqn(cx, did, ItemType::Constant);
-            cx.with_param_env(did, |cx| clean::ConstantItem(build_const(cx, did)))
+            cx.with_param_env(did, |cx| {
+                let (generics, ty, ct) = build_const_item(cx, did);
+                clean::ConstantItem(generics, Box::new(ty), ct)
+            })
         }
         Res::Def(DefKind::Macro(kind), did) => {
             let is_doc_hidden = cx.tcx.is_doc_hidden(did)
@@ -717,21 +720,20 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
     }
 }
 
-fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
+fn build_const_item(
+    cx: &mut DocContext<'_>,
+    def_id: DefId,
+) -> (clean::Generics, clean::Type, clean::Constant) {
     let mut generics =
         clean_ty_generics(cx, cx.tcx.generics_of(def_id), cx.tcx.explicit_predicates_of(def_id));
     clean::simplify::move_bounds_to_generic_parameters(&mut generics);
-
-    clean::Constant {
-        type_: Box::new(clean_middle_ty(
-            ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
-            cx,
-            Some(def_id),
-            None,
-        )),
-        generics,
-        kind: clean::ConstantKind::Extern { def_id },
-    }
+    let ty = clean_middle_ty(
+        ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
+        cx,
+        None,
+        None,
+    );
+    (generics, ty, clean::Constant { kind: clean::ConstantKind::Extern { def_id } })
 }
 
 fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 839bfdf44af..2dcbbf0d150 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -283,31 +283,17 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
 
 pub(crate) fn clean_const<'tcx>(
     constant: &hir::ConstArg<'_>,
-    cx: &mut DocContext<'tcx>,
+    _cx: &mut DocContext<'tcx>,
 ) -> Constant {
-    let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id();
-    Constant {
-        type_: Box::new(clean_middle_ty(
-            ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()),
-            cx,
-            Some(def_id),
-            None,
-        )),
-        generics: Generics::default(),
-        kind: ConstantKind::Anonymous { body: constant.value.body },
-    }
+    Constant { kind: ConstantKind::Anonymous { body: constant.value.body } }
 }
 
 pub(crate) fn clean_middle_const<'tcx>(
     constant: ty::Binder<'tcx, ty::Const<'tcx>>,
-    cx: &mut DocContext<'tcx>,
+    _cx: &mut DocContext<'tcx>,
 ) -> Constant {
     // FIXME: instead of storing the stringified expression, store `self` directly instead.
-    Constant {
-        type_: Box::new(clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None, None)),
-        generics: Generics::default(),
-        kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() },
-    }
+    Constant { kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() } }
 }
 
 pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
@@ -2738,11 +2724,11 @@ fn clean_maybe_renamed_item<'tcx>(
             ItemKind::Static(ty, mutability, body_id) => {
                 StaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: Some(body_id) })
             }
-            ItemKind::Const(ty, generics, body_id) => ConstantItem(Constant {
-                type_: Box::new(clean_ty(ty, cx)),
-                generics: clean_generics(generics, cx),
-                kind: ConstantKind::Local { body: body_id, def_id },
-            }),
+            ItemKind::Const(ty, generics, body_id) => ConstantItem(
+                clean_generics(generics, cx),
+                Box::new(clean_ty(ty, cx)),
+                Constant { kind: ConstantKind::Local { body: body_id, def_id } },
+            ),
             ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
                 bounds: ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
                 generics: clean_generics(ty.generics, cx),
@@ -3089,7 +3075,9 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
     let def_id = item.owner_id.to_def_id();
     cx.with_param_env(def_id, |cx| {
         let kind = match item.kind {
-            hir::ForeignItemKind::Fn(decl, names, generics) => {
+            // FIXME(missing_unsafe_on_extern) handle safety of foreign fns.
+            // Safety was added as part of the implementation of unsafe extern blocks PR #124482
+            hir::ForeignItemKind::Fn(decl, names, generics, _) => {
                 let (generics, decl) = enter_impl_trait(cx, |cx| {
                     // NOTE: generics must be cleaned before args
                     let generics = clean_generics(generics, cx);
@@ -3099,7 +3087,9 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
                 });
                 ForeignFunctionItem(Box::new(Function { decl, generics }))
             }
-            hir::ForeignItemKind::Static(ty, mutability) => {
+            // FIXME(missing_unsafe_on_extern) handle safety of foreign statics.
+            // Safety was added as part of the implementation of unsafe extern blocks PR #124482
+            hir::ForeignItemKind::Static(ty, mutability, _) => {
                 ForeignStaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: None })
             }
             hir::ForeignItemKind::Type => ForeignTypeItem,
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index 5ac1b742c38..995919f73f8 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -65,7 +65,7 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String
     let psess = ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec());
     let file_name = source_map.span_to_filename(span);
     let mut parser =
-        match rustc_parse::maybe_new_parser_from_source_str(&psess, file_name, snippet.clone()) {
+        match rustc_parse::new_parser_from_source_str(&psess, file_name, snippet.clone()) {
             Ok(parser) => parser,
             Err(errs) => {
                 errs.into_iter().for_each(|err| err.cancel());
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index b387809cc71..69678b727c1 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -830,7 +830,6 @@ pub(crate) enum ItemKind {
     TypeAliasItem(Box<TypeAlias>),
     OpaqueTyItem(OpaqueTy),
     StaticItem(Static),
-    ConstantItem(Constant),
     TraitItem(Box<Trait>),
     TraitAliasItem(TraitAlias),
     ImplItem(Box<Impl>),
@@ -853,6 +852,7 @@ pub(crate) enum ItemKind {
     PrimitiveItem(PrimitiveType),
     /// A required associated constant in a trait declaration.
     TyAssocConstItem(Generics, Box<Type>),
+    ConstantItem(Generics, Box<Type>, Constant),
     /// An associated constant in a trait impl or a provided one in a trait declaration.
     AssocConstItem(Generics, Box<Type>, ConstantKind),
     /// A required associated type in a trait declaration.
@@ -888,7 +888,7 @@ impl ItemKind {
             | TypeAliasItem(_)
             | OpaqueTyItem(_)
             | StaticItem(_)
-            | ConstantItem(_)
+            | ConstantItem(_, _, _)
             | TraitAliasItem(_)
             | TyMethodItem(_)
             | MethodItem(_, _)
@@ -922,7 +922,7 @@ impl ItemKind {
                 | TypeAliasItem(_)
                 | OpaqueTyItem(_)
                 | StaticItem(_)
-                | ConstantItem(_)
+                | ConstantItem(_, _, _)
                 | TraitAliasItem(_)
                 | ForeignFunctionItem(_)
                 | ForeignStaticItem(_)
@@ -1936,7 +1936,7 @@ impl PrimitiveType {
             let mut primitive_locations = FxHashMap::default();
             // NOTE: technically this misses crates that are only passed with `--extern` and not loaded when checking the crate.
             // This is a degenerate case that I don't plan to support.
-            for &crate_num in tcx.crates_including_speculative(()) {
+            for &crate_num in tcx.crates(()) {
                 let e = ExternalCrate { crate_num };
                 let crate_name = e.name(tcx);
                 debug!(?crate_num, ?crate_name);
@@ -2364,8 +2364,6 @@ pub(crate) struct Static {
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub(crate) struct Constant {
-    pub(crate) type_: Box<Type>,
-    pub(crate) generics: Generics,
     pub(crate) kind: ConstantKind,
 }
 
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 24a01414c70..7fc3d4508d7 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -353,8 +353,8 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
             s
         }
         // array lengths are obviously usize
-        ty::ConstKind::Value(ty::ValTree::Leaf(scalar))
-            if *n.ty().kind() == ty::Uint(ty::UintTy::Usize) =>
+        ty::ConstKind::Value(ty, ty::ValTree::Leaf(scalar))
+            if *ty.kind() == ty::Uint(ty::UintTy::Usize) =>
         {
             scalar.to_string()
         }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index ccd5dadb20a..ce098a1bcfb 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -347,7 +347,7 @@ pub(crate) fn run_global_ctxt(
         show_coverage,
     };
 
-    for cnum in tcx.crates_including_speculative(()) {
+    for cnum in tcx.crates(()) {
         crate::visit_lib::lib_embargo_visit_item(&mut ctxt, cnum.as_def_id());
     }
 
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index a536a713921..0d4bad6921d 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -9,7 +9,7 @@ use rustc_interface::interface;
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::attr::InnerAttrPolicy;
 use rustc_resolve::rustdoc::span_of_fragments;
 use rustc_session::config::{self, CrateType, ErrorOutputType};
@@ -638,7 +638,7 @@ pub(crate) fn make_test(
             let mut found_extern_crate = crate_name.is_none();
             let mut found_macro = false;
 
-            let mut parser = match maybe_new_parser_from_source_str(&psess, filename, source) {
+            let mut parser = match new_parser_from_source_str(&psess, filename, source) {
                 Ok(p) => p,
                 Err(errs) => {
                     errs.into_iter().for_each(|err| err.cancel());
@@ -818,16 +818,15 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool {
 
             let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
             let psess = ParseSess::with_dcx(dcx, sm);
-            let mut parser =
-                match maybe_new_parser_from_source_str(&psess, filename, source.to_owned()) {
-                    Ok(p) => p,
-                    Err(errs) => {
-                        errs.into_iter().for_each(|err| err.cancel());
-                        // If there is an unclosed delimiter, an error will be returned by the
-                        // tokentrees.
-                        return false;
-                    }
-                };
+            let mut parser = match new_parser_from_source_str(&psess, filename, source.to_owned()) {
+                Ok(p) => p,
+                Err(errs) => {
+                    errs.into_iter().for_each(|err| err.cancel());
+                    // If there is an unclosed delimiter, an error will be returned by the
+                    // tokentrees.
+                    return false;
+                }
+            };
             // If a parsing error happened, it's very likely that the attribute is incomplete.
             if let Err(e) = parser.parse_attribute(InnerAttrPolicy::Permitted) {
                 e.cancel();
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index cf11e2d7899..c85b955d4c5 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -79,7 +79,7 @@ pub(crate) trait DocFolder: Sized {
             | FunctionItem(_)
             | OpaqueTyItem(_)
             | StaticItem(_)
-            | ConstantItem(_)
+            | ConstantItem(_, _, _)
             | TraitAliasItem(_)
             | TyMethodItem(_)
             | MethodItem(_, _)
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 28ddf76a3a6..a3b88a880f2 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -155,7 +155,7 @@ impl Cache {
 
         // Cache where all our extern crates are located
         // FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
-        for &crate_num in tcx.crates_including_speculative(()) {
+        for &crate_num in tcx.crates(()) {
             let e = ExternalCrate { crate_num };
 
             let name = e.name(tcx);
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d20cef745ab..4268fadd6c5 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1438,13 +1438,9 @@ impl clean::FnDecl {
         {
             write!(f, "\n{}", Indent(n + 4))?;
         }
+
+        let last_input_index = self.inputs.values.len().checked_sub(1);
         for (i, input) in self.inputs.values.iter().enumerate() {
-            if i > 0 {
-                match line_wrapping_indent {
-                    None => write!(f, ", ")?,
-                    Some(n) => write!(f, ",\n{}", Indent(n + 4))?,
-                };
-            }
             if let Some(selfty) = input.to_self() {
                 match selfty {
                     clean::SelfValue => {
@@ -1477,18 +1473,25 @@ impl clean::FnDecl {
                 write!(f, "{}: ", input.name)?;
                 input.type_.print(cx).fmt(f)?;
             }
+            match (line_wrapping_indent, last_input_index) {
+                (_, None) => (),
+                (None, Some(last_i)) if i != last_i => write!(f, ", ")?,
+                (None, Some(_)) => (),
+                (Some(n), Some(last_i)) if i != last_i => write!(f, ",\n{}", Indent(n + 4))?,
+                (Some(_), Some(_)) => write!(f, ",\n")?,
+            }
         }
 
         if self.c_variadic {
             match line_wrapping_indent {
                 None => write!(f, ", ...")?,
-                Some(n) => write!(f, "\n{}...", Indent(n + 4))?,
+                Some(n) => write!(f, "{}...\n", Indent(n + 4))?,
             };
         }
 
         match line_wrapping_indent {
             None => write!(f, ")")?,
-            Some(n) => write!(f, "\n{})", Indent(n))?,
+            Some(n) => write!(f, "{})", Indent(n))?,
         };
 
         self.print_output(cx).fmt(f)
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index c5b88c7a951..e1f79254b24 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -266,7 +266,7 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
         clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
         clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
         clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) => item_static(buf, cx, item, i),
-        clean::ConstantItem(ref c) => item_constant(buf, cx, item, c),
+        clean::ConstantItem(generics, ty, c) => item_constant(buf, cx, item, generics, ty, c),
         clean::ForeignTypeItem => item_foreign_type(buf, cx, item),
         clean::KeywordItem => item_keyword(buf, cx, item),
         clean::OpaqueTyItem(ref e) => item_opaque_ty(buf, cx, item, e),
@@ -1844,7 +1844,14 @@ fn item_primitive(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Ite
     }
 }
 
-fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &clean::Constant) {
+fn item_constant(
+    w: &mut Buffer,
+    cx: &mut Context<'_>,
+    it: &clean::Item,
+    generics: &clean::Generics,
+    ty: &clean::Type,
+    c: &clean::Constant,
+) {
     wrap_item(w, |w| {
         let tcx = cx.tcx();
         render_attributes_in_code(w, it, cx);
@@ -1854,9 +1861,9 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
             "{vis}const {name}{generics}: {typ}{where_clause}",
             vis = visibility_print_with_space(it, cx),
             name = it.name.unwrap(),
-            generics = c.generics.print(cx),
-            typ = c.type_.print(cx),
-            where_clause = print_where_clause(&c.generics, cx, 0, Ending::NoNewline),
+            generics = generics.print(cx),
+            typ = ty.print(cx),
+            where_clause = print_where_clause(&generics, cx, 0, Ending::NoNewline),
         );
 
         // FIXME: The code below now prints
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7e6a19aa52e..afafb4fbe4b 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -183,7 +183,7 @@ impl FromWithTcx<clean::Constant> for Constant {
         let expr = constant.expr(tcx);
         let value = constant.value(tcx);
         let is_literal = constant.is_literal(tcx);
-        Constant { type_: (*constant.type_).into_tcx(tcx), expr, value, is_literal }
+        Constant { expr, value, is_literal }
     }
 }
 
@@ -321,7 +321,10 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
         ForeignTypeItem => ItemEnum::ForeignType,
         TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_tcx(tcx)),
         OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)),
-        ConstantItem(c) => ItemEnum::Constant(c.into_tcx(tcx)),
+        // FIXME(generic_const_items): Add support for generic free consts
+        ConstantItem(_generics, t, c) => {
+            ItemEnum::Constant { type_: (*t).into_tcx(tcx), const_: c.into_tcx(tcx) }
+        }
         MacroItem(m) => ItemEnum::Macro(m.source),
         ProcMacroItem(m) => ItemEnum::ProcMacro(m.into_tcx(tcx)),
         PrimitiveItem(p) => {
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index c1d90020e87..0ef24818515 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -186,7 +186,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 | types::ItemEnum::Impl(_)
                 | types::ItemEnum::TypeAlias(_)
                 | types::ItemEnum::OpaqueTy(_)
-                | types::ItemEnum::Constant(_)
+                | types::ItemEnum::Constant { .. }
                 | types::ItemEnum::Static(_)
                 | types::ItemEnum::ForeignType
                 | types::ItemEnum::Macro(_)
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 02589a137b4..d53eac0bccb 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -62,7 +62,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
                 | clean::AssocTypeItem(..)
                 | clean::TypeAliasItem(_)
                 | clean::StaticItem(_)
-                | clean::ConstantItem(_)
+                | clean::ConstantItem(_, _, _)
                 | clean::ExternCrateItem { .. }
                 | clean::ImportItem(_)
                 | clean::PrimitiveItem(_)
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 8ab24a8c12e..440b02a1fa7 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -12,7 +12,7 @@ use rustc_errors::{Applicability, Diag, DiagMessage};
 use rustc_hir::def::Namespace::*;
 use rustc_hir::def::{DefKind, Namespace, PerNS};
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
-use rustc_hir::Mutability;
+use rustc_hir::{Mutability, Safety};
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_middle::{bug, span_bug, ty};
 use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
@@ -1517,7 +1517,11 @@ impl Disambiguator {
                 "union" => Kind(DefKind::Union),
                 "module" | "mod" => Kind(DefKind::Mod),
                 "const" | "constant" => Kind(DefKind::Const),
-                "static" => Kind(DefKind::Static { mutability: Mutability::Not, nested: false }),
+                "static" => Kind(DefKind::Static {
+                    mutability: Mutability::Not,
+                    nested: false,
+                    safety: Safety::Safe,
+                }),
                 "function" | "fn" | "method" => Kind(DefKind::Fn),
                 "derive" => Kind(DefKind::Macro(MacroKind::Derive)),
                 "type" => NS(Namespace::TypeNS),
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 22daac9efb1..c92cf9d3e80 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -47,7 +47,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
     // External trait impls.
     {
         let _prof_timer = tcx.sess.prof.generic_activity("build_extern_trait_impls");
-        for &cnum in tcx.crates_including_speculative(()) {
+        for &cnum in tcx.crates(()) {
             for &impl_def_id in tcx.trait_impls_in_crate(cnum) {
                 cx.with_param_env(impl_def_id, |cx| {
                     inline::build_impl(cx, impl_def_id, None, &mut new_items_external);
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 39350f4cbbb..c185442fd55 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -5,7 +5,7 @@ use rustc_errors::{
     translation::{to_fluent_args, Translate},
     Applicability, DiagCtxt, DiagInner, LazyFallbackBundle,
 };
-use rustc_parse::parse_stream_from_source_str;
+use rustc_parse::{source_str_to_stream, unwrap_or_emit_fatal};
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 use rustc_session::parse::ParseSess;
 use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, Transparency};
@@ -51,12 +51,12 @@ fn check_rust_syntax(
     let span = DUMMY_SP.apply_mark(expn_id.to_expn_id(), Transparency::Transparent);
 
     let is_empty = rustc_driver::catch_fatal_errors(|| {
-        parse_stream_from_source_str(
+        unwrap_or_emit_fatal(source_str_to_stream(
+            &psess,
             FileName::Custom(String::from("doctest")),
             source,
-            &psess,
             Some(span),
-        )
+        ))
         .is_empty()
     })
     .unwrap_or(false);
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 64753a58a2b..e9b380fdeac 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -283,7 +283,7 @@ pub(crate) fn run(
         // Collect CrateIds corresponding to provided target crates
         // If two different versions of the crate in the dependency tree, then examples will be collected from both.
         let all_crates = tcx
-            .crates_including_speculative(())
+            .crates(())
             .iter()
             .chain([&LOCAL_CRATE])
             .map(|crate_num| (crate_num, tcx.crate_name(*crate_num)))
diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs
index 01e6cb4b93b..0660037e4d8 100644
--- a/src/librustdoc/visit.rs
+++ b/src/librustdoc/visit.rs
@@ -28,7 +28,7 @@ pub(crate) trait DocVisitor: Sized {
             | TypeAliasItem(_)
             | OpaqueTyItem(_)
             | StaticItem(_)
-            | ConstantItem(_)
+            | ConstantItem(_, _, _)
             | TraitAliasItem(_)
             | TyMethodItem(_)
             | MethodItem(_, _)
diff --git a/src/llvm-project b/src/llvm-project
-Subproject b31c30a9bb4dbbd13c359d0e2bea7f65d20adf3
+Subproject 5a5152f653959d14d68613a3a8a033fb65eec02
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 1c5a6dcfb1f..68030493e9c 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
 use std::path::PathBuf;
 
 /// rustdoc format-version.
-pub const FORMAT_VERSION: u32 = 29;
+pub const FORMAT_VERSION: u32 = 30;
 
 /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
 /// about the language items in the local crate, as well as info about external items to allow
@@ -167,8 +167,6 @@ pub enum GenericArg {
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct Constant {
-    #[serde(rename = "type")]
-    pub type_: Type,
     pub expr: String,
     pub value: Option<String>,
     pub is_literal: bool,
@@ -256,7 +254,12 @@ pub enum ItemEnum {
 
     TypeAlias(TypeAlias),
     OpaqueTy(OpaqueTy),
-    Constant(Constant),
+    Constant {
+        #[serde(rename = "type")]
+        type_: Type,
+        #[serde(rename = "const")]
+        const_: Constant,
+    },
 
     Static(Static),
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 7a6fad0984d28c8330974636972aa296b67c451
+Subproject 34a6a87d8a2330d8c9d578f927489689328a652
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index 651f2ebaee6..c3e3c0431e6 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::{Diag, DiagCtxt};
 use rustc_lint::LateContext;
-use rustc_parse::maybe_new_parser_from_source_str;
+use rustc_parse::new_parser_from_source_str;
 use rustc_parse::parser::ForceCollect;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
@@ -50,7 +50,7 @@ pub fn check(
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
                 let psess = ParseSess::with_dcx(dcx, sm);
 
-                let mut parser = match maybe_new_parser_from_source_str(&psess, filename, code) {
+                let mut parser = match new_parser_from_source_str(&psess, filename, code) {
                     Ok(p) => p,
                     Err(errs) => {
                         errs.into_iter().for_each(Diag::cancel);
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index b561054b582..77d05020c82 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
             && generics.params.is_empty() && !generics.has_where_clause_predicates
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Array(element_type, cst) = ty.kind()
-            && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
+            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
             && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size)
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
index 208d1bb6e68..f0f3f53647b 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
         if let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind
             && !self.is_from_vec_macro(cx, expr.span)
             && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()
-            && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
+            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
             && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| {
diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
index 8199366d175..45b375dbe3d 100644
--- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
@@ -37,14 +37,14 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
                         Some(lhs) => constant(cx, cx.typeck_results(), lhs)?,
                         None => {
                             let min_val_const = ty.numeric_min_val(cx.tcx)?;
-                            mir_to_const(cx, mir::Const::from_ty_const(min_val_const, cx.tcx))?
+                            mir_to_const(cx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
                         },
                     };
                     let rhs_const = match rhs {
                         Some(rhs) => constant(cx, cx.typeck_results(), rhs)?,
                         None => {
                             let max_val_const = ty.numeric_max_val(cx.tcx)?;
-                            mir_to_const(cx, mir::Const::from_ty_const(max_val_const, cx.tcx))?
+                            mir_to_const(cx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
                         },
                     };
                     let lhs_val = lhs_const.int_value(cx, ty)?;
diff --git a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs
index 143fecdd237..848b49130dc 100644
--- a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs
@@ -55,7 +55,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects {
             inner_check(cx, expr, inner_expr, true);
         } else if let ExprKind::Repeat(inner_expr, _) = expr.kind
             && let ty::Array(_, cst) = cx.typeck_results().expr_ty(expr).kind()
-            && let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind()
+            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
             && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx)
             && element_count == 0
         {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index bbdde3049db..c70f5c2df84 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -308,13 +308,15 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 ty: lt,
                 mutability: lm,
                 expr: le,
+                safety: ls,
             }),
             Static(box StaticItem {
                 ty: rt,
                 mutability: rm,
                 expr: re,
+                safety: rs,
             }),
-        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le, re),
         (
             Const(box ConstItem {
                 defaultness: ld,
@@ -451,13 +453,15 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 ty: lt,
                 mutability: lm,
                 expr: le,
+                safety: ls,
             }),
             Static(box StaticForeignItem {
                 ty: rt,
                 mutability: rm,
                 expr: re,
+                safety: rs,
             }),
-        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re) && ls == rs,
         (
             Fn(box ast::Fn {
                 defaultness: ld,
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index b10830b24e1..2f6bf920967 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -647,7 +647,7 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
 /// This function is expensive and should be used sparingly.
 pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Vec<Res> {
     fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
-        tcx.crates_including_speculative(())
+        tcx.crates(())
             .iter()
             .copied()
             .filter(move |&num| tcx.crate_name(num) == name)
@@ -1534,7 +1534,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
             if let rustc_ty::Adt(_, subst) = ty.kind()
                 && let bnd_ty = subst.type_at(0)
                 && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
-                && let Some(min_const) = mir_to_const(cx, Const::from_ty_const(min_val, cx.tcx))
+                && let Some(min_const) = mir_to_const(cx, Const::from_ty_const(min_val, bnd_ty, cx.tcx))
                 && let Some(start_const) = constant(cx, cx.typeck_results(), start)
             {
                 start_const == min_const
@@ -1547,7 +1547,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
                 if let rustc_ty::Adt(_, subst) = ty.kind()
                     && let bnd_ty = subst.type_at(0)
                     && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx)
-                    && let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, cx.tcx))
+                    && let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, bnd_ty, cx.tcx))
                     && let Some(end_const) = constant(cx, cx.typeck_results(), end)
                 {
                     end_const == max_const
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index a2cdf800a97..fd4ab72bbf4 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -94,7 +94,7 @@ pub struct TestProps {
     // Extra flags to pass to the compiler
     pub compile_flags: Vec<String>,
     // Extra flags to pass when the compiled code is run (such as --bench)
-    pub run_flags: Option<String>,
+    pub run_flags: Vec<String>,
     // If present, the name of a file that this test should match when
     // pretty-printed
     pub pp_exact: Option<PathBuf>,
@@ -107,6 +107,9 @@ pub struct TestProps {
     // Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies
     // to build and pass with the `--extern` flag.
     pub aux_crates: Vec<(String, String)>,
+    /// Similar to `aux_builds`, but also passes the resulting dylib path to
+    /// `-Zcodegen-backend`.
+    pub aux_codegen_backend: Option<String>,
     // Environment settings to use for compiling
     pub rustc_env: Vec<(String, String)>,
     // Environment variables to unset prior to compiling.
@@ -231,6 +234,7 @@ mod directives {
     pub const AUX_BIN: &'static str = "aux-bin";
     pub const AUX_BUILD: &'static str = "aux-build";
     pub const AUX_CRATE: &'static str = "aux-crate";
+    pub const AUX_CODEGEN_BACKEND: &'static str = "aux-codegen-backend";
     pub const EXEC_ENV: &'static str = "exec-env";
     pub const RUSTC_ENV: &'static str = "rustc-env";
     pub const UNSET_EXEC_ENV: &'static str = "unset-exec-env";
@@ -262,11 +266,12 @@ impl TestProps {
             error_patterns: vec![],
             regex_error_patterns: vec![],
             compile_flags: vec![],
-            run_flags: None,
+            run_flags: vec![],
             pp_exact: None,
             aux_builds: vec![],
             aux_bins: vec![],
             aux_crates: vec![],
+            aux_codegen_backend: None,
             revisions: vec![],
             rustc_env: vec![
                 ("RUSTC_ICE".to_string(), "0".to_string()),
@@ -399,7 +404,9 @@ impl TestProps {
 
                     config.parse_and_update_revisions(ln, &mut self.revisions);
 
-                    config.set_name_value_directive(ln, RUN_FLAGS, &mut self.run_flags, |r| r);
+                    if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS) {
+                        self.run_flags.extend(split_flags(&flags));
+                    }
 
                     if self.pp_exact.is_none() {
                         self.pp_exact = config.parse_pp_exact(ln, testfile);
@@ -444,6 +451,9 @@ impl TestProps {
                         &mut self.aux_crates,
                         Config::parse_aux_crate,
                     );
+                    if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND) {
+                        self.aux_codegen_backend = Some(r.trim().to_owned());
+                    }
                     config.push_name_value_directive(
                         ln,
                         EXEC_ENV,
@@ -720,6 +730,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "assembly-output",
     "aux-bin",
     "aux-build",
+    "aux-codegen-backend",
     "aux-crate",
     "build-aux-docs",
     "build-fail",
@@ -799,6 +810,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-none",
     "ignore-nto",
     "ignore-nvptx64",
+    "ignore-nvptx64-nvidia-cuda",
     "ignore-openbsd",
     "ignore-pass",
     "ignore-remote",
@@ -1267,6 +1279,8 @@ fn expand_variables(mut value: String, config: &Config) -> String {
     const CWD: &str = "{{cwd}}";
     const SRC_BASE: &str = "{{src-base}}";
     const BUILD_BASE: &str = "{{build-base}}";
+    const SYSROOT_BASE: &str = "{{sysroot-base}}";
+    const TARGET_LINKER: &str = "{{target-linker}}";
 
     if value.contains(CWD) {
         let cwd = env::current_dir().unwrap();
@@ -1281,6 +1295,14 @@ fn expand_variables(mut value: String, config: &Config) -> String {
         value = value.replace(BUILD_BASE, &config.build_base.to_string_lossy());
     }
 
+    if value.contains(SYSROOT_BASE) {
+        value = value.replace(SYSROOT_BASE, &config.sysroot_base.to_string_lossy());
+    }
+
+    if value.contains(TARGET_LINKER) {
+        value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or(""));
+    }
+
     value
 }
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 9bd0002a3d9..28c766f7e17 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1833,6 +1833,16 @@ impl<'test> TestCx<'test> {
                 ));
             }
         }
+
+        // Build any `//@ aux-codegen-backend`, and pass the resulting library
+        // to `-Zcodegen-backend` when compiling the test file.
+        if let Some(aux_file) = &self.props.aux_codegen_backend {
+            let aux_type = self.build_auxiliary(of, aux_file, aux_dir, false);
+            if let Some(lib_name) = get_lib_name(aux_file.trim_end_matches(".rs"), aux_type) {
+                let lib_path = aux_dir.join(&lib_name);
+                rustc.arg(format!("-Zcodegen-backend={}", lib_path.display()));
+            }
+        }
     }
 
     fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {
@@ -2254,6 +2264,9 @@ impl<'test> TestCx<'test> {
         }
 
         match output_file {
+            // If the test's compile flags specify an output path with `-o`,
+            // avoid a compiler warning about `--out-dir` being ignored.
+            _ if self.props.compile_flags.iter().any(|flag| flag == "-o") => {}
             TargetLocation::ThisFile(path) => {
                 rustc.arg("-o").arg(path);
             }
@@ -2355,7 +2368,7 @@ impl<'test> TestCx<'test> {
         args.push(exe_file.into_os_string());
 
         // Add the arguments in the run_flags directive
-        args.extend(self.split_maybe_args(&self.props.run_flags));
+        args.extend(self.props.run_flags.iter().map(OsString::from));
 
         let prog = args.remove(0);
         ProcArgs { prog, args }
@@ -2469,6 +2482,7 @@ impl<'test> TestCx<'test> {
         }
     }
 
+    #[track_caller]
     fn fatal(&self, err: &str) -> ! {
         self.error(err);
         error!("fatal error, panic: {:?}", err);
@@ -4173,10 +4187,12 @@ impl<'test> TestCx<'test> {
     }
 
     fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String {
-        let rflags = self.props.run_flags.as_ref();
+        // Crude heuristic to detect when the output should have JSON-specific
+        // normalization steps applied.
+        let rflags = self.props.run_flags.join(" ");
         let cflags = self.props.compile_flags.join(" ");
-        let json = rflags
-            .map_or(false, |s| s.contains("--format json") || s.contains("--format=json"))
+        let json = rflags.contains("--format json")
+            || rflags.contains("--format=json")
             || cflags.contains("--error-format json")
             || cflags.contains("--error-format pretty-json")
             || cflags.contains("--error-format=json")
diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs
index 9bd04e11cb3..525de03bbce 100644
--- a/src/tools/jsondoclint/src/item_kind.rs
+++ b/src/tools/jsondoclint/src/item_kind.rs
@@ -150,7 +150,7 @@ impl Kind {
             ItemEnum::Impl(_) => Impl,
             ItemEnum::TypeAlias(_) => TypeAlias,
             ItemEnum::OpaqueTy(_) => OpaqueTy,
-            ItemEnum::Constant(_) => Constant,
+            ItemEnum::Constant { .. } => Constant,
             ItemEnum::Static(_) => Static,
             ItemEnum::Macro(_) => Macro,
             ItemEnum::ProcMacro(_) => ProcMacro,
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index 904c2b614f3..5e35ce242fe 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -101,7 +101,10 @@ impl<'a> Validator<'a> {
                 ItemEnum::Impl(x) => self.check_impl(x, id),
                 ItemEnum::TypeAlias(x) => self.check_type_alias(x),
                 ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x),
-                ItemEnum::Constant(x) => self.check_constant(x),
+                ItemEnum::Constant { type_, const_ } => {
+                    self.check_type(type_);
+                    self.check_constant(const_);
+                }
                 ItemEnum::Static(x) => self.check_static(x),
                 ItemEnum::ForeignType => {} // nop
                 ItemEnum::Macro(x) => self.check_macro(x),
@@ -231,8 +234,8 @@ impl<'a> Validator<'a> {
         self.check_generics(&x.generics);
     }
 
-    fn check_constant(&mut self, x: &'a Constant) {
-        self.check_type(&x.type_);
+    fn check_constant(&mut self, _x: &'a Constant) {
+        // nop
     }
 
     fn check_static(&mut self, x: &'a Static) {
diff --git a/src/tools/libcxx-version/main.cpp b/src/tools/libcxx-version/main.cpp
new file mode 100644
index 00000000000..79df7ef457c
--- /dev/null
+++ b/src/tools/libcxx-version/main.cpp
@@ -0,0 +1,26 @@
+// Detecting the standard library version manually using a bunch of shell commands is very
+// complicated and fragile across different platforms. This program provides the major version
+// of the standard library on any target platform without requiring any messy work.
+//
+// It's nothing more than specifying the name of the standard library implementation (either libstdc++ or libc++)
+// and its major version.
+
+#include <iostream>
+
+int main() {
+    #ifdef _GLIBCXX_RELEASE
+        std::cout << "libstdc++ version: " << _GLIBCXX_RELEASE << std::endl;
+    #elif defined(_LIBCPP_VERSION)
+        // _LIBCPP_VERSION follows "XXYYZZ" format (e.g., 170001 for 17.0.1).
+        // ref: https://github.com/llvm/llvm-project/blob/f64732195c1030ee2627ff4e4142038e01df1d26/libcxx/include/__config#L51-L54
+        //
+        // Since we use the major version from _GLIBCXX_RELEASE, we need to extract only the first 2 characters of _LIBCPP_VERSION
+        // to provide the major version for consistency.
+        std::cout << "libc++ version: " << std::to_string(_LIBCPP_VERSION).substr(0, 2) << std::endl;
+    #else
+        std::cerr << "Coudln't recognize the standard library version." << std::endl;
+        return 1;
+    #endif
+
+    return 0;
+}
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 5032f225227..8d038c0f788 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-a330e49593ee890f9197727a3a558b6e6b37f843
+76e7a0849c07d73e4d9afde8036ee8c450127cc8
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index c17886c242f..e6ef2f5dc60 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -126,7 +126,7 @@ fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option<Namespace>)
     // the one in the sysroot and the one locally built by `cargo test`.)
     // FIXME: can we prefer the one from the sysroot?
     'crates: for krate in
-        tcx.used_crates(()).iter().filter(|&&krate| tcx.crate_name(krate).as_str() == crate_name)
+        tcx.crates(()).iter().filter(|&&krate| tcx.crate_name(krate).as_str() == crate_name)
     {
         let mut cur_item = DefId { krate: *krate, index: CRATE_DEF_INDEX };
         // Go over the modules.
@@ -1354,7 +1354,7 @@ pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
         .map(|crates| crates.split(',').map(|krate| krate.to_string()).collect::<Vec<_>>())
         .unwrap_or_default();
     let mut local_crates = Vec::new();
-    for &crate_num in tcx.crates_including_speculative(()) {
+    for &crate_num in tcx.crates(()) {
         let name = tcx.crate_name(crate_num);
         let name = name.as_str();
         if local_crate_names.iter().any(|local_name| local_name == name) {
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index 6d0682cd110..d82c523b817 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -590,6 +590,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     .expect_const()
                     .eval(*this.tcx, this.param_env(), this.tcx.span)
                     .unwrap()
+                    .1
                     .unwrap_branch();
                 let index_len = index.len();
 
diff --git a/src/tools/miri/tests/pass/function_calls/abi_compat.rs b/src/tools/miri/tests/pass/function_calls/abi_compat.rs
index 136660a305a..0cfcd532ff4 100644
--- a/src/tools/miri/tests/pass/function_calls/abi_compat.rs
+++ b/src/tools/miri/tests/pass/function_calls/abi_compat.rs
@@ -83,12 +83,24 @@ fn main() {
     test_abi_compat(main as fn(), id::<i32> as fn(i32) -> i32);
     // - 1-ZST
     test_abi_compat((), [0u8; 0]);
-    // - Guaranteed null-pointer-optimizations (RFC 3391).
+    // - Guaranteed Option<X> null-pointer-optimizations (RFC 3391).
     test_abi_compat(&0u32 as *const u32, Some(&0u32));
     test_abi_compat(main as fn(), Some(main as fn()));
     test_abi_compat(0u32, Some(num::NonZero::new(1u32).unwrap()));
     test_abi_compat(&0u32 as *const u32, Some(Wrapper(&0u32)));
-    test_abi_compat(0u32, Some(Wrapper(num::NonZero::new(1u32).unwrap())));
+    test_abi_compat(0u32, Some(Wrapper(num::NonZeroU32::new(1u32).unwrap())));
+    // - Guaranteed Result<X, ZST1> does the same as Option<X> (RFC 3391)
+    test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(&0u32));
+    test_abi_compat(main as fn(), Result::<_, ()>::Ok(main as fn()));
+    test_abi_compat(0u32, Result::<_, ()>::Ok(num::NonZeroU32::new(1).unwrap()));
+    test_abi_compat(&0u32 as *const u32, Result::<_, ()>::Ok(Wrapper(&0u32)));
+    test_abi_compat(0u32, Result::<_, ()>::Ok(Wrapper(num::NonZeroU32::new(1).unwrap())));
+    // - Guaranteed Result<ZST1, X> also does the same as Option<X> (RFC 3391)
+    test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(&0u32));
+    test_abi_compat(main as fn(), Result::<(), _>::Err(main as fn()));
+    test_abi_compat(0u32, Result::<(), _>::Err(num::NonZeroU32::new(1).unwrap()));
+    test_abi_compat(&0u32 as *const u32, Result::<(), _>::Err(Wrapper(&0u32)));
+    test_abi_compat(0u32, Result::<(), _>::Err(Wrapper(num::NonZeroU32::new(1).unwrap())));
 
     // These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible
     // with the wrapped field.
diff --git a/src/tools/opt-dist/src/environment.rs b/src/tools/opt-dist/src/environment.rs
index ff782a1687e..bc01b7fb8a3 100644
--- a/src/tools/opt-dist/src/environment.rs
+++ b/src/tools/opt-dist/src/environment.rs
@@ -17,6 +17,9 @@ pub struct Environment {
     host_llvm_dir: Utf8PathBuf,
     /// List of test paths that should be skipped when testing the optimized artifacts.
     skipped_tests: Vec<String>,
+    /// Arguments passed to `rustc-perf --cargo-config <value>` when running benchmarks.
+    #[builder(default)]
+    benchmark_cargo_config: Vec<String>,
     /// Directory containing a pre-built rustc-perf checkout.
     #[builder(default)]
     prebuilt_rustc_perf: Option<Utf8PathBuf>,
@@ -94,6 +97,10 @@ impl Environment {
     pub fn skipped_tests(&self) -> &[String] {
         &self.skipped_tests
     }
+
+    pub fn benchmark_cargo_config(&self) -> &[String] {
+        &self.benchmark_cargo_config
+    }
 }
 
 /// What is the extension of binary executables on this platform?
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index a709076f245..e4271a6e2dd 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -90,6 +90,10 @@ enum EnvironmentCmd {
 
         #[clap(flatten)]
         shared: SharedArgs,
+
+        /// Arguments passed to `rustc-perf --cargo-config <value>` when running benchmarks.
+        #[arg(long)]
+        benchmark_cargo_config: Vec<String>,
     },
     /// Perform an optimized build on Linux CI, from inside Docker.
     LinuxCi {
@@ -119,6 +123,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
             llvm_shared,
             use_bolt,
             skipped_tests,
+            benchmark_cargo_config,
             shared,
         } => {
             let env = EnvironmentBuilder::default()
@@ -132,6 +137,7 @@ fn create_environment(args: Args) -> anyhow::Result<(Environment, Vec<String>)>
                 .shared_llvm(llvm_shared)
                 .use_bolt(use_bolt)
                 .skipped_tests(skipped_tests)
+                .benchmark_cargo_config(benchmark_cargo_config)
                 .build()?;
 
             (env, shared.build_args)
diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs
index 46040e32a03..09263dc645e 100644
--- a/src/tools/opt-dist/src/training.rs
+++ b/src/tools/opt-dist/src/training.rs
@@ -36,7 +36,7 @@ fn init_compiler_benchmarks(
     // Run rustc-perf benchmarks
     // Benchmark using profile_local with eprintln, which essentially just means
     // don't actually benchmark -- just make sure we run rustc a bunch of times.
-    cmd(&[
+    let mut cmd = cmd(&[
         env.cargo_stage_0().as_str(),
         "run",
         "-p",
@@ -61,7 +61,17 @@ fn init_compiler_benchmarks(
     .env("RUST_LOG", "collector=debug")
     .env("RUSTC", env.rustc_stage_0().as_str())
     .env("RUSTC_BOOTSTRAP", "1")
-    .workdir(&env.rustc_perf_dir())
+    .workdir(&env.rustc_perf_dir());
+
+    // This propagates cargo configs to `rustc-perf --cargo-config`,
+    // which is particularly useful when the environment is air-gapped,
+    // and you want to use the default set of training crates vendored
+    // in the rustc-src tarball.
+    for config in env.benchmark_cargo_config() {
+        cmd = cmd.arg("--cargo-config").arg(config);
+    }
+
+    cmd
 }
 
 /// Describes which `llvm-profdata` binary should be used for merging PGO profiles.
diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs
index 0012e7b66af..1472a39305e 100644
--- a/src/tools/run-make-support/src/cc.rs
+++ b/src/tools/run-make-support/src/cc.rs
@@ -1,8 +1,9 @@
-use std::env;
 use std::path::Path;
 use std::process::Command;
 
-use crate::{bin_name, cygpath_windows, handle_failed_output, is_msvc, is_windows, tmp_dir, uname};
+use crate::{
+    bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, tmp_dir, uname,
+};
 
 /// Construct a new platform-specific C compiler invocation.
 ///
@@ -27,11 +28,11 @@ impl Cc {
     /// WARNING: This means that what flags are accepted by the underlying C compile is
     /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
     pub fn new() -> Self {
-        let compiler = env::var("CC").unwrap();
+        let compiler = env_var("CC");
 
         let mut cmd = Command::new(compiler);
 
-        let default_cflags = env::var("CC_DEFAULT_FLAGS").unwrap();
+        let default_cflags = env_var("CC_DEFAULT_FLAGS");
         for flag in default_cflags.split(char::is_whitespace) {
             cmd.arg(flag);
         }
diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs
index 6ccce67b250..63c5af17c1d 100644
--- a/src/tools/run-make-support/src/clang.rs
+++ b/src/tools/run-make-support/src/clang.rs
@@ -1,8 +1,7 @@
-use std::env;
 use std::path::Path;
 use std::process::Command;
 
-use crate::{bin_name, handle_failed_output, tmp_dir};
+use crate::{bin_name, env_var, handle_failed_output, tmp_dir};
 
 /// Construct a new `clang` invocation. `clang` is not always available for all targets.
 pub fn clang() -> Clang {
@@ -20,8 +19,7 @@ crate::impl_common_helpers!(Clang);
 impl Clang {
     /// Construct a new `clang` invocation. `clang` is not always available for all targets.
     pub fn new() -> Self {
-        let clang =
-            env::var("CLANG").expect("`CLANG` not specified, but this is required to find `clang`");
+        let clang = env_var("CLANG");
         let cmd = Command::new(clang);
         Self { cmd }
     }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 323fc40e648..d74a0272a62 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -12,6 +12,7 @@ pub mod rustc;
 pub mod rustdoc;
 
 use std::env;
+use std::ffi::OsString;
 use std::fs;
 use std::io;
 use std::path::{Path, PathBuf};
@@ -30,14 +31,28 @@ pub use run::{run, run_fail};
 pub use rustc::{aux_build, rustc, Rustc};
 pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
 
+pub fn env_var(name: &str) -> String {
+    match env::var(name) {
+        Ok(v) => v,
+        Err(err) => panic!("failed to retrieve environment variable {name:?}: {err:?}"),
+    }
+}
+
+pub fn env_var_os(name: &str) -> OsString {
+    match env::var_os(name) {
+        Some(v) => v,
+        None => panic!("failed to retrieve environment variable {name:?}"),
+    }
+}
+
 /// Path of `TMPDIR` (a temporary build directory, not under `/tmp`).
 pub fn tmp_dir() -> PathBuf {
-    env::var_os("TMPDIR").unwrap().into()
+    env_var_os("TMPDIR").into()
 }
 
 /// `TARGET`
 pub fn target() -> String {
-    env::var("TARGET").unwrap()
+    env_var("TARGET")
 }
 
 /// Check if target is windows-like.
@@ -62,18 +77,19 @@ pub fn static_lib(name: &str) -> PathBuf {
 }
 
 pub fn python_command() -> Command {
-    let python_path = std::env::var("PYTHON").expect("PYTHON environment variable does not exist");
+    let python_path = env_var("PYTHON");
     Command::new(python_path)
 }
 
 pub fn htmldocck() -> Command {
     let mut python = python_command();
-    python.arg(source_path().join("src/etc/htmldocck.py"));
+    python.arg(source_root().join("src/etc/htmldocck.py"));
     python
 }
 
-pub fn source_path() -> PathBuf {
-    std::env::var("S").expect("S variable does not exist").into()
+/// Path to the root rust-lang/rust source checkout.
+pub fn source_root() -> PathBuf {
+    env_var("S").into()
 }
 
 /// Construct the static library name based on the platform.
@@ -208,12 +224,12 @@ fn handle_failed_output(cmd: &Command, output: Output, caller_line_number: u32)
 
 /// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
 pub fn set_host_rpath(cmd: &mut Command) {
-    let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
+    let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
     cmd.env(&ld_lib_path_envvar, {
         let mut paths = vec![];
-        paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
-        paths.push(PathBuf::from(env::var("HOST_RPATH_DIR").unwrap()));
-        for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
+        paths.push(PathBuf::from(env_var("TMPDIR")));
+        paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
+        for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
             paths.push(p.to_path_buf());
         }
         env::join_paths(paths.iter()).unwrap()
diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs
index f114aacfa3f..77aaadfe18c 100644
--- a/src/tools/run-make-support/src/llvm_readobj.rs
+++ b/src/tools/run-make-support/src/llvm_readobj.rs
@@ -1,8 +1,7 @@
-use std::env;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-use crate::handle_failed_output;
+use crate::{env_var, handle_failed_output};
 
 /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available
 /// at `$LLVM_BIN_DIR/llvm-readobj`.
@@ -22,8 +21,7 @@ impl LlvmReadobj {
     /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available
     /// at `$LLVM_BIN_DIR/llvm-readobj`.
     pub fn new() -> Self {
-        let llvm_bin_dir = env::var("LLVM_BIN_DIR")
-            .expect("`LLVM_BIN_DIR` not specified, but this is required to find `llvm-readobj`");
+        let llvm_bin_dir = env_var("LLVM_BIN_DIR");
         let llvm_bin_dir = PathBuf::from(llvm_bin_dir);
         let llvm_readobj = llvm_bin_dir.join("llvm-readobj");
         let cmd = Command::new(llvm_readobj);
diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs
index da4f265efc3..8d8eafba99b 100644
--- a/src/tools/run-make-support/src/run.rs
+++ b/src/tools/run-make-support/src/run.rs
@@ -2,23 +2,23 @@ use std::env;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output};
 
-use crate::is_windows;
+use crate::{env_var, is_windows};
 
 use super::handle_failed_output;
 
 fn run_common(name: &str) -> (Command, Output) {
     let mut bin_path = PathBuf::new();
-    bin_path.push(env::var("TMPDIR").unwrap());
+    bin_path.push(env_var("TMPDIR"));
     bin_path.push(name);
-    let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
+    let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
     let mut cmd = Command::new(bin_path);
     cmd.env(&ld_lib_path_envvar, {
         let mut paths = vec![];
-        paths.push(PathBuf::from(env::var("TMPDIR").unwrap()));
-        for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) {
+        paths.push(PathBuf::from(env_var("TMPDIR")));
+        for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) {
             paths.push(p.to_path_buf());
         }
-        for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) {
+        for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
             paths.push(p.to_path_buf());
         }
         env::join_paths(paths.iter()).unwrap()
@@ -29,7 +29,7 @@ fn run_common(name: &str) -> (Command, Output) {
         for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
             paths.push(p.to_path_buf());
         }
-        paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf());
+        paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf());
         cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
     }
 
diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs
index 8b0252b8f04..e923c3cf4ad 100644
--- a/src/tools/run-make-support/src/rustc.rs
+++ b/src/tools/run-make-support/src/rustc.rs
@@ -1,10 +1,9 @@
-use std::env;
 use std::ffi::{OsStr, OsString};
 use std::io::Write;
 use std::path::Path;
 use std::process::{Command, Output, Stdio};
 
-use crate::{handle_failed_output, set_host_rpath, tmp_dir};
+use crate::{env_var, handle_failed_output, set_host_rpath, tmp_dir};
 
 /// Construct a new `rustc` invocation.
 pub fn rustc() -> Rustc {
@@ -26,7 +25,7 @@ pub struct Rustc {
 crate::impl_common_helpers!(Rustc);
 
 fn setup_common() -> Command {
-    let rustc = env::var("RUSTC").unwrap();
+    let rustc = env_var("RUSTC");
     let mut cmd = Command::new(rustc);
     set_host_rpath(&mut cmd);
     cmd.arg("--out-dir").arg(tmp_dir()).arg("-L").arg(tmp_dir());
@@ -70,6 +69,12 @@ impl Rustc {
         self
     }
 
+    /// Add a suffix in each output filename.
+    pub fn extra_filename(&mut self, suffix: &str) -> &mut Self {
+        self.cmd.arg(format!("-Cextra-filename={suffix}"));
+        self
+    }
+
     /// Specify type(s) of output files to generate.
     pub fn emit(&mut self, kinds: &str) -> &mut Self {
         self.cmd.arg(format!("--emit={kinds}"));
diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs
index 61d7448a6bf..34d32992e65 100644
--- a/src/tools/run-make-support/src/rustdoc.rs
+++ b/src/tools/run-make-support/src/rustdoc.rs
@@ -1,10 +1,9 @@
-use std::env;
 use std::ffi::OsStr;
 use std::io::Write;
 use std::path::Path;
 use std::process::{Command, Output, Stdio};
 
-use crate::{handle_failed_output, set_host_rpath};
+use crate::{env_var, env_var_os, handle_failed_output, set_host_rpath};
 
 /// Construct a plain `rustdoc` invocation with no flags set.
 pub fn bare_rustdoc() -> Rustdoc {
@@ -25,7 +24,7 @@ pub struct Rustdoc {
 crate::impl_common_helpers!(Rustdoc);
 
 fn setup_common() -> Command {
-    let rustdoc = env::var("RUSTDOC").unwrap();
+    let rustdoc = env_var("RUSTDOC");
     let mut cmd = Command::new(rustdoc);
     set_host_rpath(&mut cmd);
     cmd
@@ -41,7 +40,7 @@ impl Rustdoc {
     /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
     pub fn new() -> Self {
         let mut cmd = setup_common();
-        let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap();
+        let target_rpath_dir = env_var_os("TARGET_RPATH_DIR");
         cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy()));
         Self { cmd, stdin: None }
     }
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index 2b0dd0062b9..95f1a5d6e1d 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -9,6 +9,7 @@ clap = "4.0.32"
 env_logger = "0.11"
 mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
 mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
+mdbook-i18n-helpers = "0.3.3"
 
 [dependencies.mdbook]
 version = "0.4.37"
diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index 9a06754e4a6..31bba56adde 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -7,6 +7,7 @@ use clap::{arg, ArgMatches, Command};
 
 use mdbook::errors::Result as Result3;
 use mdbook::MDBook;
+use mdbook_i18n_helpers::preprocessors::Gettext;
 
 use mdbook_trpl_listing::TrplListing;
 use mdbook_trpl_note::TrplNote;
@@ -19,6 +20,11 @@ fn main() {
     .required(false)
     .value_parser(clap::value_parser!(PathBuf));
 
+    let l_arg = arg!(-l --"lang" <LANGUAGE>
+"The output language")
+    .required(false)
+    .value_parser(clap::value_parser!(String));
+
     let dir_arg = arg!([dir] "Root directory for the book\n\
                               (Defaults to the current directory when omitted)")
     .value_parser(clap::value_parser!(PathBuf));
@@ -33,6 +39,7 @@ fn main() {
             Command::new("build")
                 .about("Build the book from the markdown files")
                 .arg(d_arg)
+                .arg(l_arg)
                 .arg(&dir_arg),
         )
         .subcommand(
@@ -63,6 +70,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
     let book_dir = get_book_dir(args);
     let mut book = load_book(&book_dir)?;
 
+    if let Some(lang) = args.get_one::<String>("lang") {
+        let gettext = Gettext;
+        book.with_preprocessor(gettext);
+        book.config.set("book.language", lang).unwrap();
+    }
+
     // Set this to allow us to catch bugs in advance.
     book.config.build.create_missing = false;
 
diff --git a/src/tools/rustc-perf b/src/tools/rustc-perf
-Subproject cc81f9654dac3fe08de286907dba747538417af
+Subproject 72daa50ce2350f5a9b5ae6dc3ad6babccd14ec0
diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs
index 0ddd2c66cf9..bf581279f2a 100644
--- a/src/tools/rustdoc-gui-test/src/main.rs
+++ b/src/tools/rustdoc-gui-test/src/main.rs
@@ -123,9 +123,7 @@ If you want to install the `browser-ui-test` dependency, run `npm install browse
                     cargo.env("RUSTDOCFLAGS", test_props.compile_flags.join(" "));
                 }
 
-                if let Some(flags) = &test_props.run_flags {
-                    cargo.arg(flags);
-                }
+                cargo.args(&test_props.run_flags);
             }
 
             if try_run(&mut cargo, config.verbose).is_err() {
diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs
index 3cf133c647c..cbcc0b2d636 100644
--- a/src/tools/rustfmt/src/parse/macros/mod.rs
+++ b/src/tools/rustfmt/src/parse/macros/mod.rs
@@ -2,7 +2,7 @@ use rustc_ast::token::{Delimiter, NonterminalKind, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{ast, ptr};
 use rustc_parse::parser::{ForceCollect, Parser, Recovery};
-use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS};
+use rustc_parse::MACRO_ARGUMENTS;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{self, kw};
 use rustc_span::Symbol;
@@ -15,7 +15,7 @@ pub(crate) mod cfg_if;
 pub(crate) mod lazy_static;
 
 fn build_stream_parser<'a>(psess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> {
-    stream_to_parser(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
+    Parser::new(psess, tokens, MACRO_ARGUMENTS).recovery(Recovery::Forbidden)
 }
 
 fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> {
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index 5dcdca1d953..6051241309d 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -4,7 +4,8 @@ use std::path::{Path, PathBuf};
 use rustc_ast::token::TokenKind;
 use rustc_ast::{ast, attr, ptr};
 use rustc_errors::Diag;
-use rustc_parse::{new_parser_from_file, parser::Parser as RawParser};
+use rustc_parse::parser::Parser as RawParser;
+use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_span::{sym, Span};
 use thin_vec::ThinVec;
 
@@ -50,12 +51,9 @@ impl<'a> ParserBuilder<'a> {
 
         let parser = match Self::parser(psess.inner(), input) {
             Ok(p) => p,
-            Err(db) => {
-                if let Some(diagnostics) = db {
-                    psess.emit_diagnostics(diagnostics);
-                    return Err(ParserError::ParserCreationError);
-                }
-                return Err(ParserError::ParsePanicError);
+            Err(diagnostics) => {
+                psess.emit_diagnostics(diagnostics);
+                return Err(ParserError::ParserCreationError);
             }
         };
 
@@ -65,18 +63,14 @@ impl<'a> ParserBuilder<'a> {
     fn parser(
         psess: &'a rustc_session::parse::ParseSess,
         input: Input,
-    ) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<Diag<'a>>>> {
+    ) -> Result<RawParser<'a>, Vec<Diag<'a>>> {
         match input {
-            Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
-                new_parser_from_file(psess, file, None)
-            }))
-            .map_err(|_| None),
-            Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
+            Input::File(ref file) => new_parser_from_file(psess, file, None),
+            Input::Text(text) => new_parser_from_source_str(
                 psess,
                 rustc_span::FileName::Custom("stdin".to_owned()),
                 text,
-            )
-            .map_err(Some),
+            ),
         }
     }
 }
@@ -111,7 +105,8 @@ impl<'a> Parser<'a> {
         span: Span,
     ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> {
         let result = catch_unwind(AssertUnwindSafe(|| {
-            let mut parser = new_parser_from_file(psess.inner(), path, Some(span));
+            let mut parser =
+                unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span)));
             match parser.parse_mod(&TokenKind::Eof) {
                 Ok((a, i, spans)) => Some((a, i, spans.inner_span)),
                 Err(e) => {
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index 09e1dbde1d0..fd59aedadfe 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -111,6 +111,7 @@ pub(crate) fn format_defaultness(defaultness: ast::Defaultness) -> &'static str
 pub(crate) fn format_safety(unsafety: ast::Safety) -> &'static str {
     match unsafety {
         ast::Safety::Unsafe(..) => "unsafe ",
+        ast::Safety::Safe(..) => "safe ",
         ast::Safety::Default => "",
     }
 }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 600ca06fcdf..a015f96ae51 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -70,7 +70,6 @@ run-make/inaccessible-temp-dir/Makefile
 run-make/include_bytes_deps/Makefile
 run-make/incr-add-rust-src-component/Makefile
 run-make/incr-foreign-head-span/Makefile
-run-make/incr-prev-body-beyond-eof/Makefile
 run-make/incremental-debugger-visualizer/Makefile
 run-make/incremental-session-fail/Makefile
 run-make/inline-always-many-cgu/Makefile
@@ -136,7 +135,6 @@ run-make/lto-readonly-lib/Makefile
 run-make/lto-smoke-c/Makefile
 run-make/macos-deployment-target/Makefile
 run-make/macos-fat-archive/Makefile
-run-make/manual-crate-name/Makefile
 run-make/manual-link/Makefile
 run-make/many-crates-but-no-match/Makefile
 run-make/metadata-dep-info/Makefile
@@ -202,7 +200,6 @@ run-make/remap-path-prefix-dwarf/Makefile
 run-make/remap-path-prefix/Makefile
 run-make/reproducible-build-2/Makefile
 run-make/reproducible-build/Makefile
-run-make/resolve-rename/Makefile
 run-make/return-non-c-like-enum-from-c/Makefile
 run-make/return-non-c-like-enum/Makefile
 run-make/rlib-chain/Makefile
@@ -232,7 +229,6 @@ run-make/static-pie/Makefile
 run-make/staticlib-blank-lib/Makefile
 run-make/staticlib-dylib-linkage/Makefile
 run-make/std-core-cycle/Makefile
-run-make/suspicious-library/Makefile
 run-make/symbol-mangling-hashed/Makefile
 run-make/symbol-visibility/Makefile
 run-make/symbols-include-type-name/Makefile
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 398a6fd0fba..a6ba8959f0c 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -2445,7 +2445,6 @@ ui/issues/issue-53300.rs
 ui/issues/issue-53333.rs
 ui/issues/issue-53348.rs
 ui/issues/issue-53419.rs
-ui/issues/issue-53498.rs
 ui/issues/issue-53568.rs
 ui/issues/issue-5358-1.rs
 ui/issues/issue-53728.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index cce0fb2c1a2..f2eeda339d8 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: u32 = 900;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: u32 = 1674;
+const ISSUES_ENTRY_LIMIT: u32 = 1672;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs
index f68b7675c76..63a03834166 100644
--- a/src/tools/tidy/src/walk.rs
+++ b/src/tools/tidy/src/walk.rs
@@ -16,6 +16,7 @@ pub fn filter_dirs(path: &Path) -> bool {
         "library/stdarch",
         "src/tools/cargo",
         "src/tools/clippy",
+        "src/tools/libcxx-version",
         "src/tools/miri",
         "src/tools/rust-analyzer",
         "src/tools/rustc-perf",
diff --git a/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs b/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs
index eeeaebe52dd..df50b4af809 100644
--- a/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs
+++ b/tests/codegen/dont_codegen_private_const_fn_only_used_in_const_eval.rs
@@ -3,8 +3,25 @@
 
 //@compile-flags: --crate-type=lib -Copt-level=0
 
+#![feature(generic_const_items)]
+
 const fn foo() {}
 
 pub static FOO: () = foo();
 
 // CHECK-NOT: define{{.*}}foo{{.*}}
+
+const fn bar() {}
+
+pub const BAR: () = bar();
+
+// CHECK-NOT: define{{.*}}bar{{.*}}
+
+const fn baz() {}
+
+#[rustfmt::skip]
+pub const BAZ<const C: bool>: () = if C {
+    baz()
+};
+
+// CHECK: define{{.*}}baz{{.*}}
diff --git a/tests/codegen/riscv-abi/call-llvm-intrinsics.rs b/tests/codegen/riscv-abi/call-llvm-intrinsics.rs
index c3f795e8857..e72a649a530 100644
--- a/tests/codegen/riscv-abi/call-llvm-intrinsics.rs
+++ b/tests/codegen/riscv-abi/call-llvm-intrinsics.rs
@@ -23,7 +23,7 @@ pub fn do_call() {
 
     unsafe {
         // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them
-        // CHECK: store float 4.000000e+00, float* %{{.}}, align 4
+        // CHECK: store float 4.000000e+00, ptr %{{.}}, align 4
         // CHECK: call float @llvm.sqrt.f32(float %{{.}}
         sqrt(4.0);
     }
diff --git a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
index 060d91a2696..bcd9b0eae71 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64d-abi.rs
@@ -1,10 +1,19 @@
-//
-//@ compile-flags: -C no-prepopulate-passes
-//@ only-riscv64
-//@ only-linux
+//@ compile-flags: -O -C no-prepopulate-passes --target riscv64gc-unknown-linux-gnu
+//@ needs-llvm-components: riscv
+
+#![feature(no_core, lang_items)]
 #![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "freeze"]
+trait Freeze {}
+#[lang = "copy"]
+trait Copy {}
 
-// CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 zeroext %i)
+// CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 noundef zeroext %i)
 #[no_mangle]
 pub extern "C" fn f_fpr_tracking(
     a: f64,
@@ -144,7 +153,7 @@ pub extern "C" fn f_ret_double_int64_s() -> DoubleInt64 {
     DoubleInt64 { f: 1., i: 2 }
 }
 
-// CHECK: define void @f_double_int8_s_arg_insufficient_gprs(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h, [2 x i64] %0)
+// CHECK: define void @f_double_int8_s_arg_insufficient_gprs(i32 noundef signext %a, i32 noundef signext %b, i32 noundef signext %c, i32 noundef signext %d, i32 noundef signext %e, i32 noundef signext %f, i32 noundef signext %g, i32 noundef signext %h, [2 x i64] %0)
 #[no_mangle]
 pub extern "C" fn f_double_int8_s_arg_insufficient_gprs(
     a: i32,
@@ -250,11 +259,11 @@ pub struct IntDoubleInt {
     c: i32,
 }
 
-// CHECK: define void @f_int_double_int_s_arg(%IntDoubleInt* {{.*}}%a)
+// CHECK: define void @f_int_double_int_s_arg(ptr {{.*}} %a)
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(%IntDoubleInt* {{.*}}sret
+// CHECK: define void @f_ret_int_double_int_s(ptr {{.*}} sret([24 x i8]) align 8 dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }
diff --git a/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs b/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs
index 3d0512817f7..27018d2e6d2 100644
--- a/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs
+++ b/tests/codegen/riscv-abi/riscv64-lp64f-lp64d-abi.rs
@@ -1,10 +1,19 @@
-//
-//@ compile-flags: -C no-prepopulate-passes
-//@ only-riscv64
-//@ only-linux
+//@ compile-flags: -O -C no-prepopulate-passes --target riscv64gc-unknown-linux-gnu
+//@ needs-llvm-components: riscv
+
+#![feature(no_core, lang_items)]
 #![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "freeze"]
+trait Freeze {}
+#[lang = "copy"]
+trait Copy {}
 
-// CHECK: define void @f_fpr_tracking(float %0, float %1, float %2, float %3, float %4, float %5, float %6, float %7, i8 zeroext %i)
+// CHECK: define void @f_fpr_tracking(float %0, float %1, float %2, float %3, float %4, float %5, float %6, float %7, i8 noundef zeroext %i)
 #[no_mangle]
 pub extern "C" fn f_fpr_tracking(
     a: f32,
@@ -128,7 +137,7 @@ pub extern "C" fn f_ret_float_int64_s() -> FloatInt64 {
     FloatInt64 { f: 1., i: 2 }
 }
 
-// CHECK: define void @f_float_int8_s_arg_insufficient_gprs(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e, i32 signext %f, i32 signext %g, i32 signext %h, i64 %0)
+// CHECK: define void @f_float_int8_s_arg_insufficient_gprs(i32 noundef signext %a, i32 noundef signext %b, i32 noundef signext %c, i32 noundef signext %d, i32 noundef signext %e, i32 noundef signext %f, i32 noundef signext %g, i32 noundef signext %h, i64 %0)
 #[no_mangle]
 pub extern "C" fn f_float_int8_s_arg_insufficient_gprs(
     a: i32,
diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map
index fd8fbd9fa75..156947f4e21 100644
--- a/tests/coverage/closure_macro.cov-map
+++ b/tests/coverage/closure_macro.cov-map
@@ -7,16 +7,14 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2)
 
 Function name: closure_macro::main
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 21, 02, 02, 09, 00, 12, 02, 00, 0f, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
+Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 33, 1) to (start + 1, 33)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 18)
-    = (c0 - c1)
-- Code(Expression(0, Sub)) at (prev + 0, 15) to (start + 0, 84)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map
index 43b52008f33..0f2b4e01748 100644
--- a/tests/coverage/closure_macro_async.cov-map
+++ b/tests/coverage/closure_macro_async.cov-map
@@ -15,16 +15,14 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 35, 1) to (start + 0, 43)
 
 Function name: closure_macro_async::test::{closure#0}
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 23, 2b, 01, 21, 02, 02, 09, 00, 12, 02, 00, 0f, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 23, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 6
+Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 35, 43) to (start + 1, 33)
-- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 18)
-    = (c0 - c1)
-- Code(Expression(0, Sub)) at (prev + 0, 15) to (start + 0, 84)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
diff --git a/tests/crashes/122908.rs b/tests/crashes/122908.rs
deleted file mode 100644
index c9da1bc1879..00000000000
--- a/tests/crashes/122908.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-//@ known-bug: #122908
-trait Trait<const module_path: Trait = bar> {
-    async fn handle<F>(slf: &F) {}
-}
diff --git a/tests/crashes/124490.rs b/tests/crashes/124490.rs
deleted file mode 100644
index 9f605c32cf2..00000000000
--- a/tests/crashes/124490.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: rust-lang/rust#124490
-use io::{self as std};
-use std::collections::{self as io};
-
-mod a {
-    pub mod b {
-        pub mod c {}
-    }
-}
-
-use a::*;
-
-use b::c;
-use c as b;
-
-fn main() {}
diff --git a/tests/crashes/124552.rs b/tests/crashes/124552.rs
deleted file mode 100644
index 5320ce27843..00000000000
--- a/tests/crashes/124552.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-//@ known-bug: rust-lang/rust#124552
-
-struct B;
-
-struct Foo {
-    b: u32,
-    b: B,
-}
-
-static BAR: Foo = Foo { b: B };
-
-fn main() {}
diff --git a/tests/crashes/125013-1.rs b/tests/crashes/125013-1.rs
deleted file mode 100644
index ae66d7a1466..00000000000
--- a/tests/crashes/125013-1.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: rust-lang/rust#125013
-//@ edition:2021
-use io::{self as std};
-use std::ops::Deref::{self as io};
-pub fn main() {}
diff --git a/tests/crashes/125013-2.rs b/tests/crashes/125013-2.rs
deleted file mode 100644
index a14c8a76b63..00000000000
--- a/tests/crashes/125013-2.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//@ known-bug: rust-lang/rust#125013
-//@ edition:2021
-mod a {
-  pub mod b {
-    pub mod c {
-      pub trait D {}
-    }
-  }
-}
-
-use a::*;
-
-use e as b;
-use b::c::D as e;
-
-fn main() { }
diff --git a/tests/crashes/125556.rs b/tests/crashes/125556.rs
deleted file mode 100644
index f2e2a991b11..00000000000
--- a/tests/crashes/125556.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ known-bug: rust-lang/rust#125556
-//@ compile-flags: -Znext-solver=coherence
-
-#![feature(generic_const_exprs)]
-
-pub struct A<const z: [usize; x]> {}
-
-impl A<2> {
-    pub const fn B() {}
-}
-
-impl A<2> {
-    pub const fn B() {}
-}
diff --git a/tests/debuginfo/function-names.rs b/tests/debuginfo/function-names.rs
index 2b0c2593676..d9b61e73621 100644
--- a/tests/debuginfo/function-names.rs
+++ b/tests/debuginfo/function-names.rs
@@ -37,7 +37,7 @@
 // Const generic parameter
 // gdb-command:info functions -q function_names::const_generic_fn.*
 // gdb-check:[...]static fn function_names::const_generic_fn_bool<false>();
-// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#ad91263f6d2dd96e}>();
+// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#a70c39591cb5f53d}>();
 // gdb-check:[...]static fn function_names::const_generic_fn_signed_int<-7>();
 // gdb-check:[...]static fn function_names::const_generic_fn_unsigned_int<14>();
 
@@ -76,9 +76,6 @@
 // Const generic parameter
 // cdb-command:x a!function_names::const_generic_fn*
 // cdb-check:[...] a!function_names::const_generic_fn_bool<false> (void)
-// cdb-check:[...] a!function_names::const_generic_fn_non_int<CONST$ad91263f6d2dd96e> (void)
-// cdb-check:[...] a!function_names::const_generic_fn_unsigned_int<14> (void)
-// cdb-check:[...] a!function_names::const_generic_fn_signed_int<-7> (void)
 
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
index 0b0bac73e9f..b7a054b5d54 100644
--- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
@@ -2,7 +2,7 @@
 
 | User Type Annotations
 | 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &'static [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
 |
 fn main() -> () {
     let mut _0: ();
diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
index 0b0bac73e9f..b7a054b5d54 100644
--- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
@@ -2,7 +2,7 @@
 
 | User Type Annotations
 | 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &'static [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
 |
 fn main() -> () {
     let mut _0: ();
diff --git a/tests/pretty/hir-fn-variadic.pp b/tests/pretty/hir-fn-variadic.pp
index 978e65c825b..dfbaff69644 100644
--- a/tests/pretty/hir-fn-variadic.pp
+++ b/tests/pretty/hir-fn-variadic.pp
@@ -9,7 +9,7 @@ use ::std::prelude::rust_2015::*;
 extern crate std;
 
 extern "C" {
-    fn foo(x: i32, va1: ...);
+    unsafe fn foo(x: i32, va1: ...);
 }
 
 unsafe extern "C" fn bar(_: i32, mut va2: ...) -> usize { va2.arg::<usize>() }
diff --git a/tests/run-make-fulldeps/README.md b/tests/run-make-fulldeps/README.md
new file mode 100644
index 00000000000..dd178839022
--- /dev/null
+++ b/tests/run-make-fulldeps/README.md
@@ -0,0 +1,4 @@
+If this directory is empty, Git won't create it, and compiletest will complain
+that it can't find a nonexistent test suite directory.
+
+FIXME(#126111): Remove `run-make-fulldeps` from bootstrap.
diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/Makefile b/tests/run-make-fulldeps/hotplug_codegen_backend/Makefile
deleted file mode 100644
index 3a5a66b6755..00000000000
--- a/tests/run-make-fulldeps/hotplug_codegen_backend/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-include ../../run-make/tools.mk
-
-# ignore-stage1
-
-# This test both exists as a check that -Zcodegen-backend is capable of loading external codegen
-# backends and that this external codegen backend is only included in the dep info if
-# -Zbinary-dep-depinfo is used.
-
-all:
-	$(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \
-		-o $(TMPDIR)/the_backend.dylib
-
-	$(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
-		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \
-		--emit link,dep-info
-	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib
-	# don't declare a dependency on the codegen backend if -Zbinary-dep-depinfo isn't used.
-	grep -v "the_backend.dylib" $(TMPDIR)/some_crate.d
-	
-	$(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
-		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \
-		--emit link,dep-info -Zbinary-dep-depinfo
-	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib
-	# but declare a dependency on the codegen backend if -Zbinary-dep-depinfo it used.
-	grep "the_backend.dylib" $(TMPDIR)/some_crate.d
diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs
deleted file mode 100644
index da27b7f3463..00000000000
--- a/tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#![feature(no_core)]
-#![no_core]
diff --git a/tests/run-make-fulldeps/issue-19371/Makefile b/tests/run-make-fulldeps/issue-19371/Makefile
deleted file mode 100644
index edec68f0862..00000000000
--- a/tests/run-make-fulldeps/issue-19371/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-include ../../run-make/tools.mk
-
-# This test ensures that rustc compile_input can be called twice in one task
-# without causing a panic.
-# The program needs the path to rustc to get sysroot.
-
-all:
-	$(RUSTC) foo.rs
-	$(call RUN,foo $(TMPDIR) $(RUSTC))
diff --git a/tests/run-make-fulldeps/obtain-borrowck/Makefile b/tests/run-make-fulldeps/obtain-borrowck/Makefile
deleted file mode 100644
index 233f5c9eaf4..00000000000
--- a/tests/run-make-fulldeps/obtain-borrowck/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-include ../../run-make/tools.mk
-
-# This example shows how to implement a rustc driver that retrieves MIR bodies
-# together with the borrow checker information.
-
-# How to run this
-# $ ./x.py test tests/run-make-fulldeps/obtain-borrowck
-
-DRIVER_BINARY := "$(TMPDIR)"/driver
-SYSROOT := $(shell $(RUSTC) --print sysroot)
-
-ifdef IS_WINDOWS
-LIBSTD := -L "$(SYSROOT)\\lib\\rustlib\\$(TARGET)\\lib"
-else
-LIBSTD :=
-endif
-
-all:
-	$(RUSTC) driver.rs -o "$(DRIVER_BINARY)"
-	$(TARGET_RPATH_ENV) "$(DRIVER_BINARY)" --sysroot $(SYSROOT) $(LIBSTD) test.rs -o "$(TMPDIR)/driver_test" > "$(TMPDIR)"/output.stdout
-
-ifdef RUSTC_BLESS_TEST
-	cp "$(TMPDIR)"/output.stdout output.stdout
-else
-	$(DIFF) output.stdout "$(TMPDIR)"/output.stdout
-endif
diff --git a/tests/run-make-fulldeps/pretty-expanded/Makefile b/tests/run-make-fulldeps/pretty-expanded/Makefile
deleted file mode 100644
index 48199179ece..00000000000
--- a/tests/run-make-fulldeps/pretty-expanded/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../run-make/tools.mk
-
-all:
-	$(RUSTC) -o $(TMPDIR)/input.expanded.rs -Zunpretty=expanded input.rs
diff --git a/tests/run-make-fulldeps/pretty-expanded/input.rs b/tests/run-make-fulldeps/pretty-expanded/input.rs
deleted file mode 100644
index 64ed97572ee..00000000000
--- a/tests/run-make-fulldeps/pretty-expanded/input.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// #13544
-
-#[derive(Debug)]
-pub struct A;
-
-#[derive(Debug)]
-pub struct B(isize);
-
-#[derive(Debug)]
-pub struct C {
-    x: isize,
-}
-
-#[derive(Debug)]
-pub enum D {}
-
-#[derive(Debug)]
-pub enum E {
-    y,
-}
-
-#[derive(Debug)]
-pub enum F {
-    z(isize),
-}
diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs
index 4bca5d1f1ef..89a6636d9a0 100644
--- a/tests/run-make/alloc-no-oom-handling/rmake.rs
+++ b/tests/run-make/alloc-no-oom-handling/rmake.rs
@@ -2,14 +2,14 @@
 // when the unstable no_global_oom_handling feature is turned on.
 // See https://github.com/rust-lang/rust/pull/84266
 
-use run_make_support::rustc;
+use run_make_support::{rustc, source_root};
 
 fn main() {
     rustc()
         .edition("2021")
         .arg("-Dwarnings")
         .crate_type("rlib")
-        .input("../../../library/alloc/src/lib.rs")
+        .input(source_root().join("library/alloc/src/lib.rs"))
         .cfg("no_global_oom_handling")
         .run();
 }
diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs
index 8ff73324b08..12171c2148f 100644
--- a/tests/run-make/alloc-no-rc/rmake.rs
+++ b/tests/run-make/alloc-no-rc/rmake.rs
@@ -2,14 +2,14 @@
 // when the unstable no_rc feature is turned on.
 // See https://github.com/rust-lang/rust/pull/84266
 
-use run_make_support::rustc;
+use run_make_support::{rustc, source_root};
 
 fn main() {
     rustc()
         .edition("2021")
         .arg("-Dwarnings")
         .crate_type("rlib")
-        .input("../../../library/alloc/src/lib.rs")
+        .input(source_root().join("library/alloc/src/lib.rs"))
         .cfg("no_rc")
         .run();
 }
diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs
index 3a3ceed6867..29f204f3067 100644
--- a/tests/run-make/alloc-no-sync/rmake.rs
+++ b/tests/run-make/alloc-no-sync/rmake.rs
@@ -2,14 +2,14 @@
 // when the unstable no_sync feature is turned on.
 // See https://github.com/rust-lang/rust/pull/84266
 
-use run_make_support::rustc;
+use run_make_support::{rustc, source_root};
 
 fn main() {
     rustc()
         .edition("2021")
         .arg("-Dwarnings")
         .crate_type("rlib")
-        .input("../../../library/alloc/src/lib.rs")
+        .input(source_root().join("library/alloc/src/lib.rs"))
         .cfg("no_sync")
         .run();
 }
diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs
index f5da50ebb04..b043b149d65 100644
--- a/tests/run-make/compiler-builtins/rmake.rs
+++ b/tests/run-make/compiler-builtins/rmake.rs
@@ -14,7 +14,6 @@
 
 #![deny(warnings)]
 
-use run_make_support::object;
 use run_make_support::object::read::archive::ArchiveFile;
 use run_make_support::object::read::Object;
 use run_make_support::object::ObjectSection;
@@ -22,6 +21,7 @@ use run_make_support::object::ObjectSymbol;
 use run_make_support::object::RelocationTarget;
 use run_make_support::set_host_rpath;
 use run_make_support::tmp_dir;
+use run_make_support::{env_var, object};
 use std::collections::HashSet;
 
 const MANIFEST: &str = r#"
@@ -35,7 +35,7 @@ path = "lib.rs""#;
 
 fn main() {
     let target_dir = tmp_dir().join("target");
-    let target = std::env::var("TARGET").unwrap();
+    let target = env_var("TARGET");
 
     println!("Testing compiler_builtins for {}", target);
 
@@ -44,9 +44,9 @@ fn main() {
     std::fs::write(&manifest_path, MANIFEST.as_bytes()).unwrap();
     std::fs::write(tmp_dir().join("lib.rs"), b"#![no_std]").unwrap();
 
-    let path = std::env::var("PATH").unwrap();
-    let rustc = std::env::var("RUSTC").unwrap();
-    let bootstrap_cargo = std::env::var("BOOTSTRAP_CARGO").unwrap();
+    let path = env_var("PATH");
+    let rustc = env_var("RUSTC");
+    let bootstrap_cargo = env_var("BOOTSTRAP_CARGO");
     let mut cmd = std::process::Command::new(bootstrap_cargo);
     cmd.args([
         "build",
@@ -56,7 +56,6 @@ fn main() {
         "--target",
         &target,
     ])
-    .env_clear()
     .env("PATH", path)
     .env("RUSTC", rustc)
     .env("RUSTFLAGS", "-Copt-level=0 -Cdebug-assertions=yes")
diff --git a/tests/run-make/core-no-fp-fmt-parse/rmake.rs b/tests/run-make/core-no-fp-fmt-parse/rmake.rs
index aef28fd2528..3586922f28e 100644
--- a/tests/run-make/core-no-fp-fmt-parse/rmake.rs
+++ b/tests/run-make/core-no-fp-fmt-parse/rmake.rs
@@ -1,14 +1,14 @@
 // This test checks that the core library of Rust can be compiled without enabling
 // support for formatting and parsing floating-point numbers.
 
-use run_make_support::rustc;
+use run_make_support::{rustc, source_root};
 
 fn main() {
     rustc()
         .edition("2021")
         .arg("-Dwarnings")
         .crate_type("rlib")
-        .input("../../../library/core/src/lib.rs")
+        .input(source_root().join("library/core/src/lib.rs"))
         .cfg("no_fp_fmt_parse")
         .run();
 }
diff --git a/tests/run-make/core-no-oom-handling/rmake.rs b/tests/run-make/core-no-oom-handling/rmake.rs
index 75767421cd1..3ebbf63ab7d 100644
--- a/tests/run-make/core-no-oom-handling/rmake.rs
+++ b/tests/run-make/core-no-oom-handling/rmake.rs
@@ -2,14 +2,14 @@
 // when the no_global_oom_handling feature is turned on.
 // See https://github.com/rust-lang/rust/pull/110649
 
-use run_make_support::{rustc, tmp_dir};
+use run_make_support::{rustc, source_root, tmp_dir};
 
 fn main() {
     rustc()
         .edition("2021")
         .arg("-Dwarnings")
         .crate_type("rlib")
-        .input("../../../library/core/src/lib.rs")
+        .input(source_root().join("library/core/src/lib.rs"))
         .sysroot(tmp_dir().join("fakeroot"))
         .cfg("no_global_oom_handling")
         .run();
diff --git a/tests/run-make/incr-prev-body-beyond-eof/Makefile b/tests/run-make/incr-prev-body-beyond-eof/Makefile
deleted file mode 100644
index aa47552f52c..00000000000
--- a/tests/run-make/incr-prev-body-beyond-eof/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-# ignore-none no-std is not supported
-# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std`
-
-include ../tools.mk
-
-# Tests that we don't ICE during incremental compilation after modifying a
-# function span such that its previous end line exceeds the number of lines
-# in the new file, but its start line/column and length remain the same.
-
-SRC=$(TMPDIR)/src
-INCR=$(TMPDIR)/incr
-
-all:
-	mkdir $(SRC)
-	mkdir $(INCR)
-	cp a.rs $(SRC)/main.rs
-	$(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET)
-	cp b.rs $(SRC)/main.rs
-	$(RUSTC) -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET)
diff --git a/tests/run-make/incr-prev-body-beyond-eof/rmake.rs b/tests/run-make/incr-prev-body-beyond-eof/rmake.rs
new file mode 100644
index 00000000000..8aa3893727f
--- /dev/null
+++ b/tests/run-make/incr-prev-body-beyond-eof/rmake.rs
@@ -0,0 +1,27 @@
+// After modifying the span of a function, if the length of
+// the span remained the same but the end line number became different,
+// this would cause an internal compiler error (ICE), fixed in #76256.
+
+// This test compiles main.rs twice, first with end line 16 and
+// then with end line 12. If compilation is successful, the end line
+// was hashed by rustc in addition to the span length, and the fix still
+// works.
+
+//@ ignore-none
+// reason: no-std is not supported
+
+//@ ignore-nvptx64-nvidia-cuda
+// FIXME: can't find crate for `std`
+
+use run_make_support::{rustc, tmp_dir};
+use std::fs;
+
+fn main() {
+    // FIXME(Oneirical): Use run_make_support::fs_wrapper here.
+    fs::create_dir(tmp_dir().join("src")).unwrap();
+    fs::create_dir(tmp_dir().join("incr")).unwrap();
+    fs::copy("a.rs", tmp_dir().join("src/main.rs")).unwrap();
+    rustc().incremental(tmp_dir().join("incr")).input(tmp_dir().join("src/main.rs")).run();
+    fs::copy("b.rs", tmp_dir().join("src/main.rs")).unwrap();
+    rustc().incremental(tmp_dir().join("incr")).input(tmp_dir().join("src/main.rs")).run();
+}
diff --git a/tests/run-make/issue-125484-used-dependencies/dependency.rs b/tests/run-make/issue-125484-used-dependencies/dependency.rs
new file mode 100644
index 00000000000..d15abba5976
--- /dev/null
+++ b/tests/run-make/issue-125484-used-dependencies/dependency.rs
@@ -0,0 +1 @@
+// Empty
diff --git a/tests/run-make/issue-125484-used-dependencies/main.rs b/tests/run-make/issue-125484-used-dependencies/main.rs
new file mode 100644
index 00000000000..0c1a1f8208a
--- /dev/null
+++ b/tests/run-make/issue-125484-used-dependencies/main.rs
@@ -0,0 +1,9 @@
+pub type Foo = something::same::Thing;
+
+mod something {
+    pub mod same {
+        pub struct Thing;
+    }
+}
+
+fn main() {}
diff --git a/tests/run-make/issue-125484-used-dependencies/rmake.rs b/tests/run-make/issue-125484-used-dependencies/rmake.rs
new file mode 100644
index 00000000000..b75e82b42db
--- /dev/null
+++ b/tests/run-make/issue-125484-used-dependencies/rmake.rs
@@ -0,0 +1,18 @@
+// Non-regression test for issues #125474, #125484, #125646, with the repro taken from #125484. Some
+// queries use "used dependencies" while others use "speculatively loaded dependencies", and an
+// indexing ICE appeared in some cases when these were unexpectedly used in the same context.
+
+// FIXME: this should probably be a UI test instead of a run-make test, but I *cannot* find a way to
+// make compiletest annotations reproduce the ICE with the minimizations from issues #125474 and
+// #125484.
+
+use run_make_support::{rustc, tmp_dir};
+
+fn main() {
+    // The dependency is not itself significant, apart from sharing a name with one of main's
+    // modules.
+    rustc().crate_name("same").crate_type("rlib").input("dependency.rs").run();
+
+    // Here, an ICE would happen when building the linker command.
+    rustc().input("main.rs").extern_("same", tmp_dir().join("libsame.rlib")).run();
+}
diff --git a/tests/run-make/manual-crate-name/Makefile b/tests/run-make/manual-crate-name/Makefile
deleted file mode 100644
index c00e20c7c57..00000000000
--- a/tests/run-make/manual-crate-name/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-include ../tools.mk
-
-all:
-	$(RUSTC) --crate-name foo bar.rs
-	rm $(TMPDIR)/libfoo.rlib
diff --git a/tests/run-make/manual-crate-name/rmake.rs b/tests/run-make/manual-crate-name/rmake.rs
new file mode 100644
index 00000000000..531f531abd2
--- /dev/null
+++ b/tests/run-make/manual-crate-name/rmake.rs
@@ -0,0 +1,6 @@
+use run_make_support::{rustc, tmp_dir};
+
+fn main() {
+    rustc().input("bar.rs").crate_name("foo").run();
+    assert!(tmp_dir().join("libfoo.rlib").is_file());
+}
diff --git a/tests/run-make/resolve-rename/Makefile b/tests/run-make/resolve-rename/Makefile
deleted file mode 100644
index 00f83a5d6b2..00000000000
--- a/tests/run-make/resolve-rename/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-include ../tools.mk
-
-all:
-	$(RUSTC) -C extra-filename=-hash foo.rs
-	$(RUSTC) bar.rs
-	mv $(TMPDIR)/libfoo-hash.rlib $(TMPDIR)/libfoo-another-hash.rlib
-	$(RUSTC) baz.rs
diff --git a/tests/run-make/resolve-rename/rmake.rs b/tests/run-make/resolve-rename/rmake.rs
new file mode 100644
index 00000000000..8c6e3c24714
--- /dev/null
+++ b/tests/run-make/resolve-rename/rmake.rs
@@ -0,0 +1,16 @@
+// If a library is compiled with -C extra-filename, the rust compiler
+// will take this into account when searching for libraries. However,
+// if that library is then renamed, the rust compiler should fall back
+// to its regular library location logic and not immediately fail to find
+// the renamed library.
+// See https://github.com/rust-lang/rust/pull/49253
+
+use run_make_support::{rustc, tmp_dir};
+use std::fs;
+fn main() {
+    rustc().extra_filename("-hash").input("foo.rs").run();
+    rustc().input("bar.rs").run();
+    fs::rename(tmp_dir().join("libfoo-hash.rlib"), tmp_dir().join("libfoo-another-hash.rlib"))
+        .unwrap();
+    rustc().input("baz.rs").run();
+}
diff --git a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs
index 563e3aca9ae..b372c25447d 100644
--- a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs
+++ b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs
@@ -1,4 +1,4 @@
-use run_make_support::{htmldocck, rustc, rustdoc, source_path, tmp_dir};
+use run_make_support::{htmldocck, rustc, rustdoc, source_root, tmp_dir};
 use std::fs::read_dir;
 use std::path::Path;
 
diff --git a/tests/run-make/rustdoc-themes/rmake.rs b/tests/run-make/rustdoc-themes/rmake.rs
index e9da4e25940..d6ddd45b4a4 100644
--- a/tests/run-make/rustdoc-themes/rmake.rs
+++ b/tests/run-make/rustdoc-themes/rmake.rs
@@ -1,13 +1,13 @@
 // Test that rustdoc will properly load in a theme file and display it in the theme selector.
 
-use run_make_support::{htmldocck, rustdoc, source_path, tmp_dir};
+use run_make_support::{htmldocck, rustdoc, source_root, tmp_dir};
 
 fn main() {
     let out_dir = tmp_dir().join("rustdoc-themes");
     let test_css = out_dir.join("test.css");
 
     let no_script =
-        std::fs::read_to_string(source_path().join("src/librustdoc/html/static/css/noscript.css"))
+        std::fs::read_to_string(source_root().join("src/librustdoc/html/static/css/noscript.css"))
             .unwrap();
 
     let mut test_content = String::new();
diff --git a/tests/run-make/suspicious-library/Makefile b/tests/run-make/suspicious-library/Makefile
deleted file mode 100644
index 3b5ab3c53a5..00000000000
--- a/tests/run-make/suspicious-library/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) foo.rs -C prefer-dynamic
-	touch $(call DYLIB,foo-something-special)
-	touch $(call DYLIB,foo-something-special2)
-	$(RUSTC) bar.rs
diff --git a/tests/run-make/suspicious-library/rmake.rs b/tests/run-make/suspicious-library/rmake.rs
new file mode 100644
index 00000000000..9e91de70bfc
--- /dev/null
+++ b/tests/run-make/suspicious-library/rmake.rs
@@ -0,0 +1,14 @@
+// This test creates some fake dynamic libraries with nothing inside,
+// and checks if rustc avoids them and successfully compiles as a result.
+
+//@ ignore-cross-compile
+
+use run_make_support::{dynamic_lib, rustc};
+use std::fs::File;
+
+fn main() {
+    rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
+    File::create(dynamic_lib("foo-something-special")).unwrap();
+    File::create(dynamic_lib("foo-something-special2")).unwrap();
+    rustc().input("bar.rs").run();
+}
diff --git a/tests/run-make/windows-binary-no-external-deps/rmake.rs b/tests/run-make/windows-binary-no-external-deps/rmake.rs
index 6704fe04148..ccf2d64c853 100644
--- a/tests/run-make/windows-binary-no-external-deps/rmake.rs
+++ b/tests/run-make/windows-binary-no-external-deps/rmake.rs
@@ -2,15 +2,14 @@
 //! a "hello world" application by setting `PATH` to `C:\Windows\System32`.
 //@ only-windows
 
-use run_make_support::{rustc, tmp_dir};
-use std::env;
+use run_make_support::{env_var, rustc, tmp_dir};
 use std::path::PathBuf;
 use std::process::Command;
 
 fn main() {
     rustc().input("hello.rs").run();
 
-    let windows_dir = env::var("SystemRoot").unwrap();
+    let windows_dir = env_var("SystemRoot");
     let system32: PathBuf = [&windows_dir, "System32"].iter().collect();
     // Note: This does not use the support wrappers so that we can precisely control the PATH
     let exe = tmp_dir().join("hello.exe");
diff --git a/tests/rustdoc/async-fn.rs b/tests/rustdoc/async-fn.rs
index 010263f6ad3..4de5d8575b0 100644
--- a/tests/rustdoc/async-fn.rs
+++ b/tests/rustdoc/async-fn.rs
@@ -79,7 +79,7 @@ struct AsyncFdReadyGuard<'a, T> { x: &'a T }
 
 impl Foo {
     // @has async_fn/struct.Foo.html
-    // @has - '//*[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar ) -> impl Iterator<Item = &usize>'
+    // @has - '//*[@class="method"]' 'pub async fn complicated_lifetimes( &self, context: &impl Bar, ) -> impl Iterator<Item = &usize>'
     pub async fn complicated_lifetimes(&self, context: &impl Bar) -> impl Iterator<Item = &usize> {
         [0].iter()
     }
diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html b/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html
index 29c08c5bd5d..12c6bc214a7 100644
--- a/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html
+++ b/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html
@@ -1,2 +1 @@
-<pre class="rust item-decl"><code>pub fn create(
-) -&gt; <a class="struct" href="struct.Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000.html" title="struct decl_line_wrapping_empty_arg_list::Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000">Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000</a></code></pre>
\ No newline at end of file
+<pre class="rust item-decl"><code>pub fn create() -&gt; <a class="struct" href="struct.Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000.html" title="struct decl_line_wrapping_empty_arg_list::Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000">Padding00000000000000000000000000000000000000000000000000000000000000000000000000000000</a></code></pre>
\ No newline at end of file
diff --git a/tests/rustdoc/decl-trailing-whitespace.declaration.html b/tests/rustdoc/decl-trailing-whitespace.declaration.html
index 59c318c16f3..0cc3f0fa244 100644
--- a/tests/rustdoc/decl-trailing-whitespace.declaration.html
+++ b/tests/rustdoc/decl-trailing-whitespace.declaration.html
@@ -3,7 +3,7 @@
     fn <a href="#tymethod.poll_write" class="fn">poll_write</a>(
         self,
         cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
-        buf: &amp;mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]
+        buf: &amp;mut [<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>],
     ) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
 <span class="item-spacer" />    fn <a href="#tymethod.poll_flush" class="fn">poll_flush</a>(self, cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
 <span class="item-spacer" />    fn <a href="#tymethod.poll_close" class="fn">poll_close</a>(self, cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt;;
@@ -12,6 +12,6 @@
     fn <a href="#method.poll_write_vectored" class="fn">poll_write_vectored</a>(
         self,
         cx: &amp;mut <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="struct" href="{{channel}}/alloc/string/struct.String.html" title="struct alloc::string::String">String</a>&gt;,
-        bufs: &amp;[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>]
+        bufs: &amp;[<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>],
     ) -&gt; <a class="enum" href="{{channel}}/core/option/enum.Option.html" title="enum core::option::Option">Option</a>&lt;<a class="enum" href="{{channel}}/core/result/enum.Result.html" title="enum core::result::Result">Result</a>&lt;<a class="primitive" href="{{channel}}/std/primitive.usize.html">usize</a>, <a class="struct" href="struct.Error.html" title="struct foo::Error">Error</a>&gt;&gt; { ... }
 }</code>
\ No newline at end of file
diff --git a/tests/rustdoc/inline_cross/impl_trait.rs b/tests/rustdoc/inline_cross/impl_trait.rs
index 47e2c9dc76b..19d1673f2eb 100644
--- a/tests/rustdoc/inline_cross/impl_trait.rs
+++ b/tests/rustdoc/inline_cross/impl_trait.rs
@@ -11,7 +11,7 @@ pub use impl_trait_aux::func;
 // @has impl_trait/fn.func2.html
 // @has - '//pre[@class="rust item-decl"]' "func2<T>("
 // @has - '//pre[@class="rust item-decl"]' "_x: impl Deref<Target = Option<T>> + Iterator<Item = T>,"
-// @has - '//pre[@class="rust item-decl"]' "_y: impl Iterator<Item = u8> )"
+// @has - '//pre[@class="rust item-decl"]' "_y: impl Iterator<Item = u8>, )"
 // @!has - '//pre[@class="rust item-decl"]' 'where'
 pub use impl_trait_aux::func2;
 
diff --git a/tests/rustdoc/line-breaks.rs b/tests/rustdoc/line-breaks.rs
index 21aa3a03ce4..0f760d51973 100644
--- a/tests/rustdoc/line-breaks.rs
+++ b/tests/rustdoc/line-breaks.rs
@@ -6,7 +6,7 @@ use std::ops::Add;
 // @matches foo/fn.function_with_a_really_long_name.html '//*[@class="rust item-decl"]//code' "\
 //     function_with_a_really_long_name\(\n\
 //    \    parameter_one: i32,\n\
-//    \    parameter_two: i32\n\
+//    \    parameter_two: i32,\n\
 //    \) -> Option<i32>$"
 pub fn function_with_a_really_long_name(parameter_one: i32, parameter_two: i32) -> Option<i32> {
     Some(parameter_one + parameter_two)
diff --git a/tests/rustdoc/reexports-priv.rs b/tests/rustdoc/reexports-priv.rs
index 1eee262d233..97318a01410 100644
--- a/tests/rustdoc/reexports-priv.rs
+++ b/tests/rustdoc/reexports-priv.rs
@@ -98,7 +98,7 @@ pub mod outer {
         pub use reexports::foo;
         // @has 'foo/outer/inner/fn.foo_crate.html' '//pre[@class="rust item-decl"]' 'pub(crate) fn foo_crate()'
         pub(crate) use reexports::foo_crate;
-        // @has 'foo/outer/inner/fn.foo_super.html' '//pre[@class="rust item-decl"]' 'pub(in outer) fn foo_super( )'
+        // @has 'foo/outer/inner/fn.foo_super.html' '//pre[@class="rust item-decl"]' 'pub(in outer) fn foo_super()'
         pub(super) use::reexports::foo_super;
         // @!has 'foo/outer/inner/fn.foo_self.html'
         pub(self) use reexports::foo_self;
diff --git a/tests/run-make-fulldeps/obtain-borrowck/test.rs b/tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs
index f7b4b41feaf..7213e06792a 100644
--- a/tests/run-make-fulldeps/obtain-borrowck/test.rs
+++ b/tests/ui-fulldeps/auxiliary/obtain-borrowck-input.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)]
+
 trait X {
     fn provided(&self) -> usize {
         5
diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs
index 07466440aab..f273bbc99a8 100644
--- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs
@@ -1,3 +1,5 @@
+//@ edition: 2021
+
 #![feature(rustc_private)]
 #![deny(warnings)]
 
@@ -78,11 +80,11 @@ impl CodegenBackend for TheBackend {
             match output_name {
                 OutFileName::Real(ref path) => {
                     let mut out_file = ::std::fs::File::create(path).unwrap();
-                    write!(out_file, "This has been \"compiled\" successfully.").unwrap();
+                    writeln!(out_file, "This has been 'compiled' successfully.").unwrap();
                 }
                 OutFileName::Stdout => {
                     let mut stdout = std::io::stdout();
-                    write!(stdout, "This has been \"compiled\" successfully.").unwrap();
+                    writeln!(stdout, "This has been 'compiled' successfully.").unwrap();
                 }
             }
         }
diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout
new file mode 100644
index 00000000000..4d58fd503d0
--- /dev/null
+++ b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout
@@ -0,0 +1,4 @@
+$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so
+
+$DIR/hotplug.rs:
+$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so:
diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout
new file mode 100644
index 00000000000..48b7534d8fa
--- /dev/null
+++ b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout
@@ -0,0 +1,3 @@
+$TEST_BUILD_DIR/codegen-backend/hotplug.dep/libhotplug.rlib: $DIR/hotplug.rs
+
+$DIR/hotplug.rs:
diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.normal.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.normal.stdout
new file mode 100644
index 00000000000..1aa032de9e4
--- /dev/null
+++ b/tests/ui-fulldeps/codegen-backend/hotplug.normal.stdout
@@ -0,0 +1 @@
+This has been 'compiled' successfully.
diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.rs b/tests/ui-fulldeps/codegen-backend/hotplug.rs
new file mode 100644
index 00000000000..dc0fb3f9efd
--- /dev/null
+++ b/tests/ui-fulldeps/codegen-backend/hotplug.rs
@@ -0,0 +1,20 @@
+//@ edition: 2021
+//@ build-pass
+//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
+
+//@ aux-codegen-backend: the_backend.rs
+//@ normalize-stdout-test: "libthe_backend.dylib" -> "libthe_backend.so"
+//@ normalize-stdout-test: "the_backend.dll" -> "libthe_backend.so"
+
+//@ revisions: normal dep bindep
+//@ compile-flags: --crate-type=lib
+//@ [normal] compile-flags: --emit=link=-
+//@ [dep]    compile-flags: --emit=link,dep-info=-
+//@ [bindep] compile-flags: --emit=link,dep-info=- -Zbinary-dep-depinfo
+
+#![feature(no_core)]
+#![no_core]
+
+// This test both exists as a check that -Zcodegen-backend is capable of loading external codegen
+// backends and that this external codegen backend is only included in the dep info if
+// -Zbinary-dep-depinfo is used.
diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
index ef70e64ed7e..99cb5fc5aa1 100644
--- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -16,7 +16,7 @@ extern crate rustc_span;
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
 
-use rustc_parse::new_parser_from_file;
+use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use std::path::Path;
 
@@ -34,6 +34,6 @@ fn parse() {
 
     let path = Path::new(file!());
     let path = path.canonicalize().unwrap();
-    let mut parser = new_parser_from_file(&psess, &path, None);
+    let mut parser = unwrap_or_emit_fatal(new_parser_from_file(&psess, &path, None));
     let _ = parser.parse_crate_mod();
 }
diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/ui-fulldeps/obtain-borrowck.rs
index e67ec8690f8..e6c703addd9 100644
--- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs
+++ b/tests/ui-fulldeps/obtain-borrowck.rs
@@ -1,3 +1,10 @@
+//@ edition: 2021
+//@ run-pass
+//@ check-run-results
+//@ run-flags: --sysroot {{sysroot-base}} --edition=2021 {{src-base}}/auxiliary/obtain-borrowck-input.rs
+//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
+// ignore-tidy-linelength
+
 #![feature(rustc_private)]
 
 //! This program implements a rustc driver that retrieves MIR bodies with
diff --git a/tests/run-make-fulldeps/obtain-borrowck/output.stdout b/tests/ui-fulldeps/obtain-borrowck.run.stdout
index e011622e6b2..e011622e6b2 100644
--- a/tests/run-make-fulldeps/obtain-borrowck/output.stdout
+++ b/tests/ui-fulldeps/obtain-borrowck.run.stdout
diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
index 2b1fec94387..762ad0b79ec 100644
--- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -36,7 +36,7 @@ use rustc_ast::mut_visit::{visit_clobber, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_ast_pretty::pprust;
-use rustc_parse::new_parser_from_source_str;
+use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
@@ -46,8 +46,9 @@ use thin_vec::{thin_vec, ThinVec};
 fn parse_expr(psess: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
 
-    let mut p =
-        new_parser_from_source_str(psess, FileName::Custom(src_as_string.clone()), src_as_string);
+    let mut p = unwrap_or_emit_fatal(
+        new_parser_from_source_str(psess, FileName::Custom(src_as_string.clone()), src_as_string)
+    );
     p.parse_expr().map_err(|e| e.cancel()).ok()
 }
 
diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/ui-fulldeps/run-compiler-twice.rs
index 327c99a02c6..02748626723 100644
--- a/tests/run-make-fulldeps/issue-19371/foo.rs
+++ b/tests/ui-fulldeps/run-compiler-twice.rs
@@ -1,3 +1,13 @@
+//@ edition: 2021
+//@ run-pass
+//@ run-flags: {{sysroot-base}} {{target-linker}}
+//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
+
+// Regression test for <https://github.com/rust-lang/rust/issues/19371>.
+//
+// This test ensures that `compile_input` can be called twice in one task
+// without causing a panic.
+
 #![feature(rustc_private)]
 
 extern crate rustc_driver;
@@ -5,12 +15,12 @@ extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use std::path::{Path, PathBuf};
+
 use rustc_interface::interface;
 use rustc_session::config::{Input, Options, OutFileName, OutputType, OutputTypes};
 use rustc_span::FileName;
 
-use std::path::PathBuf;
-
 fn main() {
     let src = r#"
     fn main() {}
@@ -18,28 +28,28 @@ fn main() {
 
     let args: Vec<String> = std::env::args().collect();
 
-    if args.len() < 4 {
-        panic!("expected rustc path");
+    if args.len() < 2 {
+        panic!("expected sysroot (and optional linker)");
     }
 
-    let tmpdir = PathBuf::from(&args[1]);
-
-    let mut sysroot = PathBuf::from(&args[3]);
-    sysroot.pop();
-    sysroot.pop();
+    let sysroot = PathBuf::from(&args[1]);
+    let linker = args.get(2).map(PathBuf::from);
 
-    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
+    // compiletest sets the current dir to `output_base_dir` when running.
+    let tmpdir = std::env::current_dir().unwrap().join("tmp");
+    std::fs::create_dir_all(&tmpdir).unwrap();
 
-    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
+    compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref());
+    compile(src.to_string(), tmpdir.join("out"), sysroot.clone(), linker.as_deref());
 }
 
-fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
+fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path>) {
     let mut opts = Options::default();
     opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
     opts.maybe_sysroot = Some(sysroot);
 
-    if let Ok(linker) = std::env::var("RUSTC_LINKER") {
-        opts.cg.linker = Some(linker.into());
+    if let Some(linker) = linker {
+        opts.cg.linker = Some(linker.to_owned());
     }
 
     let name = FileName::anon_source_code(&code);
diff --git a/tests/ui/async-await/no-async-const.rs b/tests/ui/async-await/no-async-const.rs
index c5485ebc9b6..38a5df3576b 100644
--- a/tests/ui/async-await/no-async-const.rs
+++ b/tests/ui/async-await/no-async-const.rs
@@ -2,5 +2,5 @@
 //@ compile-flags: --crate-type lib
 
 pub async const fn x() {}
-//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
+//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
 //~| ERROR functions cannot be both `const` and `async`
diff --git a/tests/ui/async-await/no-async-const.stderr b/tests/ui/async-await/no-async-const.stderr
index 524d778c09b..d692ba8f473 100644
--- a/tests/ui/async-await/no-async-const.stderr
+++ b/tests/ui/async-await/no-async-const.stderr
@@ -1,10 +1,10 @@
-error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
+error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
   --> $DIR/no-async-const.rs:4:11
    |
 LL | pub async const fn x() {}
    |     ------^^^^^
    |     |     |
-   |     |     expected one of `extern`, `fn`, or `unsafe`
+   |     |     expected one of `extern`, `fn`, `safe`, or `unsafe`
    |     help: `const` must come before `async`: `const async`
    |
    = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr
new file mode 100644
index 00000000000..44f76f321cf
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr
@@ -0,0 +1,21 @@
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
+   |
+LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr
new file mode 100644
index 00000000000..44f76f321cf
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr
@@ -0,0 +1,21 @@
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
+   |
+LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
+   |
+LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
+   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
new file mode 100644
index 00000000000..8dc02b081c5
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
@@ -0,0 +1,31 @@
+// Opaque types never cover type parameters.
+
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
+
+//@ aux-crate:foreign=parametrized-trait.rs
+//@ edition:2021
+
+#![feature(type_alias_impl_trait)]
+
+type Identity<T> = impl Sized;
+
+fn define_identity<T>(x: T) -> Identity<T> {
+    x
+}
+
+impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
+//~^ ERROR type parameter `T` must be covered by another type
+
+type Opaque<T> = impl Sized;
+
+fn define_local<T>() -> Opaque<T> {
+    Local
+}
+
+impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
+//~^ ERROR type parameter `T` must be covered by another type
+
+struct Local;
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs
index 05bd0d91168..c55f3dcec68 100644
--- a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs
+++ b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.rs
@@ -1,4 +1,5 @@
 //@ edition:2021
+//@ check-pass
 // issues rust-lang/rust#111911
 // test for ICE opaque type with non-universal region substs
 
@@ -6,8 +7,6 @@
 #![allow(incomplete_features)]
 
 pub async fn foo<const X: &'static str>() {}
-//~^ ERROR const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-//~| ERROR const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
 fn bar<const N: &'static u8>() -> impl Sized {}
 
 pub fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr b/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr
deleted file mode 100644
index 1bdb9cd9501..00000000000
--- a/tests/ui/const-generics/adt_const_params/opaque_type_with_non-universal_region_substs_ice-111911.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error: const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/opaque_type_with_non-universal_region_substs_ice-111911.rs:8:43
-   |
-LL | pub async fn foo<const X: &'static str>() {}
-   |                                           ^^
-
-error: const parameter `X` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/opaque_type_with_non-universal_region_substs_ice-111911.rs:8:43
-   |
-LL | pub async fn foo<const X: &'static str>() {}
-   |                                           ^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
index 2bfa604fc56..49cf4281323 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
@@ -6,6 +6,16 @@ LL | pub struct Dependent<T, const X: T>([(); X]);
    |
    = note: type parameters may not be used in the type of const parameters
 
-error: aborting due to 1 previous error
+error[E0392]: type parameter `T` is never used
+  --> $DIR/const-param-type-depends-on-type-param.rs:11:22
+   |
+LL | pub struct Dependent<T, const X: T>([(); X]);
+   |                      ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0770`.
+Some errors have detailed explanations: E0392, E0770.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
index 2bfa604fc56..49cf4281323 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
@@ -6,6 +6,16 @@ LL | pub struct Dependent<T, const X: T>([(); X]);
    |
    = note: type parameters may not be used in the type of const parameters
 
-error: aborting due to 1 previous error
+error[E0392]: type parameter `T` is never used
+  --> $DIR/const-param-type-depends-on-type-param.rs:11:22
+   |
+LL | pub struct Dependent<T, const X: T>([(); X]);
+   |                      ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0770`.
+Some errors have detailed explanations: E0392, E0770.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.rs b/tests/ui/const-generics/const-param-type-depends-on-type-param.rs
index 1583fc4ee6c..5503b08930b 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.rs
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.rs
@@ -10,5 +10,6 @@
 
 pub struct Dependent<T, const X: T>([(); X]);
 //~^ ERROR: the type of const parameters must not depend on other generic parameters
+//~| ERROR: type parameter `T` is never used
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs
new file mode 100644
index 00000000000..29ad935c014
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs
@@ -0,0 +1,21 @@
+//@ compile-flags: -Znext-solver=coherence
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub struct A<const z: [usize; x]> {}
+//~^ ERROR: cannot find value `x` in this scope
+//~| ERROR: `[usize; x]` is forbidden as the type of a const generic parameter
+
+impl A<2> {
+    //~^ ERROR: mismatched types
+    pub const fn B() {}
+    //~^ ERROR: duplicate definitions
+}
+
+impl A<2> {
+    //~^ ERROR: mismatched types
+    pub const fn B() {}
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr
new file mode 100644
index 00000000000..0e40255bcf5
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr
@@ -0,0 +1,45 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/error_in_ty.rs:6:31
+   |
+LL | pub struct A<const z: [usize; x]> {}
+   |                    -          ^ help: a const parameter with a similar name exists: `z`
+   |                    |
+   |                    similarly named const parameter `z` defined here
+
+error: `[usize; x]` is forbidden as the type of a const generic parameter
+  --> $DIR/error_in_ty.rs:6:23
+   |
+LL | pub struct A<const z: [usize; x]> {}
+   |                       ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/error_in_ty.rs:10:8
+   |
+LL | impl A<2> {
+   |        ^ expected `[usize; x]`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/error_in_ty.rs:16:8
+   |
+LL | impl A<2> {
+   |        ^ expected `[usize; x]`, found integer
+
+error[E0592]: duplicate definitions with name `B`
+  --> $DIR/error_in_ty.rs:12:5
+   |
+LL |     pub const fn B() {}
+   |     ^^^^^^^^^^^^^^^^ duplicate definitions for `B`
+...
+LL |     pub const fn B() {}
+   |     ---------------- other definition for `B`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0308, E0425, E0592.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
index af17a37bf23..b662939c27e 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
@@ -9,9 +9,10 @@ pub trait Trait {
     fn assoc_fn() -> Self::AssocTy;
 }
 
-impl<const U: u8> Trait for Const<U> // OK, trait impl predicates
+impl<const U: u8> Trait for Const<U>
 where
-    Const<{ my_const_fn(U) }>: ,
+    // OK, trait impl predicates
+    Const<{ my_const_fn(U) }>:,
 {
     type AssocTy = Const<{ my_const_fn(U) }>;
     //~^ ERROR private type
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
index df0d43bef87..98dac313be4 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
@@ -1,5 +1,5 @@
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/eval-privacy.rs:16:5
+  --> $DIR/eval-privacy.rs:17:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -8,7 +8,7 @@ LL | const fn my_const_fn(val: u8) -> u8 {
    | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
 
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/eval-privacy.rs:16:5
+  --> $DIR/eval-privacy.rs:17:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr
index b6460e0017f..05e847cf4c8 100644
--- a/tests/ui/const-generics/issues/issue-71381.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.full.stderr
@@ -7,13 +7,25 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:23:40
+  --> $DIR/issue-71381.rs:24:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
    |
    = note: type parameters may not be used in the type of const parameters
 
-error: aborting due to 2 previous errors
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
+  --> $DIR/issue-71381.rs:17:9
+   |
+LL |         self.0 = Self::trampiline::<Args, IDX, FN> as _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
+   |
+help: consider changing this to be a mutable reference
+   |
+LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&mut self) {
+   |                                                                                         ~~~~~~~~~
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0770`.
+Some errors have detailed explanations: E0594, E0770.
+For more information about an error, try `rustc --explain E0594`.
diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr
index e16d3b7a8a4..1c30e885d1b 100644
--- a/tests/ui/const-generics/issues/issue-71381.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.min.stderr
@@ -7,7 +7,7 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
-  --> $DIR/issue-71381.rs:23:40
+  --> $DIR/issue-71381.rs:24:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
@@ -23,13 +23,25 @@ LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
    = note: the only supported types are integers, `bool` and `char`
 
 error: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:23:19
+  --> $DIR/issue-71381.rs:24:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
 
-error: aborting due to 4 previous errors
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
+  --> $DIR/issue-71381.rs:17:9
+   |
+LL |         self.0 = Self::trampiline::<Args, IDX, FN> as _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
+   |
+help: consider changing this to be a mutable reference
+   |
+LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&mut self) {
+   |                                                                                         ~~~~~~~~~
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0770`.
+Some errors have detailed explanations: E0594, E0770.
+For more information about an error, try `rustc --explain E0594`.
diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs
index e472ef31fcd..166b724a7a3 100644
--- a/tests/ui/const-generics/issues/issue-71381.rs
+++ b/tests/ui/const-generics/issues/issue-71381.rs
@@ -15,6 +15,7 @@ impl Test {
         //~^ ERROR: the type of const parameters must not depend on other generic parameters
         //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden
         self.0 = Self::trampiline::<Args, IDX, FN> as _
+        //~^ ERROR: cannot assign to `self.0`
     }
 
     unsafe extern "C" fn trampiline<
diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.rs b/tests/ui/const-generics/not_wf_param_in_rpitit.rs
new file mode 100644
index 00000000000..5471dc9022f
--- /dev/null
+++ b/tests/ui/const-generics/not_wf_param_in_rpitit.rs
@@ -0,0 +1,14 @@
+//@ edition:2021
+
+trait Trait<const N: Trait = bar> {
+    //~^ ERROR: cannot find value `bar` in this scope
+    //~| ERROR: cycle detected when computing type of `Trait::N`
+    //~| ERROR: the trait `Trait` cannot be made into an object
+    //~| ERROR: the trait `Trait` cannot be made into an object
+    //~| ERROR: the trait `Trait` cannot be made into an object
+    //~| ERROR: `(dyn Trait<{const error}> + 'static)` is forbidden as the type of a const generic parameter
+    //~| ERROR: trait objects must include the `dyn` keyword
+    async fn a() {}
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
new file mode 100644
index 00000000000..9095948d22b
--- /dev/null
+++ b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr
@@ -0,0 +1,113 @@
+error[E0425]: cannot find value `bar` in this scope
+  --> $DIR/not_wf_param_in_rpitit.rs:3:30
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |                              ^^^ not found in this scope
+
+error[E0391]: cycle detected when computing type of `Trait::N`
+  --> $DIR/not_wf_param_in_rpitit.rs:3:22
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |                      ^^^^^
+   |
+   = note: ...which immediately requires computing type of `Trait::N` again
+note: cycle used when computing explicit predicates of trait `Trait`
+  --> $DIR/not_wf_param_in_rpitit.rs:3:1
+   |
+LL | trait Trait<const N: Trait = bar> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/not_wf_param_in_rpitit.rs:3:22
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |                      ^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/not_wf_param_in_rpitit.rs:11:14
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |       ----- this trait cannot be made into an object...
+...
+LL |     async fn a() {}
+   |              ^ ...because associated function `a` has no `self` parameter
+help: consider turning `a` into a method by giving it a `&self` argument
+   |
+LL |     async fn a(&self) {}
+   |                +++++
+help: alternatively, consider constraining `a` so it does not apply to trait objects
+   |
+LL |     async fn a() where Self: Sized {}
+   |                  +++++++++++++++++
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/not_wf_param_in_rpitit.rs:3:13
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/not_wf_param_in_rpitit.rs:11:14
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |       ----- this trait cannot be made into an object...
+...
+LL |     async fn a() {}
+   |              ^ ...because associated function `a` has no `self` parameter
+help: consider turning `a` into a method by giving it a `&self` argument
+   |
+LL |     async fn a(&self) {}
+   |                +++++
+help: alternatively, consider constraining `a` so it does not apply to trait objects
+   |
+LL |     async fn a() where Self: Sized {}
+   |                  +++++++++++++++++
+
+error: `(dyn Trait<{const error}> + 'static)` is forbidden as the type of a const generic parameter
+  --> $DIR/not_wf_param_in_rpitit.rs:3:22
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |                      ^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/not_wf_param_in_rpitit.rs:3:13
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/not_wf_param_in_rpitit.rs:11:14
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |       ----- this trait cannot be made into an object...
+...
+LL |     async fn a() {}
+   |              ^ ...because associated function `a` has no `self` parameter
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider turning `a` into a method by giving it a `&self` argument
+   |
+LL |     async fn a(&self) {}
+   |                +++++
+help: alternatively, consider constraining `a` so it does not apply to trait objects
+   |
+LL |     async fn a() where Self: Sized {}
+   |                  +++++++++++++++++
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/not_wf_param_in_rpitit.rs:3:22
+   |
+LL | trait Trait<const N: Trait = bar> {
+   |                      ^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL | trait Trait<const N: dyn Trait = bar> {
+   |                      +++
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0038, E0391, E0425, E0782.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr
index 1b0d1ea50d0..b76ec10bd3f 100644
--- a/tests/ui/const-generics/transmute-fail.stderr
+++ b/tests/ui/const-generics/transmute-fail.stderr
@@ -13,7 +13,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
 LL |     std::mem::transmute(v)
    |     ^^^^^^^^^^^^^^^^^^^
    |
-   = note: source type: `[[u32; H]; W]` (this type does not have a fixed size)
+   = note: source type: `[[u32; H]; W]` (size can vary because of [u32; H])
    = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W])
 
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
diff --git a/tests/ui/const-generics/type_not_in_scope.rs b/tests/ui/const-generics/type_not_in_scope.rs
index 917abaed15e..1eb265d74d1 100644
--- a/tests/ui/const-generics/type_not_in_scope.rs
+++ b/tests/ui/const-generics/type_not_in_scope.rs
@@ -5,6 +5,7 @@ impl X {
     }
 }
 fn getn<const N: cfg_attr>() -> [u8; N] {}
-//~^ ERROR expected type, found built-in attribute `cfg_attr`
+//~^ ERROR: expected type, found built-in attribute `cfg_attr`
+//~| ERROR: mismatched types
 
 fn main() {}
diff --git a/tests/ui/const-generics/type_not_in_scope.stderr b/tests/ui/const-generics/type_not_in_scope.stderr
index 5eb81ca0522..5f45550a627 100644
--- a/tests/ui/const-generics/type_not_in_scope.stderr
+++ b/tests/ui/const-generics/type_not_in_scope.stderr
@@ -10,7 +10,15 @@ error[E0573]: expected type, found built-in attribute `cfg_attr`
 LL | fn getn<const N: cfg_attr>() -> [u8; N] {}
    |                  ^^^^^^^^ not a type
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/type_not_in_scope.rs:7:33
+   |
+LL | fn getn<const N: cfg_attr>() -> [u8; N] {}
+   |    ----                         ^^^^^^^ expected `[u8; N]`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0412, E0573.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0308, E0412, E0573.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/issue-103790.rs b/tests/ui/consts/issue-103790.rs
index 5d130821dc8..d19115ede74 100644
--- a/tests/ui/consts/issue-103790.rs
+++ b/tests/ui/consts/issue-103790.rs
@@ -5,7 +5,7 @@ struct S<const S: (), const S: S = { S }>;
 //~^ ERROR the name `S` is already used for a generic parameter in this item's generic parameters
 //~| ERROR missing generics for struct `S`
 //~| ERROR cycle detected when computing type of `S::S`
-//~| ERROR cycle detected when computing type of `S`
 //~| ERROR `()` is forbidden as the type of a const generic parameter
+//~| ERROR `S<{const error}, {const error}>` is forbidden as the type of a const generic parameter
 
 fn main() {}
diff --git a/tests/ui/consts/issue-103790.stderr b/tests/ui/consts/issue-103790.stderr
index eecaf5ff63a..c671f078cb5 100644
--- a/tests/ui/consts/issue-103790.stderr
+++ b/tests/ui/consts/issue-103790.stderr
@@ -29,37 +29,30 @@ LL | struct S<const S: (), const S: S = { S }>;
    |                                ^
    |
    = note: ...which immediately requires computing type of `S::S` again
-note: cycle used when computing type of `S`
+note: cycle used when computing explicit predicates of `S`
   --> $DIR/issue-103790.rs:4:1
    |
 LL | struct S<const S: (), const S: S = { S }>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0391]: cycle detected when computing type of `S`
-  --> $DIR/issue-103790.rs:4:1
+error: `()` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-103790.rs:4:19
    |
 LL | struct S<const S: (), const S: S = { S }>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   ^^
    |
-note: ...which requires computing type of `S::S`...
-  --> $DIR/issue-103790.rs:4:32
+   = note: the only supported types are integers, `bool` and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
    |
-LL | struct S<const S: (), const S: S = { S }>;
-   |                                ^
-   = note: ...which again requires computing type of `S`, completing the cycle
-note: cycle used when checking that `S` is well-formed
-  --> $DIR/issue-103790.rs:4:1
+LL + #![feature(adt_const_params)]
    |
-LL | struct S<const S: (), const S: S = { S }>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: `()` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-103790.rs:4:19
+error: `S<{const error}, {const error}>` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-103790.rs:4:32
    |
 LL | struct S<const S: (), const S: S = { S }>;
-   |                   ^^
+   |                                ^
    |
    = note: the only supported types are integers, `bool` and `char`
 help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
diff --git a/tests/ui/coroutine/async_gen_fn.none.stderr b/tests/ui/coroutine/async_gen_fn.none.stderr
index 7950251a75d..047f4d82486 100644
--- a/tests/ui/coroutine/async_gen_fn.none.stderr
+++ b/tests/ui/coroutine/async_gen_fn.none.stderr
@@ -7,11 +7,11 @@ LL | async gen fn foo() {}
    = help: pass `--edition 2021` to `rustc`
    = note: for more on editions, read https://doc.rust-lang.org/edition-guide
 
-error: expected one of `extern`, `fn`, or `unsafe`, found `gen`
+error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found `gen`
   --> $DIR/async_gen_fn.rs:4:7
    |
 LL | async gen fn foo() {}
-   |       ^^^ expected one of `extern`, `fn`, or `unsafe`
+   |       ^^^ expected one of `extern`, `fn`, `safe`, or `unsafe`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/coroutine/async_gen_fn.rs b/tests/ui/coroutine/async_gen_fn.rs
index 9e96ecf3ea6..e8be0434b9e 100644
--- a/tests/ui/coroutine/async_gen_fn.rs
+++ b/tests/ui/coroutine/async_gen_fn.rs
@@ -3,7 +3,7 @@
 
 async gen fn foo() {}
 //[none]~^ ERROR: `async fn` is not permitted in Rust 2015
-//[none]~| ERROR: expected one of `extern`, `fn`, or `unsafe`, found `gen`
+//[none]~| ERROR: expected one of `extern`, `fn`, `safe`, or `unsafe`, found `gen`
 //[e2024]~^^^ ERROR: gen blocks are experimental
 
 fn main() {}
diff --git a/tests/ui/coroutine/gen_fn.none.stderr b/tests/ui/coroutine/gen_fn.none.stderr
index c5342ee22e6..590210641ae 100644
--- a/tests/ui/coroutine/gen_fn.none.stderr
+++ b/tests/ui/coroutine/gen_fn.none.stderr
@@ -1,8 +1,8 @@
-error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found `gen`
+error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen`
   --> $DIR/gen_fn.rs:4:1
    |
 LL | gen fn foo() {}
-   | ^^^ expected one of 9 possible tokens
+   | ^^^ expected one of 10 possible tokens
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coroutine/gen_fn.rs b/tests/ui/coroutine/gen_fn.rs
index 3228650f415..d47b7e576d0 100644
--- a/tests/ui/coroutine/gen_fn.rs
+++ b/tests/ui/coroutine/gen_fn.rs
@@ -2,7 +2,7 @@
 //@[e2024] compile-flags: --edition 2024 -Zunstable-options
 
 gen fn foo() {}
-//[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found `gen`
+//[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen`
 //[e2024]~^^ ERROR: gen blocks are experimental
 
 fn main() {}
diff --git a/tests/ui/cross-crate/auxiliary/static_init_aux.rs b/tests/ui/cross-crate/auxiliary/static_init_aux.rs
index dca708733b9..832cee8d4d4 100644
--- a/tests/ui/cross-crate/auxiliary/static_init_aux.rs
+++ b/tests/ui/cross-crate/auxiliary/static_init_aux.rs
@@ -3,6 +3,12 @@ pub static F: fn() = f;
 pub static G: fn() = G0;
 pub static H: &(dyn Fn() + Sync) = &h;
 pub static I: fn() = Helper(j).mk();
+pub static K: fn() -> fn() = {
+    #[inline(never)]
+    fn k() {}
+    #[inline(always)]
+    || -> fn() { k }
+};
 
 static X: u32 = 42;
 static G0: fn() = g;
diff --git a/tests/ui/cross-crate/static-init.rs b/tests/ui/cross-crate/static-init.rs
index c4697a1d010..f8003856c5c 100644
--- a/tests/ui/cross-crate/static-init.rs
+++ b/tests/ui/cross-crate/static-init.rs
@@ -8,6 +8,7 @@ static F: fn() = aux::F;
 static G: fn() = aux::G;
 static H: &(dyn Fn() + Sync) = aux::H;
 static I: fn() = aux::I;
+static K: fn() -> fn() = aux::K;
 
 fn v() -> *const u32 {
     V
@@ -19,4 +20,5 @@ fn main() {
     G();
     H();
     I();
+    K()();
 }
diff --git a/tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs b/tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
index 86117965016..3322660d1a8 100644
--- a/tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
+++ b/tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs
@@ -1,5 +1,6 @@
 //@ build-pass
 //@ only-linux
+//@ ignore-riscv64 On this platform `-Csplit-debuginfo=unpacked` is unstable, see #120518
 //
 //@ compile-flags: -g --emit=llvm-ir -Csplit-debuginfo=unpacked
 //
diff --git a/tests/ui/derives/derive-hrtb-for-bare-fn-field-with-lifetime.rs b/tests/ui/derives/derive-hrtb-for-bare-fn-field-with-lifetime.rs
new file mode 100644
index 00000000000..b8a42be6832
--- /dev/null
+++ b/tests/ui/derives/derive-hrtb-for-bare-fn-field-with-lifetime.rs
@@ -0,0 +1,13 @@
+//@ run-pass
+// Issue #122622: `#[derive(Clone)]` should work for HRTB function type taking an associated type
+#![allow(dead_code)]
+trait SomeTrait {
+    type SomeType<'a>;
+}
+
+#[derive(Clone)]
+struct Foo<T: SomeTrait> {
+    x: for<'a> fn(T::SomeType<'a>)
+}
+
+fn main() {}
diff --git a/tests/ui/extern-flag/empty-extern-arg.stderr b/tests/ui/extern-flag/empty-extern-arg.stderr
index 6ad3effe0e2..2785b12a0ae 100644
--- a/tests/ui/extern-flag/empty-extern-arg.stderr
+++ b/tests/ui/extern-flag/empty-extern-arg.stderr
@@ -1,6 +1,13 @@
 error: extern location for std does not exist: 
 
+error: `#[panic_handler]` function required, but not found
+
+error: unwinding panics are not supported without std
+   |
+   = help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
+   = note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
+
 error: requires `sized` lang_item
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs b/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs
deleted file mode 100644
index ed5db56e0e8..00000000000
--- a/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-pub fn main() {
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types [E0308]
-        let _: u32 = x;
-    }
-    if let Some(&Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types [E0308]
-        let _: u32 = x;
-    }
-    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types [E0308]
-        let _: u32 = x;
-    }
-}
diff --git a/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr b/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr
deleted file mode 100644
index 0f0051325cd..00000000000
--- a/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr
+++ /dev/null
@@ -1,49 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
-   |
-LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
-   |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
-   |                      |
-   |                      expected integer, found `&_`
-   |
-   = note:   expected type `{integer}`
-           found reference `&_`
-help: consider removing `&` from the pattern
-   |
-LL |     if let Some(Some(x)) = &Some(&Some(0)) {
-   |                      ~
-
-error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
-   |
-LL |     if let Some(&Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&_`
-   |
-   = note:   expected enum `Option<{integer}>`
-           found reference `&_`
-
-error[E0308]: mismatched types
-  --> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
-   |
-LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
-   |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
-   |                      |
-   |                      expected integer, found `&mut _`
-   |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
-   |
-LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
-   |                      ^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
-   |                      ~
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
new file mode 100644
index 00000000000..eab134a4a4d
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.rs
@@ -0,0 +1,5 @@
+unsafe extern "C" {
+    //~^ ERROR extern block cannot be declared unsafe
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr
new file mode 100644
index 00000000000..7e9b199a2db
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr
@@ -0,0 +1,8 @@
+error: extern block cannot be declared unsafe
+  --> $DIR/feature-gate-unsafe-extern-blocks.rs:1:1
+   |
+LL | unsafe extern "C" {
+   | ^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.rs b/tests/ui/impl-header-lifetime-elision/assoc-type.rs
index b0089a37aa0..db3c416540f 100644
--- a/tests/ui/impl-header-lifetime-elision/assoc-type.rs
+++ b/tests/ui/impl-header-lifetime-elision/assoc-type.rs
@@ -9,7 +9,7 @@ trait MyTrait {
 
 impl MyTrait for &i32 {
     type Output = &i32;
-    //~^ ERROR `&` without an explicit lifetime name cannot be used here
+    //~^ ERROR 11:19: 11:20: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
 }
 
 impl MyTrait for &u32 {
diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr
index c4f27e0b80e..e650eeca48a 100644
--- a/tests/ui/impl-header-lifetime-elision/assoc-type.stderr
+++ b/tests/ui/impl-header-lifetime-elision/assoc-type.stderr
@@ -1,8 +1,8 @@
-error[E0637]: `&` without an explicit lifetime name cannot be used here
+error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
   --> $DIR/assoc-type.rs:11:19
    |
 LL |     type Output = &i32;
-   |                   ^ explicit lifetime name needed here
+   |                   ^ this lifetime must come from the implemented type
 
 error[E0637]: `'_` cannot be used here
   --> $DIR/assoc-type.rs:16:20
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
new file mode 100644
index 00000000000..65e90c1ca53
--- /dev/null
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.rs
@@ -0,0 +1,38 @@
+// This test should never pass!
+
+#![feature(type_alias_impl_trait)]
+
+pub trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+pub struct MyTy<'a, 'b>(Option<*mut &'a &'b ()>);
+unsafe impl Send for MyTy<'_, 'static> {}
+
+pub mod step1 {
+    use super::*;
+    pub type Step1<'a, 'b: 'a> = impl Sized + Captures<'b> + 'a;
+    pub fn step1<'a, 'b: 'a>() -> Step1<'a, 'b> {
+        MyTy::<'a, 'b>(None)
+    }
+}
+
+pub mod step2 {
+    pub type Step2<'a> = impl Send + 'a;
+
+    // Although `Step2` is WF at the definition site, it's not WF in its
+    // declaration site (above). We check this in `check_opaque_meets_bounds`,
+    // which must remain sound.
+    pub fn step2<'a, 'b: 'a>() -> Step2<'a>
+        where crate::step1::Step1<'a, 'b>: Send
+    {
+        crate::step1::step1::<'a, 'b>()
+        //~^ ERROR hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
+    }
+}
+
+fn step3<'a, 'b>() {
+    fn is_send<T: Send>() {}
+    is_send::<crate::step2::Step2::<'a>>();
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
new file mode 100644
index 00000000000..58d7f9959d3
--- /dev/null
+++ b/tests/ui/impl-trait/alias-liveness/tait-hidden-erased-unsoundness-2.stderr
@@ -0,0 +1,15 @@
+error[E0700]: hidden type for `Step2<'a>` captures lifetime that does not appear in bounds
+  --> $DIR/tait-hidden-erased-unsoundness-2.rs:28:9
+   |
+LL |     pub type Step2<'a> = impl Send + 'a;
+   |                          -------------- opaque type defined here
+...
+LL |     pub fn step2<'a, 'b: 'a>() -> Step2<'a>
+   |                      -- hidden type `Step1<'a, 'b>` captures the lifetime `'b` as defined here
+...
+LL |         crate::step1::step1::<'a, 'b>()
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/imports/cycle-import-in-diff-module-0.rs b/tests/ui/imports/cycle-import-in-diff-module-0.rs
new file mode 100644
index 00000000000..962603a8971
--- /dev/null
+++ b/tests/ui/imports/cycle-import-in-diff-module-0.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+// https://github.com/rust-lang/rust/pull/124840#issuecomment-2098148587
+
+mod a {
+    pub(crate) use crate::S;
+}
+mod b {
+    pub struct S;
+}
+use self::a::S;
+use self::b::*;
+
+fn main() {}
diff --git a/tests/ui/imports/cycle-import-in-diff-module-1.rs b/tests/ui/imports/cycle-import-in-diff-module-1.rs
new file mode 100644
index 00000000000..8c67df376c3
--- /dev/null
+++ b/tests/ui/imports/cycle-import-in-diff-module-1.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+// similar `cycle-import-in-diff-module-0.rs`
+
+mod a {
+    pub(crate) use crate::s;
+}
+mod b {
+    pub mod s {}
+}
+use self::b::*;
+use self::a::s;
+
+fn main() {}
diff --git a/tests/ui/imports/shadow-glob-module-resolution-1.rs b/tests/ui/imports/shadow-glob-module-resolution-1.rs
new file mode 100644
index 00000000000..ba1e65cddc6
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-1.rs
@@ -0,0 +1,17 @@
+// https://github.com/rust-lang/rust/issues/124490
+
+mod a {
+    pub mod b {
+        pub mod c {}
+    }
+}
+
+use a::*;
+
+use b::c;
+//~^ ERROR: cannot determine resolution for the import
+//~| ERROR: cannot determine resolution for the import
+//~| ERROR: unresolved import `b::c`
+use c as b;
+
+fn main() {}
diff --git a/tests/ui/imports/shadow-glob-module-resolution-1.stderr b/tests/ui/imports/shadow-glob-module-resolution-1.stderr
new file mode 100644
index 00000000000..f9135963fe9
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-1.stderr
@@ -0,0 +1,23 @@
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-1.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-1.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0432]: unresolved import `b::c`
+  --> $DIR/shadow-glob-module-resolution-1.rs:11:5
+   |
+LL | use b::c;
+   |     ^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/imports/shadow-glob-module-resolution-2.rs b/tests/ui/imports/shadow-glob-module-resolution-2.rs
new file mode 100644
index 00000000000..36bd72658ae
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-2.rs
@@ -0,0 +1,19 @@
+// https://github.com/rust-lang/rust/issues/125013
+
+mod a {
+  pub mod b {
+    pub mod c {
+      pub trait D {}
+    }
+  }
+}
+
+use a::*;
+
+use e as b;
+//~^ ERROR: unresolved import `e`
+use b::c::D as e;
+//~^ ERROR: cannot determine resolution for the import
+//~| ERROR: cannot determine resolution for the import
+
+fn main() { }
diff --git a/tests/ui/imports/shadow-glob-module-resolution-2.stderr b/tests/ui/imports/shadow-glob-module-resolution-2.stderr
new file mode 100644
index 00000000000..644fcb84162
--- /dev/null
+++ b/tests/ui/imports/shadow-glob-module-resolution-2.stderr
@@ -0,0 +1,26 @@
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-2.rs:15:5
+   |
+LL | use b::c::D as e;
+   |     ^^^^^^^^^^^^
+
+error: cannot determine resolution for the import
+  --> $DIR/shadow-glob-module-resolution-2.rs:15:5
+   |
+LL | use b::c::D as e;
+   |     ^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0432]: unresolved import `e`
+  --> $DIR/shadow-glob-module-resolution-2.rs:13:5
+   |
+LL | use e as b;
+   |     -^^^^^
+   |     |
+   |     no `e` in the root
+   |     help: a similar name exists in the module: `a`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr
index 5775a4032c3..48cae82feb0 100644
--- a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr
+++ b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.stderr
@@ -1,6 +1,4 @@
-warning: ignoring --out-dir flag due to -o flag
-
 error: io error modifying ./does-not-exist/
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr
index ddc1027c16b..d30fb3cfe58 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -52,7 +52,7 @@ error[E0599]: no function or associated item named `bitor` found for trait objec
 LL |     let g = BitXor::bitor;
    |                     ^^^^^ function or associated item not found in `dyn BitXor<_>`
    |
-help: there is a method `bitxor` with a similar name, but with different arguments
+help: there is a method `bitxor` with a similar name
   --> $SRC_DIR/core/src/ops/bit.rs:LL:COL
 
 error: aborting due to 4 previous errors; 2 warnings emitted
diff --git a/tests/ui/issues/issue-53498.rs b/tests/ui/issues/issue-53498.rs
deleted file mode 100644
index 9e0437c46f4..00000000000
--- a/tests/ui/issues/issue-53498.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-pub mod test {
-    pub struct A;
-    pub struct B;
-    pub struct Foo<T>(T);
-
-    impl Foo<A> {
-        fn foo() {}
-    }
-
-    impl Foo<B> {
-        fn foo() {}
-    }
-}
-
-fn main() {
-    test::Foo::<test::B>::foo(); //~ ERROR associated function `foo` is private
-}
diff --git a/tests/ui/lifetimes/no_lending_iterators.rs b/tests/ui/lifetimes/no_lending_iterators.rs
new file mode 100644
index 00000000000..21395475fb3
--- /dev/null
+++ b/tests/ui/lifetimes/no_lending_iterators.rs
@@ -0,0 +1,35 @@
+struct Data(String);
+
+impl Iterator for Data {
+    type Item = &str;
+    //~^ ERROR 4:17: 4:18: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
+
+    fn next(&mut self) -> Option<Self::Item> {
+        Some(&self.0)
+    }
+}
+
+trait Bar {
+    type Item;
+    fn poke(&mut self, item: Self::Item);
+}
+
+impl Bar for usize {
+    type Item = &usize;
+    //~^ ERROR 18:17: 18:18: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
+
+    fn poke(&mut self, item: Self::Item) {
+        self += *item;
+    }
+}
+
+impl Bar for isize {
+    type Item<'a> = &'a isize;
+    //~^ ERROR 27:14: 27:18: lifetime parameters or bounds on type `Item` do not match the trait declaration [E0195]
+
+    fn poke(&mut self, item: Self::Item) {
+        self += *item;
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/no_lending_iterators.stderr b/tests/ui/lifetimes/no_lending_iterators.stderr
new file mode 100644
index 00000000000..c3784770d79
--- /dev/null
+++ b/tests/ui/lifetimes/no_lending_iterators.stderr
@@ -0,0 +1,30 @@
+error: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
+  --> $DIR/no_lending_iterators.rs:4:17
+   |
+LL |     type Item = &str;
+   |                 ^
+   |
+note: you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type.
+  --> $DIR/no_lending_iterators.rs:3:19
+   |
+LL | impl Iterator for Data {
+   |                   ^^^^
+
+error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
+  --> $DIR/no_lending_iterators.rs:18:17
+   |
+LL |     type Item = &usize;
+   |                 ^ this lifetime must come from the implemented type
+
+error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
+  --> $DIR/no_lending_iterators.rs:27:14
+   |
+LL |     type Item;
+   |              - lifetimes in impl do not match this type in trait
+...
+LL |     type Item<'a> = &'a isize;
+   |              ^^^^ lifetimes do not match type in trait
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
index a7109c6d930..ed11947f59e 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
@@ -4,12 +4,21 @@
 #![feature(linkage)]
 
 fn main() {
+    #[rustfmt::skip]
     extern "C" {
-        #[linkage = "weak"] //~ ERROR mutable statics are not allowed with `#[linkage]`
-        static mut ABC: *const u8;
+        #[linkage = "extern_weak"] //~ ERROR extern mutable statics are not allowed with `#[linkage]`
+        static mut EXTERN_WEAK: *const u8;
     }
 
     unsafe {
-        assert_eq!(ABC as usize, 0);
+        assert_eq!(EXTERN_WEAK as usize, 0);
+    }
+
+    // static mut is fine here as this is a definition rather than declaration.
+    #[linkage = "weak"]
+    static mut WEAK_DEF: u8 = 42;
+
+    unsafe {
+        assert_eq!(WEAK_DEF, 0);
     }
 }
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
index 4db41b62393..ad999769047 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
@@ -1,10 +1,10 @@
-error: mutable statics are not allowed with `#[linkage]`
-  --> $DIR/linkage-attr-mutable-static.rs:8:9
+error: extern mutable statics are not allowed with `#[linkage]`
+  --> $DIR/linkage-attr-mutable-static.rs:9:9
    |
-LL |         #[linkage = "weak"]
-   |         ^^^^^^^^^^^^^^^^^^^
+LL |         #[linkage = "extern_weak"]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: making the static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable
+   = note: marking the extern static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
index 62e4f82a3ff..829b7f86e26 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs
@@ -23,9 +23,6 @@ pub fn main() {
     if let Some(Some(&x)) = &Some(&Some(0)) {
         let _: u32 = x;
     }
-    if let Some(&mut Some(&x)) = &Some(&mut Some(0)) {
-        let _: u32 = x;
-    }
     if let Some(&Some(&x)) = &mut Some(&Some(0)) {
         let _: u32 = x;
     }
@@ -35,9 +32,6 @@ pub fn main() {
     if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
         let _: &u32 = x;
     }
-    if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
-        let _: &u32 = x;
-    }
     if let &Some(Some(x)) = &Some(&mut Some(0)) {
         let _: &u32 = x;
     }
@@ -59,13 +53,4 @@ pub fn main() {
     if let Some(&Some(x)) = &mut Some(Some(0)) {
         let _: u32 = x;
     }
-
-    let &mut x = &&mut 0;
-    let _: &u32 = x;
-
-    let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
-    let _: &u32 = x;
-
-    let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0;
-    let _: &u32 = x;
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
index 96b4ff77ddb..40e8293e241 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs
@@ -5,26 +5,26 @@
 
 pub fn main() {
     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-        //~^ ERROR: mismatched types
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
     }
     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-        //~^ ERROR: mismatched types
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
     }
     if let Some(&Some(x)) = &mut Some(&Some(0)) {
         let _: &mut u32 = x;
         //~^ ERROR: mismatched types
     }
     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-        //~^ ERROR: mismatched types
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
     }
     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-        //~^ ERROR: mismatched types
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
     }
     if let Some(&mut Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
     }
     if let Some(&mut Some(x)) = &Some(Some(0)) {
-        //~^ ERROR: mismatched types
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
     }
 
     let &mut _ = &&0;
@@ -32,4 +32,31 @@ pub fn main() {
 
     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
     //~^ ERROR: mismatched types
+
+    if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+    }
+
+    if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
+        //~^ ERROR: cannot match inherited `&` with `&mut` pattern
+    }
+
+    let &mut _ = &&mut 0;
+    //~^ ERROR: mismatched types
+
+    let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+    //~^ ERROR: mismatched types
+
+    let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+    //~^ ERROR: mismatched types
+
+    struct Foo(u8);
+
+    let Foo(mut a) = &Foo(0);
+    //~^ ERROR: binding cannot be both mutable and by-reference
+    a = &42;
+
+    let Foo(mut a) = &mut Foo(0);
+    //~^ ERROR: binding cannot be both mutable and by-reference
+    a = &mut 42;
 }
diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr
index e06a645fc0d..26317e43d02 100644
--- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr
+++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr
@@ -1,24 +1,24 @@
-error[E0308]: mismatched types
+error: cannot match inherited `&` with `&mut` pattern
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17
    |
 LL |     if let Some(&mut Some(&_)) = &Some(&Some(0)) {
-   |                 ^^^^^^^^^^^^^    --------------- this expression has type `&Option<&Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
+   |                 ^^^^^
    |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &Some(&Some(0)) {
+   |                 ~
 
-error[E0308]: mismatched types
+error: cannot match inherited `&` with `&mut` pattern
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23
    |
 LL |     if let Some(&Some(&mut _)) = &Some(&mut Some(0)) {
-   |                       ^^^^^^     ------------------- this expression has type `&Option<&mut Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
+   |                       ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
+   |                       ~
 
 error[E0308]: mismatched types
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27
@@ -31,49 +31,49 @@ LL |         let _: &mut u32 = x;
    = note: expected mutable reference `&mut u32`
                       found reference `&{integer}`
 
-error[E0308]: mismatched types
+error: cannot match inherited `&` with `&mut` pattern
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23
    |
 LL |     if let Some(&Some(&mut _)) = &mut Some(&Some(0)) {
-   |                       ^^^^^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
-   |                       |
-   |                       expected integer, found `&mut _`
+   |                       ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &mut Some(&Some(0)) {
+   |                       ~
 
-error[E0308]: mismatched types
+error: cannot match inherited `&` with `&mut` pattern
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29
    |
 LL |     if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) {
-   |                             ^^^^^^       ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
-   |                             |
-   |                             expected integer, found `&mut _`
+   |                             ^^^^^
    |
-   = note:           expected type `{integer}`
-           found mutable reference `&mut _`
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) {
+   |                             ~
 
-error[E0308]: mismatched types
+error: cannot match inherited `&` with `&mut` pattern
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
+   |                 ^^^^^
    |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(x)) = &Some(Some(0)) {
+   |                 ~
 
-error[E0308]: mismatched types
+error: cannot match inherited `&` with `&mut` pattern
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17
    |
 LL |     if let Some(&mut Some(x)) = &Some(Some(0)) {
-   |                 ^^^^^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
-   |                 |
-   |                 expected `Option<{integer}>`, found `&mut _`
+   |                 ^^^^^
    |
-   = note:           expected enum `Option<{integer}>`
-           found mutable reference `&mut _`
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(x)) = &Some(Some(0)) {
+   |                 ~
 
 error[E0308]: mismatched types
   --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9
@@ -81,9 +81,9 @@ error[E0308]: mismatched types
 LL |     let &mut _ = &&0;
    |         ^^^^^^   --- this expression has type `&&{integer}`
    |         |
-   |         expected integer, found `&mut _`
+   |         types differ in mutability
    |
-   = note:           expected type `{integer}`
+   = note:      expected reference `&&{integer}`
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
@@ -92,11 +92,87 @@ error[E0308]: mismatched types
 LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0;
    |         ^^^^^^   ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
    |         |
-   |         expected integer, found `&mut _`
+   |         types differ in mutability
    |
-   = note:           expected type `{integer}`
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}`
            found mutable reference `&mut _`
 
-error: aborting due to 9 previous errors
+error: cannot match inherited `&` with `&mut` pattern
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:17
+   |
+LL |     if let Some(&mut Some(&_)) = &Some(&mut Some(0)) {
+   |                 ^^^^^
+   |
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(&Some(&_)) = &Some(&mut Some(0)) {
+   |                 ~
+
+error: cannot match inherited `&` with `&mut` pattern
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:40:22
+   |
+LL |     if let Some(Some(&mut x)) = &Some(Some(&mut 0)) {
+   |                      ^^^^^
+   |
+help: replace this `&mut` pattern with `&`
+   |
+LL |     if let Some(Some(&x)) = &Some(Some(&mut 0)) {
+   |                      ~
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:44:9
+   |
+LL |     let &mut _ = &&mut 0;
+   |         ^^^^^^   ------- this expression has type `&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:47:9
+   |
+LL |     let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0;
+   |         ^^^^^^   --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+   |         |
+   |         types differ in mutability
+   |
+   = note:      expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:50:14
+   |
+LL |     let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0;
+   |              ^^^^^^^^^^^^^^^^   -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}`
+   |              |
+   |              types differ in mutability
+   |
+   = note:      expected reference `&&&&mut &&&mut &mut {integer}`
+           found mutable reference `&mut _`
+
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13
+   |
+LL |     let Foo(mut a) = &Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: binding cannot be both mutable and by-reference
+  --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13
+   |
+LL |     let Foo(mut a) = &mut Foo(0);
+   |             ^^^^
+   |
+   = note: see issue #123076 <https://github.com/rust-lang/rust/issues/123076> for more information
+   = help: add `#![feature(mut_ref)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 16 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/match/ref_pat_everywhere-fail.rs b/tests/ui/match/ref_pat_everywhere-fail.rs
deleted file mode 100644
index d1b1c04730d..00000000000
--- a/tests/ui/match/ref_pat_everywhere-fail.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![allow(incomplete_features)]
-#![feature(ref_pat_everywhere)]
-pub fn main() {
-    if let Some(&x) = Some(0) {
-        //~^ ERROR: mismatched types [E0308]
-        let _: u32 = x;
-    }
-    if let Some(&mut x) = Some(&0) {
-        //~^ ERROR: mismatched types [E0308]
-        let _: u32 = x;
-    }
-}
diff --git a/tests/ui/match/ref_pat_everywhere-fail.stderr b/tests/ui/match/ref_pat_everywhere-fail.stderr
deleted file mode 100644
index 25a01129f4a..00000000000
--- a/tests/ui/match/ref_pat_everywhere-fail.stderr
+++ /dev/null
@@ -1,38 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_everywhere-fail.rs:4:17
-   |
-LL |     if let Some(&x) = Some(0) {
-   |                 ^^    ------- this expression has type `Option<{integer}>`
-   |                 |
-   |                 expected integer, found `&_`
-   |
-   = note:   expected type `{integer}`
-           found reference `&_`
-help: consider removing `&` from the pattern
-   |
-LL |     if let Some(x) = Some(0) {
-   |                 ~
-
-error[E0308]: mismatched types
-  --> $DIR/ref_pat_everywhere-fail.rs:8:17
-   |
-LL |     if let Some(&mut x) = Some(&0) {
-   |                 ^^^^^^    -------- this expression has type `Option<&{integer}>`
-   |                 |
-   |                 types differ in mutability
-   |
-   = note:      expected reference `&{integer}`
-           found mutable reference `&mut _`
-note: to declare a mutable binding use: `mut x`
-  --> $DIR/ref_pat_everywhere-fail.rs:8:17
-   |
-LL |     if let Some(&mut x) = Some(&0) {
-   |                 ^^^^^^
-help: consider removing `&mut` from the pattern
-   |
-LL |     if let Some(x) = Some(&0) {
-   |                 ~
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/match/ref_pat_everywhere.rs b/tests/ui/match/ref_pat_everywhere.rs
deleted file mode 100644
index 9a79c548475..00000000000
--- a/tests/ui/match/ref_pat_everywhere.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//@ run-pass
-#![allow(incomplete_features)]
-#![feature(ref_pat_everywhere)]
-
-pub fn main() {
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        let _: u32 = x;
-    }
-    if let Some(&Some(x)) = &Some(Some(0)) {
-        let _: u32 = x;
-    }
-    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
-        let _: u32 = x;
-    }
-    if let Some(Some(&x)) = &Some(&mut Some(0)) {
-        let _: u32 = x;
-    }
-    if let &Some(x) = &mut Some(0) {
-        let _: u32 = x;
-    }
-    if let Some(&x) = &mut Some(0) {
-        let _: u32 = x;
-    }
-}
diff --git a/tests/ui/parser/duplicate-visibility.rs b/tests/ui/parser/duplicate-visibility.rs
index 54955944c7d..f0ee60873da 100644
--- a/tests/ui/parser/duplicate-visibility.rs
+++ b/tests/ui/parser/duplicate-visibility.rs
@@ -2,8 +2,8 @@ fn main() {}
 
 extern "C" { //~ NOTE while parsing this item list starting here
     pub pub fn foo();
-    //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
-    //~| NOTE expected one of 8 possible tokens
+    //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub`
+    //~| NOTE expected one of 9 possible tokens
     //~| HELP there is already a visibility modifier, remove one
     //~| NOTE explicit visibility first seen here
 } //~ NOTE the item list ends here
diff --git a/tests/ui/parser/duplicate-visibility.stderr b/tests/ui/parser/duplicate-visibility.stderr
index b578b1fe26e..0d1421ee7f4 100644
--- a/tests/ui/parser/duplicate-visibility.stderr
+++ b/tests/ui/parser/duplicate-visibility.stderr
@@ -1,4 +1,4 @@
-error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `unsafe`, or `use`, found keyword `pub`
+error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub`
   --> $DIR/duplicate-visibility.rs:4:9
    |
 LL | extern "C" {
@@ -6,7 +6,7 @@ LL | extern "C" {
 LL |     pub pub fn foo();
    |         ^^^
    |         |
-   |         expected one of 8 possible tokens
+   |         expected one of 9 possible tokens
    |         help: there is already a visibility modifier, remove one
 ...
 LL | }
diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs
index 6ed173b6854..5907ac05260 100644
--- a/tests/ui/parser/fn-header-semantic-fail.rs
+++ b/tests/ui/parser/fn-header-semantic-fail.rs
@@ -44,13 +44,14 @@ fn main() {
 
     extern "C" {
         async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers
-        unsafe fn fe2(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+        unsafe fn fe2(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
         const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers
         extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers
-        const async unsafe extern "C" fn fe5(); //~ ERROR functions in `extern` blocks
-        //~| ERROR functions in `extern` blocks
+        const async unsafe extern "C" fn fe5();
+        //~^ ERROR functions in `extern` blocks
         //~| ERROR functions in `extern` blocks
         //~| ERROR functions in `extern` blocks
         //~| ERROR functions cannot be both `const` and `async`
+        //~| ERROR items in unadorned `extern` blocks cannot have safety qualifiers
     }
 }
diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr
index cfc54839eb7..abaa6527b0a 100644
--- a/tests/ui/parser/fn-header-semantic-fail.stderr
+++ b/tests/ui/parser/fn-header-semantic-fail.stderr
@@ -78,14 +78,14 @@ LL |     extern "C" {
 LL |         async fn fe1();
    |         ^^^^^ help: remove this qualifier
 
-error: functions in `extern` blocks cannot have qualifiers
+error: items in unadorned `extern` blocks cannot have safety qualifiers
   --> $DIR/fn-header-semantic-fail.rs:47:9
    |
 LL |     extern "C" {
-   |     ---------- in this `extern` block
+   |     ---------- help: add unsafe to this `extern` block
 LL |         async fn fe1();
 LL |         unsafe fn fe2();
-   |         ^^^^^^ help: remove this qualifier
+   |         ^^^^^^^^^^^^^^^^
 
 error: functions in `extern` blocks cannot have qualifiers
   --> $DIR/fn-header-semantic-fail.rs:48:9
@@ -105,14 +105,14 @@ LL |     extern "C" {
 LL |         extern "C" fn fe4();
    |         ^^^^^^^^^^ help: remove this qualifier
 
-error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:50:21
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:50:9
    |
 LL |     extern "C" {
-   |     ---------- in this `extern` block
+   |     ---------- help: add unsafe to this `extern` block
 ...
 LL |         const async unsafe extern "C" fn fe5();
-   |                     ^^^^^^ help: remove this qualifier
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: functions in `extern` blocks cannot have qualifiers
   --> $DIR/fn-header-semantic-fail.rs:50:15
diff --git a/tests/ui/parser/issues/issue-76437-async.rs b/tests/ui/parser/issues/issue-76437-async.rs
index 497e269d634..3fafaad0277 100644
--- a/tests/ui/parser/issues/issue-76437-async.rs
+++ b/tests/ui/parser/issues/issue-76437-async.rs
@@ -2,6 +2,6 @@
 
 mod t {
     async pub fn t() {}
-    //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+    //~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
     //~| HELP visibility `pub` must come before `async`
 }
diff --git a/tests/ui/parser/issues/issue-76437-async.stderr b/tests/ui/parser/issues/issue-76437-async.stderr
index 7f2df5c8736..483599135f5 100644
--- a/tests/ui/parser/issues/issue-76437-async.stderr
+++ b/tests/ui/parser/issues/issue-76437-async.stderr
@@ -1,10 +1,10 @@
-error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
   --> $DIR/issue-76437-async.rs:4:11
    |
 LL |     async pub fn t() {}
    |     ------^^^
    |     |     |
-   |     |     expected one of `extern`, `fn`, or `unsafe`
+   |     |     expected one of `extern`, `fn`, `safe`, or `unsafe`
    |     help: visibility `pub` must come before `async`: `pub async`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/parser/issues/issue-76437-const-async.rs b/tests/ui/parser/issues/issue-76437-const-async.rs
index 45d53c63933..d8eb6cdecf1 100644
--- a/tests/ui/parser/issues/issue-76437-const-async.rs
+++ b/tests/ui/parser/issues/issue-76437-const-async.rs
@@ -2,6 +2,6 @@
 
 mod t {
     const async pub fn t() {}
-    //~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+    //~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
     //~| HELP visibility `pub` must come before `const async`
 }
diff --git a/tests/ui/parser/issues/issue-76437-const-async.stderr b/tests/ui/parser/issues/issue-76437-const-async.stderr
index a9acccdce18..81fa8a5f557 100644
--- a/tests/ui/parser/issues/issue-76437-const-async.stderr
+++ b/tests/ui/parser/issues/issue-76437-const-async.stderr
@@ -1,10 +1,10 @@
-error: expected one of `extern`, `fn`, or `unsafe`, found keyword `pub`
+error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
   --> $DIR/issue-76437-const-async.rs:4:17
    |
 LL |     const async pub fn t() {}
    |     ------------^^^
    |     |           |
-   |     |           expected one of `extern`, `fn`, or `unsafe`
+   |     |           expected one of `extern`, `fn`, `safe`, or `unsafe`
    |     help: visibility `pub` must come before `const async`: `pub const async`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/parser/issues/issue-76437-const.rs b/tests/ui/parser/issues/issue-76437-const.rs
index c3431e3567b..dad63f137c0 100644
--- a/tests/ui/parser/issues/issue-76437-const.rs
+++ b/tests/ui/parser/issues/issue-76437-const.rs
@@ -2,6 +2,6 @@
 
 mod t {
     const pub fn t() {}
-    //~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+    //~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
     //~| HELP visibility `pub` must come before `const`
 }
diff --git a/tests/ui/parser/issues/issue-76437-const.stderr b/tests/ui/parser/issues/issue-76437-const.stderr
index 4c36d773d60..005a27b7c24 100644
--- a/tests/ui/parser/issues/issue-76437-const.stderr
+++ b/tests/ui/parser/issues/issue-76437-const.stderr
@@ -1,10 +1,10 @@
-error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
   --> $DIR/issue-76437-const.rs:4:11
    |
 LL |     const pub fn t() {}
    |     ------^^^
    |     |     |
-   |     |     expected one of `async`, `extern`, `fn`, or `unsafe`
+   |     |     expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
    |     help: visibility `pub` must come before `const`: `pub const`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/parser/issues/issue-86895.rs b/tests/ui/parser/issues/issue-86895.rs
index 4cd09843107..3e5dc41e2f4 100644
--- a/tests/ui/parser/issues/issue-86895.rs
+++ b/tests/ui/parser/issues/issue-86895.rs
@@ -1,3 +1,3 @@
 const pub () {}
-//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`
+//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
 pub fn main() {}
diff --git a/tests/ui/parser/issues/issue-86895.stderr b/tests/ui/parser/issues/issue-86895.stderr
index dcde7242d39..14183ee0a5c 100644
--- a/tests/ui/parser/issues/issue-86895.stderr
+++ b/tests/ui/parser/issues/issue-86895.stderr
@@ -1,8 +1,8 @@
-error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
   --> $DIR/issue-86895.rs:1:7
    |
 LL | const pub () {}
-   |       ^^^ expected one of `async`, `extern`, `fn`, or `unsafe`
+   |       ^^^ expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
index 694729376ba..e6235b1e892 100644
--- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs
@@ -3,8 +3,8 @@
 // Test that even when `const` is already present, the proposed fix is to remove the second `const`
 
 const async const fn test() {}
-//~^ ERROR expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
-//~| NOTE expected one of `extern`, `fn`, or `unsafe`
+//~^ ERROR expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
+//~| NOTE expected one of `extern`, `fn`, `safe`, or `unsafe`
 //~| HELP `const` already used earlier, remove this one
 //~| NOTE `const` first seen here
 //~| ERROR functions cannot be both `const` and `async`
diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr
index 4c55179ce23..ed2e4d81549 100644
--- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr
+++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.stderr
@@ -1,10 +1,10 @@
-error: expected one of `extern`, `fn`, or `unsafe`, found keyword `const`
+error: expected one of `extern`, `fn`, `safe`, or `unsafe`, found keyword `const`
   --> $DIR/const-async-const.rs:5:13
    |
 LL | const async const fn test() {}
    |             ^^^^^
    |             |
-   |             expected one of `extern`, `fn`, or `unsafe`
+   |             expected one of `extern`, `fn`, `safe`, or `unsafe`
    |             help: `const` already used earlier, remove this one
    |
 note: `const` first seen here
diff --git a/tests/ui/parser/issues/issue-87694-duplicated-pub.rs b/tests/ui/parser/issues/issue-87694-duplicated-pub.rs
index e3ea61dc4ad..816c8ff2a9f 100644
--- a/tests/ui/parser/issues/issue-87694-duplicated-pub.rs
+++ b/tests/ui/parser/issues/issue-87694-duplicated-pub.rs
@@ -1,5 +1,5 @@
 pub const pub fn test() {}
-//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
-//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
+//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
+//~| NOTE expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
 //~| HELP there is already a visibility modifier, remove one
 //~| NOTE explicit visibility first seen here
diff --git a/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr b/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr
index a210238652a..dd75f32f68f 100644
--- a/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr
+++ b/tests/ui/parser/issues/issue-87694-duplicated-pub.stderr
@@ -1,10 +1,10 @@
-error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
   --> $DIR/issue-87694-duplicated-pub.rs:1:11
    |
 LL | pub const pub fn test() {}
    |           ^^^
    |           |
-   |           expected one of `async`, `extern`, `fn`, or `unsafe`
+   |           expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
    |           help: there is already a visibility modifier, remove one
    |
 note: explicit visibility first seen here
diff --git a/tests/ui/parser/issues/issue-87694-misplaced-pub.rs b/tests/ui/parser/issues/issue-87694-misplaced-pub.rs
index 3f824617cad..b5b0bc5b2fc 100644
--- a/tests/ui/parser/issues/issue-87694-misplaced-pub.rs
+++ b/tests/ui/parser/issues/issue-87694-misplaced-pub.rs
@@ -1,5 +1,5 @@
 const pub fn test() {}
-//~^ ERROR expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
-//~| NOTE expected one of `async`, `extern`, `fn`, or `unsafe`
+//~^ ERROR expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
+//~| NOTE expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
 //~| HELP visibility `pub` must come before `const`
 //~| SUGGESTION pub const
diff --git a/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr b/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr
index 6f686a7e504..d35e09dceaf 100644
--- a/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr
+++ b/tests/ui/parser/issues/issue-87694-misplaced-pub.stderr
@@ -1,10 +1,10 @@
-error: expected one of `async`, `extern`, `fn`, or `unsafe`, found keyword `pub`
+error: expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`, found keyword `pub`
   --> $DIR/issue-87694-misplaced-pub.rs:1:7
    |
 LL | const pub fn test() {}
    | ------^^^
    | |     |
-   | |     expected one of `async`, `extern`, `fn`, or `unsafe`
+   | |     expected one of `async`, `extern`, `fn`, `safe`, or `unsafe`
    | help: visibility `pub` must come before `const`: `pub const`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/parser/no-const-fn-in-extern-block.rs b/tests/ui/parser/no-const-fn-in-extern-block.rs
index d6c578681cc..3ad9ba006d3 100644
--- a/tests/ui/parser/no-const-fn-in-extern-block.rs
+++ b/tests/ui/parser/no-const-fn-in-extern-block.rs
@@ -3,7 +3,7 @@ extern "C" {
     //~^ ERROR functions in `extern` blocks cannot have qualifiers
     const unsafe fn bar();
     //~^ ERROR functions in `extern` blocks cannot have qualifiers
-    //~| ERROR functions in `extern` blocks cannot have qualifiers
+    //~| ERROR items in unadorned `extern` blocks cannot have safety qualifiers
 }
 
 fn main() {}
diff --git a/tests/ui/parser/no-const-fn-in-extern-block.stderr b/tests/ui/parser/no-const-fn-in-extern-block.stderr
index 948ce669112..892024ce893 100644
--- a/tests/ui/parser/no-const-fn-in-extern-block.stderr
+++ b/tests/ui/parser/no-const-fn-in-extern-block.stderr
@@ -6,14 +6,14 @@ LL | extern "C" {
 LL |     const fn foo();
    |     ^^^^^ help: remove this qualifier
 
-error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/no-const-fn-in-extern-block.rs:4:11
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/no-const-fn-in-extern-block.rs:4:5
    |
 LL | extern "C" {
-   | ---------- in this `extern` block
+   | ---------- help: add unsafe to this `extern` block
 ...
 LL |     const unsafe fn bar();
-   |           ^^^^^^ help: remove this qualifier
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: functions in `extern` blocks cannot have qualifiers
   --> $DIR/no-const-fn-in-extern-block.rs:4:5
diff --git a/tests/ui/parser/unsafe-foreign-mod-2.rs b/tests/ui/parser/unsafe-foreign-mod-2.rs
index 77856fb6734..0b63a993c5b 100644
--- a/tests/ui/parser/unsafe-foreign-mod-2.rs
+++ b/tests/ui/parser/unsafe-foreign-mod-2.rs
@@ -1,8 +1,8 @@
 extern "C" unsafe {
-               //~^ ERROR expected `{`, found keyword `unsafe`
-               //~| ERROR extern block cannot be declared unsafe
+    //~^ ERROR expected `{`, found keyword `unsafe`
+    //~| ERROR extern block cannot be declared unsafe
     unsafe fn foo();
-        //~^ ERROR functions in `extern` blocks cannot have qualifiers
+    //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
 }
 
 fn main() {}
diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr
index fc05184f018..e59352395ed 100644
--- a/tests/ui/parser/unsafe-foreign-mod-2.stderr
+++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr
@@ -10,14 +10,14 @@ error: extern block cannot be declared unsafe
 LL | extern "C" unsafe {
    |            ^^^^^^
 
-error: functions in `extern` blocks cannot have qualifiers
+error: items in unadorned `extern` blocks cannot have safety qualifiers
   --> $DIR/unsafe-foreign-mod-2.rs:4:5
    |
 LL | extern "C" unsafe {
-   | ----------------- in this `extern` block
+   | ----------------- help: add unsafe to this `extern` block
 ...
 LL |     unsafe fn foo();
-   |     ^^^^^^ help: remove this qualifier
+   |     ^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs
deleted file mode 100644
index 15c542e6bf1..00000000000
--- a/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//@ edition: 2024
-//@ compile-flags: -Zunstable-options
-
-struct Foo(u8);
-
-fn main() {
-    let Foo(mut a) = &Foo(0);
-    a = &42;
-    //~^ ERROR: mismatched types
-
-    let Foo(mut a) = &mut Foo(0);
-    a = &mut 42;
-    //~^ ERROR: mismatched types
-}
diff --git a/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr
deleted file mode 100644
index 6d0a034be21..00000000000
--- a/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:8:9
-   |
-LL |     let Foo(mut a) = &Foo(0);
-   |             ----- expected due to the type of this binding
-LL |     a = &42;
-   |         ^^^ expected `u8`, found `&{integer}`
-   |
-help: consider removing the borrow
-   |
-LL -     a = &42;
-LL +     a = 42;
-   |
-
-error[E0308]: mismatched types
-  --> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:12:9
-   |
-LL |     let Foo(mut a) = &mut Foo(0);
-   |             ----- expected due to the type of this binding
-LL |     a = &mut 42;
-   |         ^^^^^^^ expected `u8`, found `&mut {integer}`
-   |
-help: consider removing the borrow
-   |
-LL -     a = &mut 42;
-LL +     a = 42;
-   |
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/pattern/match_ergonomics_2024.fixed b/tests/ui/pattern/match_ergonomics_2024.fixed
index d8dbcb217c0..1ec2b5a214b 100644
--- a/tests/ui/pattern/match_ergonomics_2024.fixed
+++ b/tests/ui/pattern/match_ergonomics_2024.fixed
@@ -2,7 +2,7 @@
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ aux-build:match_ergonomics_2024_macros.rs
-#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
+#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
diff --git a/tests/ui/pattern/match_ergonomics_2024.rs b/tests/ui/pattern/match_ergonomics_2024.rs
index 38dc0c8bebb..c9f992c12d4 100644
--- a/tests/ui/pattern/match_ergonomics_2024.rs
+++ b/tests/ui/pattern/match_ergonomics_2024.rs
@@ -2,7 +2,7 @@
 //@ run-rustfix
 //@ rustfix-only-machine-applicable
 //@ aux-build:match_ergonomics_2024_macros.rs
-#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
+#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features, unused)]
 #![deny(rust_2024_incompatible_pat)]
 
diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2021.rs b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs
index befa49fdc24..282e0ef95d2 100644
--- a/tests/ui/pattern/mut_preserve_binding_mode_2021.rs
+++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs
@@ -1,6 +1,6 @@
 //@ edition: 2021
 //@ compile-flags: -Zunstable-options
-#![feature(mut_preserve_binding_mode_2024)]
+#![feature(ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features)]
 
 struct Foo(u8);
diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs
index 5454962e16c..19aa73573b4 100644
--- a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs
+++ b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ edition: 2024
 //@ compile-flags: -Zunstable-options
-#![feature(mut_preserve_binding_mode_2024)]
+#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
 #![allow(incomplete_features, unused)]
 
 struct Foo(u8);
diff --git a/tests/ui/pattern/no_ref_mut_behind_and.rs b/tests/ui/pattern/no_ref_mut_behind_and.rs
new file mode 100644
index 00000000000..c18d64904d0
--- /dev/null
+++ b/tests/ui/pattern/no_ref_mut_behind_and.rs
@@ -0,0 +1,9 @@
+//@ edition: 2021
+//@ run-pass
+#![allow(incomplete_features)]
+#![feature(ref_pat_eat_one_layer_2024)]
+
+fn main() {
+    let &[[x]] = &[&mut [42]];
+    let _: &i32 = x;
+}
diff --git a/tests/ui/privacy/ufc-method-call.different_name.stderr b/tests/ui/privacy/ufc-method-call.different_name.stderr
new file mode 100644
index 00000000000..16496c480dd
--- /dev/null
+++ b/tests/ui/privacy/ufc-method-call.different_name.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no function or associated item named `foo` found for struct `Foo<B>` in the current scope
+  --> $DIR/ufc-method-call.rs:27:27
+   |
+LL |     pub struct Foo<T>(T);
+   |     ----------------- function or associated item `foo` not found for this struct
+...
+LL |     test::Foo::<test::B>::foo();
+   |                           ^^^ function or associated item not found in `Foo<B>`
+   |
+   = note: the function or associated item was found for
+           - `Foo<A>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/privacy/ufc-method-call.rs b/tests/ui/privacy/ufc-method-call.rs
new file mode 100644
index 00000000000..525d9a9eee9
--- /dev/null
+++ b/tests/ui/privacy/ufc-method-call.rs
@@ -0,0 +1,30 @@
+//! This test used to report that the method call cannot
+//! call the private method `Foo<A>::foo`, even though the user
+//! explicitly selected `Foo<B>::foo`. This is because we only
+//! looked for methods of the right name, without properly checking
+//! the `Self` type
+
+//@ revisions: same_name different_name
+
+pub mod test {
+    pub struct A;
+    pub struct B;
+    pub struct Foo<T>(T);
+
+    impl Foo<A> {
+        fn foo() {}
+    }
+
+    impl Foo<B> {
+        #[cfg(same_name)]
+        fn foo() {}
+        #[cfg(different_name)]
+        fn bar() {}
+    }
+}
+
+fn main() {
+    test::Foo::<test::B>::foo();
+    //[same_name]~^ ERROR associated function `foo` is private
+    //[different_name]~^^ ERROR no function or associated item named `foo` found for struct `Foo<B>`
+}
diff --git a/tests/ui/issues/issue-53498.stderr b/tests/ui/privacy/ufc-method-call.same_name.stderr
index 61a1aedf508..194ba42cbf9 100644
--- a/tests/ui/issues/issue-53498.stderr
+++ b/tests/ui/privacy/ufc-method-call.same_name.stderr
@@ -1,5 +1,5 @@
 error[E0624]: associated function `foo` is private
-  --> $DIR/issue-53498.rs:16:27
+  --> $DIR/ufc-method-call.rs:27:27
    |
 LL |         fn foo() {}
    |         -------- private associated function defined here
diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs
index a62feace2da..20467301ae1 100644
--- a/tests/ui/privacy/where-priv-type.rs
+++ b/tests/ui/privacy/where-priv-type.rs
@@ -11,55 +11,46 @@ pub struct PubTy;
 pub struct PubTyGeneric<T>(T);
 pub trait PubTr {}
 impl PubTr for PrivTy {}
-pub trait PubTrWithAssocTy { type AssocTy; }
-impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; }
-
+pub trait PubTrWithAssocTy {
+    type AssocTy;
+}
+impl PubTrWithAssocTy for PrivTy {
+    type AssocTy = PrivTy;
+}
 
 pub struct S
 //~^ WARNING type `PrivTy` is more private than the item `S`
 where
-    PrivTy:
-{}
-
+    PrivTy:, {}
 
 pub enum E
 //~^ WARNING type `PrivTy` is more private than the item `E`
 where
-    PrivTy:
-{}
-
+    PrivTy:, {}
 
 pub fn f()
 //~^ WARNING type `PrivTy` is more private than the item `f`
 where
-    PrivTy:
-{}
-
+    PrivTy:,
+{
+}
 
 impl S
 //~^ WARNING type `PrivTy` is more private than the item `S`
 where
-    PrivTy:
+    PrivTy:,
 {
     pub fn f()
     //~^ WARNING type `PrivTy` is more private than the item `S::f`
     where
-        PrivTy:
-    {}
+        PrivTy:,
+    {
+    }
 }
 
+impl PubTr for PubTy where PrivTy: {}
 
-impl PubTr for PubTy
-where
-    PrivTy:
-{}
-
-
-impl<T> PubTr for PubTyGeneric<T>
-where
-    T: PubTrWithAssocTy<AssocTy=PrivTy>
-{}
-
+impl<T> PubTr for PubTyGeneric<T> where T: PubTrWithAssocTy<AssocTy = PrivTy> {}
 
 pub struct Const<const U: u8>;
 
@@ -70,7 +61,7 @@ pub trait Trait {
 
 impl<const U: u8> Trait for Const<U>
 where
-    Const<{ my_const_fn(U) }>: ,
+    Const<{ my_const_fn(U) }>:,
 {
     type AssocTy = Const<{ my_const_fn(U) }>;
     //~^ ERROR private type
diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr
index 8ea2e17c436..08963e07c35 100644
--- a/tests/ui/privacy/where-priv-type.stderr
+++ b/tests/ui/privacy/where-priv-type.stderr
@@ -1,5 +1,5 @@
 warning: type `PrivTy` is more private than the item `S`
-  --> $DIR/where-priv-type.rs:18:1
+  --> $DIR/where-priv-type.rs:21:1
    |
 LL | pub struct S
    | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub`
@@ -12,7 +12,7 @@ LL | struct PrivTy;
    = note: `#[warn(private_bounds)]` on by default
 
 warning: type `PrivTy` is more private than the item `E`
-  --> $DIR/where-priv-type.rs:25:1
+  --> $DIR/where-priv-type.rs:26:1
    |
 LL | pub enum E
    | ^^^^^^^^^^ enum `E` is reachable at visibility `pub`
@@ -24,13 +24,13 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 warning: type `PrivTy` is more private than the item `f`
-  --> $DIR/where-priv-type.rs:32:1
+  --> $DIR/where-priv-type.rs:31:1
    |
 LL | / pub fn f()
 LL | |
 LL | | where
-LL | |     PrivTy:
-   | |___________^ function `f` is reachable at visibility `pub`
+LL | |     PrivTy:,
+   | |____________^ function `f` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:8:1
@@ -39,13 +39,13 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 warning: type `PrivTy` is more private than the item `S`
-  --> $DIR/where-priv-type.rs:39:1
+  --> $DIR/where-priv-type.rs:38:1
    |
 LL | / impl S
 LL | |
 LL | | where
-LL | |     PrivTy:
-   | |___________^ implementation `S` is reachable at visibility `pub`
+LL | |     PrivTy:,
+   | |____________^ implementation `S` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:8:1
@@ -54,13 +54,13 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 warning: type `PrivTy` is more private than the item `S::f`
-  --> $DIR/where-priv-type.rs:44:5
+  --> $DIR/where-priv-type.rs:43:5
    |
 LL | /     pub fn f()
 LL | |
 LL | |     where
-LL | |         PrivTy:
-   | |_______________^ associated function `S::f` is reachable at visibility `pub`
+LL | |         PrivTy:,
+   | |________________^ associated function `S::f` is reachable at visibility `pub`
    |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:8:1
@@ -69,7 +69,7 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/where-priv-type.rs:75:5
+  --> $DIR/where-priv-type.rs:66:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -78,7 +78,7 @@ LL | const fn my_const_fn(val: u8) -> u8 {
    | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
 
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/where-priv-type.rs:75:5
+  --> $DIR/where-priv-type.rs:66:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
diff --git a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr
index 118882f73a3..889cd0c90eb 100644
--- a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr
+++ b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr
@@ -1,185 +1,6 @@
 error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
    |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: older versions of the `rental` crate no longer compile; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
 
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 8 previous errors
-
-Future incompatibility report: Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/proc-macro/pretty-print-hack-show.local.stdout b/tests/ui/proc-macro/pretty-print-hack-show.local.stdout
deleted file mode 100644
index 3d793d2a014..00000000000
--- a/tests/ui/proc-macro/pretty-print-hack-show.local.stdout
+++ /dev/null
@@ -1,44 +0,0 @@
-PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
-PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
-PRINT-DERIVE INPUT (DEBUG): TokenStream [
-    Ident {
-        ident: "enum",
-        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:1: 4:5 (#0),
-    },
-    Ident {
-        ident: "ProceduralMasqueradeDummyType",
-        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6: 4:35 (#0),
-    },
-    Group {
-        delimiter: Brace,
-        stream: TokenStream [
-            Ident {
-                ident: "Input",
-                span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:13:5: 13:10 (#0),
-            },
-        ],
-        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:36: 14:2 (#0),
-    },
-]
-PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
-PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
-PRINT-DERIVE INPUT (DEBUG): TokenStream [
-    Ident {
-        ident: "enum",
-        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:1: 4:5 (#0),
-    },
-    Ident {
-        ident: "ProceduralMasqueradeDummyType",
-        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6: 4:35 (#0),
-    },
-    Group {
-        delimiter: Brace,
-        stream: TokenStream [
-            Ident {
-                ident: "Input",
-                span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:13:5: 13:10 (#0),
-            },
-        ],
-        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:36: 14:2 (#0),
-    },
-]
diff --git a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr
index 118882f73a3..889cd0c90eb 100644
--- a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr
+++ b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr
@@ -1,185 +1,6 @@
 error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
    |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: older versions of the `rental` crate no longer compile; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
 
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 8 previous errors
-
-Future incompatibility report: Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using an old version of `rental`
-  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
-   = note: `#[deny(proc_macro_back_compat)]` on by default
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stdout b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stdout
deleted file mode 100644
index 3d793d2a014..00000000000
--- a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stdout
+++ /dev/null
@@ -1,44 +0,0 @@
-PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
-PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
-PRINT-DERIVE INPUT (DEBUG): TokenStream [
-    Ident {
-        ident: "enum",
-        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:1: 4:5 (#0),
-    },
-    Ident {
-        ident: "ProceduralMasqueradeDummyType",
-        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6: 4:35 (#0),
-    },
-    Group {
-        delimiter: Brace,
-        stream: TokenStream [
-            Ident {
-                ident: "Input",
-                span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:13:5: 13:10 (#0),
-            },
-        ],
-        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:36: 14:2 (#0),
-    },
-]
-PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
-PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
-PRINT-DERIVE INPUT (DEBUG): TokenStream [
-    Ident {
-        ident: "enum",
-        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:1: 4:5 (#0),
-    },
-    Ident {
-        ident: "ProceduralMasqueradeDummyType",
-        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6: 4:35 (#0),
-    },
-    Group {
-        delimiter: Brace,
-        stream: TokenStream [
-            Ident {
-                ident: "Input",
-                span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:13:5: 13:10 (#0),
-            },
-        ],
-        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:36: 14:2 (#0),
-    },
-]
diff --git a/tests/ui/resolve/filter-intrinsics.rs b/tests/ui/resolve/filter-intrinsics.rs
index c0956ef85af..8d6d22817dc 100644
--- a/tests/ui/resolve/filter-intrinsics.rs
+++ b/tests/ui/resolve/filter-intrinsics.rs
@@ -1,6 +1,6 @@
 fn main() {
-    // Should suggest only `std::mem::size_of`
-    let _ = size_of::<usize>();
+    // Should suggest only `std::mem::transmute`
+    let _ = transmute::<usize>();
     //~^ ERROR cannot find
 
     // Should suggest `std::intrinsics::fabsf64`,
diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr
index cc1092dd0cf..9c9e92f6d4f 100644
--- a/tests/ui/resolve/filter-intrinsics.stderr
+++ b/tests/ui/resolve/filter-intrinsics.stderr
@@ -1,12 +1,12 @@
-error[E0425]: cannot find function `size_of` in this scope
+error[E0425]: cannot find function `transmute` in this scope
   --> $DIR/filter-intrinsics.rs:3:13
    |
-LL |     let _ = size_of::<usize>();
-   |             ^^^^^^^ not found in this scope
+LL |     let _ = transmute::<usize>();
+   |             ^^^^^^^^^ not found in this scope
    |
 help: consider importing this function
    |
-LL + use std::mem::size_of;
+LL + use std::mem::transmute;
    |
 
 error[E0425]: cannot find function `fabsf64` in this scope
diff --git a/tests/ui/resolve/issue-82865.stderr b/tests/ui/resolve/issue-82865.stderr
index 9d0439d9d87..730fd6d6026 100644
--- a/tests/ui/resolve/issue-82865.stderr
+++ b/tests/ui/resolve/issue-82865.stderr
@@ -15,13 +15,6 @@ LL |     Box::z
 LL |     mac!();
    |     ------ in this macro invocation
    |
-note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions:
-      Box::<T>::new
-      Box::<T>::new_uninit
-      Box::<T>::new_zeroed
-      Box::<T>::try_new
-      and 18 others
-  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
index 402efaf5027..ea9d48e7859 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
+++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
@@ -3,8 +3,8 @@
 //@ needs-dlltool
 //@ compile-flags: --crate-type lib --emit link
 //@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL"
-//@ normalize-stderr-test: "[^ ]*/foo.def" -> "$$DEF_FILE"
-//@ normalize-stderr-test: "[^ ]*/foo.lib" -> "$$LIB_FILE"
+//@ normalize-stderr-test: "[^ ]*/foo.dll_imports.def" -> "$$DEF_FILE"
+//@ normalize-stderr-test: "[^ ]*/foo.dll_imports.lib" -> "$$LIB_FILE"
 //@ normalize-stderr-test: "-m [^ ]*" -> "$$TARGET_MACHINE"
 //@ normalize-stderr-test: "-f [^ ]*" -> "$$ASM_FLAGS"
 //@ normalize-stderr-test: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX"
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs
index 9778217d462..6b5ba5bb624 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs
@@ -17,8 +17,6 @@ impl<T> const Foo for T where T: const Specialize {}
 //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
 //~| error: `const` can only be applied to `#[const_trait]` traits
 //~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207]
-//~| error: specialization impl does not specialize any associated items
-//~| error: could not resolve generic parameters on overridden impl
+//~| error: conflicting implementations of trait `Foo`
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr
index d18063f8d3d..70dd0350dc4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr
@@ -37,6 +37,15 @@ LL | impl<T> const Foo for T {}
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
+error[E0119]: conflicting implementations of trait `Foo`
+  --> $DIR/spec-effectvar-ice.rs:16:1
+   |
+LL | impl<T> const Foo for T {}
+   | ----------------------- first implementation here
+...
+LL | impl<T> const Foo for T where T: const Specialize {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
 error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
   --> $DIR/spec-effectvar-ice.rs:16:9
    |
@@ -46,24 +55,7 @@ LL | impl<T> const Foo for T where T: const Specialize {}
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
-error: specialization impl does not specialize any associated items
-  --> $DIR/spec-effectvar-ice.rs:16:1
-   |
-LL | impl<T> const Foo for T where T: const Specialize {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: impl is a specialization of this impl
-  --> $DIR/spec-effectvar-ice.rs:12:1
-   |
-LL | impl<T> const Foo for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: could not resolve generic parameters on overridden impl
-  --> $DIR/spec-effectvar-ice.rs:16:1
-   |
-LL | impl<T> const Foo for T where T: const Specialize {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0119, E0207.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/rust-2024/unsafe-env.e2021.stderr b/tests/ui/rust-2024/unsafe-env.e2021.stderr
index cc40ec2e466..90c1df192aa 100644
--- a/tests/ui/rust-2024/unsafe-env.e2021.stderr
+++ b/tests/ui/rust-2024/unsafe-env.e2021.stderr
@@ -1,5 +1,24 @@
+error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
+  --> $DIR/unsafe-env.rs:15:9
+   |
+LL |         unsafe_fn();
+   |         ^^^^^^^^^^^ call to unsafe function
+   |
+   = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+note: an unsafe function restricts its caller, but its body is safe by default
+  --> $DIR/unsafe-env.rs:9:1
+   |
+LL | unsafe fn unsafe_fn() {
+   | ^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/unsafe-env.rs:8:8
+   |
+LL | #[deny(unsafe_op_in_unsafe_fn)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe function or block
-  --> $DIR/unsafe-env.rs:23:5
+  --> $DIR/unsafe-env.rs:33:5
    |
 LL |     unsafe_fn();
    |     ^^^^^^^^^^^ call to unsafe function
@@ -7,17 +26,17 @@ LL |     unsafe_fn();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: unnecessary `unsafe` block
-  --> $DIR/unsafe-env.rs:26:5
+  --> $DIR/unsafe-env.rs:36:5
    |
 LL |     unsafe {
    |     ^^^^^^ unnecessary `unsafe` block
    |
 note: the lint level is defined here
-  --> $DIR/unsafe-env.rs:11:8
+  --> $DIR/unsafe-env.rs:21:8
    |
 LL | #[deny(unused_unsafe)]
    |        ^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/unsafe-env.e2024.stderr b/tests/ui/rust-2024/unsafe-env.e2024.stderr
index b43f817cf72..5ecdf3cd7a7 100644
--- a/tests/ui/rust-2024/unsafe-env.e2024.stderr
+++ b/tests/ui/rust-2024/unsafe-env.e2024.stderr
@@ -1,5 +1,42 @@
+error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe block
+  --> $DIR/unsafe-env.rs:10:5
+   |
+LL |     env::set_var("FOO", "BAR");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+note: an unsafe function restricts its caller, but its body is safe by default
+  --> $DIR/unsafe-env.rs:9:1
+   |
+LL | unsafe fn unsafe_fn() {
+   | ^^^^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/unsafe-env.rs:8:8
+   |
+LL | #[deny(unsafe_op_in_unsafe_fn)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0133]: call to unsafe function `std::env::remove_var` is unsafe and requires unsafe block
+  --> $DIR/unsafe-env.rs:12:5
+   |
+LL |     env::remove_var("FOO");
+   |     ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
+  --> $DIR/unsafe-env.rs:15:9
+   |
+LL |         unsafe_fn();
+   |         ^^^^^^^^^^^ call to unsafe function
+   |
+   = note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
 error[E0133]: call to unsafe function `set_var` is unsafe and requires unsafe block
-  --> $DIR/unsafe-env.rs:13:5
+  --> $DIR/unsafe-env.rs:23:5
    |
 LL |     env::set_var("FOO", "BAR");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
@@ -7,7 +44,7 @@ LL |     env::set_var("FOO", "BAR");
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function `remove_var` is unsafe and requires unsafe block
-  --> $DIR/unsafe-env.rs:15:5
+  --> $DIR/unsafe-env.rs:25:5
    |
 LL |     env::remove_var("FOO");
    |     ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
@@ -15,7 +52,7 @@ LL |     env::remove_var("FOO");
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function `unsafe_fn` is unsafe and requires unsafe block
-  --> $DIR/unsafe-env.rs:23:5
+  --> $DIR/unsafe-env.rs:33:5
    |
 LL |     unsafe_fn();
    |     ^^^^^^^^^^^ call to unsafe function
@@ -23,17 +60,17 @@ LL |     unsafe_fn();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: unnecessary `unsafe` block
-  --> $DIR/unsafe-env.rs:26:5
+  --> $DIR/unsafe-env.rs:36:5
    |
 LL |     unsafe {
    |     ^^^^^^ unnecessary `unsafe` block
    |
 note: the lint level is defined here
-  --> $DIR/unsafe-env.rs:11:8
+  --> $DIR/unsafe-env.rs:21:8
    |
 LL | #[deny(unused_unsafe)]
    |        ^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/unsafe-env.rs b/tests/ui/rust-2024/unsafe-env.rs
index a882f077b9b..601f44e1d3e 100644
--- a/tests/ui/rust-2024/unsafe-env.rs
+++ b/tests/ui/rust-2024/unsafe-env.rs
@@ -5,7 +5,17 @@
 
 use std::env;
 
-unsafe fn unsafe_fn() {}
+#[deny(unsafe_op_in_unsafe_fn)]
+unsafe fn unsafe_fn() {
+    env::set_var("FOO", "BAR");
+    //[e2024]~^ ERROR call to unsafe function `std::env::set_var` is unsafe
+    env::remove_var("FOO");
+    //[e2024]~^ ERROR call to unsafe function `std::env::remove_var` is unsafe
+    if false {
+        unsafe_fn();
+        //~^ ERROR call to unsafe function `unsafe_fn` is unsafe
+    }
+}
 fn safe_fn() {}
 
 #[deny(unused_unsafe)]
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr
new file mode 100644
index 00000000000..3a99caa719b
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2021.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
+  --> $DIR/extern-items-unsafe.rs:14:5
+   |
+LL |     test1(TEST1);
+   |     ^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/extern-items-unsafe.rs:14:11
+   |
+LL |     test1(TEST1);
+   |           ^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr
new file mode 100644
index 00000000000..fcf937b7ac5
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.edition2024.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
+  --> $DIR/extern-items-unsafe.rs:14:5
+   |
+LL |     test1(TEST1);
+   |     ^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: use of extern static is unsafe and requires unsafe block
+  --> $DIR/extern-items-unsafe.rs:14:11
+   |
+LL |     test1(TEST1);
+   |           ^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs
new file mode 100644
index 00000000000..ad569a256db
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items-unsafe.rs
@@ -0,0 +1,25 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+
+#![feature(unsafe_extern_blocks)]
+
+unsafe extern "C" {
+    static TEST1: i32;
+    fn test1(i: i32);
+}
+
+fn test2() {
+    test1(TEST1);
+    //~^ ERROR: call to unsafe function `test1` is unsafe
+    //~| ERROR: use of extern static is unsafe
+}
+
+fn test3() {
+    unsafe {
+        test1(TEST1);
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr
new file mode 100644
index 00000000000..d456cfc6829
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.edition2024.stderr
@@ -0,0 +1,12 @@
+error: extern blocks must be unsafe
+  --> $DIR/extern-items.rs:9:1
+   |
+LL | / extern "C" {
+LL | |
+LL | |     static TEST1: i32;
+LL | |     fn test1(i: i32);
+LL | | }
+   | |_^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
new file mode 100644
index 00000000000..16fa1bbb8a4
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/extern-items.rs
@@ -0,0 +1,20 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2021] check-pass
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+
+#![feature(unsafe_extern_blocks)]
+
+extern "C" {
+    //[edition2024]~^ ERROR extern blocks must be unsafe
+    static TEST1: i32;
+    fn test1(i: i32);
+}
+
+unsafe extern "C" {
+    static TEST2: i32;
+    fn test2(i: i32);
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
new file mode 100644
index 00000000000..74cd5621fce
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-items.rs
@@ -0,0 +1,18 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+//@ check-pass
+
+#![feature(unsafe_extern_blocks)]
+
+unsafe extern "C" {
+    safe static TEST1: i32;
+    safe fn test1(i: i32);
+}
+
+fn test2() {
+    test1(TEST1);
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr
new file mode 100644
index 00000000000..411cf48b486
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr
@@ -0,0 +1,20 @@
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5
+   |
+LL | extern "C" {
+   | ---------- help: add unsafe to this `extern` block
+LL |
+LL |     safe static TEST1: i32;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:12:5
+   |
+LL | extern "C" {
+   | ---------- help: add unsafe to this `extern` block
+...
+LL |     safe fn test1(i: i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr
new file mode 100644
index 00000000000..b634adc2999
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr
@@ -0,0 +1,32 @@
+error: extern blocks must be unsafe
+  --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:1
+   |
+LL | / extern "C" {
+LL | |
+LL | |     safe static TEST1: i32;
+LL | |
+LL | |     safe fn test1(i: i32);
+LL | |
+LL | | }
+   | |_^
+
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5
+   |
+LL | extern "C" {
+   | ---------- help: add unsafe to this `extern` block
+LL |
+LL |     safe static TEST1: i32;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: items in unadorned `extern` blocks cannot have safety qualifiers
+  --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:12:5
+   |
+LL | extern "C" {
+   | ---------- help: add unsafe to this `extern` block
+...
+LL |     safe fn test1(i: i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs
new file mode 100644
index 00000000000..11f55cb195f
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs
@@ -0,0 +1,20 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+
+#![feature(unsafe_extern_blocks)]
+
+extern "C" {
+    //[edition2024]~^ ERROR extern blocks must be unsafe
+    safe static TEST1: i32;
+    //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
+    safe fn test1(i: i32);
+    //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
+}
+
+fn test2() {
+    test1(TEST1);
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.fixed b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.fixed
new file mode 100644
index 00000000000..10c19759d8a
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.fixed
@@ -0,0 +1,19 @@
+//@ run-rustfix
+
+#![feature(unsafe_extern_blocks)]
+#![deny(missing_unsafe_on_extern)]
+#![allow(unused)]
+
+unsafe extern "C" {
+    //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern]
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+    static TEST1: i32;
+    fn test1(i: i32);
+}
+
+unsafe extern "C" {
+    static TEST2: i32;
+    fn test2(i: i32);
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.rs b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.rs
new file mode 100644
index 00000000000..b81e52ddc58
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.rs
@@ -0,0 +1,19 @@
+//@ run-rustfix
+
+#![feature(unsafe_extern_blocks)]
+#![deny(missing_unsafe_on_extern)]
+#![allow(unused)]
+
+extern "C" {
+    //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern]
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+    static TEST1: i32;
+    fn test1(i: i32);
+}
+
+unsafe extern "C" {
+    static TEST2: i32;
+    fn test2(i: i32);
+}
+
+fn main() {}
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr
new file mode 100644
index 00000000000..0a3c2cd25e3
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr
@@ -0,0 +1,25 @@
+error: extern blocks should be unsafe
+  --> $DIR/unsafe-extern-suggestion.rs:7:1
+   |
+LL |   extern "C" {
+   |   ^
+   |   |
+   |  _help: needs `unsafe` before the extern keyword: `unsafe`
+   | |
+LL | |
+LL | |
+LL | |     static TEST1: i32;
+LL | |     fn test1(i: i32);
+LL | | }
+   | |_^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #123743 <https://github.com/rust-lang/rust/issues/123743>
+note: the lint level is defined here
+  --> $DIR/unsafe-extern-suggestion.rs:4:9
+   |
+LL | #![deny(missing_unsafe_on_extern)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr
new file mode 100644
index 00000000000..8bb7ffefeea
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2021.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-items.rs:20:5
+   |
+LL |     test1(TEST1);
+   |     ^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/unsafe-items.rs:20:11
+   |
+LL |     test1(TEST1);
+   |           ^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr
new file mode 100644
index 00000000000..9a30142a632
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.edition2024.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
+  --> $DIR/unsafe-items.rs:20:5
+   |
+LL |     test1(TEST1);
+   |     ^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: use of extern static is unsafe and requires unsafe block
+  --> $DIR/unsafe-items.rs:20:11
+   |
+LL |     test1(TEST1);
+   |           ^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs
new file mode 100644
index 00000000000..9066953abc6
--- /dev/null
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-items.rs
@@ -0,0 +1,25 @@
+//@ revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+//@[edition2024] compile-flags: -Zunstable-options
+
+#![feature(unsafe_extern_blocks)]
+
+unsafe extern "C" {
+    unsafe static TEST1: i32;
+    unsafe fn test1(i: i32);
+}
+
+fn test2() {
+    unsafe {
+        test1(TEST1);
+    }
+}
+
+fn test3() {
+    test1(TEST1);
+    //~^ ERROR: call to unsafe function `test1` is unsafe
+    //~| ERROR: use of extern static is unsafe
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/dont-drop-upcast-candidate.rs b/tests/ui/specialization/dont-drop-upcast-candidate.rs
new file mode 100644
index 00000000000..98d8cad7c1f
--- /dev/null
+++ b/tests/ui/specialization/dont-drop-upcast-candidate.rs
@@ -0,0 +1,13 @@
+#![feature(unsize)]
+
+use std::marker::Unsize;
+use std::ops::Deref;
+
+trait Foo: Bar {}
+trait Bar {}
+
+impl<T> Bar for T where dyn Foo: Unsize<dyn Bar> {}
+impl Bar for () {}
+//~^ ERROR conflicting implementations of trait `Bar` for type `()`
+
+fn main() {}
diff --git a/tests/ui/specialization/dont-drop-upcast-candidate.stderr b/tests/ui/specialization/dont-drop-upcast-candidate.stderr
new file mode 100644
index 00000000000..dc0c54f9aa8
--- /dev/null
+++ b/tests/ui/specialization/dont-drop-upcast-candidate.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `Bar` for type `()`
+  --> $DIR/dont-drop-upcast-candidate.rs:10:1
+   |
+LL | impl<T> Bar for T where dyn Foo: Unsize<dyn Bar> {}
+   | ------------------------------------------------ first implementation here
+LL | impl Bar for () {}
+   | ^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/crashes/124464.rs b/tests/ui/static/duplicated-fields-issue-124464.rs
index 471479f5cf1..60609edbfeb 100644
--- a/tests/crashes/124464.rs
+++ b/tests/ui/static/duplicated-fields-issue-124464.rs
@@ -1,12 +1,16 @@
-//@ known-bug: rust-lang/rust #124464
+// Don't const eval fields with ambiguous layout.
+// See issues #125842 and #124464.
+
 enum TestOption<T> {
     TestSome(T),
     TestSome(T),
+//~^ ERROR the name `TestSome` is defined multiple times
 }
 
 pub struct Request {
     bar: TestOption<u64>,
     bar: u8,
+//~^ ERROR field `bar` is already declared
 }
 
 fn default_instance() -> &'static Request {
diff --git a/tests/ui/static/duplicated-fields-issue-124464.stderr b/tests/ui/static/duplicated-fields-issue-124464.stderr
new file mode 100644
index 00000000000..a36192ae8d6
--- /dev/null
+++ b/tests/ui/static/duplicated-fields-issue-124464.stderr
@@ -0,0 +1,22 @@
+error[E0428]: the name `TestSome` is defined multiple times
+  --> $DIR/duplicated-fields-issue-124464.rs:6:5
+   |
+LL |     TestSome(T),
+   |     ----------- previous definition of the type `TestSome` here
+LL |     TestSome(T),
+   |     ^^^^^^^^^^^ `TestSome` redefined here
+   |
+   = note: `TestSome` must be defined only once in the type namespace of this enum
+
+error[E0124]: field `bar` is already declared
+  --> $DIR/duplicated-fields-issue-124464.rs:12:5
+   |
+LL |     bar: TestOption<u64>,
+   |     -------------------- `bar` first declared here
+LL |     bar: u8,
+   |     ^^^^^^^ field already declared
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0124, E0428.
+For more information about an error, try `rustc --explain E0124`.
diff --git a/tests/ui/static/duplicated-fields-issue-125842.rs b/tests/ui/static/duplicated-fields-issue-125842.rs
new file mode 100644
index 00000000000..580b810232e
--- /dev/null
+++ b/tests/ui/static/duplicated-fields-issue-125842.rs
@@ -0,0 +1,21 @@
+// Do not try to evaluate static initalizers that reference
+// ill-defined types. This used to be an ICE.
+// See issues #125842 and #124464.
+struct Struct {
+    field: Option<u8>,
+    field: u8,
+//~^ ERROR field `field` is already declared
+}
+
+static STATIC_A: Struct = Struct {
+    field: 1
+};
+
+static STATIC_B: Struct = {
+    let field = 1;
+    Struct {
+        field,
+    }
+};
+
+fn main() {}
diff --git a/tests/ui/static/duplicated-fields-issue-125842.stderr b/tests/ui/static/duplicated-fields-issue-125842.stderr
new file mode 100644
index 00000000000..c80bb99005e
--- /dev/null
+++ b/tests/ui/static/duplicated-fields-issue-125842.stderr
@@ -0,0 +1,11 @@
+error[E0124]: field `field` is already declared
+  --> $DIR/duplicated-fields-issue-125842.rs:6:5
+   |
+LL |     field: Option<u8>,
+   |     ----------------- `field` first declared here
+LL |     field: u8,
+   |     ^^^^^^^^^ field already declared
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0124`.
diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr
index d08bb4745bf..50b561dfd16 100644
--- a/tests/ui/traits/item-privacy.stderr
+++ b/tests/ui/traits/item-privacy.stderr
@@ -126,14 +126,15 @@ LL |     S::B;
    |        ^ associated item not found in `S`
    |
    = help: items from traits can only be used if the trait is in scope
+help: there is a method `b` with a similar name
+  --> $DIR/item-privacy.rs:11:9
+   |
+LL |         fn b(&self) { }
+   |         ^^^^^^^^^^^
 help: trait `B` which provides `B` is implemented but not in scope; perhaps you want to import it
    |
 LL + use assoc_const::B;
    |
-help: there is a method `b` with a similar name
-   |
-LL |     S::b;
-   |        ~
 
 error[E0624]: associated constant `A` is private
   --> $DIR/item-privacy.rs:101:14
diff --git a/tests/ui/traits/next-solver/generalize/bivariant-alias.rs b/tests/ui/traits/next-solver/generalize/bivariant-alias.rs
new file mode 100644
index 00000000000..b03d547838a
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/bivariant-alias.rs
@@ -0,0 +1,20 @@
+//@ revisions: old next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// When generalizing an alias in a bivariant context, we have to set
+// `has_unconstrained_ty_var` as we may otherwise never check for
+// well-formedness of the generalized type, causing us to error due
+// to ambiguity.
+trait Trait {
+    type Assoc;
+}
+
+struct BivariantArg<I, T: Trait<Assoc = I>>(T);
+
+fn generalize<T: Trait>(input: BivariantArg<T::Assoc, T>) {
+    let _generalized = input;
+}
+
+pub fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.classic.stderr
index 266a532a1db..ff059bc5806 100644
--- a/tests/ui/type-alias-impl-trait/coherence.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.classic.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence.rs:14:1
+  --> $DIR/coherence.rs:16:1
    |
 LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
diff --git a/tests/ui/type-alias-impl-trait/coherence.next.stderr b/tests/ui/type-alias-impl-trait/coherence.next.stderr
new file mode 100644
index 00000000000..dab2786c1f0
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence.next.stderr
@@ -0,0 +1,14 @@
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/coherence.rs:16:1
+   |
+LL | impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------
+   | |                                    |
+   | |                                    `AliasOfForeignType<()>` is not defined in the current crate
+   | impl doesn't use only types from inside the current crate
+   |
+   = note: define and implement a trait or new type instead
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs
index 641c0fac17a..760e5210c5b 100644
--- a/tests/ui/type-alias-impl-trait/coherence.rs
+++ b/tests/ui/type-alias-impl-trait/coherence.rs
@@ -1,4 +1,6 @@
 //@ aux-build:foreign-crate.rs
+//@ revisions: classic next
+//@[next] compile-flags: -Znext-solver
 #![feature(type_alias_impl_trait)]
 
 extern crate foreign_crate;
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr
index 6a1a770228d..3b6999cabc4 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.infer.stderr
@@ -1,5 +1,5 @@
 error: `Bar` is forbidden as the type of a const generic parameter
-  --> $DIR/const_generic_type.rs:7:24
+  --> $DIR/const_generic_type.rs:8:24
    |
 LL | async fn test<const N: crate::Bar>() {
    |                        ^^^^^^^^^^
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
index a1a69bfaca3..56a10201651 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr
@@ -1,13 +1,13 @@
-error[E0283]: type annotations needed
-  --> $DIR/const_generic_type.rs:7:1
+error: unconstrained opaque type
+  --> $DIR/const_generic_type.rs:5:12
    |
-LL | async fn test<const N: crate::Bar>() {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+LL | type Bar = impl std::fmt::Display;
+   |            ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: cannot satisfy `_: std::fmt::Display`
+   = note: `Bar` must be used in combination with a concrete type within the same module
 
 error: `Bar` is forbidden as the type of a const generic parameter
-  --> $DIR/const_generic_type.rs:7:24
+  --> $DIR/const_generic_type.rs:8:24
    |
 LL | async fn test<const N: crate::Bar>() {
    |                        ^^^^^^^^^^
@@ -16,4 +16,3 @@ LL | async fn test<const N: crate::Bar>() {
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs
index 95a5e1c6286..bfd06826f00 100644
--- a/tests/ui/type-alias-impl-trait/const_generic_type.rs
+++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs
@@ -3,10 +3,10 @@
 
 #![feature(type_alias_impl_trait)]
 type Bar = impl std::fmt::Display;
+//[no_infer]~^ ERROR: unconstrained opaque type
 
 async fn test<const N: crate::Bar>() {
-    //[no_infer]~^ ERROR: type annotations needed
-    //~^^ ERROR: `Bar` is forbidden as the type of a const generic parameter
+    //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter
     #[cfg(infer)]
     let x: u32 = N;
 }
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs
index 6aa032d7ed8..92c2e7b4884 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/expanded-exhaustive.rs
@@ -25,6 +25,7 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(unnamed_fields)]
+#![feature(unsafe_extern_blocks)]
 #![feature(yeet_expr)]
 #![allow(incomplete_features)]
 
@@ -473,8 +474,8 @@ mod items {
 
     /// ItemKind::ForeignMod
     mod item_foreign_mod {
-        extern "C++" {}
-        extern {}
+        unsafe extern "C++" {}
+        unsafe extern {}
     }
 
     /// ItemKind::GlobalAsm
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index 8737063bf3c..9e45f57af35 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -26,6 +26,7 @@
 #![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(unnamed_fields)]
+#![feature(unsafe_extern_blocks)]
 #![feature(yeet_expr)]
 #![allow(incomplete_features)]
 #[prelude_import]
@@ -451,8 +452,8 @@ mod items {
     mod item_mod { }
     /// ItemKind::ForeignMod
     mod item_foreign_mod {
-        extern "C++" {}
-        extern {}
+        unsafe extern "C++" {}
+        unsafe extern {}
     }
     /// ItemKind::GlobalAsm
     mod item_global_asm {
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs
index db155f4fa3c..3f43fbfc0cf 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs
@@ -1,7 +1,6 @@
 trait Trait<const N: Trait = bar> {
     //~^ ERROR cannot find value `bar` in this scope
     //~| ERROR cycle detected when computing type of `Trait::N`
-    //~| ERROR cycle detected when computing type of `Trait::N`
     //~| ERROR the trait `Trait` cannot be made into an object
     //~| ERROR the trait `Trait` cannot be made into an object
     //~| ERROR the trait `Trait` cannot be made into an object
@@ -11,20 +10,20 @@ trait Trait<const N: Trait = bar> {
     //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     fn fnc<const N: Trait = u32>(&self) -> Trait {
-    //~^ ERROR the name `N` is already used for a generic parameter in this item's generic parameters
-    //~| ERROR expected value, found builtin type `u32`
-    //~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-    //~| ERROR associated item referring to unboxed trait object for its own trait
-    //~| ERROR the trait `Trait` cannot be made into an object
-    //~| ERROR `(dyn Trait<{const error}> + 'static)` is forbidden as the type of a const generic parameter
-    //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-    //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-    //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+        //~^ ERROR the name `N` is already used for a generic parameter in this item's generic parameters
+        //~| ERROR expected value, found builtin type `u32`
+        //~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+        //~| ERROR associated item referring to unboxed trait object for its own trait
+        //~| ERROR the trait `Trait` cannot be made into an object
+        //~| ERROR `(dyn Trait<{const error}> + 'static)` is forbidden as the type of a const generic parameter
+        //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+        //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+        //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+        //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+        //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+        //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
         bar
-    //~^ ERROR cannot find value `bar` in this scope
+        //~^ ERROR cannot find value `bar` in this scope
     }
 }
 
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
index cf985d9d1fd..f2456f99e62 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr
@@ -1,5 +1,5 @@
 error[E0403]: the name `N` is already used for a generic parameter in this item's generic parameters
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:18
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:18
    |
 LL | trait Trait<const N: Trait = bar> {
    |                   - first use of `N`
@@ -14,13 +14,13 @@ LL | trait Trait<const N: Trait = bar> {
    |                              ^^^ not found in this scope
 
 error[E0423]: expected value, found builtin type `u32`
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:29
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:29
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                             ^^^ not a value
 
 error[E0425]: cannot find value `bar` in this scope
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:26:9
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:25:9
    |
 LL |         bar
    |         ^^^ not found in this scope
@@ -53,28 +53,14 @@ LL | trait Trait<const N: Trait = bar> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0391]: cycle detected when computing type of `Trait::N`
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:13
-   |
-LL | trait Trait<const N: Trait = bar> {
-   |             ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: ...which immediately requires computing type of `Trait::N` again
-note: cycle used when computing explicit predicates of trait `Trait`
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:1
-   |
-LL | trait Trait<const N: Trait = bar> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
 error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:12
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:12
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |            ^^^^^^^^^^^^^^^^^^^^
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:21
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:21
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                     ^^^^^
@@ -87,7 +73,7 @@ LL |     fn fnc<const N: dyn Trait = u32>(&self) -> Trait {
    |                     +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:44
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:44
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                                            ^^^^^
@@ -120,7 +106,7 @@ LL | trait Trait<const N: Trait = bar> {
    |                      ^^^^^ `Trait` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:8
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:8
    |
 LL | trait Trait<const N: Trait = bar> {
    |       ----- this trait cannot be made into an object...
@@ -136,7 +122,7 @@ LL | trait Trait<const N: Trait = bar> {
    |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:8
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:8
    |
 LL | trait Trait<const N: Trait = bar> {
    |       ----- this trait cannot be made into an object...
@@ -154,7 +140,7 @@ LL | trait Trait<const N: Trait = bar> {
    = note: the only supported types are integers, `bool` and `char`
 
 error: associated item referring to unboxed trait object for its own trait
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:44
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:44
    |
 LL | trait Trait<const N: Trait = bar> {
    |       ----- in this trait
@@ -168,7 +154,7 @@ LL |     fn fnc<const N: Trait = u32>(&self) -> Self {
    |                                            ~~~~
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:21
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:21
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                     ^^^^^
@@ -182,13 +168,13 @@ LL |     fn fnc<const N: dyn Trait = u32>(&self) -> Trait {
    |                     +++
 
 error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:21
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:21
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                     ^^^^^ `Trait` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:8
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:8
    |
 LL | trait Trait<const N: Trait = bar> {
    |       ----- this trait cannot be made into an object...
@@ -204,7 +190,7 @@ LL | trait Trait<const N: Trait = bar> {
    |             ^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:8
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:8
    |
 LL | trait Trait<const N: Trait = bar> {
    |       ----- this trait cannot be made into an object...
@@ -215,14 +201,14 @@ LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: `(dyn Trait<{const error}> + 'static)` is forbidden as the type of a const generic parameter
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:13:21
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:12:21
    |
 LL |     fn fnc<const N: Trait = u32>(&self) -> Trait {
    |                     ^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
 
-error: aborting due to 14 previous errors; 5 warnings emitted
+error: aborting due to 13 previous errors; 5 warnings emitted
 
 Some errors have detailed explanations: E0038, E0391, E0403, E0423, E0425.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs
index 2995f26af4a..a953f1818c5 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs
@@ -1,15 +1,11 @@
 // Regression test for ICE #122989
 trait Foo<const N: Bar<2>> {
-//~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-//~| ERROR cycle detected when computing type of `Foo::N`
-//~| ERROR cycle detected when computing type of `Foo::N`
-//~| ERROR the trait `Foo` cannot be made into an object
-//~| ERROR the trait `Foo` cannot be made into an object
-//~| ERROR the trait `Foo` cannot be made into an object
-//~| ERROR `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter
-    fn func() {
-    }
+    //~^ WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| ERROR cycle detected when computing type of `Foo::N`
+    //~| ERROR the trait `Foo` cannot be made into an object
+    //~| ERROR `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter
+    fn func() {}
 }
 
 trait Bar<const M: Foo<2>> {}
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
index e6fdc440873..a0fd11de2dc 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
@@ -13,7 +13,7 @@ LL | trait Foo<const N: dyn Bar<2>> {
    |                    +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:20
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20
    |
 LL | trait Bar<const M: Foo<2>> {}
    |                    ^^^^^^
@@ -32,7 +32,7 @@ LL | trait Foo<const N: Bar<2>> {
    |           ^^^^^^^^^^^^^^^
    |
 note: ...which requires computing type of `Bar::M`...
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:11
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11
    |
 LL | trait Bar<const M: Foo<2>> {}
    |           ^^^^^^^^^^^^^^^
@@ -44,26 +44,6 @@ LL | trait Foo<const N: Bar<2>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error[E0391]: cycle detected when computing type of `Foo::N`
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11
-   |
-LL | trait Foo<const N: Bar<2>> {
-   |           ^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing type of `Bar::M`...
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:11
-   |
-LL | trait Bar<const M: Foo<2>> {}
-   |           ^^^^^^^^^^^^^^^
-   = note: ...which again requires computing type of `Foo::N`, completing the cycle
-note: cycle used when computing explicit predicates of trait `Foo`
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1
-   |
-LL | trait Foo<const N: Bar<2>> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:24
    |
@@ -71,43 +51,20 @@ LL | trait Foo<const N: Bar<2>> {
    |                        ^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8
-   |
-LL | trait Foo<const N: Bar<2>> {
-   |       --- this trait cannot be made into an object...
-...
-LL |     fn func() {
-   |        ^^^^ ...because associated function `func` has no `self` parameter
-help: consider turning `func` into a method by giving it a `&self` argument
-   |
-LL |     fn func(&self) {
-   |             +++++
-help: alternatively, consider constraining `func` so it does not apply to trait objects
-   |
-LL |     fn func() where Self: Sized {
-   |               +++++++++++++++++
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11
-   |
-LL | trait Foo<const N: Bar<2>> {
-   |           ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:8:8
    |
 LL | trait Foo<const N: Bar<2>> {
    |       --- this trait cannot be made into an object...
 ...
-LL |     fn func() {
+LL |     fn func() {}
    |        ^^^^ ...because associated function `func` has no `self` parameter
 help: consider turning `func` into a method by giving it a `&self` argument
    |
-LL |     fn func(&self) {
+LL |     fn func(&self) {}
    |             +++++
 help: alternatively, consider constraining `func` so it does not apply to trait objects
    |
-LL |     fn func() where Self: Sized {
+LL |     fn func() where Self: Sized {}
    |               +++++++++++++++++
 
 error: `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter
@@ -119,61 +76,37 @@ LL | trait Foo<const N: Bar<2>> {
    = note: the only supported types are integers, `bool` and `char`
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:11
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11
    |
 LL | trait Bar<const M: Foo<2>> {}
    |           ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:8:8
    |
 LL | trait Foo<const N: Bar<2>> {
    |       --- this trait cannot be made into an object...
 ...
-LL |     fn func() {
+LL |     fn func() {}
    |        ^^^^ ...because associated function `func` has no `self` parameter
 help: consider turning `func` into a method by giving it a `&self` argument
    |
-LL |     fn func(&self) {
+LL |     fn func(&self) {}
    |             +++++
 help: alternatively, consider constraining `func` so it does not apply to trait objects
    |
-LL |     fn func() where Self: Sized {
+LL |     fn func() where Self: Sized {}
    |               +++++++++++++++++
 
 error: `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:15:20
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20
    |
 LL | trait Bar<const M: Foo<2>> {}
    |                    ^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
 
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11
-   |
-LL | trait Foo<const N: Bar<2>> {
-   |           ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:8
-   |
-LL | trait Foo<const N: Bar<2>> {
-   |       --- this trait cannot be made into an object...
-...
-LL |     fn func() {
-   |        ^^^^ ...because associated function `func` has no `self` parameter
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: consider turning `func` into a method by giving it a `&self` argument
-   |
-LL |     fn func(&self) {
-   |             +++++
-help: alternatively, consider constraining `func` so it does not apply to trait objects
-   |
-LL |     fn func() where Self: Sized {
-   |               +++++++++++++++++
-
-error: aborting due to 8 previous errors; 2 warnings emitted
+error: aborting due to 5 previous errors; 2 warnings emitted
 
 Some errors have detailed explanations: E0038, E0391.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/triagebot.toml b/triagebot.toml
index 23e5c0a27f3..55f63ef2567 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -330,6 +330,7 @@ trigger_files = [
     "src/tools/compiletest",
     "src/tools/tidy",
     "src/tools/rustdoc-gui-test",
+    "src/tools/libcxx-version",
 ]
 
 [autolabel."T-infra"]
@@ -1117,6 +1118,7 @@ project-exploit-mitigations = [
 "/src/tools/tidy" =                                      ["bootstrap"]
 "/src/tools/x" =                                         ["bootstrap"]
 "/src/tools/rustdoc-gui-test" =                          ["bootstrap", "@onur-ozkan"]
+"/src/tools/libcxx-version" =                            ["@onur-ozkan"]
 
 # Enable tracking of PR review assignment
 # Documentation at: https://forge.rust-lang.org/triagebot/pr-assignment-tracking.html