about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Conjob Bot <miri@cron.bot>2023-08-16 05:32:16 +0000
committerThe Miri Conjob Bot <miri@cron.bot>2023-08-16 05:32:16 +0000
commit50b4bc07588dc1e40a1661cbef510e1f7efc4951 (patch)
tree78a47fcfe86b72de8326ebf6046a679d2ff3e7cc
parenta4d2130a4cb194280ae6e64cfea7979803ea9cb3 (diff)
parent656ee47db32e882fb02913f6204e09cc7a41a50e (diff)
downloadrust-50b4bc07588dc1e40a1661cbef510e1f7efc4951.tar.gz
rust-50b4bc07588dc1e40a1661cbef510e1f7efc4951.zip
Merge from rustc
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--Cargo.lock125
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs50
-rw-r--r--compiler/rustc_ast_lowering/src/lifetime_collector.rs17
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs12
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs16
-rw-r--r--compiler/rustc_attr/src/builtin.rs21
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs41
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs13
-rw-r--r--compiler/rustc_codegen_gcc/example/alloc_system.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs9
-rw-r--r--compiler/rustc_codegen_llvm/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs182
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs13
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs19
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs49
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs3
-rw-r--r--compiler/rustc_expand/src/base.rs5
-rw-r--r--compiler/rustc_expand/src/expand.rs21
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs7
-rw-r--r--compiler/rustc_feature/src/active.rs1
-rw-r--r--compiler/rustc_hir/src/hir.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs24
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs4
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs91
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs22
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--compiler/rustc_interface/Cargo.toml1
-rw-r--r--compiler/rustc_interface/src/passes.rs35
-rw-r--r--compiler/rustc_interface/src/queries.rs89
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint/src/context.rs3
-rw-r--r--compiler/rustc_lint/src/early.rs3
-rw-r--r--compiler/rustc_lint/src/late.rs6
-rw-r--r--compiler/rustc_lint/src/levels.rs14
-rw-r--r--compiler/rustc_lint/src/lib.rs4
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs72
-rw-r--r--compiler/rustc_lint/src/unused.rs18
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs39
-rw-r--r--compiler/rustc_llvm/build.rs1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp7
-rw-r--r--compiler/rustc_llvm/src/lib.rs8
-rw-r--r--compiler/rustc_metadata/src/creader.rs16
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs7
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs52
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs28
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs10
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/query/erase.rs1
-rw-r--r--compiler/rustc_middle/src/query/keys.rs37
-rw-r--r--compiler/rustc_middle/src/query/mod.rs36
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs22
-rw-r--r--compiler/rustc_middle/src/thir.rs1
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs2
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs13
-rw-r--r--compiler/rustc_middle/src/traits/select.rs1
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs7
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs232
-rw-r--r--compiler/rustc_mir_transform/src/coverage/debug.rs15
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs105
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs118
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs10
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs1
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs8
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs13
-rw-r--r--compiler/rustc_passes/src/check_attr.rs6
-rw-r--r--compiler/rustc_passes/src/check_const.rs6
-rw-r--r--compiler/rustc_passes/src/dead.rs132
-rw-r--r--compiler/rustc_passes/src/entry.rs6
-rw-r--r--compiler/rustc_passes/src/loops.rs4
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs4
-rw-r--r--compiler/rustc_passes/src/stability.rs6
-rw-r--r--compiler/rustc_privacy/src/lib.rs60
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs10
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs2
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--compiler/rustc_resolve/src/macros.rs3
-rw-r--r--compiler/rustc_session/src/parse.rs5
-rw-r--r--compiler/rustc_session/src/session.rs20
-rw-r--r--compiler/rustc_smir/src/lib.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs27
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs7
-rw-r--r--compiler/rustc_span/src/def_id.rs95
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/Cargo.toml2
-rw-r--r--compiler/rustc_target/src/abi/call/csky.rs31
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs2
-rw-r--r--compiler/rustc_target/src/asm/csky.rs128
-rw-r--r--compiler/rustc_target/src/asm/mod.rs24
-rw-r--r--compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs20
-rw-r--r--compiler/rustc_target/src/spec/loongarch64_unknown_none.rs3
-rw-r--r--compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs3
-rw-r--r--compiler/rustc_target/src/spec/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs102
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs82
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs31
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs31
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs155
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs209
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs55
-rw-r--r--config.example.toml8
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/sync.rs2
-rw-r--r--library/alloc/tests/str.rs7
-rw-r--r--library/core/src/any.rs587
-rw-r--r--library/core/src/error.rs745
-rw-r--r--library/core/src/ffi/c_str.rs8
-rw-r--r--library/core/src/ffi/mod.rs3
-rw-r--r--library/core/src/iter/adapters/map_windows.rs293
-rw-r--r--library/core/src/iter/adapters/mod.rs4
-rw-r--r--library/core/src/iter/mod.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs160
-rw-r--r--library/core/src/num/uint_macros.rs12
-rw-r--r--library/core/src/panicking.rs14
-rw-r--r--library/core/src/str/mod.rs7
-rw-r--r--library/core/tests/any.rs62
-rw-r--r--library/core/tests/error.rs66
-rw-r--r--library/core/tests/iter/adapters/map_windows.rs283
-rw-r--r--library/core/tests/iter/adapters/mod.rs1
-rw-r--r--library/core/tests/lib.rs5
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--library/profiler_builtins/build.rs6
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/src/env.rs13
-rw-r--r--library/std/src/env/tests.rs20
-rw-r--r--library/std/src/error.rs13
-rw-r--r--library/std/src/error/tests.rs4
-rw-r--r--library/std/src/ffi/os_str.rs8
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/os/l4re/raw.rs1
-rw-r--r--library/std/src/os/linux/raw.rs1
-rw-r--r--library/std/src/path.rs16
-rw-r--r--library/std/src/process.rs11
-rw-r--r--library/std/src/sys/common/alloc.rs1
-rw-r--r--library/std/src/sys/hermit/os.rs28
-rw-r--r--library/std/src/sys/personality/gcc.rs3
-rw-r--r--library/std/src/sys/sgx/os.rs51
-rw-r--r--library/std/src/sys/solid/os.rs28
-rw-r--r--library/std/src/sys/unix/os.rs28
-rw-r--r--library/std/src/sys/unsupported/os.rs18
-rw-r--r--library/std/src/sys/wasi/fd.rs10
-rw-r--r--library/std/src/sys/wasi/os.rs29
-rw-r--r--library/std/src/sys/wasi/thread.rs6
-rw-r--r--library/std/src/sys/windows/os.rs54
-rw-r--r--library/std/src/sys_common/wtf8.rs2
-rw-r--r--library/std/src/thread/local.rs27
-rw-r--r--library/unwind/src/libunwind.rs3
-rw-r--r--src/bootstrap/Cargo.lock4
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/bootstrap.py1
-rw-r--r--src/bootstrap/compile.rs14
-rw-r--r--src/bootstrap/config.rs30
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/bootstrap/llvm.rs6
-rwxr-xr-xsrc/ci/docker/run.sh11
-rw-r--r--src/ci/github-actions/ci.yml4
m---------src/doc/book0
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/codegen-options/index.md2
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md2
-rw-r--r--src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md70
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-linux.md2
-rw-r--r--src/doc/rustc/src/platform-support/netbsd.md2
-rw-r--r--src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md4
-rw-r--r--src/doc/unstable-book/src/compiler-flags/path-options.md2
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md25
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/librustdoc/clean/inline.rs10
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/tools/build-manifest/src/main.rs1
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/try_err.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark_used.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.rs2
-rw-r--r--src/tools/clippy/tests/ui/if_same_then_else2.stderr21
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--src/tools/rust-analyzer/Cargo.lock8
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs3
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml2
-rw-r--r--src/tools/tidy/src/deps.rs2
-rw-r--r--tests/rustdoc-gui/search-tab.goml52
-rw-r--r--tests/rustdoc-gui/sidebar-links-color.goml126
-rw-r--r--tests/rustdoc-gui/unsafe-fn.goml6
-rw-r--r--tests/ui/asm/issue-113788.rs7
-rw-r--r--tests/ui/asm/issue-113788.stderr9
-rw-r--r--tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs11
-rw-r--r--tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr78
-rw-r--r--tests/ui/check-cfg/compact-values.stderr2
-rw-r--r--tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs35
-rw-r--r--tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr23
-rw-r--r--tests/ui/did_you_mean/compatible-variants.stderr2
-rw-r--r--tests/ui/generic-associated-types/issue-102114.current.stderr (renamed from tests/ui/generic-associated-types/issue-102114.stderr)2
-rw-r--r--tests/ui/generic-associated-types/issue-102114.next.stderr12
-rw-r--r--tests/ui/generic-associated-types/issue-102114.rs3
-rw-r--r--tests/ui/generic-associated-types/issue-86218.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-90014-tait.stderr8
-rw-r--r--tests/ui/generic-const-items/reference-outlives-referent.rs9
-rw-r--r--tests/ui/generic-const-items/reference-outlives-referent.stderr20
-rw-r--r--tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr4
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr4
-rw-r--r--tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs22
-rw-r--r--tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr42
-rw-r--r--tests/ui/impl-trait/issue-99073-2.rs1
-rw-r--r--tests/ui/impl-trait/issue-99073-2.stderr18
-rw-r--r--tests/ui/impl-trait/issue-99073.rs1
-rw-r--r--tests/ui/impl-trait/issue-99073.stderr21
-rw-r--r--tests/ui/impl-trait/rpit/equal-lifetime-params-ok.rs19
-rw-r--r--tests/ui/impl-trait/rpit/non-defining-use.rs14
-rw-r--r--tests/ui/impl-trait/rpit/non-defining-use.stderr31
-rw-r--r--tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs26
-rw-r--r--tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs26
-rw-r--r--tests/ui/inline-const/pat-match-fndef.rs13
-rw-r--r--tests/ui/inline-const/pat-match-fndef.stderr17
-rw-r--r--tests/ui/internal/internal-unstable.rs2
-rw-r--r--tests/ui/internal/internal-unstable.stderr10
-rw-r--r--tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr2
-rw-r--r--tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs19
-rw-r--r--tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.stderr10
-rw-r--r--tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs13
-rw-r--r--tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.stderr10
-rw-r--r--tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs18
-rw-r--r--tests/ui/lint/lint-struct-necessary.rs31
-rw-r--r--tests/ui/lint/lint-struct-necessary.stderr19
-rw-r--r--tests/ui/lint/reference_casting.rs5
-rw-r--r--tests/ui/lint/reference_casting.stderr30
-rw-r--r--tests/ui/lint/unknown-lints/allow-in-other-module.rs26
-rw-r--r--tests/ui/lint/unknown-lints/other.rs10
-rw-r--r--tests/ui/macros/assert-eq-macro-msg.rs6
-rw-r--r--tests/ui/macros/assert-eq-macro-panic.rs6
-rw-r--r--tests/ui/macros/assert-matches-macro-msg.rs6
-rw-r--r--tests/ui/macros/assert-ne-macro-msg.rs6
-rw-r--r--tests/ui/macros/assert-ne-macro-panic.rs6
-rw-r--r--tests/ui/match/non-first-arm-doesnt-match-expected-return-type.rs21
-rw-r--r--tests/ui/match/non-first-arm-doesnt-match-expected-return-type.stderr12
-rw-r--r--tests/ui/parser/issues/issue-113203.rs7
-rw-r--r--tests/ui/parser/issues/issue-113203.stderr8
-rw-r--r--tests/ui/parser/issues/issue-70583-block-is-empty-2.rs8
-rw-r--r--tests/ui/parser/issues/issue-70583-block-is-empty-2.stderr3
-rw-r--r--tests/ui/regions/higher-ranked-implied.stderr8
-rw-r--r--tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr4
-rw-r--r--tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr4
-rw-r--r--tests/ui/regions/regions-lifetime-bounds-on-fns.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr26
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr60
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs3
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs5
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr11
-rw-r--r--tests/ui/std/slice-from-array-issue-113238.rs9
-rw-r--r--tests/ui/suggestions/issue-71394-no-from-impl.stderr2
-rw-r--r--tests/ui/suggestions/remove-question-symbol-with-paren.stderr3
-rw-r--r--tests/ui/target-feature/gate.rs1
-rw-r--r--tests/ui/target-feature/gate.stderr2
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr12
-rw-r--r--tests/ui/test-attrs/test-panic-abort.run.stdout6
-rw-r--r--tests/ui/traits/issue-105231.rs2
-rw-r--r--tests/ui/traits/issue-105231.stderr8
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs20
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr12
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs22
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs25
-rw-r--r--tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs24
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs2
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr8
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr (renamed from tests/ui/traits/trait-upcasting/type-checking-test-1.stderr)4
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr9
-rw-r--r--tests/ui/traits/trait-upcasting/type-checking-test-1.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_generalization.rs5
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr9
-rw-r--r--tests/ui/unsized/issue-75899.rs2
-rw-r--r--tests/ui/where-clauses/where-clause-bounds-inconsistency.rs1
-rw-r--r--triagebot.toml2
352 files changed, 5144 insertions, 2490 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6ff0f5e2736..b55ab229811 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -50,10 +50,10 @@ jobs:
       matrix:
         include:
           - name: mingw-check
-            os: ubuntu-20.04-16core-64gb
+            os: ubuntu-20.04-4core-16gb
             env: {}
           - name: mingw-check-tidy
-            os: ubuntu-20.04-16core-64gb
+            os: ubuntu-20.04-4core-16gb
             env: {}
           - name: x86_64-gnu-llvm-15
             os: ubuntu-20.04-16core-64gb
diff --git a/Cargo.lock b/Cargo.lock
index de6258502a3..8d707067bb9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8,31 +8,29 @@ version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
 dependencies = [
- "compiler_builtins",
  "gimli 0.27.3",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
 ]
 
 [[package]]
-name = "adler"
-version = "1.0.2"
+name = "addr2line"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
 dependencies = [
  "compiler_builtins",
+ "gimli 0.28.0",
+ "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
 ]
 
 [[package]]
-name = "ahash"
-version = "0.7.6"
+name = "adler"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 dependencies = [
- "getrandom",
- "once_cell",
- "version_check",
+ "compiler_builtins",
+ "rustc-std-workspace-core",
 ]
 
 [[package]]
@@ -178,11 +176,11 @@ dependencies = [
 
 [[package]]
 name = "ar_archive_writer"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74cfb39880a59e122232cb5fb06b20b4382d58c12fa9747d16f846d38a7b094c"
+checksum = "9792d37ca5173d7e7f4fe453739a0671d0557915a030a383d6b866476bbc3e71"
 dependencies = [
- "object",
+ "object 0.32.0",
 ]
 
 [[package]]
@@ -252,12 +250,12 @@ version = "0.3.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
 dependencies = [
- "addr2line",
+ "addr2line 0.20.0",
  "cc",
  "cfg-if",
  "libc",
  "miniz_oxide",
- "object",
+ "object 0.31.1",
  "rustc-demangle",
 ]
 
@@ -1159,9 +1157,9 @@ dependencies = [
 
 [[package]]
 name = "fallible-iterator"
-version = "0.2.0"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
+checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "fastrand"
@@ -1439,24 +1437,22 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.26.2"
+version = "0.27.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
-dependencies = [
- "fallible-iterator",
- "indexmap 1.9.3",
- "stable_deref_trait",
-]
+checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
 
 [[package]]
 name = "gimli"
-version = "0.27.3"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
+checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
 dependencies = [
  "compiler_builtins",
+ "fallible-iterator",
+ "indexmap 2.0.0",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
+ "stable_deref_trait",
 ]
 
 [[package]]
@@ -1525,18 +1521,6 @@ name = "hashbrown"
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-dependencies = [
- "ahash 0.7.6",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
-dependencies = [
- "ahash 0.8.3",
-]
 
 [[package]]
 name = "hashbrown"
@@ -1544,6 +1528,7 @@ version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
 dependencies = [
+ "ahash",
  "allocator-api2",
  "compiler_builtins",
  "rustc-std-workspace-alloc",
@@ -2450,11 +2435,20 @@ version = "0.31.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
 dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "object"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
+dependencies = [
  "compiler_builtins",
  "crc32fast",
  "flate2",
- "hashbrown 0.13.2",
- "indexmap 1.9.3",
+ "hashbrown 0.14.0",
+ "indexmap 2.0.0",
  "memchr",
  "rustc-std-workspace-alloc",
  "rustc-std-workspace-core",
@@ -3362,7 +3356,7 @@ dependencies = [
  "cstr",
  "libc",
  "measureme",
- "object",
+ "object 0.32.0",
  "rustc-demangle",
  "rustc_ast",
  "rustc_attr",
@@ -3398,7 +3392,7 @@ dependencies = [
  "itertools",
  "jobserver",
  "libc",
- "object",
+ "object 0.32.0",
  "pathdiff",
  "regex",
  "rustc_arena",
@@ -3805,6 +3799,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_expand",
+ "rustc_feature",
  "rustc_fluent_macro",
  "rustc_fs_util",
  "rustc_hir",
@@ -4331,7 +4326,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.3.2",
- "object",
+ "object 0.32.0",
  "rustc_abi",
  "rustc_data_structures",
  "rustc_feature",
@@ -4586,12 +4581,12 @@ checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
 
 [[package]]
 name = "ruzstd"
-version = "0.3.1"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe"
+checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc"
 dependencies = [
  "byteorder",
- "thiserror",
+ "thiserror-core",
  "twox-hash",
 ]
 
@@ -4860,7 +4855,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
 name = "std"
 version = "0.0.0"
 dependencies = [
- "addr2line",
+ "addr2line 0.21.0",
  "alloc",
  "cfg-if",
  "compiler_builtins",
@@ -4871,7 +4866,7 @@ dependencies = [
  "hermit-abi 0.3.2",
  "libc",
  "miniz_oxide",
- "object",
+ "object 0.32.0",
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
@@ -5139,6 +5134,26 @@ dependencies = [
 ]
 
 [[package]]
+name = "thiserror-core"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d97345f6437bb2004cd58819d8a9ef8e36cdd7661c2abc4bbde0a7c40d9f497"
+dependencies = [
+ "thiserror-core-impl",
+]
+
+[[package]]
+name = "thiserror-core-impl"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10ac1c5050e43014d16b2f94d0d2ce79e65ffdd8b38d8048f9c8f6a8a6da62ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
 name = "thiserror-impl"
 version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5151,13 +5166,13 @@ dependencies = [
 
 [[package]]
 name = "thorin-dwp"
-version = "0.6.0"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98c040e1340b889d4180c64e1d787efa9c32cb1617757e101480b61238b0d927"
+checksum = "4db52ee8fec06e119b692ef3dd2c4cf621a99204c1b8c47407870ed050305b9b"
 dependencies = [
- "gimli 0.26.2",
- "hashbrown 0.12.3",
- "object",
+ "gimli 0.28.0",
+ "hashbrown 0.14.0",
+ "object 0.32.0",
  "tracing",
 ]
 
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index b23cee14f75..7408b4fb0af 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1648,7 +1648,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         hir::ExprKind::Match(
             scrutinee,
             arena_vec![self; break_arm, continue_arm],
-            hir::MatchSource::TryDesugar,
+            hir::MatchSource::TryDesugar(scrutinee.hir_id),
         )
     }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 89775bdee26..4a47de1280c 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2495,35 +2495,31 @@ impl<'hir> GenericArgsCtor<'hir> {
 
         let id = lcx.next_node_id();
         let hir_id = lcx.next_id();
+
+        let Some(host_param_id) = lcx.host_param_id else {
+            lcx.tcx
+                .sess
+                .delay_span_bug(span, "no host param id for call in const yet no errors reported");
+            return;
+        };
+
         let body = lcx.lower_body(|lcx| {
-            (
-                &[],
-                match constness {
-                    ast::Const::Yes(_) => {
-                        let hir_id = lcx.next_id();
-                        let res =
-                            Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id());
-                        let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved(
-                            None,
-                            lcx.arena.alloc(hir::Path {
-                                span,
-                                res,
-                                segments: arena_vec![lcx; hir::PathSegment::new(Ident {
-                                    name: sym::host,
-                                    span,
-                                }, hir_id, res)],
-                            }),
-                        ));
-                        lcx.expr(span, expr_kind)
-                    }
-                    ast::Const::No => lcx.expr(
+            (&[], {
+                let hir_id = lcx.next_id();
+                let res = Res::Def(DefKind::ConstParam, host_param_id.to_def_id());
+                let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved(
+                    None,
+                    lcx.arena.alloc(hir::Path {
                         span,
-                        hir::ExprKind::Lit(
-                            lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }),
-                        ),
-                    ),
-                },
-            )
+                        res,
+                        segments: arena_vec![lcx; hir::PathSegment::new(Ident {
+                            name: sym::host,
+                            span,
+                        }, hir_id, res)],
+                    }),
+                ));
+                lcx.expr(span, expr_kind)
+            })
         });
 
         let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
index 0e0bdf17389..6f75419c387 100644
--- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs
+++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs
@@ -1,7 +1,7 @@
 use super::ResolverAstLoweringExt;
 use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor};
 use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind};
-use rustc_hir::def::LifetimeRes;
+use rustc_hir::def::{DefKind, LifetimeRes, Res};
 use rustc_middle::span_bug;
 use rustc_middle::ty::ResolverAstLowering;
 use rustc_span::symbol::{kw, Ident};
@@ -77,7 +77,20 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
     }
 
     fn visit_ty(&mut self, t: &'ast Ty) {
-        match t.kind {
+        match &t.kind {
+            TyKind::Path(None, _) => {
+                // We can sometimes encounter bare trait objects
+                // which are represented in AST as paths.
+                if let Some(partial_res) = self.resolver.get_partial_res(t.id)
+                    && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
+                {
+                    self.current_binders.push(t.id);
+                    visit::walk_ty(self, t);
+                    self.current_binders.pop();
+                } else {
+                    visit::walk_ty(self, t);
+                }
+            }
             TyKind::BareFn(_) => {
                 self.current_binders.push(t.id);
                 visit::walk_ty(self, t);
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 79fc9e4382f..bd3e676daa4 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -13,6 +13,7 @@ use rustc_ast::*;
 use rustc_ast::{walk_list, StaticItem};
 use rustc_ast_pretty::pprust::{self, State};
 use rustc_data_structures::fx::FxIndexMap;
+use rustc_feature::Features;
 use rustc_macros::Subdiagnostic;
 use rustc_parse::validate_attr;
 use rustc_session::lint::builtin::{
@@ -45,6 +46,7 @@ enum DisallowTildeConstContext<'a> {
 
 struct AstValidator<'a> {
     session: &'a Session,
+    features: &'a Features,
 
     /// The span of the `extern` in an `extern { ... }` block, if any.
     extern_mod: Option<&'a Item>,
@@ -1023,7 +1025,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
                 self.check_type_no_bounds(bounds, "this context");
 
-                if self.session.features_untracked().lazy_type_alias {
+                if self.features.lazy_type_alias {
                     if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) {
                         self.err_handler().emit_err(err);
                     }
@@ -1500,9 +1502,15 @@ fn deny_equality_constraints(
     this.err_handler().emit_err(err);
 }
 
-pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
+pub fn check_crate(
+    session: &Session,
+    features: &Features,
+    krate: &Crate,
+    lints: &mut LintBuffer,
+) -> bool {
     let mut validator = AstValidator {
         session,
+        features,
         extern_mod: None,
         in_trait_impl: false,
         in_const_trait_impl: false,
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index c4efad7caf2..10c9c3ef111 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -514,10 +514,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 }
 
-pub fn check_crate(krate: &ast::Crate, sess: &Session) {
-    maybe_stage_features(sess, krate);
-    check_incompatible_features(sess);
-    let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() };
+pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
+    maybe_stage_features(sess, features, krate);
+    check_incompatible_features(sess, features);
+    let mut visitor = PostExpansionVisitor { sess, features };
 
     let spans = sess.parse_sess.gated_spans.spans.borrow();
     macro_rules! gate_all {
@@ -600,12 +600,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     visit::walk_crate(&mut visitor, krate);
 }
 
-fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
+fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) {
     // checks if `#![feature]` has been used to enable any lang feature
     // does not check the same for lib features unless there's at least one
     // declared lang feature
     if !sess.opts.unstable_features.is_nightly_build() {
-        let lang_features = &sess.features_untracked().declared_lang_features;
+        let lang_features = &features.declared_lang_features;
         if lang_features.len() == 0 {
             return;
         }
@@ -640,9 +640,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
     }
 }
 
-fn check_incompatible_features(sess: &Session) {
-    let features = sess.features_untracked();
-
+fn check_incompatible_features(sess: &Session, features: &Features) {
     let declared_features = features
         .declared_lang_features
         .iter()
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 6ed5fc77d75..3592287b95c 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -800,18 +800,15 @@ pub struct Deprecation {
 }
 
 /// Finds the deprecation attribute. `None` if none exists.
-pub fn find_deprecation(sess: &Session, attrs: &[Attribute]) -> Option<(Deprecation, Span)> {
-    find_deprecation_generic(sess, attrs.iter())
-}
-
-fn find_deprecation_generic<'a, I>(sess: &Session, attrs_iter: I) -> Option<(Deprecation, Span)>
-where
-    I: Iterator<Item = &'a Attribute>,
-{
+pub fn find_deprecation(
+    sess: &Session,
+    features: &Features,
+    attrs: &[Attribute],
+) -> Option<(Deprecation, Span)> {
     let mut depr: Option<(Deprecation, Span)> = None;
-    let is_rustc = sess.features_untracked().staged_api;
+    let is_rustc = features.staged_api;
 
-    'outer: for attr in attrs_iter {
+    'outer: for attr in attrs {
         if !attr.has_name(sym::deprecated) {
             continue;
         }
@@ -872,7 +869,7 @@ where
                                 }
                             }
                             sym::suggestion => {
-                                if !sess.features_untracked().deprecated_suggestion {
+                                if !features.deprecated_suggestion {
                                     sess.emit_err(session_diagnostics::DeprecatedItemSuggestion {
                                         span: mi.span,
                                         is_nightly: sess.is_nightly_build().then_some(()),
@@ -890,7 +887,7 @@ where
                                     meta.span(),
                                     AttrError::UnknownMetaItem(
                                         pprust::path_to_string(&mi.path),
-                                        if sess.features_untracked().deprecated_suggestion {
+                                        if features.deprecated_suggestion {
                                             &["since", "note", "suggestion"]
                                         } else {
                                             &["since", "note"]
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 68dddd65acb..4da7b602571 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -371,40 +371,27 @@ fn check_opaque_type_parameter_valid(
     span: Span,
 ) -> Result<(), ErrorGuaranteed> {
     let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
-    match opaque_ty_hir.expect_opaque_ty().origin {
-        // No need to check return position impl trait (RPIT)
-        // because for type and const parameters they are correct
-        // by construction: we convert
-        //
-        // fn foo<P0..Pn>() -> impl Trait
-        //
-        // into
-        //
-        // type Foo<P0...Pn>
-        // fn foo<P0..Pn>() -> Foo<P0...Pn>.
-        //
-        // For lifetime parameters we convert
-        //
-        // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
-        //
-        // into
-        //
-        // type foo::<'p0..'pn>::Foo<'q0..'qm>
-        // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
-        //
-        // which would error here on all of the `'static` args.
-        OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()),
-        // Check these
-        OpaqueTyOrigin::TyAlias { .. } => {}
-    }
+    let is_ty_alias = match opaque_ty_hir.expect_opaque_ty().origin {
+        OpaqueTyOrigin::TyAlias { .. } => true,
+        OpaqueTyOrigin::AsyncFn(..) | OpaqueTyOrigin::FnReturn(..) => false,
+    };
+
     let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
     let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
     for (i, arg) in opaque_type_key.args.iter().enumerate() {
+        if let Err(guar) = arg.error_reported() {
+            return Err(guar);
+        }
+
         let arg_is_param = match arg.unpack() {
             GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
-            GenericArgKind::Lifetime(lt) => {
+            GenericArgKind::Lifetime(lt) if is_ty_alias => {
                 matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
             }
+            // FIXME(#113916): we can't currently check for unique lifetime params,
+            // see that issue for more. We will also have to ignore unused lifetime
+            // params for RPIT, but that's comparatively trivial ✨
+            GenericArgKind::Lifetime(_) => continue,
             GenericArgKind::Const(ct) => matches!(ct.kind(), ty::ConstKind::Param(_)),
         };
 
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 3e90ae6907f..9302db104b6 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -69,7 +69,7 @@ pub fn expand_assert<'cx>(
     // If `generic_assert` is enabled, generates rich captured outputs
     //
     // FIXME(c410-f3r) See https://github.com/rust-lang/rust/issues/96949
-    else if let Some(features) = cx.ecfg.features && features.generic_assert {
+    else if cx.ecfg.features.generic_assert {
         context::Context::new(cx, call_site_span).build(cond_expr, panic_path())
     }
     // If `generic_assert` is not enabled, only outputs a literal "assertion failed: ..."
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 1397cee7af8..31cac51845f 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -24,7 +24,7 @@ pub fn expand_cfg(
                 &cfg,
                 &cx.sess.parse_sess,
                 cx.current_expansion.lint_node_id,
-                cx.ecfg.features,
+                Some(cx.ecfg.features),
             );
             MacEager::expr(cx.expr_bool(sp, matches_cfg))
         }
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 49401e9ca94..f826c6e7712 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -31,10 +31,11 @@ pub(crate) fn expand(
 
 pub(crate) fn cfg_eval(
     sess: &Session,
-    features: Option<&Features>,
+    features: &Features,
     annotatable: Annotatable,
     lint_node_id: NodeId,
 ) -> Annotatable {
+    let features = Some(features);
     CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true, lint_node_id } }
         .configure_annotatable(annotatable)
         // Since the item itself has already been configured by the `InvocationCollector`,
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 7c0b36ced96..dae1bc5bfe5 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -5,6 +5,7 @@ use rustc_ast::{self as ast, attr, NodeId};
 use rustc_ast_pretty::pprust;
 use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
 use rustc_expand::expand::{AstFragment, ExpansionConfig};
+use rustc_feature::Features;
 use rustc_session::Session;
 use rustc_span::hygiene::AstPass;
 use rustc_span::source_map::SourceMap;
@@ -46,13 +47,14 @@ struct CollectProcMacros<'a> {
 pub fn inject(
     krate: &mut ast::Crate,
     sess: &Session,
+    features: &Features,
     resolver: &mut dyn ResolverExpand,
     is_proc_macro_crate: bool,
     has_proc_macro_decls: bool,
     is_test_crate: bool,
     handler: &rustc_errors::Handler,
 ) {
-    let ecfg = ExpansionConfig::default("proc_macro".to_string());
+    let ecfg = ExpansionConfig::default("proc_macro".to_string(), features);
     let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
 
     let mut collect = CollectProcMacros {
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index 07e6288ed8c..3ee3112f021 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -1,6 +1,7 @@
 use rustc_ast::{self as ast, attr};
 use rustc_expand::base::{ExtCtxt, ResolverExpand};
 use rustc_expand::expand::ExpansionConfig;
+use rustc_feature::Features;
 use rustc_session::Session;
 use rustc_span::edition::Edition::*;
 use rustc_span::hygiene::AstPass;
@@ -13,6 +14,7 @@ pub fn inject(
     pre_configured_attrs: &[ast::Attribute],
     resolver: &mut dyn ResolverExpand,
     sess: &Session,
+    features: &Features,
 ) -> usize {
     let orig_num_items = krate.items.len();
     let edition = sess.parse_sess.edition;
@@ -39,7 +41,7 @@ pub fn inject(
     let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
     let call_site = DUMMY_SP.with_call_site_ctxt(expn_id.to_expn_id());
 
-    let ecfg = ExpansionConfig::default("std_lib_injection".to_string());
+    let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features);
     let cx = ExtCtxt::new(sess, ecfg, resolver, None);
 
     // .rev() to preserve ordering above in combination with insert(0, ...)
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 507b74c2437..d8846a9f0aa 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -41,7 +41,12 @@ struct TestCtxt<'a> {
 
 /// Traverse the crate, collecting all the test functions, eliding any
 /// existing main functions, and synthesizing a main test harness
-pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn ResolverExpand) {
+pub fn inject(
+    krate: &mut ast::Crate,
+    sess: &Session,
+    features: &Features,
+    resolver: &mut dyn ResolverExpand,
+) {
     let span_diagnostic = sess.diagnostic();
     let panic_strategy = sess.panic_strategy();
     let platform_panic_strategy = sess.target.panic_strategy;
@@ -76,7 +81,7 @@ pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn Resolve
             resolver,
             reexport_test_harness_main,
             krate,
-            &sess.features_untracked(),
+            features,
             panic_strategy,
             test_runner,
         )
@@ -243,9 +248,7 @@ fn generate_test_harness(
     panic_strategy: PanicStrategy,
     test_runner: Option<ast::Path>,
 ) {
-    let mut econfig = ExpansionConfig::default("test".to_string());
-    econfig.features = Some(features);
-
+    let econfig = ExpansionConfig::default("test".to_string(), features);
     let ext_cx = ExtCtxt::new(sess, econfig, resolver, None);
 
     let expn_id = ext_cx.resolver.expansion_for_ast_pass(
diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs
index e756b347e89..3deef419f42 100644
--- a/compiler/rustc_codegen_gcc/example/alloc_system.rs
+++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs
@@ -12,6 +12,7 @@
               target_arch = "mips",
               target_arch = "mips32r6",
               target_arch = "powerpc",
+              target_arch = "csky"
               target_arch = "powerpc64"))]
 const MIN_ALIGN: usize = 8;
 #[cfg(any(target_arch = "x86_64",
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 4c3b7f5036c..905fdac92e9 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -107,7 +107,7 @@ enum ConstraintOrRegister {
 
 
 impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
-    fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) {
+    fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) {
         if options.contains(InlineAsmOptions::MAY_UNWIND) {
             self.sess()
                 .create_err(UnwindingInlineAsm { span: span[0] })
@@ -173,7 +173,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                             let is_target_supported = reg.reg_class().supported_types(asm_arch).iter()
                                 .any(|&(_, feature)| {
                                     if let Some(feature) = feature {
-                                        self.tcx.sess.target_features.contains(&feature)
+                                        self.tcx.asm_target_features(instance.def_id()).contains(&feature)
                                     } else {
                                         true // Register class is unconditionally supported
                                     }
@@ -597,6 +597,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
             InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
             InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
             InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
+            InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
+            InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
             InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r"
             InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
             InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r",
@@ -673,6 +675,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
+        InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
+        InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
         InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
         InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
         InlineAsmRegClass::Msp430(_) => unimplemented!(),
@@ -860,6 +864,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
         InlineAsmRegClass::S390x(_) => None,
         InlineAsmRegClass::Msp430(_) => None,
         InlineAsmRegClass::M68k(_) => None,
+        InlineAsmRegClass::CSKY(_) => None,
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index ad51f2d0958..be09820d08d 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -11,7 +11,7 @@ bitflags = "1.0"
 cstr = "0.2"
 libc = "0.2"
 measureme = "10.0.0"
-object = { version = "0.31.1", default-features = false, features = [
+object = { version = "0.32.0", default-features = false, features = [
     "std",
     "read",
 ] }
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index 8bb93025c45..db5c1388ef8 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{DebugInfo, OomStrategy};
 
 use crate::debuginfo;
-use crate::llvm::{self, False, True};
+use crate::llvm::{self, Context, False, Module, True, Type};
 use crate::ModuleLlvm;
 
 pub(crate) unsafe fn codegen(
@@ -29,7 +29,6 @@ pub(crate) unsafe fn codegen(
     };
     let i8 = llvm::LLVMInt8TypeInContext(llcx);
     let i8p = llvm::LLVMPointerTypeInContext(llcx, 0);
-    let void = llvm::LLVMVoidTypeInContext(llcx);
 
     if kind == AllocatorKind::Default {
         for method in ALLOCATOR_METHODS {
@@ -54,102 +53,25 @@ pub(crate) unsafe fn codegen(
                     panic!("invalid allocator output")
                 }
             };
-            let ty = llvm::LLVMFunctionType(
-                output.unwrap_or(void),
-                args.as_ptr(),
-                args.len() as c_uint,
-                False,
-            );
-            let name = global_fn_name(method.name);
-            let llfn =
-                llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
-
-            if tcx.sess.target.default_hidden_visibility {
-                llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-            }
-            if tcx.sess.must_emit_unwind_tables() {
-                let uwtable = attributes::uwtable_attr(llcx);
-                attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
-            }
 
-            let callee = default_fn_name(method.name);
-            let callee =
-                llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
-            llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
-
-            let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
-
-            let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
-            llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
-            let args = args
-                .iter()
-                .enumerate()
-                .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
-                .collect::<Vec<_>>();
-            let ret = llvm::LLVMRustBuildCall(
-                llbuilder,
-                ty,
-                callee,
-                args.as_ptr(),
-                args.len() as c_uint,
-                [].as_ptr(),
-                0 as c_uint,
-            );
-            llvm::LLVMSetTailCall(ret, True);
-            if output.is_some() {
-                llvm::LLVMBuildRet(llbuilder, ret);
-            } else {
-                llvm::LLVMBuildRetVoid(llbuilder);
-            }
-            llvm::LLVMDisposeBuilder(llbuilder);
+            let from_name = global_fn_name(method.name);
+            let to_name = default_fn_name(method.name);
+
+            create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false);
         }
     }
 
     // rust alloc error handler
-    let args = [usize, usize]; // size, align
-
-    let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False);
-    let name = "__rust_alloc_error_handler";
-    let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
-    // -> ! DIFlagNoReturn
-    let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
-    attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
-
-    if tcx.sess.target.default_hidden_visibility {
-        llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-    }
-    if tcx.sess.must_emit_unwind_tables() {
-        let uwtable = attributes::uwtable_attr(llcx);
-        attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
-    }
-
-    let callee = alloc_error_handler_name(alloc_error_handler_kind);
-    let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
-    // -> ! DIFlagNoReturn
-    attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
-    llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
-
-    let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
-
-    let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
-    llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
-    let args = args
-        .iter()
-        .enumerate()
-        .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
-        .collect::<Vec<_>>();
-    let ret = llvm::LLVMRustBuildCall(
-        llbuilder,
-        ty,
-        callee,
-        args.as_ptr(),
-        args.len() as c_uint,
-        [].as_ptr(),
-        0 as c_uint,
+    create_wrapper_function(
+        tcx,
+        llcx,
+        llmod,
+        "__rust_alloc_error_handler",
+        &alloc_error_handler_name(alloc_error_handler_kind),
+        &[usize, usize], // size, align
+        None,
+        true,
     );
-    llvm::LLVMSetTailCall(ret, True);
-    llvm::LLVMBuildRetVoid(llbuilder);
-    llvm::LLVMDisposeBuilder(llbuilder);
 
     // __rust_alloc_error_handler_should_panic
     let name = OomStrategy::SYMBOL;
@@ -175,3 +97,79 @@ pub(crate) unsafe fn codegen(
         dbg_cx.finalize(tcx.sess);
     }
 }
+
+fn create_wrapper_function(
+    tcx: TyCtxt<'_>,
+    llcx: &Context,
+    llmod: &Module,
+    from_name: &str,
+    to_name: &str,
+    args: &[&Type],
+    output: Option<&Type>,
+    no_return: bool,
+) {
+    unsafe {
+        let ty = llvm::LLVMFunctionType(
+            output.unwrap_or_else(|| llvm::LLVMVoidTypeInContext(llcx)),
+            args.as_ptr(),
+            args.len() as c_uint,
+            False,
+        );
+        let llfn = llvm::LLVMRustGetOrInsertFunction(
+            llmod,
+            from_name.as_ptr().cast(),
+            from_name.len(),
+            ty,
+        );
+        let no_return = if no_return {
+            // -> ! DIFlagNoReturn
+            let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
+            attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
+            Some(no_return)
+        } else {
+            None
+        };
+
+        if tcx.sess.target.default_hidden_visibility {
+            llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
+        }
+        if tcx.sess.must_emit_unwind_tables() {
+            let uwtable = attributes::uwtable_attr(llcx);
+            attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
+        }
+
+        let callee =
+            llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_ptr().cast(), to_name.len(), ty);
+        if let Some(no_return) = no_return {
+            // -> ! DIFlagNoReturn
+            attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
+        }
+        llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
+
+        let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
+
+        let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
+        llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
+        let args = args
+            .iter()
+            .enumerate()
+            .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
+            .collect::<Vec<_>>();
+        let ret = llvm::LLVMRustBuildCall(
+            llbuilder,
+            ty,
+            callee,
+            args.as_ptr(),
+            args.len() as c_uint,
+            [].as_ptr(),
+            0 as c_uint,
+        );
+        llvm::LLVMSetTailCall(ret, True);
+        if output.is_some() {
+            llvm::LLVMBuildRet(llbuilder, ret);
+        } else {
+            llvm::LLVMBuildRetVoid(llbuilder);
+        }
+        llvm::LLVMDisposeBuilder(llbuilder);
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 2a6ad1be763..1323261ae92 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -44,9 +44,10 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     let is_target_supported = |reg_class: InlineAsmRegClass| {
                         for &(_, feature) in reg_class.supported_types(asm_arch) {
                             if let Some(feature) = feature {
-                                let codegen_fn_attrs = self.tcx.codegen_fn_attrs(instance.def_id());
-                                if self.tcx.sess.target_features.contains(&feature)
-                                    || codegen_fn_attrs.target_features.contains(&feature)
+                                if self
+                                    .tcx
+                                    .asm_target_features(instance.def_id())
+                                    .contains(&feature)
                                 {
                                     return true;
                                 }
@@ -261,6 +262,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                 InlineAsmArch::M68k => {
                     constraints.push("~{ccr}".to_string());
                 }
+                InlineAsmArch::CSKY => {}
             }
         }
         if !options.contains(InlineAsmOptions::NOMEM) {
@@ -693,6 +695,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
             InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
             InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
             InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
+            InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
+            InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
             InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
                 bug!("LLVM backend does not support SPIR-V")
             }
@@ -792,6 +796,7 @@ fn modifier_to_llvm(
             bug!("LLVM backend does not support SPIR-V")
         }
         InlineAsmRegClass::M68k(_) => None,
+        InlineAsmRegClass::CSKY(_) => None,
         InlineAsmRegClass::Err => unreachable!(),
     }
 }
@@ -868,6 +873,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
         InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
+        InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
+        InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 8f383f68bcd..34d0e2d1df6 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -4,14 +4,14 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
-ar_archive_writer = "0.1.3"
+ar_archive_writer = "0.1.5"
 bitflags = "1.2.1"
 cc = "1.0.69"
 itertools = "0.10.1"
 tracing = "0.1"
 jobserver = "0.1.22"
 tempfile = "3.2"
-thorin-dwp = "0.6"
+thorin-dwp = "0.7"
 pathdiff = "0.2.0"
 serde_json = "1.0.59"
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
@@ -42,7 +42,7 @@ rustc_session = { path = "../rustc_session" }
 libc = "0.2.50"
 
 [dependencies.object]
-version = "0.31.1"
+version = "0.32.0"
 default-features = false
 features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write"]
 
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index bb65c3c81d9..a7ac728c59b 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2991,25 +2991,10 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
         return;
     }
 
-    let self_contained_linker = sess.opts.cg.link_self_contained.linker();
-
-    // FIXME: some targets default to using `lld`, but users can only override the linker on the CLI
-    // and cannot yet select the precise linker flavor to opt out of that. See for example issue
-    // #113597 for the `thumbv6m-none-eabi` target: a driver is used, and its default linker
-    // conflicts with the target's flavor, causing unexpected arguments being passed.
-    //
-    // Until the new `LinkerFlavor`-like CLI options are stabilized, we only adopt MCP510's behavior
-    // if its dedicated unstable CLI flags are used, to keep the current sub-optimal stable
-    // behavior.
-    let using_mcp510 =
-        self_contained_linker || sess.opts.cg.linker_flavor.is_some_and(|f| f.is_unstable());
-    if !using_mcp510 && !unstable_use_lld {
-        return;
-    }
-
     // 1. Implement the "self-contained" part of this feature by adding rustc distribution
     //    directories to the tool's search path.
-    if self_contained_linker || unstable_use_lld {
+    let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld;
+    if self_contained_linker {
         for path in sess.get_tools_search_paths(false) {
             cmd.arg({
                 let mut arg = OsString::from("-B");
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 5c7df29444b..0be84c9fa83 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -209,6 +209,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         "hexagon" => Architecture::Hexagon,
         "bpf" => Architecture::Bpf,
         "loongarch64" => Architecture::LoongArch64,
+        "csky" => Architecture::Csky,
         // Unsupported architecture.
         _ => return None,
     };
@@ -307,6 +308,13 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
             // the appropriate EF_AVR_ARCH flag.
             ef_avr_arch(&sess.target.options.cpu)
         }
+        Architecture::Csky => {
+            let e_flags = match sess.target.options.abi.as_ref() {
+                "abiv2" => elf::EF_CSKY_ABIV2,
+                _ => elf::EF_CSKY_ABIV1,
+            };
+            e_flags
+        }
         _ => 0,
     };
     // adapted from LLVM's `MCELFObjectTargetWriter::getOSABI`
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index f577f653ccd..7bed3fa6150 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -2,7 +2,6 @@
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
-#![feature(int_roundings)]
 #![feature(let_chains)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index c370ba9be56..baf6b19d3f9 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -296,6 +296,52 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
 
 const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))];
 
+const CSKY_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+    // tidy-alphabetical-start
+    ("10e60", Some(sym::csky_target_feature)),
+    ("2e3", Some(sym::csky_target_feature)),
+    ("3e3r1", Some(sym::csky_target_feature)),
+    ("3e3r2", Some(sym::csky_target_feature)),
+    ("3e3r3", Some(sym::csky_target_feature)),
+    ("3e7", Some(sym::csky_target_feature)),
+    ("7e10", Some(sym::csky_target_feature)),
+    ("cache", Some(sym::csky_target_feature)),
+    ("doloop", Some(sym::csky_target_feature)),
+    ("dsp1e2", Some(sym::csky_target_feature)),
+    ("dspe60", Some(sym::csky_target_feature)),
+    ("e1", Some(sym::csky_target_feature)),
+    ("e2", Some(sym::csky_target_feature)),
+    ("edsp", Some(sym::csky_target_feature)),
+    ("elrw", Some(sym::csky_target_feature)),
+    ("float1e2", Some(sym::csky_target_feature)),
+    ("float1e3", Some(sym::csky_target_feature)),
+    ("float3e4", Some(sym::csky_target_feature)),
+    ("float7e60", Some(sym::csky_target_feature)),
+    ("floate1", Some(sym::csky_target_feature)),
+    ("hard-tp", Some(sym::csky_target_feature)),
+    ("high-registers", Some(sym::csky_target_feature)),
+    ("hwdiv", Some(sym::csky_target_feature)),
+    ("mp", Some(sym::csky_target_feature)),
+    ("mp1e2", Some(sym::csky_target_feature)),
+    ("nvic", Some(sym::csky_target_feature)),
+    ("trust", Some(sym::csky_target_feature)),
+    ("vdsp2e60f", Some(sym::csky_target_feature)),
+    ("vdspv1", Some(sym::csky_target_feature)),
+    ("vdspv2", Some(sym::csky_target_feature)),
+    // tidy-alphabetical-end
+    //fpu
+    // tidy-alphabetical-start
+    ("fdivdu", Some(sym::csky_target_feature)),
+    ("fpuv2_df", Some(sym::csky_target_feature)),
+    ("fpuv2_sf", Some(sym::csky_target_feature)),
+    ("fpuv3_df", Some(sym::csky_target_feature)),
+    ("fpuv3_hf", Some(sym::csky_target_feature)),
+    ("fpuv3_hi", Some(sym::csky_target_feature)),
+    ("fpuv3_sf", Some(sym::csky_target_feature)),
+    ("hard-float", Some(sym::csky_target_feature)),
+    ("hard-float-abi", Some(sym::csky_target_feature)),
+    // tidy-alphabetical-end
+];
 /// When rustdoc is running, provide a list of all known features so that all their respective
 /// primitives may be documented.
 ///
@@ -311,6 +357,7 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol
         .chain(RISCV_ALLOWED_FEATURES.iter())
         .chain(WASM_ALLOWED_FEATURES.iter())
         .chain(BPF_ALLOWED_FEATURES.iter())
+        .chain(CSKY_ALLOWED_FEATURES)
         .cloned()
 }
 
@@ -325,6 +372,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
         "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
         "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
         "bpf" => BPF_ALLOWED_FEATURES,
+        "csky" => CSKY_ALLOWED_FEATURES,
         _ => &[],
     }
 }
@@ -396,6 +444,7 @@ pub fn from_target_feature(
                 Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature,
                 Some(sym::bpf_target_feature) => rust_features.bpf_target_feature,
                 Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature,
+                Some(sym::csky_target_feature) => rust_features.csky_target_feature,
                 Some(name) => bug!("unknown target feature gate {}", name),
                 None => true,
             };
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index b077c10907e..fae047bff9e 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -772,7 +772,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     };
 
                     match implsrc {
-                        Ok(Some(ImplSource::Param(ty::BoundConstness::ConstIfConst, _))) => {
+                        Ok(Some(ImplSource::Param(_))) if tcx.features().effects => {
                             debug!(
                                 "const_trait_impl: provided {:?} via where-clause in {:?}",
                                 trait_ref, param_env
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 8293bdfd969..b1b2859ef9d 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -174,8 +174,7 @@ impl Qualif for NeedsNonConstDrop {
 
         if !matches!(
             impl_src,
-            ImplSource::Builtin(BuiltinImplSource::Misc, _)
-                | ImplSource::Param(ty::BoundConstness::ConstIfConst, _)
+            ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(_)
         ) {
             // If our const destruct candidate is not ConstDestruct or implied by the param env,
             // then it's bad
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 12473a2bb0b..c4d2a374f0c 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -18,6 +18,7 @@ use rustc_errors::{
     Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic,
     MultiSpan, PResult,
 };
+use rustc_feature::Features;
 use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT;
 use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, RegisteredTools};
 use rustc_parse::{self, parser, MACRO_ARGUMENTS};
@@ -767,6 +768,7 @@ impl SyntaxExtension {
     /// and other properties converted from attributes.
     pub fn new(
         sess: &Session,
+        features: &Features,
         kind: SyntaxExtensionKind,
         span: Span,
         helper_attrs: Vec<Symbol>,
@@ -816,7 +818,7 @@ impl SyntaxExtension {
             allow_internal_unstable: (!allow_internal_unstable.is_empty())
                 .then(|| allow_internal_unstable.into()),
             stability: stability.map(|(s, _)| s),
-            deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d),
+            deprecation: attr::find_deprecation(&sess, features, attrs).map(|(d, _)| d),
             helper_attrs,
             edition,
             builtin_name,
@@ -957,6 +959,7 @@ pub trait LintStoreExpand {
     fn pre_expansion_lint(
         &self,
         sess: &Session,
+        features: &Features,
         registered_tools: &RegisteredTools,
         node_id: NodeId,
         attrs: &[Attribute],
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 165c6d47c8a..34d16bf00cd 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -796,7 +796,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             | Annotatable::FieldDef(..)
             | Annotatable::Variant(..) => panic!("unexpected annotatable"),
         };
-        if self.cx.ecfg.proc_macro_hygiene() {
+        if self.cx.ecfg.features.proc_macro_hygiene {
             return;
         }
         feature_err(
@@ -834,7 +834,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             }
         }
 
-        if !self.cx.ecfg.proc_macro_hygiene() {
+        if !self.cx.ecfg.features.proc_macro_hygiene {
             annotatable
                 .visit_with(&mut GateProcMacroInput { parse_sess: &self.cx.sess.parse_sess });
         }
@@ -1122,6 +1122,7 @@ impl InvocationCollectorNode for P<ast::Item> {
                 if let Some(lint_store) = ecx.lint_store {
                     lint_store.pre_expansion_lint(
                         ecx.sess,
+                        ecx.ecfg.features,
                         ecx.resolver.registered_tools(),
                         ecx.current_expansion.lint_node_id,
                         &attrs,
@@ -1580,7 +1581,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn cfg(&self) -> StripUnconfigured<'_> {
         StripUnconfigured {
             sess: &self.cx.sess,
-            features: self.cx.ecfg.features,
+            features: Some(self.cx.ecfg.features),
             config_tokens: false,
             lint_node_id: self.cx.current_expansion.lint_node_id,
         }
@@ -1676,7 +1677,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
     // Detect use of feature-gated or invalid attributes on macro invocations
     // since they will not be detected after macro expansion.
     fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
-        let features = self.cx.ecfg.features.unwrap();
+        let features = self.cx.ecfg.features;
         let mut attrs = attrs.iter().peekable();
         let mut span: Option<Span> = None;
         while let Some(attr) = attrs.next() {
@@ -1976,7 +1977,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
 
 pub struct ExpansionConfig<'feat> {
     pub crate_name: String,
-    pub features: Option<&'feat Features>,
+    pub features: &'feat Features,
     pub recursion_limit: Limit,
     pub trace_mac: bool,
     /// If false, strip `#[test]` nodes
@@ -1987,11 +1988,11 @@ pub struct ExpansionConfig<'feat> {
     pub proc_macro_backtrace: bool,
 }
 
-impl<'feat> ExpansionConfig<'feat> {
-    pub fn default(crate_name: String) -> ExpansionConfig<'static> {
+impl ExpansionConfig<'_> {
+    pub fn default(crate_name: String, features: &Features) -> ExpansionConfig<'_> {
         ExpansionConfig {
             crate_name,
-            features: None,
+            features,
             recursion_limit: Limit::new(1024),
             trace_mac: false,
             should_test: false,
@@ -1999,8 +2000,4 @@ impl<'feat> ExpansionConfig<'feat> {
             proc_macro_backtrace: false,
         }
     }
-
-    fn proc_macro_hygiene(&self) -> bool {
-        self.features.is_some_and(|features| features.proc_macro_hygiene)
-    }
 }
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 1b935058c04..ce8b4621720 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -16,6 +16,7 @@ use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, TransparencyError};
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::{Applicability, ErrorGuaranteed};
+use rustc_feature::Features;
 use rustc_lint_defs::builtin::{
     RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
 };
@@ -375,6 +376,7 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
 /// Converts a macro item into a syntax extension.
 pub fn compile_declarative_macro(
     sess: &Session,
+    features: &Features,
     def: &ast::Item,
     edition: Edition,
 ) -> (SyntaxExtension, Vec<(usize, Span)>) {
@@ -382,6 +384,7 @@ pub fn compile_declarative_macro(
     let mk_syn_ext = |expander| {
         SyntaxExtension::new(
             sess,
+            features,
             SyntaxExtensionKind::LegacyBang(expander),
             def.span,
             Vec::new(),
@@ -503,7 +506,7 @@ pub fn compile_declarative_macro(
                         true,
                         &sess.parse_sess,
                         def.id,
-                        sess.features_untracked(),
+                        features,
                         edition,
                     )
                     .pop()
@@ -527,7 +530,7 @@ pub fn compile_declarative_macro(
                         false,
                         &sess.parse_sess,
                         def.id,
-                        sess.features_untracked(),
+                        features,
                         edition,
                     )
                     .pop()
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 898f5fd3b70..953ea1bf523 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -282,6 +282,7 @@ declare_features! (
     (active, arm_target_feature, "1.27.0", Some(44839), None),
     (active, avx512_target_feature, "1.27.0", Some(44839), None),
     (active, bpf_target_feature, "1.54.0", Some(44839), None),
+    (active, csky_target_feature, "CURRENT_RUSTC_VERSION", Some(44839), None),
     (active, ermsb_target_feature, "1.49.0", Some(44839), None),
     (active, hexagon_target_feature, "1.27.0", Some(44839), None),
     (active, mips_target_feature, "1.27.0", Some(44839), None),
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 6340f1dcca1..0bfd62d68b2 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2148,7 +2148,7 @@ pub enum MatchSource {
     /// A desugared `for _ in _ { .. }` loop.
     ForLoopDesugar,
     /// A desugared `?` operator.
-    TryDesugar,
+    TryDesugar(HirId),
     /// A desugared `<expr>.await`.
     AwaitDesugar,
     /// A desugared `format_args!()`.
@@ -2162,7 +2162,7 @@ impl MatchSource {
         match self {
             Normal => "match",
             ForLoopDesugar => "for",
-            TryDesugar => "?",
+            TryDesugar(_) => "?",
             AwaitDesugar => ".await",
             FormatArgs => "format_args!()",
         }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 8a5099804ed..46e8cf81bc1 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -8,7 +8,7 @@ use rustc_attr as attr;
 use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ItemKind, Node, PathSegment};
 use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
@@ -1443,12 +1443,12 @@ pub(super) fn check_type_params_are_used<'tcx>(
     }
 }
 
-pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let module = tcx.hir_module_items(module_def_id);
     for id in module.items() {
         check_item_type(tcx, id);
     }
-    if module_def_id == CRATE_DEF_ID {
+    if module_def_id == LocalModDefId::CRATE_DEF_ID {
         super::entry::check_for_entry_fn(tcx);
     }
 }
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 044fb405e32..ad02ca252c4 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -308,6 +308,15 @@ fn compare_method_predicate_entailment<'tcx>(
     }
 
     if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
+        // Select obligations to make progress on inference before processing
+        // the wf obligation below.
+        // FIXME(-Ztrait-solver=next): Not needed when the hack below is removed.
+        let errors = ocx.select_where_possible();
+        if !errors.is_empty() {
+            let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
+            return Err(reported);
+        }
+
         // See #108544. Annoying, we can end up in cases where, because of winnowing,
         // we pick param env candidates over a more general impl, leading to more
         // stricter lifetime requirements than we would otherwise need. This can
@@ -378,7 +387,7 @@ fn compare_method_predicate_entailment<'tcx>(
     // lifetime parameters.
     let outlives_env = OutlivesEnvironment::with_bounds(
         param_env,
-        infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()),
+        infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
     );
     let errors = infcx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index b0dd5e5787d..945953edd5a 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -68,7 +68,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         let asm_ty = match *ty.kind() {
             // `!` is allowed for input but not for output (issue #87802)
             ty::Never if is_input => return None,
-            ty::Error(_) => return None,
+            _ if ty.references_error() => return None,
             ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
             ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
             ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 16d4d099c7e..f5beefc47f3 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -5,7 +5,7 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
 use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
@@ -1854,7 +1854,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
     }
 }
 
-fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) {
+fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) {
     let items = tcx.hir_module_items(module);
     items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
     items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id));
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 02a5d28b1e2..7b9f61d7ab2 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -22,7 +22,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{GenericParamKind, Node};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
@@ -48,7 +48,7 @@ mod type_of;
 ///////////////////////////////////////////////////////////////////////////
 // Main entry point
 
-fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx });
 }
 
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 35882ad352b..5591fa6f2a5 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -59,7 +59,7 @@ struct ParameterCollector {
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
         match *t.kind() {
-            ty::Alias(ty::Projection | ty::Inherent, ..) if !self.include_nonconstraining => {
+            ty::Alias(..) if !self.include_nonconstraining => {
                 // projections are not injective
                 return ControlFlow::Continue(());
             }
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 4f705eaf10a..788121f7a30 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -14,7 +14,7 @@ use min_specialization::check_min_specialization;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::{Span, Symbol};
@@ -51,7 +51,7 @@ mod min_specialization;
 /// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
 /// //   ^ 'a is unused and appears in assoc type, error
 /// ```
-fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let min_specialization = tcx.features().min_specialization;
     let module = tcx.hir_module_items(module_def_id);
     for id in module.items() {
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 6d926cd8aa1..7ad9f51ba70 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -107,7 +107,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let (span, code) = match prior_arm {
                 // The reason for the first arm to fail is not that the match arms diverge,
                 // but rather that there's a prior obligation that doesn't hold.
-                None => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
+                None => {
+                    (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id, match_src))
+                }
                 Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => (
                     expr.span,
                     ObligationCauseCode::MatchExpressionArm(Box::new(MatchExpressionArmCause {
@@ -120,7 +122,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         scrut_span: scrut.span,
                         source: match_src,
                         prior_arms: other_arms.clone(),
-                        scrut_hir_id: scrut.hir_id,
                         opt_suggest_box_span,
                     })),
                 ),
@@ -145,7 +146,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 other_arms.remove(0);
             }
 
-            prior_arm = Some((arm_block_id, arm_ty, arm_span));
+            if !arm_ty.is_never() {
+                // When a match arm has type `!`, then it doesn't influence the expected type for
+                // the following arm. If all of the prior arms are `!`, then the influence comes
+                // from elsewhere and we shouldn't point to any previous arm.
+                prior_arm = Some((arm_block_id, arm_ty, arm_span));
+            }
         }
 
         // If all of the arms in the `match` diverge,
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 1cfdc5b9e7f..726914a995b 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1603,7 +1603,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                         );
                         err.span_label(cause.span, "return type is not `()`");
                     }
-                    ObligationCauseCode::BlockTailExpression(blk_id) => {
+                    ObligationCauseCode::BlockTailExpression(blk_id, ..) => {
                         let parent_id = fcx.tcx.hir().parent_id(blk_id);
                         err = self.report_return_mismatched_types(
                             cause,
@@ -1650,10 +1650,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
 
                 augment_error(&mut err);
 
-                let is_insufficiently_polymorphic =
-                    matches!(coercion_error, TypeError::RegionsInsufficientlyPolymorphic(..));
-
-                if !is_insufficiently_polymorphic && let Some(expr) = expression {
+                if let Some(expr) = expression {
                     fcx.emit_coerce_suggestions(
                         &mut err,
                         expr,
@@ -1751,7 +1748,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 ) && !in_external_macro(fcx.tcx.sess, cond_expr.span)
                     && !matches!(
                         cond_expr.kind,
-                        hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
+                        hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
                     )
             {
                 err.span_label(cond_expr.span, "expected this to be `()`");
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index b05cef56ad2..5b06088c348 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -84,6 +84,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.annotate_expected_due_to_let_ty(err, expr, error);
 
+        // FIXME(#73154): For now, we do leak check when coercing function
+        // pointers in typeck, instead of only during borrowck. This can lead
+        // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
+        if matches!(error, Some(TypeError::RegionsInsufficientlyPolymorphic(..))) {
+            return;
+        }
+
         if self.is_destruct_assignment_desugaring(expr) {
             return;
         }
@@ -263,22 +270,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr_ty = self.resolve_vars_if_possible(checked_ty);
         let mut err = self.err_ctxt().report_mismatched_types(&cause, expected, expr_ty, e);
 
-        let is_insufficiently_polymorphic =
-            matches!(e, TypeError::RegionsInsufficientlyPolymorphic(..));
-
-        // FIXME(#73154): For now, we do leak check when coercing function
-        // pointers in typeck, instead of only during borrowck. This can lead
-        // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
-        if !is_insufficiently_polymorphic {
-            self.emit_coerce_suggestions(
-                &mut err,
-                expr,
-                expr_ty,
-                expected,
-                expected_ty_expr,
-                Some(e),
-            );
-        }
+        self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e));
 
         (expected, Some(err))
     }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 40f9a954034..817115012a4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1580,7 +1580,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let coerce = ctxt.coerce.as_mut().unwrap();
             if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
                 let span = self.get_expr_coercion_span(tail_expr);
-                let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
+                let cause = self.cause(
+                    span,
+                    ObligationCauseCode::BlockTailExpression(blk.hir_id, hir::MatchSource::Normal),
+                );
                 let ty_for_diagnostic = coerce.merged_ty();
                 // We use coerce_inner here because we want to augment the error
                 // suggesting to wrap the block in square brackets if it might've
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index a0d31d3a22c..72a04a02bf4 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -1681,7 +1681,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             || found_assoc(tcx.types.u64)
             || found_assoc(tcx.types.u128)
             || found_assoc(tcx.types.f32)
-            || found_assoc(tcx.types.f32);
+            || found_assoc(tcx.types.f64);
         if found_candidate
             && actual.is_numeric()
             && !actual.has_concrete_skeleton()
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index bb479b5bdcc..8d67f692568 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -3,7 +3,7 @@
 use crate::errors;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::unord::UnordMap;
-use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
+use rustc_middle::dep_graph::{SerializedDepGraph, WorkProductMap};
 use rustc_middle::query::on_disk_cache::OnDiskCache;
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::Decodable;
@@ -16,8 +16,6 @@ use super::file_format;
 use super::fs::*;
 use super::work_product;
 
-type WorkProductMap = UnordMap<WorkProductId, WorkProduct>;
-
 #[derive(Debug)]
 /// Represents the result of an attempt to load incremental compilation data.
 pub enum LoadResult<T> {
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index bfaa52f9c81..0cfaf583774 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -1,7 +1,9 @@
 use crate::errors;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::join;
-use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
+use rustc_middle::dep_graph::{
+    DepGraph, SerializedDepGraph, WorkProduct, WorkProductId, WorkProductMap,
+};
 use rustc_middle::ty::TyCtxt;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use rustc_serialize::Encodable as RustcEncodable;
@@ -101,7 +103,7 @@ pub fn save_work_product_index(
     // deleted during invalidation. Some object files don't change their
     // content, they are just not needed anymore.
     let previous_work_products = dep_graph.previous_work_products();
-    for (id, wp) in previous_work_products.iter() {
+    for (id, wp) in previous_work_products.to_sorted_stable_ord().iter() {
         if !new_work_products.contains_key(id) {
             work_product::delete_workproduct_files(sess, wp);
             debug_assert!(
@@ -146,7 +148,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
 pub fn build_dep_graph(
     sess: &Session,
     prev_graph: SerializedDepGraph,
-    prev_work_products: FxIndexMap<WorkProductId, WorkProduct>,
+    prev_work_products: WorkProductMap,
 ) -> Option<DepGraph> {
     if sess.opts.incremental.is_none() {
         // No incremental compilation.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 75cca973306..ac5468f3dfd 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -743,6 +743,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
                 err.span_label(span, "expected due to this");
             }
+            ObligationCauseCode::BlockTailExpression(
+                _,
+                hir::MatchSource::TryDesugar(scrut_hir_id),
+            ) => {
+                if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
+                    let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
+                    let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
+                        let arg_expr = args.first().expect("try desugaring call w/out arg");
+                        self.typeck_results.as_ref().and_then(|typeck_results| {
+                            typeck_results.expr_ty_opt(arg_expr)
+                        })
+                    } else {
+                        bug!("try desugaring w/out call expr as scrutinee");
+                    };
+
+                    match scrut_ty {
+                        Some(ty) if expected == ty => {
+                            let source_map = self.tcx.sess.source_map();
+                            err.span_suggestion(
+                                source_map.end_point(cause.span()),
+                                "try removing this `?`",
+                                "",
+                                Applicability::MachineApplicable,
+                            );
+                        }
+                        _ => {}
+                    }
+                }
+            },
             ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
                 arm_block_id,
                 arm_span,
@@ -752,12 +781,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 prior_arm_ty,
                 source,
                 ref prior_arms,
-                scrut_hir_id,
                 opt_suggest_box_span,
                 scrut_span,
                 ..
             }) => match source {
-                hir::MatchSource::TryDesugar => {
+                hir::MatchSource::TryDesugar(scrut_hir_id) => {
                     if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
                         let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
                         let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
@@ -1927,7 +1955,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     true
                 };
 
-            if should_suggest_fixes {
+            // FIXME(#73154): For now, we do leak check when coercing function
+            // pointers in typeck, instead of only during borrowck. This can lead
+            // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
+            if should_suggest_fixes
+                && !matches!(terr, TypeError::RegionsInsufficientlyPolymorphic(..))
+            {
                 self.suggest_tuple_pattern(cause, &exp_found, diag);
                 self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
                 self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
@@ -1973,7 +2006,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         trace: &TypeTrace<'tcx>,
         terr: TypeError<'tcx>,
     ) -> Vec<TypeErrorAdditionalDiags> {
-        use crate::traits::ObligationCauseCode::MatchExpressionArm;
+        use crate::traits::ObligationCauseCode::{BlockTailExpression, MatchExpressionArm};
         let mut suggestions = Vec::new();
         let span = trace.cause.span();
         let values = self.resolve_vars_if_possible(trace.values);
@@ -1991,11 +2024,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 // specify a byte literal
                 (ty::Uint(ty::UintTy::U8), ty::Char) => {
                     if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
-                        && let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
-                        && !code.starts_with("\\u") // forbid all Unicode escapes
-                        && code.chars().next().is_some_and(|c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII
+                        && let Some(code) =
+                            code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
+                        // forbid all Unicode escapes
+                        && !code.starts_with("\\u")
+                        // forbids literal Unicode characters beyond ASCII
+                        && code.chars().next().is_some_and(|c| c.is_ascii())
                     {
-                        suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral { span, code: escape_literal(code) })
+                        suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral {
+                            span,
+                            code: escape_literal(code),
+                        })
                     }
                 }
                 // If a character was expected and the found expression is a string literal
@@ -2006,7 +2045,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         && let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
                         && code.chars().count() == 1
                     {
-                        suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral { span, code: escape_literal(code) })
+                        suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral {
+                            span,
+                            code: escape_literal(code),
+                        })
                     }
                 }
                 // If a string was expected and the found expression is a character literal,
@@ -2016,7 +2058,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         if let Some(code) =
                             code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
                         {
-                            suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral { span, code: escape_literal(code) })
+                            suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral {
+                                span,
+                                code: escape_literal(code),
+                            })
                         }
                     }
                 }
@@ -2025,17 +2070,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 (ty::Bool, ty::Tuple(list)) => if list.len() == 0 {
                     suggestions.extend(self.suggest_let_for_letchains(&trace.cause, span));
                 }
-                (ty::Array(_, _), ty::Array(_, _)) => suggestions.extend(self.suggest_specify_actual_length(terr, trace, span)),
+                (ty::Array(_, _), ty::Array(_, _)) => {
+                    suggestions.extend(self.suggest_specify_actual_length(terr, trace, span))
+                }
                 _ => {}
             }
         }
         let code = trace.cause.code();
-        if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code
-                    && let hir::MatchSource::TryDesugar = source
-                    && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
-                {
-                    suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { found: found_ty.content(), expected: expected_ty.content() });
-                }
+        if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. })
+            | BlockTailExpression(.., source)
+        ) = code
+            && let hir::MatchSource::TryDesugar(_) = source
+            && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
+        {
+            suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
+                found: found_ty.content(),
+                expected: expected_ty.content(),
+            });
+        }
         suggestions
     }
 
@@ -2905,8 +2957,11 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
             CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
                 ObligationCauseFailureCode::ConstCompat { span, subdiags }
             }
+            BlockTailExpression(.., hir::MatchSource::TryDesugar(_)) => {
+                ObligationCauseFailureCode::TryCompat { span, subdiags }
+            }
             MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
-                hir::MatchSource::TryDesugar => {
+                hir::MatchSource::TryDesugar(_) => {
                     ObligationCauseFailureCode::TryCompat { span, subdiags }
                 }
                 _ => ObligationCauseFailureCode::MatchCompat { span, subdiags },
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 4e13ec90228..07f04ec1e44 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -29,25 +29,15 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         // version new_ty of its type where the anonymous region is replaced
         // with the named one.
         let (named, anon, anon_param_info, region_info) = if sub.has_name()
-            && self.tcx().is_suitable_region(sup).is_some()
-            && self.find_param_with_region(sup, sub).is_some()
+            && let Some(region_info) = self.tcx().is_suitable_region(sup)
+            && let Some(anon_param_info) = self.find_param_with_region(sup, sub)
         {
-            (
-                sub,
-                sup,
-                self.find_param_with_region(sup, sub).unwrap(),
-                self.tcx().is_suitable_region(sup).unwrap(),
-            )
+            (sub, sup, anon_param_info, region_info)
         } else if sup.has_name()
-            && self.tcx().is_suitable_region(sub).is_some()
-            && self.find_param_with_region(sub, sup).is_some()
+            && let Some(region_info) = self.tcx().is_suitable_region(sub)
+            && let Some(anon_param_info) = self.find_param_with_region(sub, sup)
         {
-            (
-                sup,
-                sub,
-                self.find_param_with_region(sub, sup).unwrap(),
-                self.tcx().is_suitable_region(sub).unwrap(),
-            )
+            (sup, sub, anon_param_info, region_info)
         } else {
             return None; // inapplicable
         };
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index d08b6ba5e47..3cfda0cc5c0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -146,7 +146,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
 
         if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
             if let ObligationCauseCode::ReturnValue(hir_id)
-            | ObligationCauseCode::BlockTailExpression(hir_id) = cause.code()
+            | ObligationCauseCode::BlockTailExpression(hir_id, ..) = cause.code()
             {
                 let parent_id = tcx.hir().get_parent_item(*hir_id);
                 if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
index 2775b5ded03..be6d1a3750c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs
@@ -64,7 +64,7 @@ pub fn find_param_with_region<'tcx>(
     let body_id = hir.maybe_body_owned_by(def_id)?;
 
     let owner_id = hir.body_owner(body_id);
-    let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
+    let fn_decl = hir.fn_decl_by_hir_id(owner_id)?;
     let poly_fn_sig = tcx.fn_sig(id).instantiate_identity();
 
     let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig);
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 2c7438ed9db..ae008674d01 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -15,6 +15,7 @@ rustc_attr = { path = "../rustc_attr" }
 rustc_borrowck = { path = "../rustc_borrowck" }
 rustc_builtin_macros = { path = "../rustc_builtin_macros" }
 rustc_expand = { path = "../rustc_expand" }
+rustc_feature = { path = "../rustc_feature" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_fs_util = { path = "../rustc_fs_util" }
 rustc_macros = { path = "../rustc_macros" }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index def9fdcd3c7..18a669175b9 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -11,6 +11,7 @@ use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
 use rustc_errors::PResult;
 use rustc_expand::base::{ExtCtxt, LintStoreExpand};
+use rustc_feature::Features;
 use rustc_fs_util::try_canonicalize;
 use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
 use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
@@ -98,6 +99,7 @@ pub(crate) fn create_lint_store(
 
 fn pre_expansion_lint<'a>(
     sess: &Session,
+    features: &Features,
     lint_store: &LintStore,
     registered_tools: &RegisteredTools,
     check_node: impl EarlyCheckNode<'a>,
@@ -107,6 +109,7 @@ fn pre_expansion_lint<'a>(
         || {
             rustc_lint::check_ast_node(
                 sess,
+                features,
                 true,
                 lint_store,
                 registered_tools,
@@ -125,13 +128,14 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
     fn pre_expansion_lint(
         &self,
         sess: &Session,
+        features: &Features,
         registered_tools: &RegisteredTools,
         node_id: ast::NodeId,
         attrs: &[ast::Attribute],
         items: &[rustc_ast::ptr::P<ast::Item>],
         name: Symbol,
     ) {
-        pre_expansion_lint(sess, self.0, registered_tools, (node_id, attrs, items), name);
+        pre_expansion_lint(sess, features, self.0, registered_tools, (node_id, attrs, items), name);
     }
 }
 
@@ -147,10 +151,18 @@ fn configure_and_expand(
 ) -> ast::Crate {
     let tcx = resolver.tcx();
     let sess = tcx.sess;
+    let features = tcx.features();
     let lint_store = unerased_lint_store(tcx);
     let crate_name = tcx.crate_name(LOCAL_CRATE);
     let lint_check_node = (&krate, pre_configured_attrs);
-    pre_expansion_lint(sess, lint_store, tcx.registered_tools(()), lint_check_node, crate_name);
+    pre_expansion_lint(
+        sess,
+        features,
+        lint_store,
+        tcx.registered_tools(()),
+        lint_check_node,
+        crate_name,
+    );
     rustc_builtin_macros::register_builtin_macros(resolver);
 
     let num_standard_library_imports = sess.time("crate_injection", || {
@@ -159,6 +171,7 @@ fn configure_and_expand(
             pre_configured_attrs,
             resolver,
             sess,
+            features,
         )
     });
 
@@ -198,16 +211,15 @@ fn configure_and_expand(
         }
 
         // Create the config for macro expansion
-        let features = sess.features_untracked();
         let recursion_limit = get_recursion_limit(pre_configured_attrs, sess);
         let cfg = rustc_expand::expand::ExpansionConfig {
-            features: Some(features),
+            crate_name: crate_name.to_string(),
+            features,
             recursion_limit,
             trace_mac: sess.opts.unstable_opts.trace_macros,
             should_test: sess.is_test_crate(),
             span_debug: sess.opts.unstable_opts.span_debug,
             proc_macro_backtrace: sess.opts.unstable_opts.proc_macro_backtrace,
-            ..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
         };
 
         let lint_store = LintStoreExpandImpl(lint_store);
@@ -241,11 +253,16 @@ fn configure_and_expand(
     });
 
     sess.time("maybe_building_test_harness", || {
-        rustc_builtin_macros::test_harness::inject(&mut krate, sess, resolver)
+        rustc_builtin_macros::test_harness::inject(&mut krate, sess, features, resolver)
     });
 
     let has_proc_macro_decls = sess.time("AST_validation", || {
-        rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer())
+        rustc_ast_passes::ast_validation::check_crate(
+            sess,
+            features,
+            &krate,
+            resolver.lint_buffer(),
+        )
     });
 
     let crate_types = tcx.crate_types();
@@ -270,6 +287,7 @@ fn configure_and_expand(
         rustc_builtin_macros::proc_macro_harness::inject(
             &mut krate,
             sess,
+            features,
             resolver,
             is_proc_macro_crate,
             has_proc_macro_decls,
@@ -300,7 +318,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
 
     // Needs to go *after* expansion to be able to check the results of macro expansion.
     sess.time("complete_gated_feature_checking", || {
-        rustc_ast_passes::feature_gate::check_crate(&krate, sess);
+        rustc_ast_passes::feature_gate::check_crate(&krate, sess, tcx.features());
     });
 
     // Add all buffered lints from the `ParseSess` to the `Session`.
@@ -329,6 +347,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
     let lint_store = unerased_lint_store(tcx);
     rustc_lint::check_ast_node(
         sess,
+        tcx.features(),
         false,
         lint_store,
         tcx.registered_tools(()),
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 7687e83da76..fc71c6c7e9a 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -5,7 +5,6 @@ use crate::{passes, util};
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::CodegenResults;
-use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceCell, RwLock, WorkerLocal};
@@ -86,9 +85,6 @@ pub struct Queries<'tcx> {
 
     parse: Query<ast::Crate>,
     pre_configure: Query<(ast::Crate, ast::AttrVec)>,
-    crate_name: Query<Symbol>,
-    crate_types: Query<Vec<CrateType>>,
-    stable_crate_id: Query<StableCrateId>,
     // This just points to what's in `gcx_cell`.
     gcx: Query<&'tcx GlobalCtxt<'tcx>>,
 }
@@ -102,9 +98,6 @@ impl<'tcx> Queries<'tcx> {
             hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
             parse: Default::default(),
             pre_configure: Default::default(),
-            crate_name: Default::default(),
-            crate_types: Default::default(),
-            stable_crate_id: Default::default(),
             gcx: Default::default(),
         }
     }
@@ -138,39 +131,12 @@ impl<'tcx> Queries<'tcx> {
         })
     }
 
-    fn crate_name(&self) -> Result<QueryResult<'_, Symbol>> {
-        self.crate_name.compute(|| {
-            let pre_configure_result = self.pre_configure()?;
-            let (_, pre_configured_attrs) = &*pre_configure_result.borrow();
-            // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
-            Ok(find_crate_name(self.session(), pre_configured_attrs))
-        })
-    }
-
-    fn crate_types(&self) -> Result<QueryResult<'_, Vec<CrateType>>> {
-        self.crate_types.compute(|| {
-            let pre_configure_result = self.pre_configure()?;
-            let (_, pre_configured_attrs) = &*pre_configure_result.borrow();
-            Ok(util::collect_crate_types(&self.session(), &pre_configured_attrs))
-        })
-    }
-
-    fn stable_crate_id(&self) -> Result<QueryResult<'_, StableCrateId>> {
-        self.stable_crate_id.compute(|| {
-            let sess = self.session();
-            Ok(StableCrateId::new(
-                *self.crate_name()?.borrow(),
-                self.crate_types()?.borrow().contains(&CrateType::Executable),
-                sess.opts.cg.metadata.clone(),
-                sess.cfg_version,
-            ))
-        })
-    }
-
-    fn dep_graph_future(&self) -> Result<Option<DepGraphFuture>> {
+    fn dep_graph_future(
+        &self,
+        crate_name: Symbol,
+        stable_crate_id: StableCrateId,
+    ) -> Result<Option<DepGraphFuture>> {
         let sess = self.session();
-        let crate_name = *self.crate_name()?.borrow();
-        let stable_crate_id = *self.stable_crate_id()?.borrow();
 
         // `load_dep_graph` can only be called after `prepare_session_directory`.
         rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
@@ -195,15 +161,8 @@ impl<'tcx> Queries<'tcx> {
         dep_graph_future
             .and_then(|future| {
                 let sess = self.session();
-                let (prev_graph, mut prev_work_products) =
+                let (prev_graph, prev_work_products) =
                     sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
-                // Convert from UnordMap to FxIndexMap by sorting
-                let prev_work_product_ids =
-                    prev_work_products.items().map(|x| *x.0).into_sorted_stable_ord();
-                let prev_work_products = prev_work_product_ids
-                    .into_iter()
-                    .map(|x| (x, prev_work_products.remove(&x).unwrap()))
-                    .collect::<FxIndexMap<_, _>>();
                 rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
             })
             .unwrap_or_else(DepGraph::new_disabled)
@@ -211,32 +170,39 @@ impl<'tcx> Queries<'tcx> {
 
     pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
+            let sess = self.session();
+            let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
+
+            // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
+            let crate_name = find_crate_name(sess, &pre_configured_attrs);
+            let crate_types = util::collect_crate_types(sess, &pre_configured_attrs);
+            let stable_crate_id = StableCrateId::new(
+                crate_name,
+                crate_types.contains(&CrateType::Executable),
+                sess.opts.cg.metadata.clone(),
+                sess.cfg_version,
+            );
+
             // Compute the dependency graph (in the background). We want to do this as early as
             // possible, to give the DepGraph maximum time to load before `dep_graph` is called.
-            let dep_graph_future = self.dep_graph_future()?;
+            let dep_graph_future = self.dep_graph_future(crate_name, stable_crate_id)?;
 
-            let crate_name = self.crate_name()?.steal();
-            let crate_types = self.crate_types()?.steal();
-            let stable_crate_id = self.stable_crate_id()?.steal();
-            let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
-
-            let sess = self.session();
             let lint_store = Lrc::new(passes::create_lint_store(
                 sess,
                 &*self.codegen_backend().metadata_loader(),
                 self.compiler.register_lints.as_deref(),
                 &pre_configured_attrs,
             ));
-            let cstore = RwLock::new(Box::new(CStore::new(stable_crate_id)) as _);
+            let cstore = RwLock::new(Box::new(CStore::new(
+                self.codegen_backend().metadata_loader(),
+                stable_crate_id,
+            )) as _);
             let definitions = RwLock::new(Definitions::new(stable_crate_id));
             let source_span = AppendOnlyIndexVec::new();
             let _id = source_span.push(krate.spans.inner_span);
             debug_assert_eq!(_id, CRATE_DEF_ID);
             let untracked = Untracked { cstore, source_span, definitions };
 
-            // FIXME: Move features from session to tcx and make them immutable.
-            sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
-
             let qcx = passes::create_global_ctxt(
                 self.compiler,
                 crate_types,
@@ -254,11 +220,10 @@ impl<'tcx> Queries<'tcx> {
                 feed.crate_name(crate_name);
 
                 let feed = tcx.feed_unit_query();
-                feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
-                feed.metadata_loader(
-                    tcx.arena.alloc(Steal::new(self.codegen_backend().metadata_loader())),
+                feed.features_query(
+                    tcx.arena.alloc(rustc_expand::config::features(sess, &pre_configured_attrs)),
                 );
-                feed.features_query(tcx.sess.features_untracked());
+                feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
             });
             Ok(qcx)
         })
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 2c9d212a6a6..4b6917fdfdd 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2215,7 +2215,7 @@ declare_lint! {
     ///
     /// ### Example
     ///
-    /// ```rust,compile_fail
+    /// ```rust
     /// #![feature(rustc_attrs)]
     /// ```
     ///
@@ -2226,7 +2226,7 @@ declare_lint! {
     /// These features are an implementation detail of the compiler and standard
     /// library and are not supposed to be used in user code.
     pub INTERNAL_FEATURES,
-    Deny,
+    Warn,
     "internal features are not supposed to be used"
 }
 
@@ -2237,7 +2237,7 @@ declare_lint_pass!(
 
 impl EarlyLintPass for IncompleteInternalFeatures {
     fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
-        let features = cx.sess().features_untracked();
+        let features = cx.builder.features();
         features
             .declared_lang_features
             .iter()
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index f7e56b30553..f73797415bc 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync;
 use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder, DiagnosticMessage};
 use rustc_errors::{Applicability, DecorateLint, MultiSpan, SuggestionStyle};
+use rustc_feature::Features;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -1071,6 +1072,7 @@ pub trait LintContext: Sized {
 impl<'a> EarlyContext<'a> {
     pub(crate) fn new(
         sess: &'a Session,
+        features: &'a Features,
         warn_about_weird_lints: bool,
         lint_store: &'a LintStore,
         registered_tools: &'a RegisteredTools,
@@ -1079,6 +1081,7 @@ impl<'a> EarlyContext<'a> {
         EarlyContext {
             builder: LintLevelsBuilder::new(
                 sess,
+                features,
                 warn_about_weird_lints,
                 lint_store,
                 registered_tools,
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 9f1f5a26ee5..211ea8f4347 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -20,6 +20,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::{self as ast_visit, Visitor};
 use rustc_ast::{self as ast, walk_list, HasAttrs};
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_feature::Features;
 use rustc_middle::ty::RegisteredTools;
 use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
 use rustc_session::Session;
@@ -381,6 +382,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
 
 pub fn check_ast_node<'a>(
     sess: &Session,
+    features: &Features,
     pre_expansion: bool,
     lint_store: &LintStore,
     registered_tools: &RegisteredTools,
@@ -390,6 +392,7 @@ pub fn check_ast_node<'a>(
 ) {
     let context = EarlyContext::new(
         sess,
+        features,
         !pre_expansion,
         lint_store,
         registered_tools,
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index 3331dbad4a9..73af51d9e90 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -19,7 +19,7 @@ use rustc_ast as ast;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::join;
 use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_hir::intravisit as hir_visit;
 use rustc_hir::intravisit::Visitor;
 use rustc_middle::hir::nested_filter;
@@ -338,7 +338,7 @@ crate::late_lint_methods!(impl_late_lint_pass, []);
 
 pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
     tcx: TyCtxt<'tcx>,
-    module_def_id: LocalDefId,
+    module_def_id: LocalModDefId,
     builtin_lints: T,
 ) {
     let context = LateContext {
@@ -369,7 +369,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
 
 fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>(
     tcx: TyCtxt<'tcx>,
-    module_def_id: LocalDefId,
+    module_def_id: LocalModDefId,
     context: LateContext<'tcx>,
     pass: T,
 ) {
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 18b178d8882..1f4e5fa4d3b 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -12,6 +12,7 @@ use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
+use rustc_feature::Features;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
@@ -119,6 +120,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
 
     let mut builder = LintLevelsBuilder {
         sess: tcx.sess,
+        features: tcx.features(),
         provider: QueryMapExpectationsWrapper {
             tcx,
             cur: hir::CRATE_HIR_ID,
@@ -148,6 +150,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
 
     let mut levels = LintLevelsBuilder {
         sess: tcx.sess,
+        features: tcx.features(),
         provider: LintLevelQueryMap {
             tcx,
             cur: owner.into(),
@@ -435,6 +438,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'
 
 pub struct LintLevelsBuilder<'s, P> {
     sess: &'s Session,
+    features: &'s Features,
     provider: P,
     warn_about_weird_lints: bool,
     store: &'s LintStore,
@@ -448,12 +452,14 @@ pub(crate) struct BuilderPush {
 impl<'s> LintLevelsBuilder<'s, TopDown> {
     pub(crate) fn new(
         sess: &'s Session,
+        features: &'s Features,
         warn_about_weird_lints: bool,
         store: &'s LintStore,
         registered_tools: &'s RegisteredTools,
     ) -> Self {
         let mut builder = LintLevelsBuilder {
             sess,
+            features,
             provider: TopDown { sets: LintLevelSets::new(), cur: COMMAND_LINE },
             warn_about_weird_lints,
             store,
@@ -526,6 +532,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         self.sess
     }
 
+    pub(crate) fn features(&self) -> &Features {
+        self.features
+    }
+
     pub(crate) fn lint_store(&self) -> &LintStore {
         self.store
     }
@@ -716,7 +726,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                     ast::MetaItemKind::NameValue(ref name_value) => {
                         if item.path == sym::reason {
                             if let ast::LitKind::Str(rationale, _) = name_value.kind {
-                                if !self.sess.features_untracked().lint_reasons {
+                                if !self.features.lint_reasons {
                                     feature_err(
                                         &self.sess.parse_sess,
                                         sym::lint_reasons,
@@ -992,7 +1002,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     #[track_caller]
     fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool {
         if let Some(feature) = lint_id.lint.feature_gate {
-            if !self.sess.features_untracked().enabled(feature) {
+            if !self.features.enabled(feature) {
                 let lint = builtin::UNKNOWN_LINTS;
                 let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
                 struct_lint_level(
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 42378951af3..585b10e79e4 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -90,7 +90,7 @@ use rustc_ast as ast;
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
 use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::{
@@ -145,7 +145,7 @@ pub fn provide(providers: &mut Providers) {
     *providers = Providers { lint_mod, ..*providers };
 }
 
-fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new());
 }
 
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index ed3d4721049..43f50a04aad 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -98,32 +98,56 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
 fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
     let e = e.peel_blocks();
 
-    // <expr> as *mut ...
-    let e = if let ExprKind::Cast(e, t) = e.kind
-        && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(t.hir_id).kind() {
-        e
-    // <expr>.cast_mut()
-    } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
-        && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
-        && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) {
-        expr
-    } else {
-        return false;
-    };
+    fn from_casts<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
+        // <expr> as *mut ...
+        let e = if let ExprKind::Cast(e, t) = e.kind
+            && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(t.hir_id).kind() {
+            e
+        // <expr>.cast_mut()
+        } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
+            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
+            && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) {
+            expr
+        } else {
+            return None;
+        };
 
-    let e = e.peel_blocks();
+        let e = e.peel_blocks();
+
+        // <expr> as *const ...
+        let e = if let ExprKind::Cast(e, t) = e.kind
+            && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) = cx.typeck_results().node_type(t.hir_id).kind() {
+            e
+        // ptr::from_ref(<expr>)
+        } else if let ExprKind::Call(path, [arg]) = e.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && cx.tcx.is_diagnostic_item(sym::ptr_from_ref, def_id) {
+            arg
+        } else {
+            return None;
+        };
+
+        Some(e)
+    }
+
+    fn from_transmute<'tcx>(
+        cx: &LateContext<'tcx>,
+        e: &'tcx Expr<'tcx>,
+    ) -> Option<&'tcx Expr<'tcx>> {
+        // mem::transmute::<_, *mut _>(<expr>)
+        if let ExprKind::Call(path, [arg]) = e.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && cx.tcx.is_diagnostic_item(sym::transmute, def_id)
+            && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(e.hir_id).kind() {
+            Some(arg)
+        } else {
+            None
+        }
+    }
 
-    // <expr> as *const ...
-    let e = if let ExprKind::Cast(e, t) = e.kind
-        && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) = cx.typeck_results().node_type(t.hir_id).kind() {
-        e
-    // ptr::from_ref(<expr>)
-    } else if let ExprKind::Call(path, [arg]) = e.kind
-        && let ExprKind::Path(ref qpath) = path.kind
-        && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
-        && cx.tcx.is_diagnostic_item(sym::ptr_from_ref, def_id) {
-        arg
-    } else {
+    let Some(e) = from_casts(cx, e).or_else(|| from_transmute(cx, e)) else {
         return false;
     };
 
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 3db6b302790..6041f80753b 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -666,6 +666,24 @@ trait UnusedDelimLint {
         if !followed_by_block {
             return false;
         }
+
+        // Check if we need parens for `match &( Struct { feild:  }) {}`.
+        {
+            let mut innermost = inner;
+            loop {
+                innermost = match &innermost.kind {
+                    ExprKind::AddrOf(_, _, expr) => expr,
+                    _ => {
+                        if parser::contains_exterior_struct_lit(&innermost) {
+                            return true;
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
         let mut innermost = inner;
         loop {
             innermost = match &innermost.kind {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 3747e562cec..96c31a90da8 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3366,6 +3366,7 @@ declare_lint_pass! {
         BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
         CENUM_IMPL_DROP_CAST,
         COHERENCE_LEAK_CHECK,
+        COINDUCTIVE_OVERLAP_IN_COHERENCE,
         CONFLICTING_REPR_HINTS,
         CONST_EVALUATABLE_UNCHECKED,
         CONST_ITEM_MUTATION,
@@ -4423,6 +4424,44 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `coinductive_overlap_in_coherence` lint detects impls which are currently
+    /// considered not overlapping, but may be considered to overlap if support for
+    /// coinduction is added to the trait solver.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(coinductive_overlap_in_coherence)]
+    ///
+    /// trait CyclicTrait {}
+    /// impl<T: CyclicTrait> CyclicTrait for T {}
+    ///
+    /// trait Trait {}
+    /// impl<T: CyclicTrait> Trait for T {}
+    /// // conflicting impl with the above
+    /// impl Trait for u8 {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// We have two choices for impl which satisfy `u8: Trait`: the blanket impl
+    /// for generic `T`, and the direct impl for `u8`. These two impls nominally
+    /// overlap, since we can infer `T = u8` in the former impl, but since the where
+    /// clause `u8: CyclicTrait` would end up resulting in a cycle (since it depends
+    /// on itself), the blanket impl is not considered to hold for `u8`. This will
+    /// change in a future release.
+    pub COINDUCTIVE_OVERLAP_IN_COHERENCE,
+    Warn,
+    "impls that are not considered to overlap may be considered to \
+    overlap in the future",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #114040 <https://github.com/rust-lang/rust/issues/114040>",
+    };
+}
+
+declare_lint! {
     /// The `unknown_diagnostic_attributes` lint detects unrecognized diagnostic attributes.
     ///
     /// ### Example
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index aa1121d6bb3..4302b161833 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -12,6 +12,7 @@ const OPTIONAL_COMPONENTS: &[&str] = &[
     "avr",
     "loongarch",
     "m68k",
+    "csky",
     "mips",
     "powerpc",
     "systemz",
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index b3371dbe834..b566ea496de 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -105,6 +105,12 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
 #define SUBTARGET_M68K
 #endif
 
+#ifdef LLVM_COMPONENT_CSKY
+#define SUBTARGET_CSKY SUBTARGET(CSKY)
+#else
+#define SUBTARGET_CSKY
+#endif
+
 #ifdef LLVM_COMPONENT_MIPS
 #define SUBTARGET_MIPS SUBTARGET(Mips)
 #else
@@ -159,6 +165,7 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
   SUBTARGET_AARCH64                                                            \
   SUBTARGET_AVR                                                                \
   SUBTARGET_M68K                                                               \
+  SUBTARGET_CSKY                                                               \
   SUBTARGET_MIPS                                                               \
   SUBTARGET_PPC                                                                \
   SUBTARGET_SYSTEMZ                                                            \
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index a49ded4fd7b..eb70961503d 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -103,6 +103,14 @@ pub fn initialize_available_targets() {
         LLVMInitializeM68kAsmParser
     );
     init_target!(
+        llvm_component = "csky",
+        LLVMInitializeCSKYTargetInfo,
+        LLVMInitializeCSKYTarget,
+        LLVMInitializeCSKYTargetMC,
+        LLVMInitializeCSKYAsmPrinter,
+        LLVMInitializeCSKYAsmParser
+    );
+    init_target!(
         llvm_component = "loongarch",
         LLVMInitializeLoongArchTargetInfo,
         LLVMInitializeLoongArchTarget,
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 3c76f9a8e52..fce80ab37dd 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -15,8 +15,9 @@ use rustc_hir::definitions::Definitions;
 use rustc_index::IndexVec;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, CrateType, ExternLocation};
-use rustc_session::cstore::ExternCrateSource;
-use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate};
+use rustc_session::cstore::{
+    CrateDepKind, CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn,
+};
 use rustc_session::lint;
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
@@ -33,6 +34,8 @@ use std::time::Duration;
 use std::{cmp, env, iter};
 
 pub struct CStore {
+    metadata_loader: Box<MetadataLoaderDyn>,
+
     metas: IndexVec<CrateNum, Option<Box<CrateMetadata>>>,
     injected_panic_runtime: Option<CrateNum>,
     /// This crate needs an allocator and either provides it itself, or finds it in a dependency.
@@ -261,10 +264,14 @@ impl CStore {
         }
     }
 
-    pub fn new(local_stable_crate_id: StableCrateId) -> CStore {
+    pub fn new(
+        metadata_loader: Box<MetadataLoaderDyn>,
+        local_stable_crate_id: StableCrateId,
+    ) -> CStore {
         let mut stable_crate_ids = StableCrateIdMap::default();
         stable_crate_ids.insert(local_stable_crate_id, LOCAL_CRATE);
         CStore {
+            metadata_loader,
             // We add an empty entry for LOCAL_CRATE (which maps to zero) in
             // order to make array indices in `metas` match with the
             // corresponding `CrateNum`. This first entry will always remain
@@ -538,10 +545,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
             (LoadResult::Previous(cnum), None)
         } else {
             info!("falling back to a load");
-            let metadata_loader = self.tcx.metadata_loader(()).borrow();
             let mut locator = CrateLocator::new(
                 self.sess,
-                &**metadata_loader,
+                &*self.cstore.metadata_loader,
                 name,
                 // The all loop is because `--crate-type=rlib --crate-type=rlib` is
                 // legal and produces both inside this type.
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 9e67bb655d4..e8f66c36a86 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -842,7 +842,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, sess))
     }
 
-    fn load_proc_macro(self, id: DefIndex, sess: &Session) -> SyntaxExtension {
+    fn load_proc_macro(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension {
         let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
                 let helper_attrs =
@@ -861,9 +861,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             }
         };
 
+        let sess = tcx.sess;
         let attrs: Vec<_> = self.get_item_attrs(id, sess).collect();
         SyntaxExtension::new(
             sess,
+            tcx.features(),
             kind,
             self.get_span(id, sess),
             helper_attrs,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7dbfe0e0cb0..aeda8af6d2c 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -6,6 +6,7 @@ use crate::rmeta::AttrFlags;
 
 use rustc_ast as ast;
 use rustc_attr::Deprecation;
+use rustc_data_structures::sync::Lrc;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
@@ -23,7 +24,6 @@ use rustc_span::hygiene::{ExpnHash, ExpnId};
 use rustc_span::symbol::{kw, Symbol};
 use rustc_span::Span;
 
-use rustc_data_structures::sync::Lrc;
 use std::any::Any;
 
 use super::{Decodable, DecodeContext, DecodeIterator};
@@ -522,12 +522,13 @@ impl CStore {
         self.get_crate_data(def.krate).get_ctor(def.index)
     }
 
-    pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
+    pub fn load_macro_untracked(&self, id: DefId, tcx: TyCtxt<'_>) -> LoadedMacro {
+        let sess = tcx.sess;
         let _prof_timer = sess.prof.generic_activity("metadata_load_macro");
 
         let data = self.get_crate_data(id.krate);
         if data.root.is_proc_macro_crate() {
-            return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
+            return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, tcx));
         }
 
         let span = data.get_span(id.index, sess);
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index 5a320865c95..952c796f52e 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -40,7 +40,6 @@ macro_rules! arena_types {
                 rustc_data_structures::sync::Lrc<rustc_ast::Crate>,
             )>,
             [] output_filenames: std::sync::Arc<rustc_session::config::OutputFilenames>,
-            [] metadata_loader: rustc_data_structures::steal::Steal<Box<rustc_session::cstore::MetadataLoaderDyn>>,
             [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
             [] resolutions: rustc_middle::ty::ResolverGlobalCtxt,
             [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
@@ -131,6 +130,7 @@ macro_rules! arena_types {
             [] closure_kind_origin: (rustc_span::Span, rustc_middle::hir::place::Place<'tcx>),
             [] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
             [] mod_child: rustc_middle::metadata::ModChild,
+            [] features: rustc_feature::Features,
         ]);
     )
 }
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 06251bccc98..04c09d33400 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -60,7 +60,7 @@ use crate::mir::mono::MonoItem;
 use crate::ty::TyCtxt;
 
 use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, ModDefId, LOCAL_CRATE};
 use rustc_hir::definitions::DefPathHash;
 use rustc_hir::{HirId, ItemLocalId, OwnerId};
 use rustc_query_system::dep_graph::FingerprintStyle;
@@ -387,3 +387,53 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
         }
     }
 }
+
+macro_rules! impl_for_typed_def_id {
+    ($Name:ident, $LocalName:ident) => {
+        impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $Name {
+            #[inline(always)]
+            fn fingerprint_style() -> FingerprintStyle {
+                FingerprintStyle::DefPathHash
+            }
+
+            #[inline(always)]
+            fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+                self.to_def_id().to_fingerprint(tcx)
+            }
+
+            #[inline(always)]
+            fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+                self.to_def_id().to_debug_str(tcx)
+            }
+
+            #[inline(always)]
+            fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+                DefId::recover(tcx, dep_node).map($Name::new_unchecked)
+            }
+        }
+
+        impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $LocalName {
+            #[inline(always)]
+            fn fingerprint_style() -> FingerprintStyle {
+                FingerprintStyle::DefPathHash
+            }
+
+            #[inline(always)]
+            fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+                self.to_def_id().to_fingerprint(tcx)
+            }
+
+            #[inline(always)]
+            fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+                self.to_def_id().to_debug_str(tcx)
+            }
+
+            #[inline(always)]
+            fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
+                LocalDefId::recover(tcx, dep_node).map($LocalName::new_unchecked)
+            }
+        }
+    };
+}
+
+impl_for_typed_def_id! { ModDefId, LocalModDefId }
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 3ad9b0d79e7..f79ce08b8ae 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -8,7 +8,7 @@ mod dep_node;
 
 pub use rustc_query_system::dep_graph::{
     debug::DepNodeFilter, hash_result, DepContext, DepNodeColor, DepNodeIndex,
-    SerializedDepNodeIndex, WorkProduct, WorkProductId,
+    SerializedDepNodeIndex, WorkProduct, WorkProductId, WorkProductMap,
 };
 
 pub use dep_node::{label_strs, DepKind, DepNode, DepNodeExt};
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 224f897492b..467962b39bb 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::*;
@@ -148,7 +148,7 @@ impl<'hir> Map<'hir> {
     }
 
     #[inline]
-    pub fn module_items(self, module: LocalDefId) -> impl Iterator<Item = ItemId> + 'hir {
+    pub fn module_items(self, module: LocalModDefId) -> impl Iterator<Item = ItemId> + 'hir {
         self.tcx.hir_module_items(module).items()
     }
 
@@ -169,8 +169,8 @@ impl<'hir> Map<'hir> {
     }
 
     #[inline]
-    pub fn local_def_id_to_hir_id(self, def_id: LocalDefId) -> HirId {
-        self.tcx.local_def_id_to_hir_id(def_id)
+    pub fn local_def_id_to_hir_id(self, def_id: impl Into<LocalDefId>) -> HirId {
+        self.tcx.local_def_id_to_hir_id(def_id.into())
     }
 
     /// Do not call this function directly. The query should be called.
@@ -529,8 +529,8 @@ impl<'hir> Map<'hir> {
         self.krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core))
     }
 
-    pub fn get_module(self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
-        let hir_id = HirId::make_owner(module);
+    pub fn get_module(self, module: LocalModDefId) -> (&'hir Mod<'hir>, Span, HirId) {
+        let hir_id = HirId::make_owner(module.to_local_def_id());
         match self.tcx.hir_owner(hir_id.owner).map(|o| o.node) {
             Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => {
                 (m, span, hir_id)
@@ -542,7 +542,7 @@ impl<'hir> Map<'hir> {
 
     /// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`.
     pub fn walk_toplevel_module(self, visitor: &mut impl Visitor<'hir>) {
-        let (top_mod, span, hir_id) = self.get_module(CRATE_DEF_ID);
+        let (top_mod, span, hir_id) = self.get_module(LocalModDefId::CRATE_DEF_ID);
         visitor.visit_mod(top_mod, span, hir_id);
     }
 
@@ -595,7 +595,7 @@ impl<'hir> Map<'hir> {
 
     /// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to
     /// item-likes in a single module.
-    pub fn visit_item_likes_in_module<V>(self, module: LocalDefId, visitor: &mut V)
+    pub fn visit_item_likes_in_module<V>(self, module: LocalModDefId, visitor: &mut V)
     where
         V: Visitor<'hir>,
     {
@@ -618,17 +618,19 @@ impl<'hir> Map<'hir> {
         }
     }
 
-    pub fn for_each_module(self, mut f: impl FnMut(LocalDefId)) {
+    pub fn for_each_module(self, mut f: impl FnMut(LocalModDefId)) {
         let crate_items = self.tcx.hir_crate_items(());
         for module in crate_items.submodules.iter() {
-            f(module.def_id)
+            f(LocalModDefId::new_unchecked(module.def_id))
         }
     }
 
     #[inline]
-    pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
+    pub fn par_for_each_module(self, f: impl Fn(LocalModDefId) + DynSend + DynSync) {
         let crate_items = self.tcx.hir_crate_items(());
-        par_for_each_in(&crate_items.submodules[..], |module| f(module.def_id))
+        par_for_each_in(&crate_items.submodules[..], |module| {
+            f(LocalModDefId::new_unchecked(module.def_id))
+        })
     }
 
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
@@ -1324,7 +1326,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
     }
 }
 
-pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> ModuleItems {
+pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems {
     let mut collector = ItemCollector::new(tcx, false);
 
     let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id);
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 06b25556c82..e8fd469e1fb 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -11,7 +11,7 @@ use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::*;
 use rustc_query_system::ich::StableHashingContext;
 use rustc_span::{ExpnId, DUMMY_SP};
@@ -101,22 +101,22 @@ impl<'tcx> TyCtxt<'tcx> {
         map::Map { tcx: self }
     }
 
-    pub fn parent_module(self, id: HirId) -> LocalDefId {
+    pub fn parent_module(self, id: HirId) -> LocalModDefId {
         if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod {
-            id.owner.def_id
+            LocalModDefId::new_unchecked(id.owner.def_id)
         } else {
             self.parent_module_from_def_id(id.owner.def_id)
         }
     }
 
-    pub fn parent_module_from_def_id(self, mut id: LocalDefId) -> LocalDefId {
+    pub fn parent_module_from_def_id(self, mut id: LocalDefId) -> LocalModDefId {
         while let Some(parent) = self.opt_local_parent(id) {
             id = parent;
             if self.def_kind(id) == DefKind::Mod {
                 break;
             }
         }
-        id
+        LocalModDefId::new_unchecked(id)
     }
 
     pub fn impl_subject(self, def_id: DefId) -> EarlyBinder<ImplSubject<'tcx>> {
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index f5576b59571..d3fc1b2850e 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -35,7 +35,6 @@
 #![feature(if_let_guard)]
 #![feature(inline_const)]
 #![feature(iter_from_generator)]
-#![feature(local_key_cell_methods)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(extern_types)]
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 2c481745d98..348f79ed6a8 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -235,6 +235,7 @@ trivial! {
     rustc_hir::def_id::DefId,
     rustc_hir::def_id::DefIndex,
     rustc_hir::def_id::LocalDefId,
+    rustc_hir::def_id::LocalModDefId,
     rustc_hir::def::DefKind,
     rustc_hir::Defaultness,
     rustc_hir::definitions::DefKey,
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index a8aec3096d5..01bdc4c9904 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -8,7 +8,7 @@ use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::{TyAndLayout, ValidityRequirement};
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::{GenericArg, GenericArgsRef};
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, ModDefId, LOCAL_CRATE};
 use rustc_hir::hir_id::{HirId, OwnerId};
 use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector};
 use rustc_span::symbol::{Ident, Symbol};
@@ -175,6 +175,41 @@ impl AsLocalKey for DefId {
     }
 }
 
+impl Key for LocalModDefId {
+    type CacheSelector = DefaultCacheSelector<Self>;
+
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+        tcx.def_span(*self)
+    }
+
+    #[inline(always)]
+    fn key_as_def_id(&self) -> Option<DefId> {
+        Some(self.to_def_id())
+    }
+}
+
+impl Key for ModDefId {
+    type CacheSelector = DefaultCacheSelector<Self>;
+
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
+        tcx.def_span(*self)
+    }
+
+    #[inline(always)]
+    fn key_as_def_id(&self) -> Option<DefId> {
+        Some(self.to_def_id())
+    }
+}
+
+impl AsLocalKey for ModDefId {
+    type LocalKey = LocalModDefId;
+
+    #[inline(always)]
+    fn as_local_key(&self) -> Option<Self::LocalKey> {
+        self.as_local()
+    }
+}
+
 impl Key for SimplifiedType {
     type CacheSelector = DefaultCacheSelector<Self>;
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 52a18c99edb..e289ddab120 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -67,7 +67,7 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, DocLinkResMap};
 use rustc_hir::def_id::{
-    CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet,
+    CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId,
 };
 use rustc_hir::lang_items::{LangItem, LanguageItems};
 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
@@ -167,7 +167,7 @@ rustc_queries! {
     ///
     /// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
     /// Avoid calling this query directly.
-    query hir_module_items(key: LocalDefId) -> &'tcx rustc_middle::hir::ModuleItems {
+    query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems {
         arena_cache
         desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) }
         cache_on_disk_if { true }
@@ -896,7 +896,7 @@ rustc_queries! {
     }
 
     /// Performs lint checking for the module.
-    query lint_mod(key: LocalDefId) -> () {
+    query lint_mod(key: LocalModDefId) -> () {
         desc { |tcx| "linting {}", describe_as_module(key, tcx) }
     }
 
@@ -905,35 +905,35 @@ rustc_queries! {
     }
 
     /// Checks the attributes in the module.
-    query check_mod_attrs(key: LocalDefId) -> () {
+    query check_mod_attrs(key: LocalModDefId) -> () {
         desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) }
     }
 
     /// Checks for uses of unstable APIs in the module.
-    query check_mod_unstable_api_usage(key: LocalDefId) -> () {
+    query check_mod_unstable_api_usage(key: LocalModDefId) -> () {
         desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) }
     }
 
     /// Checks the const bodies in the module for illegal operations (e.g. `if` or `loop`).
-    query check_mod_const_bodies(key: LocalDefId) -> () {
+    query check_mod_const_bodies(key: LocalModDefId) -> () {
         desc { |tcx| "checking consts in {}", describe_as_module(key, tcx) }
     }
 
     /// Checks the loops in the module.
-    query check_mod_loops(key: LocalDefId) -> () {
+    query check_mod_loops(key: LocalModDefId) -> () {
         desc { |tcx| "checking loops in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_naked_functions(key: LocalDefId) -> () {
+    query check_mod_naked_functions(key: LocalModDefId) -> () {
         desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_item_types(key: LocalDefId) -> () {
+    query check_mod_item_types(key: LocalModDefId) -> () {
         desc { |tcx| "checking item types in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_privacy(key: LocalDefId) -> () {
-        desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) }
+    query check_mod_privacy(key: LocalModDefId) -> () {
+        desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
     }
 
     query check_liveness(key: LocalDefId) {
@@ -952,19 +952,19 @@ rustc_queries! {
         desc { "finding live symbols in crate" }
     }
 
-    query check_mod_deathness(key: LocalDefId) -> () {
+    query check_mod_deathness(key: LocalModDefId) -> () {
         desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_impl_wf(key: LocalDefId) -> () {
+    query check_mod_impl_wf(key: LocalModDefId) -> () {
         desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_type_wf(key: LocalDefId) -> () {
+    query check_mod_type_wf(key: LocalModDefId) -> () {
         desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
     }
 
-    query collect_mod_item_types(key: LocalDefId) -> () {
+    query collect_mod_item_types(key: LocalModDefId) -> () {
         desc { |tcx| "collecting item types in {}", describe_as_module(key, tcx) }
     }
 
@@ -2096,12 +2096,6 @@ rustc_queries! {
         desc { "looking up enabled feature gates" }
     }
 
-    query metadata_loader((): ()) -> &'tcx Steal<Box<rustc_session::cstore::MetadataLoaderDyn>> {
-        feedable
-        no_hash
-        desc { "raw operations for metadata file access" }
-    }
-
     query crate_for_resolver((): ()) -> &'tcx Steal<(rustc_ast::Crate, rustc_ast::AttrVec)> {
         feedable
         no_hash
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 97edfc2fca2..a1aac284621 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -545,6 +545,7 @@ macro_rules! define_feedable {
 
 mod sealed {
     use super::{DefId, LocalDefId, OwnerId};
+    use rustc_hir::def_id::{LocalModDefId, ModDefId};
 
     /// An analogue of the `Into` trait that's intended only for query parameters.
     ///
@@ -588,6 +589,27 @@ mod sealed {
             self.to_def_id()
         }
     }
+
+    impl IntoQueryParam<DefId> for ModDefId {
+        #[inline(always)]
+        fn into_query_param(self) -> DefId {
+            self.to_def_id()
+        }
+    }
+
+    impl IntoQueryParam<DefId> for LocalModDefId {
+        #[inline(always)]
+        fn into_query_param(self) -> DefId {
+            self.to_def_id()
+        }
+    }
+
+    impl IntoQueryParam<LocalDefId> for LocalModDefId {
+        #[inline(always)]
+        fn into_query_param(self) -> LocalDefId {
+            self.into()
+        }
+    }
 }
 
 pub use sealed::IntoQueryParam;
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 8e2e71fd879..ebc1c11902b 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -346,6 +346,7 @@ pub enum ExprKind<'tcx> {
     /// A `match` expression.
     Match {
         scrutinee: ExprId,
+        scrutinee_hir_id: hir::HirId,
         arms: Box<[ArmId]>,
     },
     /// A block.
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 55ec17423ec..681400dbb94 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -70,7 +70,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
             visitor.visit_expr(&visitor.thir()[expr]);
         }
         Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
-        Match { scrutinee, ref arms } => {
+        Match { scrutinee, ref arms, .. } => {
             visitor.visit_expr(&visitor.thir()[scrutinee]);
             for &arm in &**arms {
                 visitor.visit_arm(&visitor.thir()[arm]);
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 85116555fc0..3465759b913 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -402,7 +402,7 @@ pub enum ObligationCauseCode<'tcx> {
     OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
 
     /// Block implicit return
-    BlockTailExpression(hir::HirId),
+    BlockTailExpression(hir::HirId, hir::MatchSource),
 
     /// #[feature(trivial_bounds)] is not enabled
     TrivialBound,
@@ -543,7 +543,6 @@ pub struct MatchExpressionArmCause<'tcx> {
     pub scrut_span: Span,
     pub source: hir::MatchSource,
     pub prior_arms: Vec<Span>,
-    pub scrut_hir_id: hir::HirId,
     pub opt_suggest_box_span: Option<Span>,
 }
 
@@ -649,7 +648,7 @@ pub enum ImplSource<'tcx, N> {
     /// for some type parameter. The `Vec<N>` represents the
     /// obligations incurred from normalizing the where-clause (if
     /// any).
-    Param(ty::BoundConstness, Vec<N>),
+    Param(Vec<N>),
 
     /// Successful resolution for a builtin impl.
     Builtin(BuiltinImplSource, Vec<N>),
@@ -659,21 +658,21 @@ impl<'tcx, N> ImplSource<'tcx, N> {
     pub fn nested_obligations(self) -> Vec<N> {
         match self {
             ImplSource::UserDefined(i) => i.nested,
-            ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n,
+            ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
         }
     }
 
     pub fn borrow_nested_obligations(&self) -> &[N] {
         match self {
             ImplSource::UserDefined(i) => &i.nested,
-            ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => &n,
+            ImplSource::Param(n) | ImplSource::Builtin(_, n) => &n,
         }
     }
 
     pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
         match self {
             ImplSource::UserDefined(i) => &mut i.nested,
-            ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n,
+            ImplSource::Param(n) | ImplSource::Builtin(_, n) => n,
         }
     }
 
@@ -687,7 +686,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
                 args: i.args,
                 nested: i.nested.into_iter().map(f).collect(),
             }),
-            ImplSource::Param(ct, n) => ImplSource::Param(ct, n.into_iter().map(f).collect()),
+            ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()),
             ImplSource::Builtin(source, n) => {
                 ImplSource::Builtin(source, n.into_iter().map(f).collect())
             }
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index a90d58f5fc1..ffae3579889 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -127,6 +127,7 @@ pub enum SelectionCandidate<'tcx> {
     /// an applicable bound in the trait definition. The `usize` is an index
     /// into the list returned by `tcx.item_bounds`. The constness is the
     /// constness of the bound in the trait.
+    // FIXME(effects) do we need this constness
     ProjectionCandidate(usize, ty::BoundConstness),
 
     /// Implementation of a `Fn`-family trait by one of the anonymous types
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index d7dc429f53b..ec450cf5590 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -13,8 +13,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
                 write!(f, "Builtin({source:?}, {d:?})")
             }
 
-            super::ImplSource::Param(ct, n) => {
-                write!(f, "ImplSourceParamData({n:?}, {ct:?})")
+            super::ImplSource::Param(n) => {
+                write!(f, "ImplSourceParamData({n:?})")
             }
         }
     }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 48aa25dba6d..1274f427e4f 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -238,7 +238,7 @@ pub struct ImplHeader<'tcx> {
     pub impl_def_id: DefId,
     pub self_ty: Ty<'tcx>,
     pub trait_ref: Option<TraitRef<'tcx>>,
-    pub predicates: Vec<Predicate<'tcx>>,
+    pub predicates: Vec<(Predicate<'tcx>, Span)>,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
@@ -355,8 +355,8 @@ impl TyCtxt<'_> {
 
     #[inline]
     #[track_caller]
-    pub fn local_parent(self, id: LocalDefId) -> LocalDefId {
-        self.parent(id.to_def_id()).expect_local()
+    pub fn local_parent(self, id: impl Into<LocalDefId>) -> LocalDefId {
+        self.parent(id.into().to_def_id()).expect_local()
     }
 
     pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 83a75d0c6b9..05871d0bc39 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -329,7 +329,8 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
 }
 
 // This is only used by query descriptions
-pub fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
+pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> String {
+    let def_id = def_id.into();
     if def_id.is_top_level_module() {
         "top-level module".to_string()
     } else {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index bb6513363c9..ac0c88468fa 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_data_structures::sso::SsoHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
-use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPathData, DefPathDataName, DisambiguatedDefPathData};
 use rustc_hir::LangItem;
 use rustc_session::config::TrimmedDefPaths;
@@ -326,7 +326,8 @@ pub trait PrettyPrinter<'tcx>:
             {
                 this
                     .tcx()
-                    .module_children(visible_parent)
+                    // FIXME(typed_def_id): Further propagate ModDefId
+                    .module_children(ModDefId::new_unchecked(*visible_parent))
                     .iter()
                     .filter(|child| child.res.opt_def_id() == Some(def_id))
                     .find(|child| child.vis.is_public() && child.ident.name != kw::Underscore)
@@ -551,7 +552,8 @@ pub trait PrettyPrinter<'tcx>:
                 // that's public and whose identifier isn't `_`.
                 let reexport = self
                     .tcx()
-                    .module_children(visible_parent)
+                    // FIXME(typed_def_id): Further propagate ModDefId
+                    .module_children(ModDefId::new_unchecked(visible_parent))
                     .iter()
                     .filter(|child| child.res.opt_def_id() == Some(def_id))
                     .find(|child| child.vis.is_public() && child.ident.name != kw::Underscore)
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 295cddb1e15..fe5190900e9 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -65,7 +65,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
                 let target = self.parse_block(args[1])?;
                 self.parse_call(args[2], destination, target)
             },
-            ExprKind::Match { scrutinee, arms } => {
+            ExprKind::Match { scrutinee, arms, .. } => {
                 let discr = self.parse_operand(*scrutinee)?;
                 self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
             },
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index c750727903f..a5c86e31a29 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -47,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::Block { block: ast_block } => {
                 this.ast_block(destination, block, ast_block, source_info)
             }
-            ExprKind::Match { scrutinee, ref arms } => {
+            ExprKind::Match { scrutinee, ref arms, .. } => {
                 this.match_expr(destination, expr_span, block, &this.thir[scrutinee], arms)
             }
             ExprKind::If { cond, then, else_opt, if_then_scope } => {
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 994ac8a3286..6c1f7d7a606 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -445,7 +445,6 @@ impl<'tcx> Cx<'tcx> {
                     let rhs = self.mirror_expr(rhs);
                     self.overloaded_operator(expr, Box::new([lhs, rhs]))
                 } else {
-                    // FIXME overflow
                     match op.node {
                         hir::BinOpKind::And => ExprKind::LogicalOp {
                             op: LogicalOp::And,
@@ -733,6 +732,7 @@ impl<'tcx> Cx<'tcx> {
             },
             hir::ExprKind::Match(ref discr, ref arms, _) => ExprKind::Match {
                 scrutinee: self.mirror_expr(discr),
+                scrutinee_hir_id: discr.hir_id,
                 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
             },
             hir::ExprKind::Loop(ref body, ..) => {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index a786e659664..383e80851f0 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -135,10 +135,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
                 });
                 return;
             }
-            ExprKind::Match { scrutinee, box ref arms } => {
+            ExprKind::Match { scrutinee, scrutinee_hir_id, box ref arms } => {
                 let source = match ex.span.desugaring_kind() {
                     Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
-                    Some(DesugaringKind::QuestionMark) => hir::MatchSource::TryDesugar,
+                    Some(DesugaringKind::QuestionMark) => {
+                        hir::MatchSource::TryDesugar(scrutinee_hir_id)
+                    }
                     Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
                     _ => hir::MatchSource::Normal,
                 };
@@ -277,7 +279,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
             | hir::MatchSource::FormatArgs => report_arm_reachability(&cx, &report),
             // Unreachable patterns in try and await expressions occur when one of
             // the arms are an uninhabited type. Which is OK.
-            hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
+            hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar(_) => {}
         }
 
         // Check if the match is exhaustive.
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 251c6b4b6da..1376344cfda 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
@@ -325,6 +325,11 @@ impl<'tcx> ConstToPat<'tcx> {
                 // `PartialEq::eq` on it.
                 return Err(FallbackToConstRef);
             }
+            ty::FnDef(..) => {
+                self.saw_const_match_error.set(true);
+                tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
+                PatKind::Wild
+            }
             ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
                 debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
                 self.saw_const_match_error.set(true);
@@ -440,7 +445,7 @@ impl<'tcx> ConstToPat<'tcx> {
                     }
                 }
             },
-            ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => PatKind::Constant {
+            ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => PatKind::Constant {
                 value: mir::ConstantKind::Ty(ty::Const::new_value(tcx, cv, ty)),
             },
             ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 903dbeeadfa..3b6276cfeb0 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -321,7 +321,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
                 print_indented!(self, "}", depth_lvl);
             }
-            Match { scrutinee, arms } => {
+            Match { scrutinee, arms, .. } => {
                 print_indented!(self, "Match {", depth_lvl);
                 print_indented!(self, "scrutinee:", depth_lvl + 1);
                 self.print_expr(*scrutinee, depth_lvl + 2);
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 97bdb878ab1..d1f2f0c76c8 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -8,25 +8,50 @@ use debug::{DebugCounters, NESTED_INDENT};
 use graph::{BasicCoverageBlock, BcbBranch, CoverageGraph, TraverseCoverageGraphWithLoops};
 use spans::CoverageSpan;
 
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::WithNumNodes;
 use rustc_index::bit_set::BitSet;
+use rustc_index::IndexVec;
 use rustc_middle::mir::coverage::*;
 
-/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
-/// `Coverage` statements.
+/// Generates and stores coverage counter and coverage expression information
+/// associated with nodes/edges in the BCB graph.
 pub(super) struct CoverageCounters {
     function_source_hash: u64,
     next_counter_id: CounterId,
     next_expression_id: ExpressionId,
+
+    /// Coverage counters/expressions that are associated with individual BCBs.
+    bcb_counters: IndexVec<BasicCoverageBlock, Option<CoverageKind>>,
+    /// Coverage counters/expressions that are associated with the control-flow
+    /// edge between two BCBs.
+    bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), CoverageKind>,
+    /// Tracks which BCBs have a counter associated with some incoming edge.
+    /// Only used by debug assertions, to verify that BCBs with incoming edge
+    /// counters do not have their own physical counters (expressions are allowed).
+    bcb_has_incoming_edge_counters: BitSet<BasicCoverageBlock>,
+    /// Expression nodes that are not directly associated with any particular
+    /// BCB/edge, but are needed as operands to more complex expressions.
+    /// These are always `CoverageKind::Expression`.
+    pub(super) intermediate_expressions: Vec<CoverageKind>,
+
     pub debug_counters: DebugCounters,
 }
 
 impl CoverageCounters {
-    pub fn new(function_source_hash: u64) -> Self {
+    pub(super) fn new(function_source_hash: u64, basic_coverage_blocks: &CoverageGraph) -> Self {
+        let num_bcbs = basic_coverage_blocks.num_nodes();
+
         Self {
             function_source_hash,
             next_counter_id: CounterId::START,
             next_expression_id: ExpressionId::START,
+
+            bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
+            bcb_edge_counters: FxHashMap::default(),
+            bcb_has_incoming_edge_counters: BitSet::new_empty(num_bcbs),
+            intermediate_expressions: Vec::new(),
+
             debug_counters: DebugCounters::new(),
         }
     }
@@ -38,15 +63,14 @@ impl CoverageCounters {
     }
 
     /// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
-    /// indirectly associated with `CoverageSpans`, and returns additional `Expression`s
+    /// indirectly associated with `CoverageSpans`, and accumulates additional `Expression`s
     /// representing intermediate values.
     pub fn make_bcb_counters(
         &mut self,
-        basic_coverage_blocks: &mut CoverageGraph,
+        basic_coverage_blocks: &CoverageGraph,
         coverage_spans: &[CoverageSpan],
-    ) -> Result<Vec<CoverageKind>, Error> {
-        let mut bcb_counters = BcbCounters::new(self, basic_coverage_blocks);
-        bcb_counters.make_bcb_counters(coverage_spans)
+    ) -> Result<(), Error> {
+        MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(coverage_spans)
     }
 
     fn make_counter<F>(&mut self, debug_block_label_fn: F) -> CoverageKind
@@ -106,21 +130,95 @@ impl CoverageCounters {
         self.next_expression_id = next.next_id();
         next
     }
+
+    fn set_bcb_counter(
+        &mut self,
+        bcb: BasicCoverageBlock,
+        counter_kind: CoverageKind,
+    ) -> Result<Operand, Error> {
+        debug_assert!(
+            // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
+            // have an expression (to be injected into an existing `BasicBlock` represented by this
+            // `BasicCoverageBlock`).
+            counter_kind.is_expression() || !self.bcb_has_incoming_edge_counters.contains(bcb),
+            "attempt to add a `Counter` to a BCB target with existing incoming edge counters"
+        );
+        let operand = counter_kind.as_operand();
+        if let Some(replaced) = self.bcb_counters[bcb].replace(counter_kind) {
+            Error::from_string(format!(
+                "attempt to set a BasicCoverageBlock coverage counter more than once; \
+                {bcb:?} already had counter {replaced:?}",
+            ))
+        } else {
+            Ok(operand)
+        }
+    }
+
+    fn set_bcb_edge_counter(
+        &mut self,
+        from_bcb: BasicCoverageBlock,
+        to_bcb: BasicCoverageBlock,
+        counter_kind: CoverageKind,
+    ) -> Result<Operand, Error> {
+        if level_enabled!(tracing::Level::DEBUG) {
+            // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
+            // have an expression (to be injected into an existing `BasicBlock` represented by this
+            // `BasicCoverageBlock`).
+            if self.bcb_counter(to_bcb).is_some_and(|c| !c.is_expression()) {
+                return Error::from_string(format!(
+                    "attempt to add an incoming edge counter from {from_bcb:?} when the target BCB already \
+                    has a `Counter`"
+                ));
+            }
+        }
+        self.bcb_has_incoming_edge_counters.insert(to_bcb);
+        let operand = counter_kind.as_operand();
+        if let Some(replaced) = self.bcb_edge_counters.insert((from_bcb, to_bcb), counter_kind) {
+            Error::from_string(format!(
+                "attempt to set an edge counter more than once; from_bcb: \
+                {from_bcb:?} already had counter {replaced:?}",
+            ))
+        } else {
+            Ok(operand)
+        }
+    }
+
+    pub(super) fn bcb_counter(&self, bcb: BasicCoverageBlock) -> Option<&CoverageKind> {
+        self.bcb_counters[bcb].as_ref()
+    }
+
+    pub(super) fn take_bcb_counter(&mut self, bcb: BasicCoverageBlock) -> Option<CoverageKind> {
+        self.bcb_counters[bcb].take()
+    }
+
+    pub(super) fn drain_bcb_counters(
+        &mut self,
+    ) -> impl Iterator<Item = (BasicCoverageBlock, CoverageKind)> + '_ {
+        self.bcb_counters
+            .iter_enumerated_mut()
+            .filter_map(|(bcb, counter)| Some((bcb, counter.take()?)))
+    }
+
+    pub(super) fn drain_bcb_edge_counters(
+        &mut self,
+    ) -> impl Iterator<Item = ((BasicCoverageBlock, BasicCoverageBlock), CoverageKind)> + '_ {
+        self.bcb_edge_counters.drain()
+    }
 }
 
 /// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be
 /// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable expression
 /// (adding or subtracting two other counters or expressions) can compute the same result as an
 /// embedded counter, an `Expression` should be used.
-struct BcbCounters<'a> {
+struct MakeBcbCounters<'a> {
     coverage_counters: &'a mut CoverageCounters,
-    basic_coverage_blocks: &'a mut CoverageGraph,
+    basic_coverage_blocks: &'a CoverageGraph,
 }
 
-impl<'a> BcbCounters<'a> {
+impl<'a> MakeBcbCounters<'a> {
     fn new(
         coverage_counters: &'a mut CoverageCounters,
-        basic_coverage_blocks: &'a mut CoverageGraph,
+        basic_coverage_blocks: &'a CoverageGraph,
     ) -> Self {
         Self { coverage_counters, basic_coverage_blocks }
     }
@@ -135,13 +233,9 @@ impl<'a> BcbCounters<'a> {
     /// Returns any non-code-span expressions created to represent intermediate values (such as to
     /// add two counters so the result can be subtracted from another counter), or an Error with
     /// message for subsequent debugging.
-    fn make_bcb_counters(
-        &mut self,
-        coverage_spans: &[CoverageSpan],
-    ) -> Result<Vec<CoverageKind>, Error> {
+    fn make_bcb_counters(&mut self, coverage_spans: &[CoverageSpan]) -> Result<(), Error> {
         debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
         let num_bcbs = self.basic_coverage_blocks.num_nodes();
-        let mut collect_intermediate_expressions = Vec::with_capacity(num_bcbs);
 
         let mut bcbs_with_coverage = BitSet::new_empty(num_bcbs);
         for covspan in coverage_spans {
@@ -162,16 +256,10 @@ impl<'a> BcbCounters<'a> {
         while let Some(bcb) = traversal.next(self.basic_coverage_blocks) {
             if bcbs_with_coverage.contains(bcb) {
                 debug!("{:?} has at least one `CoverageSpan`. Get or make its counter", bcb);
-                let branching_counter_operand =
-                    self.get_or_make_counter_operand(bcb, &mut collect_intermediate_expressions)?;
+                let branching_counter_operand = self.get_or_make_counter_operand(bcb)?;
 
                 if self.bcb_needs_branch_counters(bcb) {
-                    self.make_branch_counters(
-                        &mut traversal,
-                        bcb,
-                        branching_counter_operand,
-                        &mut collect_intermediate_expressions,
-                    )?;
+                    self.make_branch_counters(&mut traversal, bcb, branching_counter_operand)?;
                 }
             } else {
                 debug!(
@@ -183,7 +271,7 @@ impl<'a> BcbCounters<'a> {
         }
 
         if traversal.is_complete() {
-            Ok(collect_intermediate_expressions)
+            Ok(())
         } else {
             Error::from_string(format!(
                 "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: {:?}",
@@ -197,7 +285,6 @@ impl<'a> BcbCounters<'a> {
         traversal: &mut TraverseCoverageGraphWithLoops,
         branching_bcb: BasicCoverageBlock,
         branching_counter_operand: Operand,
-        collect_intermediate_expressions: &mut Vec<CoverageKind>,
     ) -> Result<(), Error> {
         let branches = self.bcb_branches(branching_bcb);
         debug!(
@@ -205,9 +292,7 @@ impl<'a> BcbCounters<'a> {
             branching_bcb,
             branches
                 .iter()
-                .map(|branch| {
-                    format!("{:?}: {:?}", branch, branch.counter(&self.basic_coverage_blocks))
-                })
+                .map(|branch| { format!("{:?}: {:?}", branch, self.branch_counter(branch)) })
                 .collect::<Vec<_>>()
                 .join("\n  "),
         );
@@ -233,17 +318,10 @@ impl<'a> BcbCounters<'a> {
                         counter",
                         branch, branching_bcb
                     );
-                    self.get_or_make_counter_operand(
-                        branch.target_bcb,
-                        collect_intermediate_expressions,
-                    )?
+                    self.get_or_make_counter_operand(branch.target_bcb)?
                 } else {
                     debug!("  {:?} has multiple incoming edges, so adding an edge counter", branch);
-                    self.get_or_make_edge_counter_operand(
-                        branching_bcb,
-                        branch.target_bcb,
-                        collect_intermediate_expressions,
-                    )?
+                    self.get_or_make_edge_counter_operand(branching_bcb, branch.target_bcb)?
                 };
                 if let Some(sumup_counter_operand) =
                     some_sumup_counter_operand.replace(branch_counter_operand)
@@ -259,7 +337,7 @@ impl<'a> BcbCounters<'a> {
                         self.format_counter(&intermediate_expression)
                     );
                     let intermediate_expression_operand = intermediate_expression.as_operand();
-                    collect_intermediate_expressions.push(intermediate_expression);
+                    self.coverage_counters.intermediate_expressions.push(intermediate_expression);
                     some_sumup_counter_operand.replace(intermediate_expression_operand);
                 }
             }
@@ -284,29 +362,24 @@ impl<'a> BcbCounters<'a> {
         debug!("{:?} gets an expression: {}", expression_branch, self.format_counter(&expression));
         let bcb = expression_branch.target_bcb;
         if expression_branch.is_only_path_to_target() {
-            self.basic_coverage_blocks[bcb].set_counter(expression)?;
+            self.coverage_counters.set_bcb_counter(bcb, expression)?;
         } else {
-            self.basic_coverage_blocks[bcb].set_edge_counter_from(branching_bcb, expression)?;
+            self.coverage_counters.set_bcb_edge_counter(branching_bcb, bcb, expression)?;
         }
         Ok(())
     }
 
-    fn get_or_make_counter_operand(
-        &mut self,
-        bcb: BasicCoverageBlock,
-        collect_intermediate_expressions: &mut Vec<CoverageKind>,
-    ) -> Result<Operand, Error> {
-        self.recursive_get_or_make_counter_operand(bcb, collect_intermediate_expressions, 1)
+    fn get_or_make_counter_operand(&mut self, bcb: BasicCoverageBlock) -> Result<Operand, Error> {
+        self.recursive_get_or_make_counter_operand(bcb, 1)
     }
 
     fn recursive_get_or_make_counter_operand(
         &mut self,
         bcb: BasicCoverageBlock,
-        collect_intermediate_expressions: &mut Vec<CoverageKind>,
         debug_indent_level: usize,
     ) -> Result<Operand, Error> {
         // If the BCB already has a counter, return it.
-        if let Some(counter_kind) = self.basic_coverage_blocks[bcb].counter() {
+        if let Some(counter_kind) = &self.coverage_counters.bcb_counters[bcb] {
             debug!(
                 "{}{:?} already has a counter: {}",
                 NESTED_INDENT.repeat(debug_indent_level),
@@ -339,7 +412,7 @@ impl<'a> BcbCounters<'a> {
                     self.format_counter(&counter_kind),
                 );
             }
-            return self.basic_coverage_blocks[bcb].set_counter(counter_kind);
+            return self.coverage_counters.set_bcb_counter(bcb, counter_kind);
         }
 
         // A BCB with multiple incoming edges can compute its count by `Expression`, summing up the
@@ -355,7 +428,6 @@ impl<'a> BcbCounters<'a> {
         let first_edge_counter_operand = self.recursive_get_or_make_edge_counter_operand(
             predecessors.next().unwrap(),
             bcb,
-            collect_intermediate_expressions,
             debug_indent_level + 1,
         )?;
         let mut some_sumup_edge_counter_operand = None;
@@ -363,7 +435,6 @@ impl<'a> BcbCounters<'a> {
             let edge_counter_operand = self.recursive_get_or_make_edge_counter_operand(
                 predecessor,
                 bcb,
-                collect_intermediate_expressions,
                 debug_indent_level + 1,
             )?;
             if let Some(sumup_edge_counter_operand) =
@@ -381,7 +452,7 @@ impl<'a> BcbCounters<'a> {
                     self.format_counter(&intermediate_expression)
                 );
                 let intermediate_expression_operand = intermediate_expression.as_operand();
-                collect_intermediate_expressions.push(intermediate_expression);
+                self.coverage_counters.intermediate_expressions.push(intermediate_expression);
                 some_sumup_edge_counter_operand.replace(intermediate_expression_operand);
             }
         }
@@ -397,43 +468,34 @@ impl<'a> BcbCounters<'a> {
             bcb,
             self.format_counter(&counter_kind)
         );
-        self.basic_coverage_blocks[bcb].set_counter(counter_kind)
+        self.coverage_counters.set_bcb_counter(bcb, counter_kind)
     }
 
     fn get_or_make_edge_counter_operand(
         &mut self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
-        collect_intermediate_expressions: &mut Vec<CoverageKind>,
     ) -> Result<Operand, Error> {
-        self.recursive_get_or_make_edge_counter_operand(
-            from_bcb,
-            to_bcb,
-            collect_intermediate_expressions,
-            1,
-        )
+        self.recursive_get_or_make_edge_counter_operand(from_bcb, to_bcb, 1)
     }
 
     fn recursive_get_or_make_edge_counter_operand(
         &mut self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
-        collect_intermediate_expressions: &mut Vec<CoverageKind>,
         debug_indent_level: usize,
     ) -> Result<Operand, Error> {
         // If the source BCB has only one successor (assumed to be the given target), an edge
         // counter is unnecessary. Just get or make a counter for the source BCB.
         let successors = self.bcb_successors(from_bcb).iter();
         if successors.len() == 1 {
-            return self.recursive_get_or_make_counter_operand(
-                from_bcb,
-                collect_intermediate_expressions,
-                debug_indent_level + 1,
-            );
+            return self.recursive_get_or_make_counter_operand(from_bcb, debug_indent_level + 1);
         }
 
         // If the edge already has a counter, return it.
-        if let Some(counter_kind) = self.basic_coverage_blocks[to_bcb].edge_counter_from(from_bcb) {
+        if let Some(counter_kind) =
+            self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
+        {
             debug!(
                 "{}Edge {:?}->{:?} already has a counter: {}",
                 NESTED_INDENT.repeat(debug_indent_level),
@@ -454,7 +516,7 @@ impl<'a> BcbCounters<'a> {
             to_bcb,
             self.format_counter(&counter_kind)
         );
-        self.basic_coverage_blocks[to_bcb].set_edge_counter_from(from_bcb, counter_kind)
+        self.coverage_counters.set_bcb_edge_counter(from_bcb, to_bcb, counter_kind)
     }
 
     /// Select a branch for the expression, either the recommended `reloop_branch`, or if none was
@@ -464,8 +526,7 @@ impl<'a> BcbCounters<'a> {
         traversal: &TraverseCoverageGraphWithLoops,
         branches: &[BcbBranch],
     ) -> BcbBranch {
-        let branch_needs_a_counter =
-            |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
+        let branch_needs_a_counter = |branch: &BcbBranch| self.branch_has_no_counter(branch);
 
         let some_reloop_branch = self.find_some_reloop_branch(traversal, &branches);
         if let Some(reloop_branch_without_counter) =
@@ -478,10 +539,8 @@ impl<'a> BcbCounters<'a> {
             );
             reloop_branch_without_counter
         } else {
-            let &branch_without_counter = branches
-                .iter()
-                .find(|&&branch| branch.counter(&self.basic_coverage_blocks).is_none())
-                .expect(
+            let &branch_without_counter =
+                branches.iter().find(|&branch| self.branch_has_no_counter(branch)).expect(
                     "needs_branch_counters was `true` so there should be at least one \
                     branch",
                 );
@@ -508,8 +567,7 @@ impl<'a> BcbCounters<'a> {
         traversal: &TraverseCoverageGraphWithLoops,
         branches: &[BcbBranch],
     ) -> Option<BcbBranch> {
-        let branch_needs_a_counter =
-            |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
+        let branch_needs_a_counter = |branch: &BcbBranch| self.branch_has_no_counter(branch);
 
         let mut some_reloop_branch: Option<BcbBranch> = None;
         for context in traversal.context_stack.iter().rev() {
@@ -520,7 +578,7 @@ impl<'a> BcbCounters<'a> {
                         self.bcb_dominates(branch.target_bcb, backedge_from_bcb)
                     }) {
                         if let Some(reloop_branch) = some_reloop_branch {
-                            if reloop_branch.counter(&self.basic_coverage_blocks).is_none() {
+                            if self.branch_has_no_counter(&reloop_branch) {
                                 // we already found a candidate reloop_branch that still
                                 // needs a counter
                                 continue;
@@ -586,12 +644,24 @@ impl<'a> BcbCounters<'a> {
     }
 
     fn bcb_needs_branch_counters(&self, bcb: BasicCoverageBlock) -> bool {
-        let branch_needs_a_counter =
-            |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
+        let branch_needs_a_counter = |branch: &BcbBranch| self.branch_has_no_counter(branch);
         let branches = self.bcb_branches(bcb);
         branches.len() > 1 && branches.iter().any(branch_needs_a_counter)
     }
 
+    fn branch_has_no_counter(&self, branch: &BcbBranch) -> bool {
+        self.branch_counter(branch).is_none()
+    }
+
+    fn branch_counter(&self, branch: &BcbBranch) -> Option<&CoverageKind> {
+        let to_bcb = branch.target_bcb;
+        if let Some(from_bcb) = branch.edge_from_bcb {
+            self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
+        } else {
+            self.coverage_counters.bcb_counters[to_bcb].as_ref()
+        }
+    }
+
     /// Returns true if the BasicCoverageBlock has zero or one incoming edge. (If zero, it should be
     /// the entry point for the function.)
     #[inline]
diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs
index 26f9cfd0b86..d2c0c4ba069 100644
--- a/compiler/rustc_mir_transform/src/coverage/debug.rs
+++ b/compiler/rustc_mir_transform/src/coverage/debug.rs
@@ -108,6 +108,7 @@
 //!         recursively, generating labels with nested operations, enclosed in parentheses
 //!         (for example: `bcb2 + (bcb0 - bcb1)`).
 
+use super::counters::CoverageCounters;
 use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph};
 use super::spans::CoverageSpan;
 
@@ -659,18 +660,21 @@ pub(super) fn dump_coverage_graphviz<'tcx>(
     mir_body: &mir::Body<'tcx>,
     pass_name: &str,
     basic_coverage_blocks: &CoverageGraph,
-    debug_counters: &DebugCounters,
+    coverage_counters: &CoverageCounters,
     graphviz_data: &GraphvizData,
     intermediate_expressions: &[CoverageKind],
     debug_used_expressions: &UsedExpressions,
 ) {
+    let debug_counters = &coverage_counters.debug_counters;
+
     let mir_source = mir_body.source;
     let def_id = mir_source.def_id();
     let node_content = |bcb| {
         bcb_to_string_sections(
             tcx,
             mir_body,
-            debug_counters,
+            coverage_counters,
+            bcb,
             &basic_coverage_blocks[bcb],
             graphviz_data.get_bcb_coverage_spans_with_counters(bcb),
             graphviz_data.get_bcb_dependency_counters(bcb),
@@ -736,12 +740,15 @@ pub(super) fn dump_coverage_graphviz<'tcx>(
 fn bcb_to_string_sections<'tcx>(
     tcx: TyCtxt<'tcx>,
     mir_body: &mir::Body<'tcx>,
-    debug_counters: &DebugCounters,
+    coverage_counters: &CoverageCounters,
+    bcb: BasicCoverageBlock,
     bcb_data: &BasicCoverageBlockData,
     some_coverage_spans_with_counters: Option<&[(CoverageSpan, CoverageKind)]>,
     some_dependency_counters: Option<&[CoverageKind]>,
     some_intermediate_expressions: Option<&[CoverageKind]>,
 ) -> Vec<String> {
+    let debug_counters = &coverage_counters.debug_counters;
+
     let len = bcb_data.basic_blocks.len();
     let mut sections = Vec::new();
     if let Some(collect_intermediate_expressions) = some_intermediate_expressions {
@@ -777,7 +784,7 @@ fn bcb_to_string_sections<'tcx>(
                 .join("  \n"),
         ));
     }
-    if let Some(counter_kind) = &bcb_data.counter_kind {
+    if let Some(counter_kind) = coverage_counters.bcb_counter(bcb) {
         sections.push(format!("{counter_kind:?}"));
     }
     let non_term_blocks = bcb_data.basic_blocks[0..len - 1]
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index f94dad4c8da..59b01ffec0f 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -1,12 +1,8 @@
-use super::Error;
-
 use itertools::Itertools;
-use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::dominators::{self, Dominators};
 use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode};
 use rustc_index::bit_set::BitSet;
 use rustc_index::{IndexSlice, IndexVec};
-use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::{self, BasicBlock, BasicBlockData, Terminator, TerminatorKind};
 
 use std::cmp::Ordering;
@@ -15,10 +11,7 @@ use std::ops::{Index, IndexMut};
 const ID_SEPARATOR: &str = ",";
 
 /// A coverage-specific simplification of the MIR control flow graph (CFG). The `CoverageGraph`s
-/// nodes are `BasicCoverageBlock`s, which encompass one or more MIR `BasicBlock`s, plus a
-/// `CoverageKind` counter (to be added by `CoverageCounters::make_bcb_counters`), and an optional
-/// set of additional counters--if needed--to count incoming edges, if there are more than one.
-/// (These "edge counters" are eventually converted into new MIR `BasicBlock`s.)
+/// nodes are `BasicCoverageBlock`s, which encompass one or more MIR `BasicBlock`s.
 #[derive(Debug)]
 pub(super) struct CoverageGraph {
     bcbs: IndexVec<BasicCoverageBlock, BasicCoverageBlockData>,
@@ -196,13 +189,6 @@ impl CoverageGraph {
     }
 
     #[inline(always)]
-    pub fn iter_enumerated_mut(
-        &mut self,
-    ) -> impl Iterator<Item = (BasicCoverageBlock, &mut BasicCoverageBlockData)> {
-        self.bcbs.iter_enumerated_mut()
-    }
-
-    #[inline(always)]
     pub fn bcb_from_bb(&self, bb: BasicBlock) -> Option<BasicCoverageBlock> {
         if bb.index() < self.bb_to_bcb.len() { self.bb_to_bcb[bb] } else { None }
     }
@@ -320,14 +306,12 @@ rustc_index::newtype_index! {
 #[derive(Debug, Clone)]
 pub(super) struct BasicCoverageBlockData {
     pub basic_blocks: Vec<BasicBlock>,
-    pub counter_kind: Option<CoverageKind>,
-    edge_from_bcbs: Option<FxHashMap<BasicCoverageBlock, CoverageKind>>,
 }
 
 impl BasicCoverageBlockData {
     pub fn from(basic_blocks: Vec<BasicBlock>) -> Self {
         assert!(basic_blocks.len() > 0);
-        Self { basic_blocks, counter_kind: None, edge_from_bcbs: None }
+        Self { basic_blocks }
     }
 
     #[inline(always)]
@@ -345,80 +329,6 @@ impl BasicCoverageBlockData {
         &mir_body[self.last_bb()].terminator()
     }
 
-    pub fn set_counter(&mut self, counter_kind: CoverageKind) -> Result<Operand, Error> {
-        debug_assert!(
-            // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
-            // have an expression (to be injected into an existing `BasicBlock` represented by this
-            // `BasicCoverageBlock`).
-            self.edge_from_bcbs.is_none() || counter_kind.is_expression(),
-            "attempt to add a `Counter` to a BCB target with existing incoming edge counters"
-        );
-        let operand = counter_kind.as_operand();
-        if let Some(replaced) = self.counter_kind.replace(counter_kind) {
-            Error::from_string(format!(
-                "attempt to set a BasicCoverageBlock coverage counter more than once; \
-                {self:?} already had counter {replaced:?}",
-            ))
-        } else {
-            Ok(operand)
-        }
-    }
-
-    #[inline(always)]
-    pub fn counter(&self) -> Option<&CoverageKind> {
-        self.counter_kind.as_ref()
-    }
-
-    #[inline(always)]
-    pub fn take_counter(&mut self) -> Option<CoverageKind> {
-        self.counter_kind.take()
-    }
-
-    pub fn set_edge_counter_from(
-        &mut self,
-        from_bcb: BasicCoverageBlock,
-        counter_kind: CoverageKind,
-    ) -> Result<Operand, Error> {
-        if level_enabled!(tracing::Level::DEBUG) {
-            // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
-            // have an expression (to be injected into an existing `BasicBlock` represented by this
-            // `BasicCoverageBlock`).
-            if self.counter_kind.as_ref().is_some_and(|c| !c.is_expression()) {
-                return Error::from_string(format!(
-                    "attempt to add an incoming edge counter from {from_bcb:?} when the target BCB already \
-                    has a `Counter`"
-                ));
-            }
-        }
-        let operand = counter_kind.as_operand();
-        if let Some(replaced) =
-            self.edge_from_bcbs.get_or_insert_default().insert(from_bcb, counter_kind)
-        {
-            Error::from_string(format!(
-                "attempt to set an edge counter more than once; from_bcb: \
-                {from_bcb:?} already had counter {replaced:?}",
-            ))
-        } else {
-            Ok(operand)
-        }
-    }
-
-    #[inline]
-    pub fn edge_counter_from(&self, from_bcb: BasicCoverageBlock) -> Option<&CoverageKind> {
-        if let Some(edge_from_bcbs) = &self.edge_from_bcbs {
-            edge_from_bcbs.get(&from_bcb)
-        } else {
-            None
-        }
-    }
-
-    #[inline]
-    pub fn take_edge_counters(
-        &mut self,
-    ) -> Option<impl Iterator<Item = (BasicCoverageBlock, CoverageKind)>> {
-        self.edge_from_bcbs.take().map(|m| m.into_iter())
-    }
-
     pub fn id(&self) -> String {
         format!("@{}", self.basic_blocks.iter().map(|bb| bb.index().to_string()).join(ID_SEPARATOR))
     }
@@ -448,17 +358,6 @@ impl BcbBranch {
         Self { edge_from_bcb, target_bcb: to_bcb }
     }
 
-    pub fn counter<'a>(
-        &self,
-        basic_coverage_blocks: &'a CoverageGraph,
-    ) -> Option<&'a CoverageKind> {
-        if let Some(from_bcb) = self.edge_from_bcb {
-            basic_coverage_blocks[self.target_bcb].edge_counter_from(from_bcb)
-        } else {
-            basic_coverage_blocks[self.target_bcb].counter()
-        }
-    }
-
     pub fn is_only_path_to_target(&self) -> bool {
         self.edge_from_bcb.is_none()
     }
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index f713613d313..e08b6d6f6e8 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -137,6 +137,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
 
         let function_source_hash = hash_mir_source(tcx, hir_body);
         let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
+        let coverage_counters = CoverageCounters::new(function_source_hash, &basic_coverage_blocks);
+
         Self {
             pass_name,
             tcx,
@@ -145,7 +147,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
             fn_sig_span,
             body_span,
             basic_coverage_blocks,
-            coverage_counters: CoverageCounters::new(function_source_hash),
+            coverage_counters,
         }
     }
 
@@ -199,52 +201,47 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         // `BasicCoverageBlock`s not already associated with a `CoverageSpan`.
         //
         // Intermediate expressions (used to compute other `Expression` values), which have no
-        // direct associate to any `BasicCoverageBlock`, are returned in the method `Result`.
-        let intermediate_expressions_or_error = self
+        // direct association with any `BasicCoverageBlock`, are accumulated inside `coverage_counters`.
+        let result = self
             .coverage_counters
             .make_bcb_counters(&mut self.basic_coverage_blocks, &coverage_spans);
 
-        let (result, intermediate_expressions) = match intermediate_expressions_or_error {
-            Ok(intermediate_expressions) => {
-                // If debugging, add any intermediate expressions (which are not associated with any
-                // BCB) to the `debug_used_expressions` map.
-                if debug_used_expressions.is_enabled() {
-                    for intermediate_expression in &intermediate_expressions {
-                        debug_used_expressions.add_expression_operands(intermediate_expression);
-                    }
+        if let Ok(()) = result {
+            // If debugging, add any intermediate expressions (which are not associated with any
+            // BCB) to the `debug_used_expressions` map.
+            if debug_used_expressions.is_enabled() {
+                for intermediate_expression in &self.coverage_counters.intermediate_expressions {
+                    debug_used_expressions.add_expression_operands(intermediate_expression);
                 }
-
-                ////////////////////////////////////////////////////
-                // Remove the counter or edge counter from of each `CoverageSpan`s associated
-                // `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR.
-                //
-                // `Coverage` statements injected from `CoverageSpan`s will include the code regions
-                // (source code start and end positions) to be counted by the associated counter.
-                //
-                // These `CoverageSpan`-associated counters are removed from their associated
-                // `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph`
-                // are indirect counters (to be injected next, without associated code regions).
-                self.inject_coverage_span_counters(
-                    coverage_spans,
-                    &mut graphviz_data,
-                    &mut debug_used_expressions,
-                );
-
-                ////////////////////////////////////////////////////
-                // For any remaining `BasicCoverageBlock` counters (that were not associated with
-                // any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s)
-                // to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on
-                // are in fact counted, even though they don't directly contribute to counting
-                // their own independent code region's coverage.
-                self.inject_indirect_counters(&mut graphviz_data, &mut debug_used_expressions);
-
-                // Intermediate expressions will be injected as the final step, after generating
-                // debug output, if any.
-                ////////////////////////////////////////////////////
-
-                (Ok(()), intermediate_expressions)
             }
-            Err(e) => (Err(e), Vec::new()),
+
+            ////////////////////////////////////////////////////
+            // Remove the counter or edge counter from of each `CoverageSpan`s associated
+            // `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR.
+            //
+            // `Coverage` statements injected from `CoverageSpan`s will include the code regions
+            // (source code start and end positions) to be counted by the associated counter.
+            //
+            // These `CoverageSpan`-associated counters are removed from their associated
+            // `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph`
+            // are indirect counters (to be injected next, without associated code regions).
+            self.inject_coverage_span_counters(
+                coverage_spans,
+                &mut graphviz_data,
+                &mut debug_used_expressions,
+            );
+
+            ////////////////////////////////////////////////////
+            // For any remaining `BasicCoverageBlock` counters (that were not associated with
+            // any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s)
+            // to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on
+            // are in fact counted, even though they don't directly contribute to counting
+            // their own independent code region's coverage.
+            self.inject_indirect_counters(&mut graphviz_data, &mut debug_used_expressions);
+
+            // Intermediate expressions will be injected as the final step, after generating
+            // debug output, if any.
+            ////////////////////////////////////////////////////
         };
 
         if graphviz_data.is_enabled() {
@@ -255,9 +252,9 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
                 self.mir_body,
                 self.pass_name,
                 &self.basic_coverage_blocks,
-                &self.coverage_counters.debug_counters,
+                &self.coverage_counters,
                 &graphviz_data,
-                &intermediate_expressions,
+                &self.coverage_counters.intermediate_expressions,
                 &debug_used_expressions,
             );
         }
@@ -273,7 +270,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
 
         ////////////////////////////////////////////////////
         // Finally, inject the intermediate expressions collected along the way.
-        for intermediate_expression in intermediate_expressions {
+        for intermediate_expression in self.coverage_counters.intermediate_expressions.drain(..) {
             inject_intermediate_expression(self.mir_body, intermediate_expression);
         }
     }
@@ -303,7 +300,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
             let span = covspan.span;
             let counter_kind = if let Some(&counter_operand) = bcb_counters[bcb].as_ref() {
                 self.coverage_counters.make_identity_counter(counter_operand)
-            } else if let Some(counter_kind) = self.bcb_data_mut(bcb).take_counter() {
+            } else if let Some(counter_kind) = self.coverage_counters.take_bcb_counter(bcb) {
                 bcb_counters[bcb] = Some(counter_kind.as_operand());
                 debug_used_expressions.add_expression_operands(&counter_kind);
                 counter_kind
@@ -343,19 +340,17 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         debug_used_expressions: &mut debug::UsedExpressions,
     ) {
         let mut bcb_counters_without_direct_coverage_spans = Vec::new();
-        for (target_bcb, target_bcb_data) in self.basic_coverage_blocks.iter_enumerated_mut() {
-            if let Some(counter_kind) = target_bcb_data.take_counter() {
-                bcb_counters_without_direct_coverage_spans.push((None, target_bcb, counter_kind));
-            }
-            if let Some(edge_counters) = target_bcb_data.take_edge_counters() {
-                for (from_bcb, counter_kind) in edge_counters {
-                    bcb_counters_without_direct_coverage_spans.push((
-                        Some(from_bcb),
-                        target_bcb,
-                        counter_kind,
-                    ));
-                }
-            }
+        for (target_bcb, counter_kind) in self.coverage_counters.drain_bcb_counters() {
+            bcb_counters_without_direct_coverage_spans.push((None, target_bcb, counter_kind));
+        }
+        for ((from_bcb, target_bcb), counter_kind) in
+            self.coverage_counters.drain_bcb_edge_counters()
+        {
+            bcb_counters_without_direct_coverage_spans.push((
+                Some(from_bcb),
+                target_bcb,
+                counter_kind,
+            ));
         }
 
         // If debug is enabled, validate that every BCB or edge counter not directly associated
@@ -431,11 +426,6 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
     }
 
     #[inline]
-    fn bcb_data_mut(&mut self, bcb: BasicCoverageBlock) -> &mut BasicCoverageBlockData {
-        &mut self.basic_coverage_blocks[bcb]
-    }
-
-    #[inline]
     fn format_counter(&self, counter_kind: &CoverageKind) -> String {
         self.coverage_counters.debug_counters.format_counter(counter_kind)
     }
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 248a192f8f5..d797a6057a7 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -675,16 +675,16 @@ fn test_make_bcb_counters() {
                 ));
             }
         }
-        let mut coverage_counters = counters::CoverageCounters::new(0);
-        let intermediate_expressions = coverage_counters
+        let mut coverage_counters = counters::CoverageCounters::new(0, &basic_coverage_blocks);
+        let () = coverage_counters
             .make_bcb_counters(&mut basic_coverage_blocks, &coverage_spans)
             .expect("should be Ok");
-        assert_eq!(intermediate_expressions.len(), 0);
+        assert_eq!(coverage_counters.intermediate_expressions.len(), 0);
 
         let_bcb!(1);
         assert_eq!(
             0, // bcb1 has a `Counter` with id = 0
-            match basic_coverage_blocks[bcb1].counter().expect("should have a counter") {
+            match coverage_counters.bcb_counter(bcb1).expect("should have a counter") {
                 CoverageKind::Counter { id, .. } => id,
                 _ => panic!("expected a Counter"),
             }
@@ -694,7 +694,7 @@ fn test_make_bcb_counters() {
         let_bcb!(2);
         assert_eq!(
             1, // bcb2 has a `Counter` with id = 1
-            match basic_coverage_blocks[bcb2].counter().expect("should have a counter") {
+            match coverage_counters.bcb_counter(bcb2).expect("should have a counter") {
                 CoverageKind::Counter { id, .. } => id,
                 _ => panic!("expected a Counter"),
             }
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 1931ee5e528..a375a1d69cd 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -74,7 +74,6 @@ pub(crate) fn parse_token_trees<'a>(
             // because the delimiter mismatch is more likely to be the root cause of error
 
             let mut buffer = Vec::with_capacity(1);
-            // Not using `emit_unclosed_delims` to use `db.buffer`
             for unmatched in unmatched_delims {
                 if let Some(err) = make_unclosed_delims_error(unmatched, &sess) {
                     err.buffer(&mut buffer);
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 4e639a54cf7..6c8ef34063f 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1717,13 +1717,7 @@ impl<'a> Parser<'a> {
             self.recover_await_prefix(await_sp)?
         };
         let sp = self.error_on_incorrect_await(lo, hi, &expr, is_question);
-        let kind = match expr.kind {
-            // Avoid knock-down errors as we don't know whether to interpret this as `foo().await?`
-            // or `foo()?.await` (the very reason we went with postfix syntax 😅).
-            ExprKind::Try(_) => ExprKind::Err,
-            _ => ExprKind::Await(expr, await_sp),
-        };
-        let expr = self.mk_expr(lo.to(sp), kind);
+        let expr = self.mk_expr(lo.to(sp), ExprKind::Err);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index c5b46b809b1..ce4d4a60551 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -29,7 +29,6 @@ use rustc_ast::{Async, AttrArgs, AttrArgsEq, Expr, ExprKind, Mutability, StrLit}
 use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Ordering;
 use rustc_errors::PResult;
 use rustc_errors::{
     Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, IntoDiagnostic, MultiSpan,
@@ -1455,18 +1454,6 @@ pub(crate) fn make_unclosed_delims_error(
     Some(err)
 }
 
-pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedDelim>, sess: &ParseSess) {
-    let _ = sess.reached_eof.fetch_or(
-        unclosed_delims.iter().any(|unmatched_delim| unmatched_delim.found_delim.is_none()),
-        Ordering::Relaxed,
-    );
-    for unmatched in unclosed_delims.drain(..) {
-        if let Some(mut e) = make_unclosed_delims_error(unmatched, sess) {
-            e.emit();
-        }
-    }
-}
-
 /// A helper struct used when building an `AttrTokenStream` from
 /// a `LazyAttrTokenStream`. Both delimiter and non-delimited tokens
 /// are stored as `FlatToken::Token`. A vector of `FlatToken`s
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 4f9b362e237..197b335bdec 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, IntoDiagnosticArg, MultiSpan};
 use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{
     self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
@@ -2465,10 +2465,10 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>)
     }
 }
 
-fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let check_attr_visitor = &mut CheckAttrVisitor { tcx, abort: Cell::new(false) };
     tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor);
-    if module_def_id.is_top_level_module() {
+    if module_def_id.to_local_def_id().is_top_level_module() {
         check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None);
         check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
     }
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index e70817d7b7c..8437e9a40e2 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -9,7 +9,7 @@
 
 use rustc_attr as attr;
 use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::query::Providers;
@@ -45,7 +45,7 @@ impl NonConstExpr {
 
             Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for],
 
-            Self::Match(TryDesugar) => &[sym::const_try],
+            Self::Match(TryDesugar(_)) => &[sym::const_try],
 
             // All other expressions are allowed.
             Self::Loop(Loop | While) | Self::Match(Normal | FormatArgs) => &[],
@@ -55,7 +55,7 @@ impl NonConstExpr {
     }
 }
 
-fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let mut vis = CheckConstVisitor::new(tcx);
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis);
 }
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 07b437f463f..d1c3bcf3839 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -4,10 +4,11 @@
 
 use hir::def_id::{LocalDefIdMap, LocalDefIdSet};
 use itertools::Itertools;
+use rustc_data_structures::unord::UnordSet;
 use rustc_errors::MultiSpan;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Node, PatKind, TyKind};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
@@ -42,8 +43,16 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     )
 }
 
+/// Determine if a work from the worklist is coming from the a `#[allow]`
+/// or a `#[expect]` of `dead_code`
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+enum ComesFromAllowExpect {
+    Yes,
+    No,
+}
+
 struct MarkSymbolVisitor<'tcx> {
-    worklist: Vec<LocalDefId>,
+    worklist: Vec<(LocalDefId, ComesFromAllowExpect)>,
     tcx: TyCtxt<'tcx>,
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
     live_symbols: LocalDefIdSet,
@@ -72,7 +81,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     fn check_def_id(&mut self, def_id: DefId) {
         if let Some(def_id) = def_id.as_local() {
             if should_explore(self.tcx, def_id) || self.struct_constructors.contains_key(&def_id) {
-                self.worklist.push(def_id);
+                self.worklist.push((def_id, ComesFromAllowExpect::No));
             }
             self.live_symbols.insert(def_id);
         }
@@ -269,12 +278,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     }
 
     fn mark_live_symbols(&mut self) {
-        let mut scanned = LocalDefIdSet::default();
-        while let Some(id) = self.worklist.pop() {
-            if !scanned.insert(id) {
+        let mut scanned = UnordSet::default();
+        while let Some(work) = self.worklist.pop() {
+            if !scanned.insert(work) {
                 continue;
             }
 
+            let (id, comes_from_allow_expect) = work;
+
             // Avoid accessing the HIR for the synthesized associated type generated for RPITITs.
             if self.tcx.is_impl_trait_in_trait(id.to_def_id()) {
                 self.live_symbols.insert(id);
@@ -286,7 +297,30 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
             let id = self.struct_constructors.get(&id).copied().unwrap_or(id);
 
             if let Some(node) = self.tcx.hir().find_by_def_id(id) {
-                self.live_symbols.insert(id);
+                // When using `#[allow]` or `#[expect]` of `dead_code`, we do a QOL improvement
+                // by declaring fn calls, statics, ... within said items as live, as well as
+                // the item itself, although technically this is not the case.
+                //
+                // This means that the lint for said items will never be fired.
+                //
+                // This doesn't make any difference for the item declared with `#[allow]`, as
+                // the lint firing will be a nop, as it will be silenced by the `#[allow]` of
+                // the item.
+                //
+                // However, for `#[expect]`, the presence or absence of the lint is relevant,
+                // so we don't add it to the list of live symbols when it comes from a
+                // `#[expect]`. This means that we will correctly report an item as live or not
+                // for the `#[expect]` case.
+                //
+                // Note that an item can and will be duplicated on the worklist with different
+                // `ComesFromAllowExpect`, particulary if it was added from the
+                // `effective_visibilities` query or from the `#[allow]`/`#[expect]` checks,
+                // this "duplication" is essential as otherwise a function with `#[expect]`
+                // called from a `pub fn` may be falsely reported as not live, falsely
+                // triggering the `unfulfilled_lint_expectations` lint.
+                if comes_from_allow_expect != ComesFromAllowExpect::Yes {
+                    self.live_symbols.insert(id);
+                }
                 self.visit_node(node);
             }
         }
@@ -513,16 +547,20 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
     }
 }
 
-fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
+fn has_allow_dead_code_or_lang_attr(
+    tcx: TyCtxt<'_>,
+    def_id: LocalDefId,
+) -> Option<ComesFromAllowExpect> {
     fn has_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         tcx.has_attr(def_id, sym::lang)
             // Stable attribute for #[lang = "panic_impl"]
             || tcx.has_attr(def_id, sym::panic_handler)
     }
 
-    fn has_allow_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
+    fn has_allow_expect_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
-        tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0 == lint::Allow
+        let lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).0;
+        matches!(lint_level, lint::Allow | lint::Expect(_))
     }
 
     fn has_used_like_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
@@ -537,9 +575,13 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool
         }
     }
 
-    has_allow_dead_code(tcx, def_id)
-        || has_used_like_attr(tcx, def_id)
-        || has_lang_attr(tcx, def_id)
+    if has_allow_expect_dead_code(tcx, def_id) {
+        Some(ComesFromAllowExpect::Yes)
+    } else if has_used_like_attr(tcx, def_id) || has_lang_attr(tcx, def_id) {
+        Some(ComesFromAllowExpect::No)
+    } else {
+        None
+    }
 }
 
 // These check_* functions seeds items that
@@ -557,21 +599,23 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool
 //     * Implementations of traits and trait methods
 fn check_item<'tcx>(
     tcx: TyCtxt<'tcx>,
-    worklist: &mut Vec<LocalDefId>,
+    worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
     struct_constructors: &mut LocalDefIdMap<LocalDefId>,
     id: hir::ItemId,
 ) {
     let allow_dead_code = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id);
-    if allow_dead_code {
-        worklist.push(id.owner_id.def_id);
+    if let Some(comes_from_allow) = allow_dead_code {
+        worklist.push((id.owner_id.def_id, comes_from_allow));
     }
 
     match tcx.def_kind(id.owner_id) {
         DefKind::Enum => {
             let item = tcx.hir().item(id);
             if let hir::ItemKind::Enum(ref enum_def, _) = item.kind {
-                if allow_dead_code {
-                    worklist.extend(enum_def.variants.iter().map(|variant| variant.def_id));
+                if let Some(comes_from_allow) = allow_dead_code {
+                    worklist.extend(
+                        enum_def.variants.iter().map(|variant| (variant.def_id, comes_from_allow)),
+                    );
                 }
 
                 for variant in enum_def.variants {
@@ -583,7 +627,7 @@ fn check_item<'tcx>(
         }
         DefKind::Impl { of_trait } => {
             if of_trait {
-                worklist.push(id.owner_id.def_id);
+                worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
             }
 
             // get DefIds from another query
@@ -594,8 +638,10 @@ fn check_item<'tcx>(
 
             // And we access the Map here to get HirId from LocalDefId
             for id in local_def_ids {
-                if of_trait || has_allow_dead_code_or_lang_attr(tcx, id) {
-                    worklist.push(id);
+                if of_trait {
+                    worklist.push((id, ComesFromAllowExpect::No));
+                } else if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id) {
+                    worklist.push((id, comes_from_allow));
                 }
             }
         }
@@ -609,43 +655,59 @@ fn check_item<'tcx>(
         }
         DefKind::GlobalAsm => {
             // global_asm! is always live.
-            worklist.push(id.owner_id.def_id);
+            worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
         }
         _ => {}
     }
 }
 
-fn check_trait_item(tcx: TyCtxt<'_>, worklist: &mut Vec<LocalDefId>, id: hir::TraitItemId) {
+fn check_trait_item(
+    tcx: TyCtxt<'_>,
+    worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
+    id: hir::TraitItemId,
+) {
     use hir::TraitItemKind::{Const, Fn};
     if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) {
         let trait_item = tcx.hir().trait_item(id);
         if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_)))
-            && has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id)
+            && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id)
         {
-            worklist.push(trait_item.owner_id.def_id);
+            worklist.push((trait_item.owner_id.def_id, comes_from_allow));
         }
     }
 }
 
-fn check_foreign_item(tcx: TyCtxt<'_>, worklist: &mut Vec<LocalDefId>, id: hir::ForeignItemId) {
+fn check_foreign_item(
+    tcx: TyCtxt<'_>,
+    worklist: &mut Vec<(LocalDefId, ComesFromAllowExpect)>,
+    id: hir::ForeignItemId,
+) {
     if matches!(tcx.def_kind(id.owner_id), DefKind::Static(_) | DefKind::Fn)
-        && has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id)
+        && let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id.owner_id.def_id)
     {
-        worklist.push(id.owner_id.def_id);
+        worklist.push((id.owner_id.def_id, comes_from_allow));
     }
 }
 
-fn create_and_seed_worklist(tcx: TyCtxt<'_>) -> (Vec<LocalDefId>, LocalDefIdMap<LocalDefId>) {
+fn create_and_seed_worklist(
+    tcx: TyCtxt<'_>,
+) -> (Vec<(LocalDefId, ComesFromAllowExpect)>, LocalDefIdMap<LocalDefId>) {
     let effective_visibilities = &tcx.effective_visibilities(());
     // see `MarkSymbolVisitor::struct_constructors`
     let mut struct_constructors = Default::default();
     let mut worklist = effective_visibilities
         .iter()
         .filter_map(|(&id, effective_vis)| {
-            effective_vis.is_public_at_level(Level::Reachable).then_some(id)
+            effective_vis
+                .is_public_at_level(Level::Reachable)
+                .then_some(id)
+                .map(|id| (id, ComesFromAllowExpect::No))
         })
         // Seed entry point
-        .chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local()))
+        .chain(
+            tcx.entry_fn(())
+                .and_then(|(def_id, _)| def_id.as_local().map(|id| (id, ComesFromAllowExpect::No))),
+        )
         .collect::<Vec<_>>();
 
     let crate_items = tcx.hir_crate_items(());
@@ -878,13 +940,11 @@ impl<'tcx> DeadVisitor<'tcx> {
             return true;
         };
 
-        self.live_symbols.contains(&def_id)
-            || has_allow_dead_code_or_lang_attr(self.tcx, def_id)
-            || name.as_str().starts_with('_')
+        self.live_symbols.contains(&def_id) || name.as_str().starts_with('_')
     }
 }
 
-fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
+fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
     let (live_symbols, ignored_derived_traits) = tcx.live_symbols_and_ignored_derived_traits(());
     let mut visitor = DeadVisitor { tcx, live_symbols, ignored_derived_traits };
 
@@ -909,7 +969,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
 
         if !live_symbols.contains(&item.owner_id.def_id) {
             let parent = tcx.local_parent(item.owner_id.def_id);
-            if parent != module && !live_symbols.contains(&parent) {
+            if parent != module.to_local_def_id() && !live_symbols.contains(&parent) {
                 // We already have diagnosed something.
                 continue;
             }
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 6a29159e917..4f71704b885 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -187,12 +187,6 @@ fn sigpipe(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
 
 fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
     let sp = tcx.def_span(CRATE_DEF_ID);
-    if tcx.sess.parse_sess.reached_eof.load(rustc_data_structures::sync::Ordering::Relaxed) {
-        // There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about
-        // the missing `fn main()` then as it might have been hidden inside an unclosed block.
-        tcx.sess.delay_span_bug(sp, "`main` not found, but expected unclosed brace error");
-        return;
-    }
 
     // There is no main function.
     let mut has_filename = true;
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 7c64df6a50e..0aaf85086e4 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -1,7 +1,7 @@
 use Context::*;
 
 use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Destination, Movability, Node};
 use rustc_middle::hir::map::Map;
@@ -34,7 +34,7 @@ struct CheckLoopVisitor<'a, 'hir> {
     cx: Context,
 }
 
-fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut CheckLoopVisitor { sess: &tcx.sess, hir_map: tcx.hir(), cx: Normal },
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 769b389009b..7f36c59ad98 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -3,7 +3,7 @@
 use rustc_ast::InlineAsmOptions;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind};
 use rustc_middle::query::Providers;
@@ -23,7 +23,7 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_naked_functions, ..*providers };
 }
 
-fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let items = tcx.hir_module_items(module_def_id);
     for def_id in items.definitions() {
         if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) {
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 3950ac9dd31..9c265e8ec11 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -9,7 +9,7 @@ use rustc_attr::{
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
+use rustc_hir::def_id::{LocalDefId, LocalModDefId, CRATE_DEF_ID};
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
@@ -115,7 +115,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         let attrs = self.tcx.hir().attrs(self.tcx.hir().local_def_id_to_hir_id(def_id));
         debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
 
-        let depr = attr::find_deprecation(&self.tcx.sess, attrs);
+        let depr = attr::find_deprecation(self.tcx.sess, self.tcx.features(), attrs);
         let mut is_deprecated = false;
         if let Some((depr, span)) = &depr {
             is_deprecated = true;
@@ -682,7 +682,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
 
 /// Cross-references the feature names of unstable APIs with enabled
 /// features and possibly prints errors.
-fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx });
 }
 
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 30a4235d371..0eb344ba690 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -20,7 +20,7 @@ use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
+use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind};
 use rustc_middle::bug;
@@ -382,8 +382,9 @@ impl VisibilityLike for EffectiveVisibility {
     ) -> Self {
         let effective_vis =
             find.effective_visibilities.effective_vis(def_id).copied().unwrap_or_else(|| {
-                let private_vis =
-                    ty::Visibility::Restricted(find.tcx.parent_module_from_def_id(def_id));
+                let private_vis = ty::Visibility::Restricted(
+                    find.tcx.parent_module_from_def_id(def_id).to_local_def_id(),
+                );
                 EffectiveVisibility::from_vis(private_vis)
             });
 
@@ -412,7 +413,7 @@ struct EmbargoVisitor<'tcx> {
     /// pub macro m() {
     ///     n::p::f()
     /// }
-    macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>,
+    macro_reachable: FxHashSet<(LocalModDefId, LocalModDefId)>,
     /// Preliminary pass for marking all underlying types of `impl Trait`s as reachable.
     impl_trait_pass: bool,
     /// Has something changed in the level map?
@@ -449,7 +450,9 @@ impl<'tcx> EmbargoVisitor<'tcx> {
         max_vis: Option<ty::Visibility>,
         level: Level,
     ) {
-        let private_vis = ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id));
+        // FIXME(typed_def_id): Make `Visibility::Restricted` use a `LocalModDefId` by default.
+        let private_vis =
+            ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id).into());
         if max_vis != Some(private_vis) {
             self.changed |= self.effective_visibilities.update(
                 def_id,
@@ -508,6 +511,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252).
             return;
         }
+        // FIXME(typed_def_id): Introduce checked constructors that check def_kind.
+        let macro_module_def_id = LocalModDefId::new_unchecked(macro_module_def_id);
 
         if self.effective_visibilities.public_at_level(local_def_id).is_none() {
             return;
@@ -519,10 +524,10 @@ impl<'tcx> EmbargoVisitor<'tcx> {
         loop {
             let changed_reachability =
                 self.update_macro_reachable(module_def_id, macro_module_def_id, macro_ev);
-            if changed_reachability || module_def_id == CRATE_DEF_ID {
+            if changed_reachability || module_def_id == LocalModDefId::CRATE_DEF_ID {
                 break;
             }
-            module_def_id = self.tcx.local_parent(module_def_id);
+            module_def_id = LocalModDefId::new_unchecked(self.tcx.local_parent(module_def_id));
         }
     }
 
@@ -530,8 +535,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
     /// module. Returns `true` if the level has changed.
     fn update_macro_reachable(
         &mut self,
-        module_def_id: LocalDefId,
-        defining_mod: LocalDefId,
+        module_def_id: LocalModDefId,
+        defining_mod: LocalModDefId,
         macro_ev: EffectiveVisibility,
     ) -> bool {
         if self.macro_reachable.insert((module_def_id, defining_mod)) {
@@ -544,8 +549,8 @@ impl<'tcx> EmbargoVisitor<'tcx> {
 
     fn update_macro_reachable_mod(
         &mut self,
-        module_def_id: LocalDefId,
-        defining_mod: LocalDefId,
+        module_def_id: LocalModDefId,
+        defining_mod: LocalModDefId,
         macro_ev: EffectiveVisibility,
     ) {
         let module = self.tcx.hir().get_module(module_def_id).0;
@@ -560,7 +565,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
                 macro_ev,
             );
         }
-        for child in self.tcx.module_children_local(module_def_id) {
+        for child in self.tcx.module_children_local(module_def_id.to_local_def_id()) {
             // FIXME: Use module children for the logic above too.
             if !child.reexport_chain.is_empty()
                 && child.vis.is_accessible_from(defining_mod, self.tcx)
@@ -577,7 +582,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
         def_id: LocalDefId,
         def_kind: DefKind,
         vis: ty::Visibility,
-        module: LocalDefId,
+        module: LocalModDefId,
         macro_ev: EffectiveVisibility,
     ) {
         self.update(def_id, macro_ev, Level::Reachable);
@@ -608,7 +613,11 @@ impl<'tcx> EmbargoVisitor<'tcx> {
             // the module, however may be reachable.
             DefKind::Mod => {
                 if vis.is_accessible_from(module, self.tcx) {
-                    self.update_macro_reachable(def_id, module, macro_ev);
+                    self.update_macro_reachable(
+                        LocalModDefId::new_unchecked(def_id),
+                        module,
+                        macro_ev,
+                    );
                 }
             }
 
@@ -892,7 +901,7 @@ fn vis_to_string<'tcx>(def_id: LocalDefId, vis: ty::Visibility, tcx: TyCtxt<'tcx
         ty::Visibility::Restricted(restricted_id) => {
             if restricted_id.is_top_level_module() {
                 "pub(crate)".to_string()
-            } else if restricted_id == tcx.parent_module_from_def_id(def_id) {
+            } else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
                 "pub(self)".to_string()
             } else {
                 format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
@@ -1800,7 +1809,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
             let vis_descr = match vis {
                 ty::Visibility::Public => "public",
                 ty::Visibility::Restricted(vis_def_id) => {
-                    if vis_def_id == self.tcx.parent_module(hir_id) {
+                    if vis_def_id == self.tcx.parent_module(hir_id).to_local_def_id() {
                         "private"
                     } else if vis_def_id.is_top_level_module() {
                         "crate-private"
@@ -2196,7 +2205,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
                     kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
                         | hir::ItemKind::OpaqueTy(..),
                     ..
-                }) => ty::Visibility::Restricted(tcx.parent_module(hir_id)),
+                }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_local_def_id()),
                 // Visibilities of trait impl items are inherited from their traits
                 // and are not filled in resolve.
                 Node::ImplItem(impl_item) => {
@@ -2224,18 +2233,25 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
     }
 }
 
-fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
+fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     // Check privacy of names not checked in previous compilation stages.
-    let mut visitor =
-        NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id };
+    let mut visitor = NamePrivacyVisitor {
+        tcx,
+        maybe_typeck_results: None,
+        current_item: module_def_id.to_local_def_id(),
+    };
     let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
 
     intravisit::walk_mod(&mut visitor, module, hir_id);
 
     // Check privacy of explicitly written types and traits as well as
     // inferred types of expressions and patterns.
-    let mut visitor =
-        TypePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id, span };
+    let mut visitor = TypePrivacyVisitor {
+        tcx,
+        maybe_typeck_results: None,
+        current_item: module_def_id.to_local_def_id(),
+        span,
+    };
     intravisit::walk_mod(&mut visitor, module, hir_id);
 }
 
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 3803f7eca0a..30422ea1102 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::profiling::{EventId, QueryInvocationId, SelfProfilerRef};
 use rustc_data_structures::sharded::{self, Sharded};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -93,7 +93,7 @@ pub struct DepGraphData<K: DepKind> {
     /// things available to us. If we find that they are not dirty, we
     /// load the path to the file storing those work-products here into
     /// this map. We can later look for and extract that data.
-    previous_work_products: FxIndexMap<WorkProductId, WorkProduct>,
+    previous_work_products: WorkProductMap,
 
     dep_node_debug: Lock<FxHashMap<DepNode<K>, String>>,
 
@@ -116,7 +116,7 @@ impl<K: DepKind> DepGraph<K> {
     pub fn new(
         profiler: &SelfProfilerRef,
         prev_graph: SerializedDepGraph<K>,
-        prev_work_products: FxIndexMap<WorkProductId, WorkProduct>,
+        prev_work_products: WorkProductMap,
         encoder: FileEncoder,
         record_graph: bool,
         record_stats: bool,
@@ -688,7 +688,7 @@ impl<K: DepKind> DepGraph<K> {
 
     /// Access the map of work-products created during the cached run. Only
     /// used during saving of the dep-graph.
-    pub fn previous_work_products(&self) -> &FxIndexMap<WorkProductId, WorkProduct> {
+    pub fn previous_work_products(&self) -> &WorkProductMap {
         &self.data.as_ref().unwrap().previous_work_products
     }
 
@@ -1051,6 +1051,8 @@ pub struct WorkProduct {
     pub saved_files: UnordMap<String, String>,
 }
 
+pub type WorkProductMap = UnordMap<WorkProductId, WorkProduct>;
+
 // Index type for `DepNodeData`'s edges.
 rustc_index::newtype_index! {
     struct EdgeIndex {}
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 40e7131987f..0fd9e35d6dc 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -7,7 +7,7 @@ mod serialized;
 pub use dep_node::{DepKindStruct, DepNode, DepNodeParams, WorkProductId};
 pub use graph::{
     hash_result, DepGraph, DepGraphData, DepNodeColor, DepNodeIndex, TaskDeps, TaskDepsRef,
-    WorkProduct,
+    WorkProduct, WorkProductMap,
 };
 pub use query::DepGraphQuery;
 pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index a655667d01d..127bec22c17 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -171,7 +171,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             return macro_data.clone();
         }
 
-        let load_macro_untracked = self.cstore().load_macro_untracked(def_id, &self.tcx.sess);
+        let load_macro_untracked = self.cstore().load_macro_untracked(def_id, self.tcx);
         let (ext, macro_rules) = match load_macro_untracked {
             LoadedMacro::MacroDef(item, edition) => (
                 Lrc::new(self.compile_macro(&item, edition).0),
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index e403386e60c..76e54e60d14 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1282,7 +1282,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let registered_tools = tcx.registered_tools(());
 
-        let features = tcx.sess.features_untracked();
+        let features = tcx.features();
 
         let mut resolver = Resolver {
             tcx,
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 614a29e7578..6a5b675b4bb 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -920,7 +920,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         item: &ast::Item,
         edition: Edition,
     ) -> (SyntaxExtension, Vec<(usize, Span)>) {
-        let (mut result, mut rule_spans) = compile_declarative_macro(self.tcx.sess, item, edition);
+        let (mut result, mut rule_spans) =
+            compile_declarative_macro(self.tcx.sess, self.tcx.features(), item, edition);
 
         if let Some(builtin_name) = result.builtin_name {
             // The macro was marked with `#[rustc_builtin_macro]`.
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index bca49981668..1cf63e9b7ba 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -8,7 +8,7 @@ use crate::lint::{
 };
 use rustc_ast::node_id::NodeId;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc};
+use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
 use rustc_errors::{emitter::SilentEmitter, Handler};
 use rustc_errors::{
     fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
@@ -204,8 +204,6 @@ pub struct ParseSess {
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
     pub gated_spans: GatedSpans,
     pub symbol_gallery: SymbolGallery,
-    /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
-    pub reached_eof: AtomicBool,
     /// Environment variables accessed during the build and their values when they exist.
     pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
     /// File paths accessed during the build.
@@ -242,7 +240,6 @@ impl ParseSess {
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             gated_spans: GatedSpans::default(),
             symbol_gallery: SymbolGallery::default(),
-            reached_eof: AtomicBool::new(false),
             env_depinfo: Default::default(),
             file_depinfo: Default::default(),
             assume_incomplete_release: false,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 5d7572f65a5..086ce4e6964 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -17,7 +17,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::jobserver::{self, Client};
 use rustc_data_structures::profiling::{duration_to_secs_str, SelfProfiler, SelfProfilerRef};
 use rustc_data_structures::sync::{
-    self, AtomicU64, AtomicUsize, Lock, Lrc, OnceCell, OneThread, Ordering, Ordering::SeqCst,
+    self, AtomicU64, AtomicUsize, Lock, Lrc, OneThread, Ordering, Ordering::SeqCst,
 };
 use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitterWriter;
 use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
@@ -152,8 +152,6 @@ pub struct Session {
     /// Input, input file path and output file path to this compilation process.
     pub io: CompilerIO,
 
-    features: OnceCell<rustc_feature::Features>,
-
     incr_comp_session: OneThread<RefCell<IncrCompSession>>,
     /// Used for incremental compilation tests. Will only be populated if
     /// `-Zquery-dep-graph` is specified.
@@ -705,21 +703,6 @@ impl Session {
         self.opts.cg.instrument_coverage() == InstrumentCoverage::ExceptUnusedFunctions
     }
 
-    /// Gets the features enabled for the current compilation session.
-    /// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
-    /// dependency tracking. Use tcx.features() instead.
-    #[inline]
-    pub fn features_untracked(&self) -> &rustc_feature::Features {
-        self.features.get().unwrap()
-    }
-
-    pub fn init_features(&self, features: rustc_feature::Features) {
-        match self.features.set(features) {
-            Ok(()) => {}
-            Err(_) => panic!("`features` was initialized twice"),
-        }
-    }
-
     pub fn is_sanitizer_cfi_enabled(&self) -> bool {
         self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
     }
@@ -1464,7 +1447,6 @@ pub fn build_session(
         parse_sess,
         sysroot,
         io,
-        features: OnceCell::new(),
         incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
         cgu_reuse_tracker,
         prof,
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 6ebba56c76d..8cb533c8d67 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -11,7 +11,6 @@
     test(attr(allow(unused_variables), deny(warnings)))
 )]
 #![cfg_attr(not(feature = "default"), feature(rustc_private))]
-#![feature(local_key_cell_methods)]
 #![feature(ptr_metadata)]
 #![feature(type_alias_impl_trait)] // Used to define opaque types.
 #![feature(intra_doc_pointers)]
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 6ab473c3b54..06b37008ebe 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -10,7 +10,7 @@
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
 use crate::stable_mir::ty::{
-    allocation_filter, new_allocation, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
+    allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
 };
 use crate::stable_mir::{self, Context};
 use rustc_hir as hir;
@@ -187,7 +187,11 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
         use mir::Rvalue::*;
         match self {
             Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
-            Repeat(op, len) => stable_mir::mir::Rvalue::Repeat(op.stable(tables), opaque(len)),
+            Repeat(op, len) => {
+                let cnst = ConstantKind::from_const(*len, tables.tcx);
+                let len = Const { literal: cnst.stable(tables) };
+                stable_mir::mir::Rvalue::Repeat(op.stable(tables), len)
+            }
             Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
                 opaque(region),
                 kind.stable(tables),
@@ -372,7 +376,11 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
         use stable_mir::ty::TermKind;
         match self {
             ty::TermKind::Ty(ty) => TermKind::Type(tables.intern_ty(*ty)),
-            ty::TermKind::Const(const_) => TermKind::Const(opaque(const_)),
+            ty::TermKind::Const(cnst) => {
+                let cnst = ConstantKind::from_const(*cnst, tables.tcx);
+                let cnst = Const { literal: cnst.stable(tables) };
+                TermKind::Const(cnst)
+            }
         }
     }
 }
@@ -829,7 +837,10 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
         match self {
             ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(opaque(region)),
             ty::GenericArgKind::Type(ty) => GenericArgKind::Type(tables.intern_ty(*ty)),
-            ty::GenericArgKind::Const(const_) => GenericArgKind::Const(opaque(&const_)),
+            ty::GenericArgKind::Const(cnst) => {
+                let cnst = ConstantKind::from_const(*cnst, tables.tcx);
+                GenericArgKind::Const(stable_mir::ty::Const { literal: cnst.stable(tables) })
+            }
         }
     }
 }
@@ -1035,7 +1046,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             }
             ty::Str => TyKind::RigidTy(RigidTy::Str),
             ty::Array(ty, constant) => {
-                TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), opaque(constant)))
+                let cnst = ConstantKind::from_const(*constant, tables.tcx);
+                let cnst = stable_mir::ty::Const { literal: cnst.stable(tables) };
+                TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), cnst))
             }
             ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(tables.intern_ty(*ty))),
             ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => {
@@ -1165,7 +1178,9 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> {
                     let const_val = tables.tcx.valtree_to_const_val((c.ty(), val));
                     stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables))
                 }
-                _ => todo!(),
+                ty::ParamCt(param) => stable_mir::ty::ConstantKind::ParamCt(opaque(&param)),
+                ty::ErrorCt(_) => unreachable!(),
+                _ => unimplemented!(),
             },
             ConstantKind::Unevaluated(unev_const, ty) => {
                 stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 8a23af75749..f8ff6741208 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -15,7 +15,11 @@ impl Ty {
     }
 }
 
-pub(crate) type Const = Opaque;
+#[derive(Debug, Clone)]
+pub struct Const {
+    pub literal: ConstantKind,
+}
+
 type Ident = Opaque;
 pub(crate) type Region = Opaque;
 type Span = Opaque;
@@ -417,6 +421,7 @@ pub fn allocation_filter<'tcx>(
 pub enum ConstantKind {
     Allocated(Allocation),
     Unevaluated(UnevaluatedConst),
+    ParamCt(Opaque),
 }
 
 #[derive(Clone, Debug)]
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index f65a6aa4fb2..595babc26ae 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -28,10 +28,16 @@ impl CrateNum {
         CrateNum::from_usize(x)
     }
 
+    // FIXME(typed_def_id): Replace this with `as_mod_def_id`.
     #[inline]
     pub fn as_def_id(self) -> DefId {
         DefId { krate: self, index: CRATE_DEF_INDEX }
     }
+
+    #[inline]
+    pub fn as_mod_def_id(self) -> ModDefId {
+        ModDefId::new_unchecked(DefId { krate: self, index: CRATE_DEF_INDEX })
+    }
 }
 
 impl fmt::Display for CrateNum {
@@ -485,3 +491,92 @@ impl<CTX: HashStableContext> ToStableHashKey<CTX> for CrateNum {
         self.as_def_id().to_stable_hash_key(hcx)
     }
 }
+
+macro_rules! typed_def_id {
+    ($Name:ident, $LocalName:ident) => {
+        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
+        pub struct $Name(DefId);
+
+        impl $Name {
+            pub const fn new_unchecked(def_id: DefId) -> Self {
+                Self(def_id)
+            }
+
+            pub fn to_def_id(self) -> DefId {
+                self.into()
+            }
+
+            pub fn is_local(self) -> bool {
+                self.0.is_local()
+            }
+
+            pub fn as_local(self) -> Option<$LocalName> {
+                self.0.as_local().map($LocalName::new_unchecked)
+            }
+        }
+
+        impl From<$LocalName> for $Name {
+            fn from(local: $LocalName) -> Self {
+                Self(local.0.to_def_id())
+            }
+        }
+
+        impl From<$Name> for DefId {
+            fn from(typed: $Name) -> Self {
+                typed.0
+            }
+        }
+
+        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
+        pub struct $LocalName(LocalDefId);
+
+        impl !Ord for $LocalName {}
+        impl !PartialOrd for $LocalName {}
+
+        impl $LocalName {
+            pub const fn new_unchecked(def_id: LocalDefId) -> Self {
+                Self(def_id)
+            }
+
+            pub fn to_def_id(self) -> DefId {
+                self.0.into()
+            }
+
+            pub fn to_local_def_id(self) -> LocalDefId {
+                self.0
+            }
+        }
+
+        impl From<$LocalName> for LocalDefId {
+            fn from(typed: $LocalName) -> Self {
+                typed.0
+            }
+        }
+
+        impl From<$LocalName> for DefId {
+            fn from(typed: $LocalName) -> Self {
+                typed.0.into()
+            }
+        }
+    };
+}
+
+// N.B.: when adding new typed `DefId`s update the corresponding trait impls in
+// `rustc_middle::dep_graph::def_node` for `DepNodeParams`.
+typed_def_id! { ModDefId, LocalModDefId }
+
+impl LocalModDefId {
+    pub const CRATE_DEF_ID: Self = Self::new_unchecked(CRATE_DEF_ID);
+}
+
+impl ModDefId {
+    pub fn is_top_level_module(self) -> bool {
+        self.0.is_top_level_module()
+    }
+}
+
+impl LocalModDefId {
+    pub fn is_top_level_module(self) -> bool {
+        self.0.is_top_level_module()
+    }
+}
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 745a3590720..a0daebf5baa 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -574,6 +574,7 @@ symbols! {
         crate_type,
         crate_visibility_modifier,
         crt_dash_static: "crt-static",
+        csky_target_feature,
         cstring_type,
         ctlz,
         ctlz_nonzero,
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
index a71e2e8cc57..393e59e8b00 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -16,6 +16,6 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
 
 [dependencies.object]
-version = "0.31.1"
+version = "0.32.0"
 default-features = false
 features = ["elf"]
diff --git a/compiler/rustc_target/src/abi/call/csky.rs b/compiler/rustc_target/src/abi/call/csky.rs
new file mode 100644
index 00000000000..bbe95fa20ac
--- /dev/null
+++ b/compiler/rustc_target/src/abi/call/csky.rs
@@ -0,0 +1,31 @@
+// See https://github.com/llvm/llvm-project/blob/d85b94bf0080dcd780656c0f5e6342800720eba9/llvm/lib/Target/CSKY/CSKYCallingConv.td
+use crate::abi::call::{ArgAbi, FnAbi};
+
+fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
+    if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
+        ret.make_indirect();
+    } else {
+        ret.extend_integer_width_to(32);
+    }
+}
+
+fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
+    if arg.layout.is_aggregate() || arg.layout.size.bits() > 64 {
+        arg.make_indirect();
+    } else {
+        arg.extend_integer_width_to(32);
+    }
+}
+
+pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+    if !fn_abi.ret.is_ignore() {
+        classify_ret(&mut fn_abi.ret);
+    }
+
+    for arg in fn_abi.args.iter_mut() {
+        if arg.is_ignore() {
+            continue;
+        }
+        classify_arg(arg);
+    }
+}
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index e4989bdfbcd..8fab13d5d5d 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -9,6 +9,7 @@ mod amdgpu;
 mod arm;
 mod avr;
 mod bpf;
+mod csky;
 mod hexagon;
 mod loongarch;
 mod m68k;
@@ -712,6 +713,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "avr" => avr::compute_abi_info(self),
             "loongarch64" => loongarch::compute_abi_info(cx, self),
             "m68k" => m68k::compute_abi_info(self),
+            "csky" => csky::compute_abi_info(self),
             "mips" | "mips32r6" => mips::compute_abi_info(cx, self),
             "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self),
             "powerpc" => powerpc::compute_abi_info(self),
diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs
new file mode 100644
index 00000000000..6f0e7f79949
--- /dev/null
+++ b/compiler/rustc_target/src/asm/csky.rs
@@ -0,0 +1,128 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+use rustc_span::Symbol;
+use std::fmt;
+
+def_reg_class! {
+    CSKY CSKYInlineAsmRegClass {
+        reg,
+        freg,
+    }
+}
+
+impl CSKYInlineAsmRegClass {
+    pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
+        &[]
+    }
+
+    pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
+        None
+    }
+
+    pub fn suggest_modifier(
+        self,
+        _arch: InlineAsmArch,
+        _ty: InlineAsmType,
+    ) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn supported_types(
+        self,
+        _arch: InlineAsmArch,
+    ) -> &'static [(InlineAsmType, Option<Symbol>)] {
+        match self {
+            Self::reg => types! { _: I8, I16, I32; },
+            Self::freg => types! { _: F32; },
+        }
+    }
+}
+
+// The reserved registers are taken from <https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp#79>
+def_regs! {
+    CSKY CSKYInlineAsmReg CSKYInlineAsmRegClass {
+        r0: reg = ["r0","a0"],
+        r1: reg = ["r1","a1"],
+        r2: reg = ["r2","a2"],
+        r3: reg = ["r3","a3"],
+        r4: reg = ["r4","l0"],
+        r5: reg = ["r5","l1"],
+        r6: reg = ["r6","l2"],
+        r9: reg = ["r9","l5"],// feature e2
+        r10: reg = ["r10","l6"],// feature e2
+        r11: reg = ["r11","l7"],// feature e2
+        r12: reg = ["r12","t0"],// feature e2
+        r13: reg = ["r13","t1"],// feature e2
+        r16: reg = ["r16","l8"],// feature high-register
+        r17: reg = ["r17","l9"],// feature high-register
+        r18: reg = ["r18","t2"],// feature high-register
+        r19: reg = ["r19","t3"],// feature high-register
+        r20: reg = ["r20","t4"],// feature high-register
+        r21: reg = ["r21","t5"],// feature high-register
+        r22: reg = ["r22","t6"],// feature high-register
+        r23: reg = ["r23","t7", "fp"],// feature high-register
+        r24: reg = ["r24","t8", "sop"],// feature high-register
+        r25: reg = ["r25","t9","tp", "bsp"],// feature high-register
+        f0: freg = ["fr0","vr0"],
+        f1: freg = ["fr1","vr1"],
+        f2: freg = ["fr2","vr2"],
+        f3: freg = ["fr3","vr3"],
+        f4: freg = ["fr4","vr4"],
+        f5: freg = ["fr5","vr5"],
+        f6: freg = ["fr6","vr6"],
+        f7: freg = ["fr7","vr7"],
+        f8: freg = ["fr8","vr8"],
+        f9: freg = ["fr9","vr9"],
+        f10: freg = ["fr10","vr10"],
+        f11: freg = ["fr11","vr11"],
+        f12: freg = ["fr12","vr12"],
+        f13: freg = ["fr13","vr13"],
+        f14: freg = ["fr14","vr14"],
+        f15: freg = ["fr15","vr15"],
+        f16: freg = ["fr16","vr16"],
+        f17: freg = ["fr17","vr17"],
+        f18: freg = ["fr18","vr18"],
+        f19: freg = ["fr19","vr19"],
+        f20: freg = ["fr20","vr20"],
+        f21: freg = ["fr21","vr21"],
+        f22: freg = ["fr22","vr22"],
+        f23: freg = ["fr23","vr23"],
+        f24: freg = ["fr24","vr24"],
+        f25: freg = ["fr25","vr25"],
+        f26: freg = ["fr26","vr26"],
+        f27: freg = ["fr27","vr27"],
+        f28: freg = ["fr28","vr28"],
+        f29: freg = ["fr29","vr29"],
+        f30: freg = ["fr30","vr30"],
+        f31: freg = ["fr31","vr31"],
+        #error = ["r7", "l3"] =>
+            "the base pointer cannot be used as an operand for inline asm",
+        #error = ["r8","l4"] =>
+            "the frame pointer cannot be used as an operand for inline asm",
+        #error = ["r14","sp"] =>
+            "the stack pointer cannot be used as an operand for inline asm",
+        #error = ["r15","lr"] =>
+            "the link register cannot be used as an operand for inline asm",
+        #error = ["r31","tls"] =>
+            "reserver for tls",
+        #error = ["r28", "gb", "rgb", "rdb"] =>
+            "the global pointer cannot be used as an operand for inline asm",
+        #error = ["r26","r27","r29","tb", "rtb", "r30","svbr"] =>
+            "reserved by the ABI",
+    }
+}
+
+impl CSKYInlineAsmReg {
+    pub fn emit(
+        self,
+        out: &mut dyn fmt::Write,
+        _arch: InlineAsmArch,
+        _modifier: Option<char>,
+    ) -> fmt::Result {
+        out.write_str(self.name())
+    }
+}
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 7c27732079b..a11884bea26 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -167,6 +167,7 @@ mod aarch64;
 mod arm;
 mod avr;
 mod bpf;
+mod csky;
 mod hexagon;
 mod loongarch;
 mod m68k;
@@ -184,6 +185,7 @@ pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
 pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
 pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass};
 pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass};
+pub use csky::{CSKYInlineAsmReg, CSKYInlineAsmRegClass};
 pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
 pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass};
 pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass};
@@ -220,6 +222,7 @@ pub enum InlineAsmArch {
     Avr,
     Msp430,
     M68k,
+    CSKY,
 }
 
 impl FromStr for InlineAsmArch {
@@ -248,6 +251,7 @@ impl FromStr for InlineAsmArch {
             "avr" => Ok(Self::Avr),
             "msp430" => Ok(Self::Msp430),
             "m68k" => Ok(Self::M68k),
+            "csky" => Ok(Self::CSKY),
             _ => Err(()),
         }
     }
@@ -272,6 +276,7 @@ pub enum InlineAsmReg {
     Avr(AvrInlineAsmReg),
     Msp430(Msp430InlineAsmReg),
     M68k(M68kInlineAsmReg),
+    CSKY(CSKYInlineAsmReg),
     // Placeholder for invalid register constraints for the current target
     Err,
 }
@@ -292,6 +297,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.name(),
             Self::Msp430(r) => r.name(),
             Self::M68k(r) => r.name(),
+            Self::CSKY(r) => r.name(),
             Self::Err => "<reg>",
         }
     }
@@ -311,6 +317,7 @@ impl InlineAsmReg {
             Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()),
             Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()),
             Self::M68k(r) => InlineAsmRegClass::M68k(r.reg_class()),
+            Self::CSKY(r) => InlineAsmRegClass::CSKY(r.reg_class()),
             Self::Err => InlineAsmRegClass::Err,
         }
     }
@@ -344,6 +351,7 @@ impl InlineAsmReg {
             InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?),
             InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?),
             InlineAsmArch::M68k => Self::M68k(M68kInlineAsmReg::parse(name)?),
+            InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmReg::parse(name)?),
         })
     }
 
@@ -371,6 +379,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::M68k(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+            Self::CSKY(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::Err => unreachable!(),
         }
     }
@@ -397,6 +406,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.emit(out, arch, modifier),
             Self::Msp430(r) => r.emit(out, arch, modifier),
             Self::M68k(r) => r.emit(out, arch, modifier),
+            Self::CSKY(r) => r.emit(out, arch, modifier),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
@@ -416,6 +426,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
             Self::Msp430(_) => cb(self),
             Self::M68k(_) => cb(self),
+            Self::CSKY(_) => cb(self),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
@@ -440,6 +451,7 @@ pub enum InlineAsmRegClass {
     Avr(AvrInlineAsmRegClass),
     Msp430(Msp430InlineAsmRegClass),
     M68k(M68kInlineAsmRegClass),
+    CSKY(CSKYInlineAsmRegClass),
     // Placeholder for invalid register constraints for the current target
     Err,
 }
@@ -463,6 +475,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.name(),
             Self::Msp430(r) => r.name(),
             Self::M68k(r) => r.name(),
+            Self::CSKY(r) => r.name(),
             Self::Err => rustc_span::symbol::sym::reg,
         }
     }
@@ -488,6 +501,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr),
             Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430),
             Self::M68k(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::M68k),
+            Self::CSKY(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::CSKY),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -520,6 +534,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.suggest_modifier(arch, ty),
             Self::Msp430(r) => r.suggest_modifier(arch, ty),
             Self::M68k(r) => r.suggest_modifier(arch, ty),
+            Self::CSKY(r) => r.suggest_modifier(arch, ty),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -548,6 +563,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.default_modifier(arch),
             Self::Msp430(r) => r.default_modifier(arch),
             Self::M68k(r) => r.default_modifier(arch),
+            Self::CSKY(r) => r.default_modifier(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -575,6 +591,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.supported_types(arch),
             Self::Msp430(r) => r.supported_types(arch),
             Self::M68k(r) => r.supported_types(arch),
+            Self::CSKY(r) => r.supported_types(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -607,6 +624,7 @@ impl InlineAsmRegClass {
             InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
             InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
             InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?),
+            InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmRegClass::parse(name)?),
         })
     }
 
@@ -630,6 +648,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.valid_modifiers(arch),
             Self::Msp430(r) => r.valid_modifiers(arch),
             Self::M68k(r) => r.valid_modifiers(arch),
+            Self::CSKY(r) => r.valid_modifiers(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -826,6 +845,11 @@ pub fn allocatable_registers(
             m68k::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
         }
+        InlineAsmArch::CSKY => {
+            let mut map = csky::regclass_map();
+            csky::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
+            map
+        }
     }
 }
 
diff --git a/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs
new file mode 100644
index 00000000000..7d03dd26f5d
--- /dev/null
+++ b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs
@@ -0,0 +1,20 @@
+use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
+
+// This target is for glibc Linux on Csky
+
+pub fn target() -> Target {
+    Target {
+        //https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/clang/lib/Basic/Targets/CSKY.h
+        llvm_target: "csky-unknown-linux-gnuabiv2".into(),
+        pointer_width: 32,
+        data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(),
+        arch: "csky".into(),
+        options: TargetOptions {
+            abi: "abiv2".into(),
+            features: "+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(),
+            late_link_args_static: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a"]),
+            max_atomic_width: Some(32),
+            ..super::linux_gnu_base::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
index 209d481d6f8..dbc96d68eae 100644
--- a/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none.rs
@@ -10,7 +10,8 @@ pub fn target() -> Target {
         options: TargetOptions {
             cpu: "generic".into(),
             features: "+f,+d".into(),
-            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
index f444a7f24bb..c4d5c7bc44c 100644
--- a/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/loongarch64_unknown_none_softfloat.rs
@@ -11,7 +11,8 @@ pub fn target() -> Target {
             cpu: "generic".into(),
             features: "-f,-d".into(),
             abi: "softfloat".into(),
-            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
             llvm_abiname: "lp64s".into(),
             max_atomic_width: Some(64),
             relocation_model: RelocModel::Static,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 1871239d7de..af2b96ccb51 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -338,7 +338,7 @@ impl LinkerFlavor {
             || stem == "clang++"
             || stem.ends_with("-clang++")
         {
-            (Some(Cc::Yes), None)
+            (Some(Cc::Yes), Some(Lld::No))
         } else if stem == "wasm-ld"
             || stem.ends_with("-wasm-ld")
             || stem == "ld.lld"
@@ -1246,6 +1246,7 @@ supported_targets! {
     ("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
     ("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu),
     ("m68k-unknown-linux-gnu", m68k_unknown_linux_gnu),
+    ("csky-unknown-linux-gnuabiv2", csky_unknown_linux_gnuabiv2),
     ("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
     ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
     ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 1391b51e67f..36194f973b5 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -281,23 +281,27 @@ pub(super) trait GoalKind<'tcx>:
     ) -> QueryResult<'tcx>;
 
     /// Consider (possibly several) candidates to upcast or unsize a type to another
-    /// type.
-    ///
-    /// The most common forms of unsizing are array to slice, and concrete (Sized)
-    /// type into a `dyn Trait`. ADTs and Tuples can also have their final field
-    /// unsized if it's generic.
-    ///
-    /// `dyn Trait1` can be unsized to `dyn Trait2` if they are the same trait, or
-    /// if `Trait2` is a (transitive) supertrait of `Trait2`.
+    /// type, excluding the coercion of a sized type into a `dyn Trait`.
     ///
     /// We return the `BuiltinImplSource` for each candidate as it is needed
     /// for unsize coercion in hir typeck and because it is difficult to
     /// otherwise recompute this for codegen. This is a bit of a mess but the
     /// easiest way to maintain the existing behavior for now.
-    fn consider_builtin_unsize_candidates(
+    fn consider_structural_builtin_unsize_candidates(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)>;
+
+    /// Consider the `Unsize` candidate corresponding to coercing a sized type
+    /// into a `dyn Trait`.
+    ///
+    /// This is computed separately from the rest of the `Unsize` candidates
+    /// since it is only done once per self type, and not once per
+    /// *normalization step* (in `assemble_candidates_via_self_ty`).
+    fn consider_unsize_to_dyn_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx>;
 }
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -312,10 +316,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         let mut candidates = self.assemble_candidates_via_self_ty(goal, 0);
 
+        self.assemble_unsize_to_dyn_candidate(goal, &mut candidates);
+
         self.assemble_blanket_impl_candidates(goal, &mut candidates);
 
         self.assemble_param_env_candidates(goal, &mut candidates);
 
+        self.assemble_coherence_unknowable_candidates(goal, &mut candidates);
+
         candidates
     }
 
@@ -363,10 +371,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         self.assemble_object_bound_candidates(goal, &mut candidates);
 
-        self.assemble_coherence_unknowable_candidates(goal, &mut candidates);
-
         self.assemble_candidates_after_normalizing_self_ty(goal, &mut candidates, num_steps);
-
         candidates
     }
 
@@ -531,6 +536,23 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
+    fn assemble_unsize_to_dyn_candidate<G: GoalKind<'tcx>>(
+        &mut self,
+        goal: Goal<'tcx, G>,
+        candidates: &mut Vec<Candidate<'tcx>>,
+    ) {
+        let tcx = self.tcx();
+        if tcx.lang_items().unsize_trait() == Some(goal.predicate.trait_def_id(tcx)) {
+            match G::consider_unsize_to_dyn_candidate(self, goal) {
+                Ok(result) => candidates.push(Candidate {
+                    source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
+                    result,
+                }),
+                Err(NoSolution) => (),
+            }
+        }
+    }
+
     fn assemble_blanket_impl_candidates<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -611,7 +633,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         // There may be multiple unsize candidates for a trait with several supertraits:
         // `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
         if lang_items.unsize_trait() == Some(trait_def_id) {
-            for (result, source) in G::consider_builtin_unsize_candidates(self, goal) {
+            for (result, source) in G::consider_structural_builtin_unsize_candidates(self, goal) {
                 candidates.push(Candidate { source: CandidateSource::BuiltinImpl(source), result });
             }
         }
@@ -827,6 +849,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             ty::Dynamic(bounds, ..) => bounds,
         };
 
+        // Do not consider built-in object impls for non-object-safe types.
+        if bounds.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) {
+            return;
+        }
+
         // Consider all of the auto-trait and projection bounds, which don't
         // need to be recorded as a `BuiltinImplSource::Object` since they don't
         // really have a vtable base...
@@ -877,26 +904,43 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, G>,
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
+        let tcx = self.tcx();
         match self.solver_mode() {
             SolverMode::Normal => return,
-            SolverMode::Coherence => {
-                let trait_ref = goal.predicate.trait_ref(self.tcx());
-                match coherence::trait_ref_is_knowable(self.tcx(), trait_ref) {
-                    Ok(()) => {}
-                    Err(_) => match self
-                        .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
-                    {
-                        Ok(result) => candidates.push(Candidate {
-                            source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
-                            result,
-                        }),
-                        // FIXME: This will be reachable at some point if we're in
-                        // `assemble_candidates_after_normalizing_self_ty` and we get a
-                        // universe error. We'll deal with it at this point.
-                        Err(NoSolution) => bug!("coherence candidate resulted in NoSolution"),
-                    },
+            SolverMode::Coherence => {}
+        };
+
+        let result = self.probe_candidate("coherence unknowable").enter(|ecx| {
+            let trait_ref = goal.predicate.trait_ref(tcx);
+
+            #[derive(Debug)]
+            enum FailureKind {
+                Overflow,
+                NoSolution(NoSolution),
+            }
+            let lazily_normalize_ty = |ty| match ecx.try_normalize_ty(goal.param_env, ty) {
+                Ok(Some(ty)) => Ok(ty),
+                Ok(None) => Err(FailureKind::Overflow),
+                Err(e) => Err(FailureKind::NoSolution(e)),
+            };
+
+            match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty) {
+                Err(FailureKind::Overflow) => {
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW)
+                }
+                Err(FailureKind::NoSolution(NoSolution)) | Ok(Ok(())) => Err(NoSolution),
+                Ok(Err(_)) => {
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
                 }
             }
+        });
+
+        match result {
+            Ok(result) => candidates.push(Candidate {
+                source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
+                result,
+            }),
+            Err(NoSolution) => {}
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index b882ec254e3..c47767101a4 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -161,14 +161,12 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
     ty: Ty<'tcx>,
 ) -> Result<Vec<Ty<'tcx>>, NoSolution> {
     match *ty.kind() {
-        ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
-        | ty::FnDef(..)
-        | ty::FnPtr(_)
-        | ty::Error(_) => Ok(vec![]),
+        ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Ok(vec![]),
 
         // Implementations are provided in core
         ty::Uint(_)
         | ty::Int(_)
+        | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
         | ty::Bool
         | ty::Float(_)
         | ty::Char
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 60c49f665a6..5c2cbe39953 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -388,44 +388,60 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             && is_normalizes_to_hack == IsNormalizesToHack::No
             && !self.search_graph.in_cycle()
         {
-            debug!("rerunning goal to check result is stable");
-            self.search_graph.reset_encountered_overflow(encountered_overflow);
-            let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
-            let Ok(new_canonical_response) = EvalCtxt::evaluate_canonical_goal(
-                self.tcx(),
-                self.search_graph,
-                canonical_goal,
-                // FIXME(-Ztrait-solver=next): we do not track what happens in `evaluate_canonical_goal`
-                &mut ProofTreeBuilder::new_noop(),
-            ) else {
-                bug!(
-                    "goal went from {certainty:?} to error: re-canonicalized goal={canonical_goal:#?} \
-                    first_response={canonical_response:#?},
-                    second response was error"
-                );
-            };
-            // We only check for modulo regions as we convert all regions in
-            // the input to new existentials, even if they're expected to be
-            // `'static` or a placeholder region.
-            if !new_canonical_response.value.var_values.is_identity_modulo_regions() {
-                bug!(
-                    "unstable result: re-canonicalized goal={canonical_goal:#?} \
-                    first_response={canonical_response:#?} \
-                    second_response={new_canonical_response:#?}"
-                );
-            }
-            if certainty != new_canonical_response.value.certainty {
-                bug!(
-                    "unstable certainty: {certainty:#?} re-canonicalized goal={canonical_goal:#?} \
-                     first_response={canonical_response:#?} \
-                     second_response={new_canonical_response:#?}"
-                );
-            }
+            // The nested evaluation has to happen with the original state
+            // of `encountered_overflow`.
+            let from_original_evaluation =
+                self.search_graph.reset_encountered_overflow(encountered_overflow);
+            self.check_evaluate_goal_stable_result(goal, canonical_goal, canonical_response);
+            // In case the evaluation was unstable, we manually make sure that this
+            // debug check does not influence the result of the parent goal.
+            self.search_graph.reset_encountered_overflow(from_original_evaluation);
         }
 
         Ok((has_changed, certainty, nested_goals))
     }
 
+    fn check_evaluate_goal_stable_result(
+        &mut self,
+        goal: Goal<'tcx, ty::Predicate<'tcx>>,
+        original_input: CanonicalInput<'tcx>,
+        original_result: CanonicalResponse<'tcx>,
+    ) {
+        let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
+        let result = EvalCtxt::evaluate_canonical_goal(
+            self.tcx(),
+            self.search_graph,
+            canonical_goal,
+            // FIXME(-Ztrait-solver=next): we do not track what happens in `evaluate_canonical_goal`
+            &mut ProofTreeBuilder::new_noop(),
+        );
+
+        macro_rules! fail {
+            ($msg:expr) => {{
+                let msg = $msg;
+                warn!(
+                    "unstable result: {msg}\n\
+                    original goal: {original_input:?},\n\
+                    original result: {original_result:?}\n\
+                    re-canonicalized goal: {canonical_goal:?}\n\
+                    second response: {result:?}"
+                );
+                return;
+            }};
+        }
+
+        let Ok(new_canonical_response) = result else { fail!("second response was error") };
+        // We only check for modulo regions as we convert all regions in
+        // the input to new existentials, even if they're expected to be
+        // `'static` or a placeholder region.
+        if !new_canonical_response.value.var_values.is_identity_modulo_regions() {
+            fail!("additional constraints from second response")
+        }
+        if original_result.value.certainty != new_canonical_response.value.certainty {
+            fail!("unstable certainty")
+        }
+    }
+
     fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult<'tcx> {
         let Goal { param_env, predicate } = goal;
         let kind = predicate.kind();
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index ca4a4c9510c..42d7a587cac 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -123,7 +123,7 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
             // It's fine not to do anything to rematch these, since there are no
             // nested obligations.
             (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => {
-                Ok(Some(ImplSource::Param(ty::BoundConstness::NotConst, nested_obligations)))
+                Ok(Some(ImplSource::Param(nested_obligations)))
             }
 
             (Certainty::Maybe(_), _) => Ok(None),
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 63d4a38119f..75a99f799a2 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -283,6 +283,37 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         Ok(self.make_ambiguous_response_no_constraints(maybe_cause))
     }
+
+    /// Normalize a type when it is structually matched on.
+    ///
+    /// For self types this is generally already handled through
+    /// `assemble_candidates_after_normalizing_self_ty`, so anything happening
+    /// in [`EvalCtxt::assemble_candidates_via_self_ty`] does not have to normalize
+    /// the self type. It is required when structurally matching on any other
+    /// arguments of a trait goal, e.g. when assembling builtin unsize candidates.
+    fn try_normalize_ty(
+        &mut self,
+        param_env: ty::ParamEnv<'tcx>,
+        mut ty: Ty<'tcx>,
+    ) -> Result<Option<Ty<'tcx>>, NoSolution> {
+        for _ in 0..self.local_overflow_limit() {
+            let ty::Alias(_, projection_ty) = *ty.kind() else {
+                return Ok(Some(ty));
+            };
+
+            let normalized_ty = self.next_ty_infer();
+            let normalizes_to_goal = Goal::new(
+                self.tcx(),
+                param_env,
+                ty::ProjectionPredicate { projection_ty, term: normalized_ty.into() },
+            );
+            self.add_goal(normalizes_to_goal);
+            self.try_evaluate_added_goals()?;
+            ty = self.resolve_vars_if_possible(normalized_ty);
+        }
+
+        Ok(None)
+    }
 }
 
 fn response_no_constraints_raw<'tcx>(
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index e1980f4d7bb..e47e228774e 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -1,4 +1,4 @@
-use crate::traits::specialization_graph;
+use crate::traits::{check_args_compatible, specialization_graph};
 
 use super::assembly::{self, structural_traits};
 use super::EvalCtxt;
@@ -190,11 +190,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
             };
 
-            if !assoc_def.item.defaultness(tcx).has_value() {
-                let guar = tcx.sess.delay_span_bug(
-                    tcx.def_span(assoc_def.item.def_id),
-                    "missing value for assoc item in impl",
-                );
+            let error_response = |ecx: &mut EvalCtxt<'_, 'tcx>, reason| {
+                let guar = tcx.sess.delay_span_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,
@@ -208,7 +205,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 };
                 ecx.eq(goal.param_env, goal.predicate.term, error_term)
                     .expect("expected goal term to be fully unconstrained");
-                return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+                ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            };
+
+            if !assoc_def.item.defaultness(tcx).has_value() {
+                return error_response(ecx, "missing value for assoc item in impl");
             }
 
             // Getting the right args here is complex, e.g. given:
@@ -233,6 +234,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 assoc_def.defining_node,
             );
 
+            if !check_args_compatible(tcx, assoc_def.item, args) {
+                return error_response(
+                    ecx,
+                    "associated item has mismatched generic item arguments",
+                );
+            }
+
             // Finally we construct the actual value of the associated type.
             let term = match assoc_def.item.kind {
                 ty::AssocKind::Type => tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into()),
@@ -497,7 +505,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
         )
     }
 
-    fn consider_builtin_unsize_candidates(
+    fn consider_unsize_to_dyn_candidate(
+        _ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx> {
+        bug!("`Unsize` does not have an associated type: {:?}", goal)
+    }
+
+    fn consider_structural_builtin_unsize_candidates(
         _ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> {
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs
index b860f374c0a..49ebfa4e6cb 100644
--- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs
@@ -134,9 +134,13 @@ impl<'tcx> SearchGraph<'tcx> {
     /// Resets `encountered_overflow` of the current goal.
     ///
     /// This should only be used for the check in `evaluate_goal`.
-    pub(super) fn reset_encountered_overflow(&mut self, encountered_overflow: bool) {
-        if encountered_overflow {
-            self.stack.raw.last_mut().unwrap().encountered_overflow = true;
+    pub(super) fn reset_encountered_overflow(&mut self, encountered_overflow: bool) -> bool {
+        if let Some(last) = self.stack.raw.last_mut() {
+            let prev = last.encountered_overflow;
+            last.encountered_overflow = encountered_overflow;
+            prev
+        } else {
+            false
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index db80b62d8a2..8685f3100a8 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -423,7 +423,55 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         ecx.evaluate_added_goals_and_make_canonical_response(certainty)
     }
 
-    fn consider_builtin_unsize_candidates(
+    fn consider_unsize_to_dyn_candidate(
+        ecx: &mut EvalCtxt<'_, 'tcx>,
+        goal: Goal<'tcx, Self>,
+    ) -> QueryResult<'tcx> {
+        ecx.probe(|_| CandidateKind::UnsizeAssembly).enter(|ecx| {
+            let a_ty = goal.predicate.self_ty();
+            // We need to normalize the b_ty since it's destructured as a `dyn Trait`.
+            let Some(b_ty) =
+                ecx.try_normalize_ty(goal.param_env, goal.predicate.trait_ref.args.type_at(1))?
+            else {
+                return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW);
+            };
+
+            let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
+                return Err(NoSolution);
+            };
+
+            let tcx = ecx.tcx();
+
+            // Can only unsize to an object-safe trait.
+            if b_data.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) {
+                return Err(NoSolution);
+            }
+
+            // Check that the type implements all of the predicates of the trait object.
+            // (i.e. the principal, all of the associated types match, and any auto traits)
+            ecx.add_goals(b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))));
+
+            // The type must be `Sized` to be unsized.
+            if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
+                ecx.add_goal(goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])));
+            } else {
+                return Err(NoSolution);
+            }
+
+            // The type must outlive the lifetime of the `dyn` we're unsizing into.
+            ecx.add_goal(goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
+            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        })
+    }
+
+    /// ```ignore (builtin impl example)
+    /// trait Trait {
+    ///     fn foo(&self);
+    /// }
+    /// // results in the following builtin impl
+    /// impl<'a, T: Trait + 'a> Unsize<dyn Trait + 'a> for T {}
+    /// ```
+    fn consider_structural_builtin_unsize_candidates(
         ecx: &mut EvalCtxt<'_, 'tcx>,
         goal: Goal<'tcx, Self>,
     ) -> Vec<(CanonicalResponse<'tcx>, BuiltinImplSource)> {
@@ -448,7 +496,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             // We need to normalize the b_ty since it's matched structurally
             // in the other functions below.
             let b_ty = match ecx
-                .normalize_non_self_ty(goal.predicate.trait_ref.args.type_at(1), goal.param_env)
+                .try_normalize_ty(goal.param_env, goal.predicate.trait_ref.args.type_at(1))
             {
                 Ok(Some(b_ty)) => b_ty,
                 Ok(None) => return vec![misc_candidate(ecx, Certainty::OVERFLOW)],
@@ -468,11 +516,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
                     goal, a_data, a_region, b_data, b_region,
                 ),
 
-                // `T` -> `dyn Trait` unsizing
-                (_, &ty::Dynamic(b_data, b_region, ty::Dyn)) => result_to_single(
-                    ecx.consider_builtin_unsize_to_dyn(goal, b_data, b_region),
-                    BuiltinImplSource::Misc,
-                ),
+                // `T` -> `dyn Trait` unsizing is handled separately in `consider_unsize_to_dyn_candidate`
+                (_, &ty::Dynamic(..)) => vec![],
 
                 // `[T; N]` -> `[T]` unsizing
                 (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => result_to_single(
@@ -552,16 +597,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             self.walk_vtable(
                 a_principal.with_self_ty(tcx, a_ty),
                 |ecx, new_a_principal, _, vtable_vptr_slot| {
-                    if let Ok(resp) = ecx.consider_builtin_upcast_to_principal(
-                        goal,
-                        a_data,
-                        a_region,
-                        b_data,
-                        b_region,
-                        Some(new_a_principal.map_bound(|trait_ref| {
-                            ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
-                        })),
-                    ) {
+                    if let Ok(resp) = ecx.probe_candidate("dyn upcast").enter(|ecx| {
+                        ecx.consider_builtin_upcast_to_principal(
+                            goal,
+                            a_data,
+                            a_region,
+                            b_data,
+                            b_region,
+                            Some(new_a_principal.map_bound(|trait_ref| {
+                                ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
+                            })),
+                        )
+                    }) {
                         responses
                             .push((resp, BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }));
                     }
@@ -572,43 +619,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         responses
     }
 
-    /// ```ignore (builtin impl example)
-    /// trait Trait {
-    ///     fn foo(&self);
-    /// }
-    /// // results in the following builtin impl
-    /// impl<'a, T: Trait + 'a> Unsize<dyn Trait + 'a> for T {}
-    /// ```
-    fn consider_builtin_unsize_to_dyn(
-        &mut self,
-        goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
-        b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
-        b_region: ty::Region<'tcx>,
-    ) -> QueryResult<'tcx> {
-        let tcx = self.tcx();
-        let Goal { predicate: (a_ty, _b_ty), .. } = goal;
-
-        // Can only unsize to an object-safe trait
-        if b_data.principal_def_id().is_some_and(|def_id| !tcx.check_is_object_safe(def_id)) {
-            return Err(NoSolution);
-        }
-
-        // Check that the type implements all of the predicates of the trait object.
-        // (i.e. the principal, all of the associated types match, and any auto traits)
-        self.add_goals(b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))));
-
-        // The type must be `Sized` to be unsized.
-        if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
-            self.add_goal(goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])));
-        } else {
-            return Err(NoSolution);
-        }
-
-        // The type must outlive the lifetime of the `dyn` we're unsizing into.
-        self.add_goal(goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
-        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-    }
-
     fn consider_builtin_upcast_to_principal(
         &mut self,
         goal: Goal<'tcx, (Ty<'tcx>, Ty<'tcx>)>,
@@ -927,41 +937,4 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let candidates = self.assemble_and_evaluate_candidates(goal);
         self.merge_candidates(candidates)
     }
-
-    /// Normalize a non-self type when it is structually matched on when solving
-    /// a built-in goal.
-    ///
-    /// This is handled already through `assemble_candidates_after_normalizing_self_ty`
-    /// for the self type, but for other goals, additional normalization of other
-    /// arguments may be needed to completely implement the semantics of the trait.
-    ///
-    /// This is required when structurally matching on any trait argument that is
-    /// not the self type.
-    fn normalize_non_self_ty(
-        &mut self,
-        mut ty: Ty<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Result<Option<Ty<'tcx>>, NoSolution> {
-        if !matches!(ty.kind(), ty::Alias(..)) {
-            return Ok(Some(ty));
-        }
-
-        for _ in 0..self.local_overflow_limit() {
-            let ty::Alias(_, projection_ty) = *ty.kind() else {
-                return Ok(Some(ty));
-            };
-
-            let normalized_ty = self.next_ty_infer();
-            let normalizes_to_goal = Goal::new(
-                self.tcx(),
-                param_env,
-                ty::ProjectionPredicate { projection_ty, term: normalized_ty.into() },
-            );
-            self.add_goal(normalizes_to_goal);
-            self.try_evaluate_added_goals()?;
-            ty = self.resolve_vars_if_possible(normalized_ty);
-        }
-
-        Ok(None)
-    }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 19d5baa30ec..5746781ae35 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -7,7 +7,7 @@
 use crate::infer::outlives::env::OutlivesEnvironment;
 use crate::infer::InferOk;
 use crate::traits::outlives_bounds::InferCtxtExt as _;
-use crate::traits::select::IntercrateAmbiguityCause;
+use crate::traits::select::{IntercrateAmbiguityCause, TreatInductiveCycleAs};
 use crate::traits::util::impl_subject_and_oblig;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{
@@ -24,6 +24,7 @@ use rustc_middle::traits::DefiningAnchor;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
+use rustc_session::lint::builtin::COINDUCTIVE_OVERLAP_IN_COHERENCE;
 use rustc_span::symbol::sym;
 use rustc_span::DUMMY_SP;
 use std::fmt::Debug;
@@ -151,14 +152,16 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
             .predicates_of(impl_def_id)
             .instantiate(tcx, impl_args)
             .iter()
-            .map(|(c, _)| c.as_predicate())
+            .map(|(c, s)| (c.as_predicate(), s))
             .collect(),
     };
 
-    let InferOk { value: mut header, obligations } =
-        selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(header);
+    let InferOk { value: mut header, obligations } = selcx
+        .infcx
+        .at(&ObligationCause::dummy_with_span(tcx.def_span(impl_def_id)), param_env)
+        .normalize(header);
 
-    header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
+    header.predicates.extend(obligations.into_iter().map(|o| (o.predicate, o.cause.span)));
     header
 }
 
@@ -207,16 +210,76 @@ fn overlap<'tcx>(
     let equate_obligations = equate_impl_headers(selcx.infcx, &impl1_header, &impl2_header)?;
     debug!("overlap: unification check succeeded");
 
-    if overlap_mode.use_implicit_negative()
-        && impl_intersection_has_impossible_obligation(
-            selcx,
-            param_env,
-            &impl1_header,
-            impl2_header,
-            equate_obligations,
-        )
-    {
-        return None;
+    if overlap_mode.use_implicit_negative() {
+        for mode in [TreatInductiveCycleAs::Ambig, TreatInductiveCycleAs::Recur] {
+            if let Some(failing_obligation) = selcx.with_treat_inductive_cycle_as(mode, |selcx| {
+                impl_intersection_has_impossible_obligation(
+                    selcx,
+                    param_env,
+                    &impl1_header,
+                    &impl2_header,
+                    &equate_obligations,
+                )
+            }) {
+                if matches!(mode, TreatInductiveCycleAs::Recur) {
+                    let first_local_impl = impl1_header
+                        .impl_def_id
+                        .as_local()
+                        .or(impl2_header.impl_def_id.as_local())
+                        .expect("expected one of the impls to be local");
+                    infcx.tcx.struct_span_lint_hir(
+                        COINDUCTIVE_OVERLAP_IN_COHERENCE,
+                        infcx.tcx.local_def_id_to_hir_id(first_local_impl),
+                        infcx.tcx.def_span(first_local_impl),
+                        format!(
+                            "implementations {} will conflict in the future",
+                            match impl1_header.trait_ref {
+                                Some(trait_ref) => {
+                                    let trait_ref = infcx.resolve_vars_if_possible(trait_ref);
+                                    format!(
+                                        "of `{}` for `{}`",
+                                        trait_ref.print_only_trait_path(),
+                                        trait_ref.self_ty()
+                                    )
+                                }
+                                None => format!(
+                                    "for `{}`",
+                                    infcx.resolve_vars_if_possible(impl1_header.self_ty)
+                                ),
+                            },
+                        ),
+                        |lint| {
+                            lint.note(
+                                "impls that are not considered to overlap may be considered to \
+                                overlap in the future",
+                            )
+                            .span_label(
+                                infcx.tcx.def_span(impl1_header.impl_def_id),
+                                "the first impl is here",
+                            )
+                            .span_label(
+                                infcx.tcx.def_span(impl2_header.impl_def_id),
+                                "the second impl is here",
+                            );
+                            if !failing_obligation.cause.span.is_dummy() {
+                                lint.span_label(
+                                    failing_obligation.cause.span,
+                                    format!(
+                                        "`{}` may be considered to hold in future releases, \
+                                        causing the impls to overlap",
+                                        infcx
+                                            .resolve_vars_if_possible(failing_obligation.predicate)
+                                    ),
+                                );
+                            }
+                            lint
+                        },
+                    );
+                }
+
+                return None;
+            }
+        }
     }
 
     // We toggle the `leak_check` by using `skip_leak_check` when constructing the
@@ -284,40 +347,30 @@ fn impl_intersection_has_impossible_obligation<'cx, 'tcx>(
     selcx: &mut SelectionContext<'cx, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     impl1_header: &ty::ImplHeader<'tcx>,
-    impl2_header: ty::ImplHeader<'tcx>,
-    obligations: PredicateObligations<'tcx>,
-) -> bool {
+    impl2_header: &ty::ImplHeader<'tcx>,
+    obligations: &PredicateObligations<'tcx>,
+) -> Option<PredicateObligation<'tcx>> {
     let infcx = selcx.infcx;
 
-    let obligation_guaranteed_to_fail = move |obligation: &PredicateObligation<'tcx>| {
-        if infcx.next_trait_solver() {
-            infcx.evaluate_obligation(obligation).map_or(false, |result| !result.may_apply())
-        } else {
-            // We use `evaluate_root_obligation` to correctly track
-            // intercrate ambiguity clauses. We do not need this in the
-            // new solver.
-            selcx.evaluate_root_obligation(obligation).map_or(
-                false, // Overflow has occurred, and treat the obligation as possibly holding.
-                |result| !result.may_apply(),
-            )
-        }
-    };
-
-    let opt_failing_obligation = [&impl1_header.predicates, &impl2_header.predicates]
+    [&impl1_header.predicates, &impl2_header.predicates]
         .into_iter()
         .flatten()
-        .map(|&predicate| {
-            Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, predicate)
+        .map(|&(predicate, span)| {
+            Obligation::new(infcx.tcx, ObligationCause::dummy_with_span(span), param_env, predicate)
+        })
+        .chain(obligations.into_iter().cloned())
+        .find(|obligation: &PredicateObligation<'tcx>| {
+            if infcx.next_trait_solver() {
+                infcx.evaluate_obligation(obligation).map_or(false, |result| !result.may_apply())
+            } else {
+                // We use `evaluate_root_obligation` to correctly track intercrate
+                // ambiguity clauses. We cannot use this in the new solver.
+                selcx.evaluate_root_obligation(obligation).map_or(
+                    false, // Overflow has occurred, and treat the obligation as possibly holding.
+                    |result| !result.may_apply(),
+                )
+            }
         })
-        .chain(obligations)
-        .find(obligation_guaranteed_to_fail);
-
-    if let Some(failing_obligation) = opt_failing_obligation {
-        debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
-        true
-    } else {
-        false
-    }
 }
 
 /// Check if both impls can be satisfied by a common type by considering whether
@@ -452,22 +505,23 @@ fn prove_negated_obligation<'tcx>(
 /// This both checks whether any downstream or sibling crates could
 /// implement it and whether an upstream crate can add this impl
 /// without breaking backwards compatibility.
-#[instrument(level = "debug", skip(tcx), ret)]
-pub fn trait_ref_is_knowable<'tcx>(
+#[instrument(level = "debug", skip(tcx, lazily_normalize_ty), ret)]
+pub fn trait_ref_is_knowable<'tcx, E: Debug>(
     tcx: TyCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
-) -> Result<(), Conflict> {
+    mut lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
+) -> Result<Result<(), Conflict>, E> {
     if Some(trait_ref.def_id) == tcx.lang_items().fn_ptr_trait() {
         // The only types implementing `FnPtr` are function pointers,
         // so if there's no impl of `FnPtr` in the current crate,
         // then such an impl will never be added in the future.
-        return Ok(());
+        return Ok(Ok(()));
     }
 
-    if orphan_check_trait_ref(trait_ref, InCrate::Remote).is_ok() {
+    if orphan_check_trait_ref(trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() {
         // A downstream or cousin crate is allowed to implement some
         // substitution of this trait-ref.
-        return Err(Conflict::Downstream);
+        return Ok(Err(Conflict::Downstream));
     }
 
     if trait_ref_is_local_or_fundamental(tcx, trait_ref) {
@@ -476,7 +530,7 @@ pub fn trait_ref_is_knowable<'tcx>(
         // allowed to implement a substitution of this trait ref, which
         // means impls could only come from dependencies of this crate,
         // which we already know about.
-        return Ok(());
+        return Ok(Ok(()));
     }
 
     // This is a remote non-fundamental trait, so if another crate
@@ -487,10 +541,10 @@ pub fn trait_ref_is_knowable<'tcx>(
     // and if we are an intermediate owner, then we don't care
     // about future-compatibility, which means that we're OK if
     // we are an owner.
-    if orphan_check_trait_ref(trait_ref, InCrate::Local).is_ok() {
-        Ok(())
+    if orphan_check_trait_ref(trait_ref, InCrate::Local, &mut lazily_normalize_ty)?.is_ok() {
+        Ok(Ok(()))
     } else {
-        Err(Conflict::Upstream)
+        Ok(Err(Conflict::Upstream))
     }
 }
 
@@ -526,7 +580,7 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
         return Ok(());
     }
 
-    orphan_check_trait_ref(trait_ref, InCrate::Local)
+    orphan_check_trait_ref::<!>(trait_ref, InCrate::Local, |ty| Ok(ty)).unwrap()
 }
 
 /// Checks whether a trait-ref is potentially implementable by a crate.
@@ -615,11 +669,12 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
 ///
 /// Note that this function is never called for types that have both type
 /// parameters and inference variables.
-#[instrument(level = "trace", ret)]
-fn orphan_check_trait_ref<'tcx>(
+#[instrument(level = "trace", skip(lazily_normalize_ty), ret)]
+fn orphan_check_trait_ref<'tcx, E: Debug>(
     trait_ref: ty::TraitRef<'tcx>,
     in_crate: InCrate,
-) -> Result<(), OrphanCheckErr<'tcx>> {
+    lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
+) -> Result<Result<(), OrphanCheckErr<'tcx>>, E> {
     if trait_ref.has_infer() && trait_ref.has_param() {
         bug!(
             "can't orphan check a trait ref with both params and inference variables {:?}",
@@ -627,9 +682,10 @@ fn orphan_check_trait_ref<'tcx>(
         );
     }
 
-    let mut checker = OrphanChecker::new(in_crate);
-    match trait_ref.visit_with(&mut checker) {
+    let mut checker = OrphanChecker::new(in_crate, lazily_normalize_ty);
+    Ok(match trait_ref.visit_with(&mut checker) {
         ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)),
+        ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)) => return Err(err),
         ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(ty)) => {
             // Does there exist some local type after the `ParamTy`.
             checker.search_first_local_ty = true;
@@ -642,34 +698,39 @@ fn orphan_check_trait_ref<'tcx>(
             }
         }
         ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(_)) => Ok(()),
-    }
+    })
 }
 
-struct OrphanChecker<'tcx> {
+struct OrphanChecker<'tcx, F> {
     in_crate: InCrate,
     in_self_ty: bool,
+    lazily_normalize_ty: F,
     /// Ignore orphan check failures and exclusively search for the first
     /// local type.
     search_first_local_ty: bool,
     non_local_tys: Vec<(Ty<'tcx>, bool)>,
 }
 
-impl<'tcx> OrphanChecker<'tcx> {
-    fn new(in_crate: InCrate) -> Self {
+impl<'tcx, F, E> OrphanChecker<'tcx, F>
+where
+    F: FnOnce(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
+{
+    fn new(in_crate: InCrate, lazily_normalize_ty: F) -> Self {
         OrphanChecker {
             in_crate,
             in_self_ty: true,
+            lazily_normalize_ty,
             search_first_local_ty: false,
             non_local_tys: Vec::new(),
         }
     }
 
-    fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx>> {
+    fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx, E>> {
         self.non_local_tys.push((t, self.in_self_ty));
         ControlFlow::Continue(())
     }
 
-    fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx>> {
+    fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx, E>> {
         if self.search_first_local_ty {
             ControlFlow::Continue(())
         } else {
@@ -685,18 +746,28 @@ impl<'tcx> OrphanChecker<'tcx> {
     }
 }
 
-enum OrphanCheckEarlyExit<'tcx> {
+enum OrphanCheckEarlyExit<'tcx, E> {
+    NormalizationFailure(E),
     ParamTy(Ty<'tcx>),
     LocalTy(Ty<'tcx>),
 }
 
-impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> {
-    type BreakTy = OrphanCheckEarlyExit<'tcx>;
+impl<'tcx, F, E> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx, F>
+where
+    F: FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
+{
+    type BreakTy = OrphanCheckEarlyExit<'tcx, E>;
     fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
         ControlFlow::Continue(())
     }
 
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+        // Need to lazily normalize here in with `-Ztrait-solver=next-coherence`.
+        let ty = match (self.lazily_normalize_ty)(ty) {
+            Ok(ty) => ty,
+            Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)),
+        };
+
         let result = match *ty.kind() {
             ty::Bool
             | ty::Char
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index d071cf76fd3..5e075984238 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2700,7 +2700,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             | ObligationCauseCode::MatchImpl(..)
             | ObligationCauseCode::ReturnType
             | ObligationCauseCode::ReturnValue(_)
-            | ObligationCauseCode::BlockTailExpression(_)
+            | ObligationCauseCode::BlockTailExpression(..)
             | ObligationCauseCode::AwaitableExpr(_)
             | ObligationCauseCode::ForLoopIterator
             | ObligationCauseCode::QuestionMark
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 71a82baeec6..88d03003309 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -59,8 +59,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ParamCandidate(param) => {
                 let obligations =
                     self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
-                // FIXME(effects)
-                ImplSource::Param(ty::BoundConstness::NotConst, obligations)
+                ImplSource::Param(obligations)
             }
 
             ImplCandidate(impl_def_id) => {
@@ -72,9 +71,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
             }
 
-            ProjectionCandidate(idx, constness) => {
+            ProjectionCandidate(idx, _) => {
                 let obligations = self.confirm_projection_candidate(obligation, idx)?;
-                ImplSource::Param(constness, obligations)
+                ImplSource::Param(obligations)
             }
 
             ObjectCandidate(idx) => self.confirm_object_candidate(obligation, idx)?,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 4371b6c1239..19385e2d7f2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -118,6 +118,8 @@ pub struct SelectionContext<'cx, 'tcx> {
     /// policy. In essence, canonicalized queries need their errors propagated
     /// rather than immediately reported because we do not have accurate spans.
     query_mode: TraitQueryMode,
+
+    treat_inductive_cycle: TreatInductiveCycleAs,
 }
 
 // A stack that walks back up the stack frame.
@@ -198,6 +200,27 @@ enum BuiltinImplConditions<'tcx> {
     Ambiguous,
 }
 
+#[derive(Copy, Clone)]
+pub enum TreatInductiveCycleAs {
+    /// This is the previous behavior, where `Recur` represents an inductive
+    /// cycle that is known not to hold. This is not forwards-compatible with
+    /// coinduction, and will be deprecated. This is the default behavior
+    /// of the old trait solver due to back-compat reasons.
+    Recur,
+    /// This is the behavior of the new trait solver, where inductive cycles
+    /// are treated as ambiguous and possibly holding.
+    Ambig,
+}
+
+impl From<TreatInductiveCycleAs> for EvaluationResult {
+    fn from(treat: TreatInductiveCycleAs) -> EvaluationResult {
+        match treat {
+            TreatInductiveCycleAs::Ambig => EvaluatedToUnknown,
+            TreatInductiveCycleAs::Recur => EvaluatedToRecur,
+        }
+    }
+}
+
 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
@@ -205,9 +228,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             freshener: infcx.freshener(),
             intercrate_ambiguity_causes: None,
             query_mode: TraitQueryMode::Standard,
+            treat_inductive_cycle: TreatInductiveCycleAs::Recur,
         }
     }
 
+    // Sets the `TreatInductiveCycleAs` mode temporarily in the selection context
+    pub fn with_treat_inductive_cycle_as<T>(
+        &mut self,
+        treat_inductive_cycle: TreatInductiveCycleAs,
+        f: impl FnOnce(&mut Self) -> T,
+    ) -> T {
+        // Should be executed in a context where caching is disabled,
+        // otherwise the cache is poisoned with the temporary result.
+        assert!(self.is_intercrate());
+        let treat_inductive_cycle =
+            std::mem::replace(&mut self.treat_inductive_cycle, treat_inductive_cycle);
+        let value = f(self);
+        self.treat_inductive_cycle = treat_inductive_cycle;
+        value
+    }
+
     pub fn with_query_mode(
         infcx: &'cx InferCtxt<'tcx>,
         query_mode: TraitQueryMode,
@@ -719,7 +759,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 stack.update_reached_depth(stack_arg.1);
                                 return Ok(EvaluatedToOk);
                             } else {
-                                return Ok(EvaluatedToRecur);
+                                return Ok(self.treat_inductive_cycle.into());
                             }
                         }
                         return Ok(EvaluatedToOk);
@@ -837,7 +877,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             }
                         }
                         ProjectAndUnifyResult::FailedNormalization => Ok(EvaluatedToAmbig),
-                        ProjectAndUnifyResult::Recursive => Ok(EvaluatedToRecur),
+                        ProjectAndUnifyResult::Recursive => Ok(self.treat_inductive_cycle.into()),
                         ProjectAndUnifyResult::MismatchedProjectionTypes(_) => Ok(EvaluatedToErr),
                     }
                 }
@@ -1151,7 +1191,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Some(EvaluatedToOk)
             } else {
                 debug!("evaluate_stack --> recursive, inductive");
-                Some(EvaluatedToRecur)
+                Some(self.treat_inductive_cycle.into())
             }
         } else {
             None
@@ -1457,7 +1497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // bound regions.
         let trait_ref = predicate.skip_binder().trait_ref;
 
-        coherence::trait_ref_is_knowable(self.tcx(), trait_ref)
+        coherence::trait_ref_is_knowable::<!>(self.tcx(), trait_ref, |ty| Ok(ty)).unwrap()
     }
 
     /// Returns `true` if the global caches can be used.
@@ -2118,14 +2158,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         use self::BuiltinImplConditions::{Ambiguous, None, Where};
 
         match *self_ty.kind() {
-            ty::Infer(ty::IntVar(_))
-            | ty::Infer(ty::FloatVar(_))
-            | ty::FnDef(..)
-            | ty::FnPtr(_)
-            | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
+            ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())),
 
             ty::Uint(_)
             | ty::Int(_)
+            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
             | ty::Bool
             | ty::Float(_)
             | ty::Char
diff --git a/config.example.toml b/config.example.toml
index b10922f8d04..5c4bee87553 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -94,7 +94,7 @@ changelog-seen = 2
 # the same format as above, but since these targets are experimental, they are
 # not built by default and the experimental Rust compilation targets that depend
 # on them will not work unless the user opts in to building them.
-#experimental-targets = "AVR;M68k"
+#experimental-targets = "AVR;M68k;CSKY"
 
 # Cap the number of parallel linker invocations when compiling LLVM.
 # This can be useful when building LLVM with debug info, which significantly
@@ -758,8 +758,10 @@ changelog-seen = 2
 # This option will override the same option under [build] section.
 #sanitizers = build.sanitizers (bool)
 
-# Build the profiler runtime for this target(required when compiling with options that depend
-# on this runtime, such as `-C profile-generate` or `-C instrument-coverage`).
+# When true, build the profiler runtime for this target (required when compiling
+# with options that depend on this runtime, such as `-C profile-generate` or
+# `-C instrument-coverage`). This may also be given a path to an existing build
+# of the profiling runtime library from LLVM's compiler-rt.
 # This option will override the same option under [build] section.
 #profiler = build.profiler (bool)
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 80681a7a7cf..cb8691aac13 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -138,7 +138,6 @@
 #![feature(maybe_uninit_uninit_array_transpose)]
 #![feature(pattern)]
 #![feature(pointer_byte_offsets)]
-#![feature(provide_any)]
 #![feature(ptr_internals)]
 #![feature(ptr_metadata)]
 #![feature(ptr_sub_ptr)]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 6c701225a84..e2a2fe932ab 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -3575,7 +3575,7 @@ impl<T: core::error::Error + ?Sized> core::error::Error for Arc<T> {
         core::error::Error::source(&**self)
     }
 
-    fn provide<'a>(&'a self, req: &mut core::any::Demand<'a>) {
+    fn provide<'a>(&'a self, req: &mut core::error::Request<'a>) {
         core::error::Error::provide(&**self, req);
     }
 }
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index 8a4b4ac4e8d..cb59a9d4ab2 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -2438,10 +2438,7 @@ fn ceil_char_boundary() {
     check_many("🇯🇵", 0..=0, 0);
     check_many("🇯🇵", 1..=4, 4);
     check_many("🇯🇵", 5..=8, 8);
-}
 
-#[test]
-#[should_panic]
-fn ceil_char_boundary_above_len_panic() {
-    let _ = "x".ceil_char_boundary(2);
+    // above len
+    check_many("hello", 5..=10, 5);
 }
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 277c2f76a08..8f5404d9713 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -83,72 +83,6 @@
 //! }
 //! ```
 //!
-//! # `Provider` and `Demand`
-//!
-//! `Provider` and the associated APIs support generic, type-driven access to data, and a mechanism
-//! for implementers to provide such data. The key parts of the interface are the `Provider`
-//! trait for objects which can provide data, and the [`request_value`] and [`request_ref`]
-//! functions for requesting data from an object which implements `Provider`. Generally, end users
-//! should not call `request_*` directly, they are helper functions for intermediate implementers
-//! to use to implement a user-facing interface. This is purely for the sake of ergonomics, there is
-//! no safety concern here; intermediate implementers can typically support methods rather than
-//! free functions and use more specific names.
-//!
-//! Typically, a data provider is a trait object of a trait which extends `Provider`. A user will
-//! request data from a trait object by specifying the type of the data.
-//!
-//! ## Data flow
-//!
-//! * A user requests an object of a specific type, which is delegated to `request_value` or
-//!   `request_ref`
-//! * `request_*` creates a `Demand` object and passes it to `Provider::provide`
-//! * The data provider's implementation of `Provider::provide` tries providing values of
-//!   different types using `Demand::provide_*`. If the type matches the type requested by
-//!   the user, the value will be stored in the `Demand` object.
-//! * `request_*` unpacks the `Demand` object and returns any stored value to the user.
-//!
-//! ## Examples
-//!
-//! ```
-//! # #![feature(provide_any)]
-//! use std::any::{Provider, Demand, request_ref};
-//!
-//! // Definition of MyTrait, a data provider.
-//! trait MyTrait: Provider {
-//!     // ...
-//! }
-//!
-//! // Methods on `MyTrait` trait objects.
-//! impl dyn MyTrait + '_ {
-//!     /// Get a reference to a field of the implementing struct.
-//!     pub fn get_context_by_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
-//!         request_ref::<T>(self)
-//!     }
-//! }
-//!
-//! // Downstream implementation of `MyTrait` and `Provider`.
-//! # struct SomeConcreteType { some_string: String }
-//! impl MyTrait for SomeConcreteType {
-//!     // ...
-//! }
-//!
-//! impl Provider for SomeConcreteType {
-//!     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-//!         // Provide a string reference. We could provide multiple values with
-//!         // different types here.
-//!         demand.provide_ref::<String>(&self.some_string);
-//!     }
-//! }
-//!
-//! // Downstream usage of `MyTrait`.
-//! fn use_my_trait(obj: &dyn MyTrait) {
-//!     // Request a &String from obj.
-//!     let _ = obj.get_context_by_ref::<String>().unwrap();
-//! }
-//! ```
-//!
-//! In this example, if the concrete type of `obj` in `use_my_trait` is `SomeConcreteType`, then
-//! the `get_context_by_ref` call will return a reference to `obj.some_string` with type `&String`.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -798,524 +732,3 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
 pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
     type_name::<T>()
 }
-
-///////////////////////////////////////////////////////////////////////////////
-// Provider trait
-///////////////////////////////////////////////////////////////////////////////
-
-/// Trait implemented by a type which can dynamically provide values based on type.
-#[unstable(feature = "provide_any", issue = "96024")]
-pub trait Provider {
-    /// Data providers should implement this method to provide *all* values they are able to
-    /// provide by using `demand`.
-    ///
-    /// Note that the `provide_*` methods on `Demand` have short-circuit semantics: if an earlier
-    /// method has successfully provided a value, then later methods will not get an opportunity to
-    /// provide.
-    ///
-    /// # Examples
-    ///
-    /// Provides a reference to a field with type `String` as a `&str`, and a value of
-    /// type `i32`.
-    ///
-    /// ```rust
-    /// # #![feature(provide_any)]
-    /// use std::any::{Provider, Demand};
-    /// # struct SomeConcreteType { field: String, num_field: i32 }
-    ///
-    /// impl Provider for SomeConcreteType {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand.provide_ref::<str>(&self.field)
-    ///             .provide_value::<i32>(self.num_field);
-    ///     }
-    /// }
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>);
-}
-
-/// Request a value from the `Provider`.
-///
-/// # Examples
-///
-/// Get a string value from a provider.
-///
-/// ```rust
-/// # #![feature(provide_any)]
-/// use std::any::{Provider, request_value};
-///
-/// fn get_string(provider: &impl Provider) -> String {
-///     request_value::<String>(provider).unwrap()
-/// }
-/// ```
-#[unstable(feature = "provide_any", issue = "96024")]
-pub fn request_value<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<T>
-where
-    T: 'static,
-{
-    request_by_type_tag::<'a, tags::Value<T>>(provider)
-}
-
-/// Request a reference from the `Provider`.
-///
-/// # Examples
-///
-/// Get a string reference from a provider.
-///
-/// ```rust
-/// # #![feature(provide_any)]
-/// use std::any::{Provider, request_ref};
-///
-/// fn get_str(provider: &impl Provider) -> &str {
-///     request_ref::<str>(provider).unwrap()
-/// }
-/// ```
-#[unstable(feature = "provide_any", issue = "96024")]
-pub fn request_ref<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<&'a T>
-where
-    T: 'static + ?Sized,
-{
-    request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(provider)
-}
-
-/// Request a specific value by tag from the `Provider`.
-fn request_by_type_tag<'a, I>(provider: &'a (impl Provider + ?Sized)) -> Option<I::Reified>
-where
-    I: tags::Type<'a>,
-{
-    let mut tagged = TaggedOption::<'a, I>(None);
-    provider.provide(tagged.as_demand());
-    tagged.0
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Demand and its methods
-///////////////////////////////////////////////////////////////////////////////
-
-/// A helper object for providing data by type.
-///
-/// A data provider provides values by calling this type's provide methods.
-#[unstable(feature = "provide_any", issue = "96024")]
-#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
-pub struct Demand<'a>(dyn Erased<'a> + 'a);
-
-impl<'a> Demand<'a> {
-    /// Create a new `&mut Demand` from a `&mut dyn Erased` trait object.
-    fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Demand<'a> {
-        // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Demand<'a>` is safe since
-        // `Demand` is repr(transparent).
-        unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Demand<'a>) }
-    }
-
-    /// Provide a value or other type with only static lifetimes.
-    ///
-    /// # Examples
-    ///
-    /// Provides an `u8`.
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    ///
-    /// use std::any::{Provider, Demand};
-    /// # struct SomeConcreteType { field: u8 }
-    ///
-    /// impl Provider for SomeConcreteType {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand.provide_value::<u8>(self.field);
-    ///     }
-    /// }
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    pub fn provide_value<T>(&mut self, value: T) -> &mut Self
-    where
-        T: 'static,
-    {
-        self.provide::<tags::Value<T>>(value)
-    }
-
-    /// Provide a value or other type with only static lifetimes computed using a closure.
-    ///
-    /// # Examples
-    ///
-    /// Provides a `String` by cloning.
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    ///
-    /// use std::any::{Provider, Demand};
-    /// # struct SomeConcreteType { field: String }
-    ///
-    /// impl Provider for SomeConcreteType {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand.provide_value_with::<String>(|| self.field.clone());
-    ///     }
-    /// }
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
-    where
-        T: 'static,
-    {
-        self.provide_with::<tags::Value<T>>(fulfil)
-    }
-
-    /// Provide a reference. The referee type must be bounded by `'static`,
-    /// but may be unsized.
-    ///
-    /// # Examples
-    ///
-    /// Provides a reference to a field as a `&str`.
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    ///
-    /// use std::any::{Provider, Demand};
-    /// # struct SomeConcreteType { field: String }
-    ///
-    /// impl Provider for SomeConcreteType {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand.provide_ref::<str>(&self.field);
-    ///     }
-    /// }
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self {
-        self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
-    }
-
-    /// Provide a reference computed using a closure. The referee type
-    /// must be bounded by `'static`, but may be unsized.
-    ///
-    /// # Examples
-    ///
-    /// Provides a reference to a field as a `&str`.
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    ///
-    /// use std::any::{Provider, Demand};
-    /// # struct SomeConcreteType { business: String, party: String }
-    /// # fn today_is_a_weekday() -> bool { true }
-    ///
-    /// impl Provider for SomeConcreteType {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand.provide_ref_with::<str>(|| {
-    ///             if today_is_a_weekday() {
-    ///                 &self.business
-    ///             } else {
-    ///                 &self.party
-    ///             }
-    ///         });
-    ///     }
-    /// }
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    pub fn provide_ref_with<T: ?Sized + 'static>(
-        &mut self,
-        fulfil: impl FnOnce() -> &'a T,
-    ) -> &mut Self {
-        self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
-    }
-
-    /// Provide a value with the given `Type` tag.
-    fn provide<I>(&mut self, value: I::Reified) -> &mut Self
-    where
-        I: tags::Type<'a>,
-    {
-        if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
-            res.0 = Some(value);
-        }
-        self
-    }
-
-    /// Provide a value with the given `Type` tag, using a closure to prevent unnecessary work.
-    fn provide_with<I>(&mut self, fulfil: impl FnOnce() -> I::Reified) -> &mut Self
-    where
-        I: tags::Type<'a>,
-    {
-        if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
-            res.0 = Some(fulfil());
-        }
-        self
-    }
-
-    /// Check if the `Demand` would be satisfied if provided with a
-    /// value of the specified type. If the type does not match or has
-    /// already been provided, returns false.
-    ///
-    /// # Examples
-    ///
-    /// Check if an `u8` still needs to be provided and then provides
-    /// it.
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    ///
-    /// use std::any::{Provider, Demand};
-    ///
-    /// struct Parent(Option<u8>);
-    ///
-    /// impl Provider for Parent {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         if let Some(v) = self.0 {
-    ///             demand.provide_value::<u8>(v);
-    ///         }
-    ///     }
-    /// }
-    ///
-    /// struct Child {
-    ///     parent: Parent,
-    /// }
-    ///
-    /// impl Child {
-    ///     // Pretend that this takes a lot of resources to evaluate.
-    ///     fn an_expensive_computation(&self) -> Option<u8> {
-    ///         Some(99)
-    ///     }
-    /// }
-    ///
-    /// impl Provider for Child {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         // In general, we don't know if this call will provide
-    ///         // an `u8` value or not...
-    ///         self.parent.provide(demand);
-    ///
-    ///         // ...so we check to see if the `u8` is needed before
-    ///         // we run our expensive computation.
-    ///         if demand.would_be_satisfied_by_value_of::<u8>() {
-    ///             if let Some(v) = self.an_expensive_computation() {
-    ///                 demand.provide_value::<u8>(v);
-    ///             }
-    ///         }
-    ///
-    ///         // The demand will be satisfied now, regardless of if
-    ///         // the parent provided the value or we did.
-    ///         assert!(!demand.would_be_satisfied_by_value_of::<u8>());
-    ///     }
-    /// }
-    ///
-    /// let parent = Parent(Some(42));
-    /// let child = Child { parent };
-    /// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
-    ///
-    /// let parent = Parent(None);
-    /// let child = Child { parent };
-    /// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
-    where
-        T: 'static,
-    {
-        self.would_be_satisfied_by::<tags::Value<T>>()
-    }
-
-    /// Check if the `Demand` would be satisfied if provided with a
-    /// reference to a value of the specified type. If the type does
-    /// not match or has already been provided, returns false.
-    ///
-    /// # Examples
-    ///
-    /// Check if a `&str` still needs to be provided and then provides
-    /// it.
-    ///
-    /// ```rust
-    /// #![feature(provide_any)]
-    ///
-    /// use std::any::{Provider, Demand};
-    ///
-    /// struct Parent(Option<String>);
-    ///
-    /// impl Provider for Parent {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         if let Some(v) = &self.0 {
-    ///             demand.provide_ref::<str>(v);
-    ///         }
-    ///     }
-    /// }
-    ///
-    /// struct Child {
-    ///     parent: Parent,
-    ///     name: String,
-    /// }
-    ///
-    /// impl Child {
-    ///     // Pretend that this takes a lot of resources to evaluate.
-    ///     fn an_expensive_computation(&self) -> Option<&str> {
-    ///         Some(&self.name)
-    ///     }
-    /// }
-    ///
-    /// impl Provider for Child {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         // In general, we don't know if this call will provide
-    ///         // a `str` reference or not...
-    ///         self.parent.provide(demand);
-    ///
-    ///         // ...so we check to see if the `&str` is needed before
-    ///         // we run our expensive computation.
-    ///         if demand.would_be_satisfied_by_ref_of::<str>() {
-    ///             if let Some(v) = self.an_expensive_computation() {
-    ///                 demand.provide_ref::<str>(v);
-    ///             }
-    ///         }
-    ///
-    ///         // The demand will be satisfied now, regardless of if
-    ///         // the parent provided the reference or we did.
-    ///         assert!(!demand.would_be_satisfied_by_ref_of::<str>());
-    ///     }
-    /// }
-    ///
-    /// let parent = Parent(Some("parent".into()));
-    /// let child = Child { parent, name: "child".into() };
-    /// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
-    ///
-    /// let parent = Parent(None);
-    /// let child = Child { parent, name: "child".into() };
-    /// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
-    /// ```
-    #[unstable(feature = "provide_any", issue = "96024")]
-    pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
-    where
-        T: ?Sized + 'static,
-    {
-        self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
-    }
-
-    fn would_be_satisfied_by<I>(&self) -> bool
-    where
-        I: tags::Type<'a>,
-    {
-        matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
-    }
-}
-
-#[unstable(feature = "provide_any", issue = "96024")]
-impl<'a> fmt::Debug for Demand<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Demand").finish_non_exhaustive()
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Type tags
-///////////////////////////////////////////////////////////////////////////////
-
-mod tags {
-    //! Type tags are used to identify a type using a separate value. This module includes type tags
-    //! for some very common types.
-    //!
-    //! Currently type tags are not exposed to the user. But in the future, if you want to use the
-    //! Provider API with more complex types (typically those including lifetime parameters), you
-    //! will need to write your own tags.
-
-    use crate::marker::PhantomData;
-
-    /// This trait is implemented by specific tag types in order to allow
-    /// describing a type which can be requested for a given lifetime `'a`.
-    ///
-    /// A few example implementations for type-driven tags can be found in this
-    /// module, although crates may also implement their own tags for more
-    /// complex types with internal lifetimes.
-    pub trait Type<'a>: Sized + 'static {
-        /// The type of values which may be tagged by this tag for the given
-        /// lifetime.
-        type Reified: 'a;
-    }
-
-    /// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a
-    /// `?Sized` bound). E.g., `str`.
-    pub trait MaybeSizedType<'a>: Sized + 'static {
-        type Reified: 'a + ?Sized;
-    }
-
-    impl<'a, T: Type<'a>> MaybeSizedType<'a> for T {
-        type Reified = T::Reified;
-    }
-
-    /// Type-based tag for types bounded by `'static`, i.e., with no borrowed elements.
-    #[derive(Debug)]
-    pub struct Value<T: 'static>(PhantomData<T>);
-
-    impl<'a, T: 'static> Type<'a> for Value<T> {
-        type Reified = T;
-    }
-
-    /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound).
-    #[derive(Debug)]
-    pub struct MaybeSizedValue<T: ?Sized + 'static>(PhantomData<T>);
-
-    impl<'a, T: ?Sized + 'static> MaybeSizedType<'a> for MaybeSizedValue<T> {
-        type Reified = T;
-    }
-
-    /// Type-based tag for reference types (`&'a T`, where T is represented by
-    /// `<I as MaybeSizedType<'a>>::Reified`.
-    #[derive(Debug)]
-    pub struct Ref<I>(PhantomData<I>);
-
-    impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
-        type Reified = &'a I::Reified;
-    }
-}
-
-/// An `Option` with a type tag `I`.
-///
-/// Since this struct implements `Erased`, the type can be erased to make a dynamically typed
-/// option. The type can be checked dynamically using `Erased::tag_id` and since this is statically
-/// checked for the concrete type, there is some degree of type safety.
-#[repr(transparent)]
-struct TaggedOption<'a, I: tags::Type<'a>>(Option<I::Reified>);
-
-impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> {
-    fn as_demand(&mut self) -> &mut Demand<'a> {
-        Demand::new(self as &mut (dyn Erased<'a> + 'a))
-    }
-}
-
-/// Represents a type-erased but identifiable object.
-///
-/// This trait is exclusively implemented by the `TaggedOption` type.
-unsafe trait Erased<'a>: 'a {
-    /// The `TypeId` of the erased type.
-    fn tag_id(&self) -> TypeId;
-}
-
-unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {
-    fn tag_id(&self) -> TypeId {
-        TypeId::of::<I>()
-    }
-}
-
-#[unstable(feature = "provide_any", issue = "96024")]
-impl<'a> dyn Erased<'a> + 'a {
-    /// Returns some reference to the dynamic value if it is tagged with `I`,
-    /// or `None` otherwise.
-    #[inline]
-    fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
-    where
-        I: tags::Type<'a>,
-    {
-        if self.tag_id() == TypeId::of::<I>() {
-            // SAFETY: Just checked whether we're pointing to an I.
-            Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
-        } else {
-            None
-        }
-    }
-
-    /// Returns some mutable reference to the dynamic value if it is tagged with `I`,
-    /// or `None` otherwise.
-    #[inline]
-    fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
-    where
-        I: tags::Type<'a>,
-    {
-        if self.tag_id() == TypeId::of::<I>() {
-            // SAFETY: Just checked whether we're pointing to an I.
-            Some(unsafe { &mut *(self as *mut Self).cast::<TaggedOption<'a, I>>() })
-        } else {
-            None
-        }
-    }
-}
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 11cb0827578..1170221c10c 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -4,8 +4,8 @@
 #[cfg(test)]
 mod tests;
 
-use crate::any::{Demand, Provider, TypeId};
-use crate::fmt::{Debug, Display};
+use crate::any::TypeId;
+use crate::fmt::{Debug, Display, Formatter, Result};
 
 /// `Error` is a trait representing the basic expectations for error values,
 /// i.e., values of type `E` in [`Result<T, E>`].
@@ -123,16 +123,21 @@ pub trait Error: Debug + Display {
 
     /// Provides type based access to context intended for error reports.
     ///
-    /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
+    /// Used in conjunction with [`Request::provide_value`] and [`Request::provide_ref`] to extract
     /// references to member variables from `dyn Error` trait objects.
     ///
     /// # Example
     ///
     /// ```rust
-    /// #![feature(provide_any)]
     /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
     /// use core::fmt;
-    /// use core::any::Demand;
+    /// use core::error::{request_ref, Request};
+    ///
+    /// #[derive(Debug)]
+    /// enum MyLittleTeaPot {
+    ///     Empty,
+    /// }
     ///
     /// #[derive(Debug)]
     /// struct MyBacktrace {
@@ -147,21 +152,7 @@ pub trait Error: Debug + Display {
     /// }
     ///
     /// #[derive(Debug)]
-    /// struct SourceError {
-    ///     // ...
-    /// }
-    ///
-    /// impl fmt::Display for SourceError {
-    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f, "Example Source Error")
-    ///     }
-    /// }
-    ///
-    /// impl std::error::Error for SourceError {}
-    ///
-    /// #[derive(Debug)]
     /// struct Error {
-    ///     source: SourceError,
     ///     backtrace: MyBacktrace,
     /// }
     ///
@@ -172,38 +163,26 @@ pub trait Error: Debug + Display {
     /// }
     ///
     /// impl std::error::Error for Error {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand
-    ///             .provide_ref::<MyBacktrace>(&self.backtrace)
-    ///             .provide_ref::<dyn std::error::Error + 'static>(&self.source);
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         request
+    ///             .provide_ref::<MyBacktrace>(&self.backtrace);
     ///     }
     /// }
     ///
     /// fn main() {
     ///     let backtrace = MyBacktrace::new();
-    ///     let source = SourceError {};
-    ///     let error = Error { source, backtrace };
+    ///     let error = Error { backtrace };
     ///     let dyn_error = &error as &dyn std::error::Error;
-    ///     let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
+    ///     let backtrace_ref = request_ref::<MyBacktrace>(dyn_error).unwrap();
     ///
     ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
+    ///     assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
     /// }
     /// ```
     #[unstable(feature = "error_generic_member_access", issue = "99301")]
     #[allow(unused_variables)]
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {}
-}
-
-#[unstable(feature = "error_generic_member_access", issue = "99301")]
-impl<E> Provider for E
-where
-    E: Error + ?Sized,
-{
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-        self.provide(demand)
-    }
+    fn provide<'a>(&'a self, request: &mut Request<'a>) {}
 }
-
 mod private {
     // This is a hack to prevent `type_id` from being overridden by `Error`
     // implementations, since that can enable unsound downcasting.
@@ -215,20 +194,6 @@ mod private {
 #[unstable(feature = "never_type", issue = "35121")]
 impl Error for ! {}
 
-impl<'a> dyn Error + 'a {
-    /// Request a reference of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
-        core::any::request_ref(self)
-    }
-
-    /// Request a value of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_value<T: 'static>(&'a self) -> Option<T> {
-        core::any::request_value(self)
-    }
-}
-
 // Copied from `any.rs`.
 impl dyn Error + 'static {
     /// Returns `true` if the inner type is the same as `T`.
@@ -293,18 +258,6 @@ impl dyn Error + 'static + Send {
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
         <dyn Error + 'static>::downcast_mut::<T>(self)
     }
-
-    /// Request a reference of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
-        <dyn Error>::request_ref(self)
-    }
-
-    /// Request a value of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_value<T: 'static>(&self) -> Option<T> {
-        <dyn Error>::request_value(self)
-    }
 }
 
 impl dyn Error + 'static + Send + Sync {
@@ -328,18 +281,6 @@ impl dyn Error + 'static + Send + Sync {
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
         <dyn Error + 'static>::downcast_mut::<T>(self)
     }
-
-    /// Request a reference of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
-        <dyn Error>::request_ref(self)
-    }
-
-    /// Request a value of type `T` as context about this error.
-    #[unstable(feature = "error_generic_member_access", issue = "99301")]
-    pub fn request_value<T: 'static>(&self) -> Option<T> {
-        <dyn Error>::request_value(self)
-    }
 }
 
 impl dyn Error {
@@ -412,6 +353,654 @@ impl dyn Error {
     }
 }
 
+/// Request a value of type `T` from the given `impl Error`.
+///
+/// # Examples
+///
+/// Get a string value from an error.
+///
+/// ```rust
+/// # #![feature(error_generic_member_access)]
+/// # #![feature(error_in_core)]
+/// use std::error::Error;
+/// use core::error::request_value;
+///
+/// fn get_string(err: &impl Error) -> String {
+///     request_value::<String>(err).unwrap()
+/// }
+/// ```
+#[unstable(feature = "error_generic_member_access", issue = "99301")]
+pub fn request_value<'a, T>(err: &'a (impl Error + ?Sized)) -> Option<T>
+where
+    T: 'static,
+{
+    request_by_type_tag::<'a, tags::Value<T>>(err)
+}
+
+/// Request a reference of type `T` from the given `impl Error`.
+///
+/// # Examples
+///
+/// Get a string reference from an error.
+///
+/// ```rust
+/// # #![feature(error_generic_member_access)]
+/// # #![feature(error_in_core)]
+/// use core::error::Error;
+/// use core::error::request_ref;
+///
+/// fn get_str(err: &impl Error) -> &str {
+///     request_ref::<str>(err).unwrap()
+/// }
+/// ```
+#[unstable(feature = "error_generic_member_access", issue = "99301")]
+pub fn request_ref<'a, T>(err: &'a (impl Error + ?Sized)) -> Option<&'a T>
+where
+    T: 'static + ?Sized,
+{
+    request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(err)
+}
+
+/// Request a specific value by tag from the `Error`.
+fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option<I::Reified>
+where
+    I: tags::Type<'a>,
+{
+    let mut tagged = TaggedOption::<'a, I>(None);
+    err.provide(tagged.as_request());
+    tagged.0
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Request and its methods
+///////////////////////////////////////////////////////////////////////////////
+
+/// `Request` supports generic, type-driven access to data. It's use is currently restricted to the
+/// standard library in cases where trait authors wish to allow trait implementors to share generic
+/// information across trait boundaries. The motivating and prototypical use case is
+/// `core::error::Error` which would otherwise require a method per concrete type (eg.
+/// `std::backtrace::Backtrace` instance that implementors want to expose to users).
+///
+/// # Data flow
+///
+/// To describe the intended data flow for Request objects, let's consider two conceptual users
+/// separated by API boundaries:
+///
+/// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers
+/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
+///
+/// * Producer - the producer provides objects when requested via Request; eg. a library with an
+/// an `Error` implementation that automatically captures backtraces at the time instances are
+/// created.
+///
+/// The consumer only needs to know where to submit their request and are expected to handle the
+/// request not being fulfilled by the use of `Option<T>` in the responses offered by the producer.
+///
+/// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise
+/// prepared to generate a value requested). eg, `backtrace::Backtrace` or
+/// `std::backtrace::Backtrace`
+/// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace). In the case
+/// of a `dyn Error` trait object (the Producer), there are methods called `request_ref` and
+/// `request_value` are available to simplify obtaining an ``Option<T>`` for a given type. * The
+/// Producer, when requested, populates the given Request object which is given as a mutable
+/// reference.
+/// * The Consumer extracts a value or reference to the requested type from the `Request` object
+/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
+/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
+/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
+/// Producer cannot currently offer an instance of the requested type, not it can't or never will.
+///
+/// # Examples
+///
+/// The best way to demonstrate this is using an example implementation of `Error`'s `provide` trait
+/// method:
+///
+/// ```
+/// #![feature(error_generic_member_access)]
+/// #![feature(error_in_core)]
+/// use core::fmt;
+/// use core::error::Request;
+/// use core::error::request_ref;
+///
+/// #[derive(Debug)]
+/// enum MyLittleTeaPot {
+///     Empty,
+/// }
+///
+/// #[derive(Debug)]
+/// struct MyBacktrace {
+///     // ...
+/// }
+///
+/// impl MyBacktrace {
+///     fn new() -> MyBacktrace {
+///         // ...
+///         # MyBacktrace {}
+///     }
+/// }
+///
+/// #[derive(Debug)]
+/// struct Error {
+///     backtrace: MyBacktrace,
+/// }
+///
+/// impl fmt::Display for Error {
+///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+///         write!(f, "Example Error")
+///     }
+/// }
+///
+/// impl std::error::Error for Error {
+///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+///         request
+///             .provide_ref::<MyBacktrace>(&self.backtrace);
+///     }
+/// }
+///
+/// fn main() {
+///     let backtrace = MyBacktrace::new();
+///     let error = Error { backtrace };
+///     let dyn_error = &error as &dyn std::error::Error;
+///     let backtrace_ref = request_ref::<MyBacktrace>(dyn_error).unwrap();
+///
+///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
+///     assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
+/// }
+/// ```
+///
+#[unstable(feature = "error_generic_member_access", issue = "99301")]
+#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435
+pub struct Request<'a>(dyn Erased<'a> + 'a);
+
+impl<'a> Request<'a> {
+    /// Create a new `&mut Request` from a `&mut dyn Erased` trait object.
+    fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Request<'a> {
+        // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Request<'a>` is safe since
+        // `Request` is repr(transparent).
+        unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Request<'a>) }
+    }
+
+    /// Provide a value or other type with only static lifetimes.
+    ///
+    /// # Examples
+    ///
+    /// Provides an `u8`.
+    ///
+    /// ```rust
+    /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
+    ///
+    /// use core::error::Request;
+    ///
+    /// #[derive(Debug)]
+    /// struct SomeConcreteType { field: u8 }
+    ///
+    /// impl std::fmt::Display for SomeConcreteType {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "{} failed", self.field)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for SomeConcreteType {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         request.provide_value::<u8>(self.field);
+    ///     }
+    /// }
+    /// ```
+    #[unstable(feature = "error_generic_member_access", issue = "99301")]
+    pub fn provide_value<T>(&mut self, value: T) -> &mut Self
+    where
+        T: 'static,
+    {
+        self.provide::<tags::Value<T>>(value)
+    }
+
+    /// Provide a value or other type with only static lifetimes computed using a closure.
+    ///
+    /// # Examples
+    ///
+    /// Provides a `String` by cloning.
+    ///
+    /// ```rust
+    /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
+    ///
+    /// use core::error::Request;
+    ///
+    /// #[derive(Debug)]
+    /// struct SomeConcreteType { field: String }
+    ///
+    /// impl std::fmt::Display for SomeConcreteType {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "{} failed", self.field)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for SomeConcreteType {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         request.provide_value_with::<String>(|| self.field.clone());
+    ///     }
+    /// }
+    /// ```
+    #[unstable(feature = "error_generic_member_access", issue = "99301")]
+    pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
+    where
+        T: 'static,
+    {
+        self.provide_with::<tags::Value<T>>(fulfil)
+    }
+
+    /// Provide a reference. The referee type must be bounded by `'static`,
+    /// but may be unsized.
+    ///
+    /// # Examples
+    ///
+    /// Provides a reference to a field as a `&str`.
+    ///
+    /// ```rust
+    /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
+    ///
+    /// use core::error::Request;
+    ///
+    /// #[derive(Debug)]
+    /// struct SomeConcreteType { field: String }
+    ///
+    /// impl std::fmt::Display for SomeConcreteType {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "{} failed", self.field)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for SomeConcreteType {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         request.provide_ref::<str>(&self.field);
+    ///     }
+    /// }
+    /// ```
+    #[unstable(feature = "error_generic_member_access", issue = "99301")]
+    pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self {
+        self.provide::<tags::Ref<tags::MaybeSizedValue<T>>>(value)
+    }
+
+    /// Provide a reference computed using a closure. The referee type
+    /// must be bounded by `'static`, but may be unsized.
+    ///
+    /// # Examples
+    ///
+    /// Provides a reference to a field as a `&str`.
+    ///
+    /// ```rust
+    /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
+    ///
+    /// use core::error::Request;
+    ///
+    /// #[derive(Debug)]
+    /// struct SomeConcreteType { business: String, party: String }
+    /// fn today_is_a_weekday() -> bool { true }
+    ///
+    /// impl std::fmt::Display for SomeConcreteType {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "{} failed", self.business)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for SomeConcreteType {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         request.provide_ref_with::<str>(|| {
+    ///             if today_is_a_weekday() {
+    ///                 &self.business
+    ///             } else {
+    ///                 &self.party
+    ///             }
+    ///         });
+    ///     }
+    /// }
+    /// ```
+    #[unstable(feature = "error_generic_member_access", issue = "99301")]
+    pub fn provide_ref_with<T: ?Sized + 'static>(
+        &mut self,
+        fulfil: impl FnOnce() -> &'a T,
+    ) -> &mut Self {
+        self.provide_with::<tags::Ref<tags::MaybeSizedValue<T>>>(fulfil)
+    }
+
+    /// Provide a value with the given `Type` tag.
+    fn provide<I>(&mut self, value: I::Reified) -> &mut Self
+    where
+        I: tags::Type<'a>,
+    {
+        if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
+            res.0 = Some(value);
+        }
+        self
+    }
+
+    /// Provide a value with the given `Type` tag, using a closure to prevent unnecessary work.
+    fn provide_with<I>(&mut self, fulfil: impl FnOnce() -> I::Reified) -> &mut Self
+    where
+        I: tags::Type<'a>,
+    {
+        if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
+            res.0 = Some(fulfil());
+        }
+        self
+    }
+
+    /// Check if the `Request` would be satisfied if provided with a
+    /// value of the specified type. If the type does not match or has
+    /// already been provided, returns false.
+    ///
+    /// # Examples
+    ///
+    /// Check if an `u8` still needs to be provided and then provides
+    /// it.
+    ///
+    /// ```rust
+    /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
+    ///
+    /// use core::error::Request;
+    /// use core::error::request_value;
+    ///
+    /// #[derive(Debug)]
+    /// struct Parent(Option<u8>);
+    ///
+    /// impl std::fmt::Display for Parent {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "a parent failed")
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for Parent {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         if let Some(v) = self.0 {
+    ///             request.provide_value::<u8>(v);
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// #[derive(Debug)]
+    /// struct Child {
+    ///     parent: Parent,
+    /// }
+    ///
+    /// impl Child {
+    ///     // Pretend that this takes a lot of resources to evaluate.
+    ///     fn an_expensive_computation(&self) -> Option<u8> {
+    ///         Some(99)
+    ///     }
+    /// }
+    ///
+    /// impl std::fmt::Display for Child {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "child failed: \n  because of parent: {}", self.parent)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for Child {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         // In general, we don't know if this call will provide
+    ///         // an `u8` value or not...
+    ///         self.parent.provide(request);
+    ///
+    ///         // ...so we check to see if the `u8` is needed before
+    ///         // we run our expensive computation.
+    ///         if request.would_be_satisfied_by_value_of::<u8>() {
+    ///             if let Some(v) = self.an_expensive_computation() {
+    ///                 request.provide_value::<u8>(v);
+    ///             }
+    ///         }
+    ///
+    ///         // The request will be satisfied now, regardless of if
+    ///         // the parent provided the value or we did.
+    ///         assert!(!request.would_be_satisfied_by_value_of::<u8>());
+    ///     }
+    /// }
+    ///
+    /// let parent = Parent(Some(42));
+    /// let child = Child { parent };
+    /// assert_eq!(Some(42), request_value::<u8>(&child));
+    ///
+    /// let parent = Parent(None);
+    /// let child = Child { parent };
+    /// assert_eq!(Some(99), request_value::<u8>(&child));
+    ///
+    /// ```
+    #[unstable(feature = "error_generic_member_access", issue = "99301")]
+    pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
+    where
+        T: 'static,
+    {
+        self.would_be_satisfied_by::<tags::Value<T>>()
+    }
+
+    /// Check if the `Request` would be satisfied if provided with a
+    /// reference to a value of the specified type. If the type does
+    /// not match or has already been provided, returns false.
+    ///
+    /// # Examples
+    ///
+    /// Check if a `&str` still needs to be provided and then provides
+    /// it.
+    ///
+    /// ```rust
+    /// #![feature(error_generic_member_access)]
+    /// #![feature(error_in_core)]
+    ///
+    /// use core::error::Request;
+    /// use core::error::request_ref;
+    ///
+    /// #[derive(Debug)]
+    /// struct Parent(Option<String>);
+    ///
+    /// impl std::fmt::Display for Parent {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "a parent failed")
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for Parent {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         if let Some(v) = &self.0 {
+    ///             request.provide_ref::<str>(v);
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// #[derive(Debug)]
+    /// struct Child {
+    ///     parent: Parent,
+    ///     name: String,
+    /// }
+    ///
+    /// impl Child {
+    ///     // Pretend that this takes a lot of resources to evaluate.
+    ///     fn an_expensive_computation(&self) -> Option<&str> {
+    ///         Some(&self.name)
+    ///     }
+    /// }
+    ///
+    /// impl std::fmt::Display for Child {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///         write!(f, "{} failed: \n  {}", self.name, self.parent)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for Child {
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         // In general, we don't know if this call will provide
+    ///         // a `str` reference or not...
+    ///         self.parent.provide(request);
+    ///
+    ///         // ...so we check to see if the `&str` is needed before
+    ///         // we run our expensive computation.
+    ///         if request.would_be_satisfied_by_ref_of::<str>() {
+    ///             if let Some(v) = self.an_expensive_computation() {
+    ///                 request.provide_ref::<str>(v);
+    ///             }
+    ///         }
+    ///
+    ///         // The request will be satisfied now, regardless of if
+    ///         // the parent provided the reference or we did.
+    ///         assert!(!request.would_be_satisfied_by_ref_of::<str>());
+    ///     }
+    /// }
+    ///
+    /// let parent = Parent(Some("parent".into()));
+    /// let child = Child { parent, name: "child".into() };
+    /// assert_eq!(Some("parent"), request_ref::<str>(&child));
+    ///
+    /// let parent = Parent(None);
+    /// let child = Child { parent, name: "child".into() };
+    /// assert_eq!(Some("child"), request_ref::<str>(&child));
+    /// ```
+    #[unstable(feature = "error_generic_member_access", issue = "99301")]
+    pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
+    where
+        T: ?Sized + 'static,
+    {
+        self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
+    }
+
+    fn would_be_satisfied_by<I>(&self) -> bool
+    where
+        I: tags::Type<'a>,
+    {
+        matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
+    }
+}
+
+#[unstable(feature = "error_generic_member_access", issue = "99301")]
+impl<'a> Debug for Request<'a> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        f.debug_struct("Request").finish_non_exhaustive()
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Type tags
+///////////////////////////////////////////////////////////////////////////////
+
+pub(crate) mod tags {
+    //! Type tags are used to identify a type using a separate value. This module includes type tags
+    //! for some very common types.
+    //!
+    //! Currently type tags are not exposed to the user. But in the future, if you want to use the
+    //! Request API with more complex types (typically those including lifetime parameters), you
+    //! will need to write your own tags.
+
+    use crate::marker::PhantomData;
+
+    /// This trait is implemented by specific tag types in order to allow
+    /// describing a type which can be requested for a given lifetime `'a`.
+    ///
+    /// A few example implementations for type-driven tags can be found in this
+    /// module, although crates may also implement their own tags for more
+    /// complex types with internal lifetimes.
+    pub(crate) trait Type<'a>: Sized + 'static {
+        /// The type of values which may be tagged by this tag for the given
+        /// lifetime.
+        type Reified: 'a;
+    }
+
+    /// Similar to the [`Type`] trait, but represents a type which may be unsized (i.e., has a
+    /// `?Sized` bound). E.g., `str`.
+    pub(crate) trait MaybeSizedType<'a>: Sized + 'static {
+        type Reified: 'a + ?Sized;
+    }
+
+    impl<'a, T: Type<'a>> MaybeSizedType<'a> for T {
+        type Reified = T::Reified;
+    }
+
+    /// Type-based tag for types bounded by `'static`, i.e., with no borrowed elements.
+    #[derive(Debug)]
+    pub(crate) struct Value<T: 'static>(PhantomData<T>);
+
+    impl<'a, T: 'static> Type<'a> for Value<T> {
+        type Reified = T;
+    }
+
+    /// Type-based tag similar to [`Value`] but which may be unsized (i.e., has a `?Sized` bound).
+    #[derive(Debug)]
+    pub(crate) struct MaybeSizedValue<T: ?Sized + 'static>(PhantomData<T>);
+
+    impl<'a, T: ?Sized + 'static> MaybeSizedType<'a> for MaybeSizedValue<T> {
+        type Reified = T;
+    }
+
+    /// Type-based tag for reference types (`&'a T`, where T is represented by
+    /// `<I as MaybeSizedType<'a>>::Reified`.
+    #[derive(Debug)]
+    pub(crate) struct Ref<I>(PhantomData<I>);
+
+    impl<'a, I: MaybeSizedType<'a>> Type<'a> for Ref<I> {
+        type Reified = &'a I::Reified;
+    }
+}
+
+/// An `Option` with a type tag `I`.
+///
+/// Since this struct implements `Erased`, the type can be erased to make a dynamically typed
+/// option. The type can be checked dynamically using `Erased::tag_id` and since this is statically
+/// checked for the concrete type, there is some degree of type safety.
+#[repr(transparent)]
+pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option<I::Reified>);
+
+impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> {
+    pub(crate) fn as_request(&mut self) -> &mut Request<'a> {
+        Request::new(self as &mut (dyn Erased<'a> + 'a))
+    }
+}
+
+/// Represents a type-erased but identifiable object.
+///
+/// This trait is exclusively implemented by the `TaggedOption` type.
+unsafe trait Erased<'a>: 'a {
+    /// The `TypeId` of the erased type.
+    fn tag_id(&self) -> TypeId;
+}
+
+unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {
+    fn tag_id(&self) -> TypeId {
+        TypeId::of::<I>()
+    }
+}
+
+impl<'a> dyn Erased<'a> + 'a {
+    /// Returns some reference to the dynamic value if it is tagged with `I`,
+    /// or `None` otherwise.
+    #[inline]
+    fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
+    where
+        I: tags::Type<'a>,
+    {
+        if self.tag_id() == TypeId::of::<I>() {
+            // SAFETY: Just checked whether we're pointing to an I.
+            Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
+        } else {
+            None
+        }
+    }
+
+    /// Returns some mutable reference to the dynamic value if it is tagged with `I`,
+    /// or `None` otherwise.
+    #[inline]
+    fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
+    where
+        I: tags::Type<'a>,
+    {
+        if self.tag_id() == TypeId::of::<I>() {
+            // SAFETY: Just checked whether we're pointing to an I.
+            Some(unsafe { &mut *(self as *mut Self).cast::<TaggedOption<'a, I>>() })
+        } else {
+            None
+        }
+    }
+}
+
 /// An iterator over an [`Error`] and its sources.
 ///
 /// If you want to omit the initial error and only process
@@ -449,8 +1038,8 @@ impl<'a, T: Error + ?Sized> Error for &'a T {
         Error::source(&**self)
     }
 
-    fn provide<'b>(&'b self, demand: &mut Demand<'b>) {
-        Error::provide(&**self, demand);
+    fn provide<'b>(&'b self, request: &mut Request<'b>) {
+        Error::provide(&**self, request);
     }
 }
 
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index b59ec12790d..4082b208c12 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -82,12 +82,12 @@ use crate::str;
 #[stable(feature = "core_c_str", since = "1.64.0")]
 #[rustc_has_incoherent_inherent_impls]
 #[lang = "CStr"]
-// FIXME:
 // `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
 // on `CStr` being layout-compatible with `[u8]`.
-// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`.
-// Anyway, `CStr` representation and layout are considered implementation detail, are
-// not documented and must not be relied upon.
+// However, `CStr` layout is considered an implementation detail and must not be relied upon. We
+// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
+// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
+#[cfg_attr(not(doc), repr(transparent))]
 pub struct CStr {
     // FIXME: this should not be represented with a DST slice but rather with
     //        just a raw `c_char` along with some form of marker to make
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index 3fcd5e7c1cb..b2c9a0800c9 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -110,7 +110,8 @@ mod c_char_definition {
                     target_arch = "powerpc64",
                     target_arch = "s390x",
                     target_arch = "riscv64",
-                    target_arch = "riscv32"
+                    target_arch = "riscv32",
+                    target_arch = "csky"
                 )
             ),
             all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs
new file mode 100644
index 00000000000..3c0e80b2559
--- /dev/null
+++ b/library/core/src/iter/adapters/map_windows.rs
@@ -0,0 +1,293 @@
+use crate::{
+    fmt,
+    iter::{ExactSizeIterator, FusedIterator},
+    mem::{self, MaybeUninit},
+    ptr,
+};
+
+/// An iterator over the mapped windows of another iterator.
+///
+/// This `struct` is created by the [`Iterator::map_windows`]. See its
+/// documentation for more information.
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+pub struct MapWindows<I: Iterator, F, const N: usize> {
+    f: F,
+    inner: MapWindowsInner<I, N>,
+}
+
+struct MapWindowsInner<I: Iterator, const N: usize> {
+    // We fuse the inner iterator because there shouldn't be "holes" in
+    // the sliding window. Once the iterator returns a `None`, we make
+    // our `MapWindows` iterator return `None` forever.
+    iter: Option<I>,
+    // Since iterators are assumed lazy, i.e. it only yields an item when
+    // `Iterator::next()` is called, and `MapWindows` is not an exception.
+    //
+    // Before the first iteration, we keep the buffer `None`. When the user
+    // first call `next` or other methods that makes the iterator advance,
+    // we collect the first `N` items yielded from the inner iterator and
+    // put it into the buffer.
+    //
+    // When the inner iterator has returned a `None` (i.e. fused), we take
+    // away this `buffer` and leave it `None` to reclaim its resources.
+    //
+    // FIXME: should we shrink the size of `buffer` using niche optimization?
+    buffer: Option<Buffer<I::Item, N>>,
+}
+
+// `Buffer` uses two times of space to reduce moves among the iterations.
+// `Buffer<T, N>` is semantically `[MaybeUninit<T>; 2 * N]`. However, due
+// to limitations of const generics, we use this different type. Note that
+// it has the same underlying memory layout.
+struct Buffer<T, const N: usize> {
+    // Invariant: `self.buffer[self.start..self.start + N]` is initialized,
+    // with all other elements being uninitialized. This also
+    // implies that `self.start <= N`.
+    buffer: [[MaybeUninit<T>; N]; 2],
+    start: usize,
+}
+
+impl<I: Iterator, F, const N: usize> MapWindows<I, F, N> {
+    pub(in crate::iter) fn new(iter: I, f: F) -> Self {
+        assert!(N != 0, "array in `Iterator::map_windows` must contain more than 0 elements");
+
+        // Only ZST arrays' length can be so large.
+        if mem::size_of::<I::Item>() == 0 {
+            assert!(
+                N.checked_mul(2).is_some(),
+                "array size of `Iterator::map_windows` is too large"
+            );
+        }
+
+        Self { inner: MapWindowsInner::new(iter), f }
+    }
+}
+
+impl<I: Iterator, const N: usize> MapWindowsInner<I, N> {
+    #[inline]
+    fn new(iter: I) -> Self {
+        Self { iter: Some(iter), buffer: None }
+    }
+
+    fn next_window(&mut self) -> Option<&[I::Item; N]> {
+        let iter = self.iter.as_mut()?;
+        match self.buffer {
+            // It is the first time to advance. We collect
+            // the first `N` items from `self.iter` to initialize `self.buffer`.
+            None => self.buffer = Buffer::try_from_iter(iter),
+            Some(ref mut buffer) => match iter.next() {
+                None => {
+                    // Fuse the inner iterator since it yields a `None`.
+                    self.iter.take();
+                    self.buffer.take();
+                }
+                // Advance the iterator. We first call `next` before changing our buffer
+                // at all. This means that if `next` panics, our invariant is upheld and
+                // our `Drop` impl drops the correct elements.
+                Some(item) => buffer.push(item),
+            },
+        }
+        self.buffer.as_ref().map(Buffer::as_array_ref)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let Some(ref iter) = self.iter else { return (0, Some(0)) };
+        let (lo, hi) = iter.size_hint();
+        if self.buffer.is_some() {
+            // If the first `N` items are already yielded by the inner iterator,
+            // the size hint is then equal to the that of the inner iterator's.
+            (lo, hi)
+        } else {
+            // If the first `N` items are not yet yielded by the inner iterator,
+            // the first `N` elements should be counted as one window, so both bounds
+            // should subtract `N - 1`.
+            (lo.saturating_sub(N - 1), hi.map(|hi| hi.saturating_sub(N - 1)))
+        }
+    }
+}
+
+impl<T, const N: usize> Buffer<T, N> {
+    fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> {
+        let first_half = crate::array::iter_next_chunk(iter).ok()?;
+        let buffer = [MaybeUninit::new(first_half).transpose(), MaybeUninit::uninit_array()];
+        Some(Self { buffer, start: 0 })
+    }
+
+    #[inline]
+    fn buffer_ptr(&self) -> *const MaybeUninit<T> {
+        self.buffer.as_ptr().cast()
+    }
+
+    #[inline]
+    fn buffer_mut_ptr(&mut self) -> *mut MaybeUninit<T> {
+        self.buffer.as_mut_ptr().cast()
+    }
+
+    #[inline]
+    fn as_array_ref(&self) -> &[T; N] {
+        debug_assert!(self.start + N <= 2 * N);
+
+        // SAFETY: our invariant guarantees these elements are initialized.
+        unsafe { &*self.buffer_ptr().add(self.start).cast() }
+    }
+
+    #[inline]
+    fn as_uninit_array_mut(&mut self) -> &mut MaybeUninit<[T; N]> {
+        debug_assert!(self.start + N <= 2 * N);
+
+        // SAFETY: our invariant guarantees these elements are in bounds.
+        unsafe { &mut *self.buffer_mut_ptr().add(self.start).cast() }
+    }
+
+    /// Pushes a new item `next` to the back, and pops the front-most one.
+    ///
+    /// All the elements will be shifted to the front end when pushing reaches
+    /// the back end.
+    fn push(&mut self, next: T) {
+        let buffer_mut_ptr = self.buffer_mut_ptr();
+        debug_assert!(self.start + N <= 2 * N);
+
+        let to_drop = if self.start == N {
+            // We have reached the end of our buffer and have to copy
+            // everything to the start. Example layout for N = 3.
+            //
+            //    0   1   2   3   4   5            0   1   2   3   4   5
+            //  ┌───┬───┬───┬───┬───┬───┐        ┌───┬───┬───┬───┬───┬───┐
+            //  │ - │ - │ - │ a │ b │ c │   ->   │ b │ c │ n │ - │ - │ - │
+            //  └───┴───┴───┴───┴───┴───┘        └───┴───┴───┴───┴───┴───┘
+            //                ↑                    ↑
+            //              start                start
+
+            // SAFETY: the two pointers are valid for reads/writes of N -1
+            // elements because our array's size is semantically 2 * N. The
+            // regions also don't overlap for the same reason.
+            //
+            // We leave the old elements in place. As soon as `start` is set
+            // to 0, we treat them as uninitialized and treat their copies
+            // as initialized.
+            let to_drop = unsafe {
+                ptr::copy_nonoverlapping(buffer_mut_ptr.add(self.start + 1), buffer_mut_ptr, N - 1);
+                (*buffer_mut_ptr.add(N - 1)).write(next);
+                buffer_mut_ptr.add(self.start)
+            };
+            self.start = 0;
+            to_drop
+        } else {
+            // SAFETY: `self.start` is < N as guaranteed by the invariant
+            // plus the check above. Even if the drop at the end panics,
+            // the invariant is upheld.
+            //
+            // Example layout for N = 3:
+            //
+            //    0   1   2   3   4   5            0   1   2   3   4   5
+            //  ┌───┬───┬───┬───┬───┬───┐        ┌───┬───┬───┬───┬───┬───┐
+            //  │ - │ a │ b │ c │ - │ - │   ->   │ - │ - │ b │ c │ n │ - │
+            //  └───┴───┴───┴───┴───┴───┘        └───┴───┴───┴───┴───┴───┘
+            //        ↑                                    ↑
+            //      start                                start
+            //
+            let to_drop = unsafe {
+                (*buffer_mut_ptr.add(self.start + N)).write(next);
+                buffer_mut_ptr.add(self.start)
+            };
+            self.start += 1;
+            to_drop
+        };
+
+        // SAFETY: the index is valid and this is element `a` in the
+        // diagram above and has not been dropped yet.
+        unsafe { ptr::drop_in_place(to_drop.cast::<T>()) };
+    }
+}
+
+impl<T: Clone, const N: usize> Clone for Buffer<T, N> {
+    fn clone(&self) -> Self {
+        let mut buffer = Buffer {
+            buffer: [MaybeUninit::uninit_array(), MaybeUninit::uninit_array()],
+            start: self.start,
+        };
+        buffer.as_uninit_array_mut().write(self.as_array_ref().clone());
+        buffer
+    }
+}
+
+impl<I, const N: usize> Clone for MapWindowsInner<I, N>
+where
+    I: Iterator + Clone,
+    I::Item: Clone,
+{
+    fn clone(&self) -> Self {
+        Self { iter: self.iter.clone(), buffer: self.buffer.clone() }
+    }
+}
+
+impl<T, const N: usize> Drop for Buffer<T, N> {
+    fn drop(&mut self) {
+        // SAFETY: our invariant guarantees that N elements starting from
+        // `self.start` are initialized. We drop them here.
+        unsafe {
+            let initialized_part: *mut [T] = crate::ptr::slice_from_raw_parts_mut(
+                self.buffer_mut_ptr().add(self.start).cast(),
+                N,
+            );
+            ptr::drop_in_place(initialized_part);
+        }
+    }
+}
+
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+impl<I, F, R, const N: usize> Iterator for MapWindows<I, F, N>
+where
+    I: Iterator,
+    F: FnMut(&[I::Item; N]) -> R,
+{
+    type Item = R;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let window = self.inner.next_window()?;
+        let out = (self.f)(window);
+        Some(out)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+// Note that even if the inner iterator not fused, the `MapWindows` is still fused,
+// because we don't allow "holes" in the mapping window.
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+impl<I, F, R, const N: usize> FusedIterator for MapWindows<I, F, N>
+where
+    I: Iterator,
+    F: FnMut(&[I::Item; N]) -> R,
+{
+}
+
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+impl<I, F, R, const N: usize> ExactSizeIterator for MapWindows<I, F, N>
+where
+    I: ExactSizeIterator,
+    F: FnMut(&[I::Item; N]) -> R,
+{
+}
+
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+impl<I: Iterator + fmt::Debug, F, const N: usize> fmt::Debug for MapWindows<I, F, N> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("MapWindows").field("iter", &self.inner.iter).finish()
+    }
+}
+
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+impl<I, F, const N: usize> Clone for MapWindows<I, F, N>
+where
+    I: Iterator + Clone,
+    F: Clone,
+    I::Item: Clone,
+{
+    fn clone(&self) -> Self {
+        Self { f: self.f.clone(), inner: self.inner.clone() }
+    }
+}
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index 8cc2b7cec41..6f4fa7010f4 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -16,6 +16,7 @@ mod inspect;
 mod intersperse;
 mod map;
 mod map_while;
+mod map_windows;
 mod peekable;
 mod rev;
 mod scan;
@@ -57,6 +58,9 @@ pub use self::intersperse::{Intersperse, IntersperseWith};
 #[stable(feature = "iter_map_while", since = "1.57.0")]
 pub use self::map_while::MapWhile;
 
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+pub use self::map_windows::MapWindows;
+
 #[unstable(feature = "trusted_random_access", issue = "none")]
 pub use self::zip::TrustedRandomAccess;
 
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index be04dfe042e..ca977d1ef82 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -440,6 +440,8 @@ pub use self::adapters::Copied;
 pub use self::adapters::Flatten;
 #[stable(feature = "iter_map_while", since = "1.57.0")]
 pub use self::adapters::MapWhile;
+#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+pub use self::adapters::MapWindows;
 #[unstable(feature = "inplace_iteration", issue = "none")]
 pub use self::adapters::SourceIter;
 #[stable(feature = "iterator_step_by", since = "1.28.0")]
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index cecc120a6e2..ac1fc26a1ef 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -10,7 +10,8 @@ use super::super::{ArrayChunks, Chain, Cloned, Copied, Cycle, Enumerate, Filter,
 use super::super::{FlatMap, Flatten};
 use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
 use super::super::{
-    Inspect, Map, MapWhile, Peekable, Rev, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile,
+    Inspect, Map, MapWhile, MapWindows, Peekable, Rev, Scan, Skip, SkipWhile, StepBy, Take,
+    TakeWhile,
 };
 
 fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
@@ -1591,6 +1592,163 @@ pub trait Iterator {
         Flatten::new(self)
     }
 
+    /// Calls the given function `f` for each contiguous window of size `N` over
+    /// `self` and returns an iterator over the outputs of `f`. Like [`slice::windows()`],
+    /// the windows during mapping overlap as well.
+    ///
+    /// In the following example, the closure is called three times with the
+    /// arguments `&['a', 'b']`, `&['b', 'c']` and `&['c', 'd']` respectively.
+    ///
+    /// ```
+    /// #![feature(iter_map_windows)]
+    ///
+    /// let strings = "abcd".chars()
+    ///     .map_windows(|[x, y]| format!("{}+{}", x, y))
+    ///     .collect::<Vec<String>>();
+    ///
+    /// assert_eq!(strings, vec!["a+b", "b+c", "c+d"]);
+    /// ```
+    ///
+    /// Note that the const parameter `N` is usually inferred by the
+    /// destructured argument in the closure.
+    ///
+    /// The returned iterator yields 𝑘 − `N` + 1 items (where 𝑘 is the number of
+    /// items yielded by `self`). If 𝑘 is less than `N`, this method yields an
+    /// empty iterator.
+    ///
+    /// The returned iterator implements [`FusedIterator`], because once `self`
+    /// returns `None`, even if it returns a `Some(T)` again in the next iterations,
+    /// we cannot put it into a contigious array buffer, and thus the returned iterator
+    /// should be fused.
+    ///
+    /// [`slice::windows()`]: slice::windows
+    /// [`FusedIterator`]: crate::iter::FusedIterator
+    ///
+    /// # Panics
+    ///
+    /// Panics if `N` is 0. This check will most probably get changed to a
+    /// compile time error before this method gets stabilized.
+    ///
+    /// ```should_panic
+    /// #![feature(iter_map_windows)]
+    ///
+    /// let iter = std::iter::repeat(0).map_windows(|&[]| ());
+    /// ```
+    ///
+    /// # Examples
+    ///
+    /// Building the sums of neighboring numbers.
+    ///
+    /// ```
+    /// #![feature(iter_map_windows)]
+    ///
+    /// let mut it = [1, 3, 8, 1].iter().map_windows(|&[a, b]| a + b);
+    /// assert_eq!(it.next(), Some(4));  // 1 + 3
+    /// assert_eq!(it.next(), Some(11)); // 3 + 8
+    /// assert_eq!(it.next(), Some(9));  // 8 + 1
+    /// assert_eq!(it.next(), None);
+    /// ```
+    ///
+    /// Since the elements in the following example implement `Copy`, we can
+    /// just copy the array and get an iterator over the windows.
+    ///
+    /// ```
+    /// #![feature(iter_map_windows)]
+    ///
+    /// let mut it = "ferris".chars().map_windows(|w: &[_; 3]| *w);
+    /// assert_eq!(it.next(), Some(['f', 'e', 'r']));
+    /// assert_eq!(it.next(), Some(['e', 'r', 'r']));
+    /// assert_eq!(it.next(), Some(['r', 'r', 'i']));
+    /// assert_eq!(it.next(), Some(['r', 'i', 's']));
+    /// assert_eq!(it.next(), None);
+    /// ```
+    ///
+    /// You can also use this function to check the sortedness of an iterator.
+    /// For the simple case, rather use [`Iterator::is_sorted`].
+    ///
+    /// ```
+    /// #![feature(iter_map_windows)]
+    ///
+    /// let mut it = [0.5, 1.0, 3.5, 3.0, 8.5, 8.5, f32::NAN].iter()
+    ///     .map_windows(|[a, b]| a <= b);
+    ///
+    /// assert_eq!(it.next(), Some(true));  // 0.5 <= 1.0
+    /// assert_eq!(it.next(), Some(true));  // 1.0 <= 3.5
+    /// assert_eq!(it.next(), Some(false)); // 3.5 <= 3.0
+    /// assert_eq!(it.next(), Some(true));  // 3.0 <= 8.5
+    /// assert_eq!(it.next(), Some(true));  // 8.5 <= 8.5
+    /// assert_eq!(it.next(), Some(false)); // 8.5 <= NAN
+    /// assert_eq!(it.next(), None);
+    /// ```
+    ///
+    /// For non-fused iterators, they are fused after `map_windows`.
+    ///
+    /// ```
+    /// #![feature(iter_map_windows)]
+    ///
+    /// #[derive(Default)]
+    /// struct NonFusedIterator {
+    ///     state: i32,
+    /// }
+    ///
+    /// impl Iterator for NonFusedIterator {
+    ///     type Item = i32;
+    ///
+    ///     fn next(&mut self) -> Option<i32> {
+    ///         let val = self.state;
+    ///         self.state = self.state + 1;
+    ///
+    ///         // yields `0..5` first, then only even numbers since `6..`.
+    ///         if val < 5 || val % 2 == 0 {
+    ///             Some(val)
+    ///         } else {
+    ///             None
+    ///         }
+    ///     }
+    /// }
+    ///
+    ///
+    /// let mut iter = NonFusedIterator::default();
+    ///
+    /// // yields 0..5 first.
+    /// assert_eq!(iter.next(), Some(0));
+    /// assert_eq!(iter.next(), Some(1));
+    /// assert_eq!(iter.next(), Some(2));
+    /// assert_eq!(iter.next(), Some(3));
+    /// assert_eq!(iter.next(), Some(4));
+    /// // then we can see our iterator going back and forth
+    /// assert_eq!(iter.next(), None);
+    /// assert_eq!(iter.next(), Some(6));
+    /// assert_eq!(iter.next(), None);
+    /// assert_eq!(iter.next(), Some(8));
+    /// assert_eq!(iter.next(), None);
+    ///
+    /// // however, with `.map_windows()`, it is fused.
+    /// let mut iter = NonFusedIterator::default()
+    ///     .map_windows(|arr: &[_; 2]| *arr);
+    ///
+    /// assert_eq!(iter.next(), Some([0, 1]));
+    /// assert_eq!(iter.next(), Some([1, 2]));
+    /// assert_eq!(iter.next(), Some([2, 3]));
+    /// assert_eq!(iter.next(), Some([3, 4]));
+    /// assert_eq!(iter.next(), None);
+    ///
+    /// // it will always return `None` after the first time.
+    /// assert_eq!(iter.next(), None);
+    /// assert_eq!(iter.next(), None);
+    /// assert_eq!(iter.next(), None);
+    /// ```
+    #[inline]
+    #[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]
+    #[rustc_do_not_const_check]
+    fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
+    where
+        Self: Sized,
+        F: FnMut(&[Self::Item; N]) -> R,
+    {
+        MapWindows::new(self, f)
+    }
+
     /// Creates an iterator which ends after the first [`None`].
     ///
     /// After an iterator returns [`None`], future calls may or may not yield
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 6f6b6dbb80b..2136d29255f 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2074,10 +2074,10 @@ macro_rules! uint_impl {
         /// Basic usage:
         ///
         /// ```
-        /// #![feature(int_roundings)]
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".div_ceil(4), 2);")]
         /// ```
-        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
+        #[rustc_const_stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -2109,11 +2109,11 @@ macro_rules! uint_impl {
         /// Basic usage:
         ///
         /// ```
-        /// #![feature(int_roundings)]
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".next_multiple_of(8), 16);")]
         #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".next_multiple_of(8), 24);")]
         /// ```
-        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
+        #[rustc_const_stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -2134,13 +2134,13 @@ macro_rules! uint_impl {
         /// Basic usage:
         ///
         /// ```
-        /// #![feature(int_roundings)]
         #[doc = concat!("assert_eq!(16_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(16));")]
         #[doc = concat!("assert_eq!(23_", stringify!($SelfT), ".checked_next_multiple_of(8), Some(24));")]
         #[doc = concat!("assert_eq!(1_", stringify!($SelfT), ".checked_next_multiple_of(0), None);")]
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.checked_next_multiple_of(2), None);")]
         /// ```
-        #[unstable(feature = "int_roundings", issue = "88581")]
+        #[stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
+        #[rustc_const_stable(feature = "int_roundings1", since = "CURRENT_RUSTC_VERSION")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index f0fcdab00ad..7b6249207fe 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -267,16 +267,14 @@ fn assert_failed_inner(
 
     match args {
         Some(args) => panic!(
-            r#"assertion failed: `(left {} right)`
-  left: `{:?}`,
- right: `{:?}`: {}"#,
-            op, left, right, args
+            r#"assertion `left {op} right` failed: {args}
+  left: {left:?}
+ right: {right:?}"#
         ),
         None => panic!(
-            r#"assertion failed: `(left {} right)`
-  left: `{:?}`,
- right: `{:?}`"#,
-            op, left, right,
+            r#"assertion `left {op} right` failed
+  left: {left:?}
+ right: {right:?}"#
         ),
     }
 }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 71c03f7bfc5..e5f34952c7d 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -267,14 +267,13 @@ impl str {
 
     /// Finds the closest `x` not below `index` where `is_char_boundary(x)` is `true`.
     ///
+    /// If `index` is greater than the length of the string, this returns the length of the string.
+    ///
     /// This method is the natural complement to [`floor_char_boundary`]. See that method
     /// for more details.
     ///
     /// [`floor_char_boundary`]: str::floor_char_boundary
     ///
-    /// # Panics
-    ///
-    /// Panics if `index > self.len()`.
     ///
     /// # Examples
     ///
@@ -292,7 +291,7 @@ impl str {
     #[inline]
     pub fn ceil_char_boundary(&self, index: usize) -> usize {
         if index > self.len() {
-            slice_error_fail(self, index, index)
+            self.len()
         } else {
             let upper_bound = Ord::min(index + 4, self.len());
             self.as_bytes()[index..upper_bound]
diff --git a/library/core/tests/any.rs b/library/core/tests/any.rs
index a8f6b7ebb92..8d2d31b6431 100644
--- a/library/core/tests/any.rs
+++ b/library/core/tests/any.rs
@@ -147,65 +147,3 @@ fn dyn_type_name() {
         std::any::type_name::<dyn Foo<Bar = i32> + Send + Sync>()
     );
 }
-
-// Test the `Provider` API.
-
-struct SomeConcreteType {
-    some_string: String,
-}
-
-impl Provider for SomeConcreteType {
-    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-        demand
-            .provide_ref::<String>(&self.some_string)
-            .provide_ref::<str>(&self.some_string)
-            .provide_value_with::<String>(|| "bye".to_owned());
-    }
-}
-
-// Test the provide and request mechanisms with a by-reference trait object.
-#[test]
-fn test_provider() {
-    let obj: &dyn Provider = &SomeConcreteType { some_string: "hello".to_owned() };
-
-    assert_eq!(&**request_ref::<String>(obj).unwrap(), "hello");
-    assert_eq!(&*request_value::<String>(obj).unwrap(), "bye");
-    assert_eq!(request_value::<u8>(obj), None);
-}
-
-// Test the provide and request mechanisms with a boxed trait object.
-#[test]
-fn test_provider_boxed() {
-    let obj: Box<dyn Provider> = Box::new(SomeConcreteType { some_string: "hello".to_owned() });
-
-    assert_eq!(&**request_ref::<String>(&*obj).unwrap(), "hello");
-    assert_eq!(&*request_value::<String>(&*obj).unwrap(), "bye");
-    assert_eq!(request_value::<u8>(&*obj), None);
-}
-
-// Test the provide and request mechanisms with a concrete object.
-#[test]
-fn test_provider_concrete() {
-    let obj = SomeConcreteType { some_string: "hello".to_owned() };
-
-    assert_eq!(&**request_ref::<String>(&obj).unwrap(), "hello");
-    assert_eq!(&*request_value::<String>(&obj).unwrap(), "bye");
-    assert_eq!(request_value::<u8>(&obj), None);
-}
-
-trait OtherTrait: Provider {}
-
-impl OtherTrait for SomeConcreteType {}
-
-impl dyn OtherTrait {
-    fn get_ref<T: 'static + ?Sized>(&self) -> Option<&T> {
-        request_ref::<T>(self)
-    }
-}
-
-// Test the provide and request mechanisms via an intermediate trait.
-#[test]
-fn test_provider_intermediate() {
-    let obj: &dyn OtherTrait = &SomeConcreteType { some_string: "hello".to_owned() };
-    assert_eq!(obj.get_ref::<str>().unwrap(), "hello");
-}
diff --git a/library/core/tests/error.rs b/library/core/tests/error.rs
new file mode 100644
index 00000000000..cb7cb5441d1
--- /dev/null
+++ b/library/core/tests/error.rs
@@ -0,0 +1,66 @@
+use core::error::{request_value, request_ref, Request};
+
+// Test the `Request` API.
+#[derive(Debug)]
+struct SomeConcreteType {
+    some_string: String,
+}
+
+impl std::fmt::Display for SomeConcreteType {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "A")
+    }
+}
+
+impl std::error::Error for SomeConcreteType {
+    fn provide<'a>(&'a self, request: &mut Request<'a>) {
+        request
+            .provide_ref::<String>(&self.some_string)
+            .provide_ref::<str>(&self.some_string)
+            .provide_value_with::<String>(|| "bye".to_owned());
+    }
+}
+
+// Test the Error.provide and request mechanisms with a by-reference trait object.
+#[test]
+fn test_error_generic_member_access() {
+    let obj = &SomeConcreteType { some_string: "hello".to_owned() };
+
+    assert_eq!(request_ref::<String>(&*obj).unwrap(), "hello");
+    assert_eq!(request_value::<String>(&*obj).unwrap(), "bye");
+    assert_eq!(request_value::<u8>(&obj), None);
+}
+
+// Test the Error.provide and request mechanisms with a by-reference trait object.
+#[test]
+fn test_request_constructor() {
+    let obj: &dyn std::error::Error = &SomeConcreteType { some_string: "hello".to_owned() };
+
+    assert_eq!(request_ref::<String>(&*obj).unwrap(), "hello");
+    assert_eq!(request_value::<String>(&*obj).unwrap(), "bye");
+    assert_eq!(request_value::<u8>(&obj), None);
+}
+
+// Test the Error.provide and request mechanisms with a boxed trait object.
+#[test]
+fn test_error_generic_member_access_boxed() {
+    let obj: Box<dyn std::error::Error> =
+        Box::new(SomeConcreteType { some_string: "hello".to_owned() });
+
+    assert_eq!(request_ref::<String>(&*obj).unwrap(), "hello");
+    assert_eq!(request_value::<String>(&*obj).unwrap(), "bye");
+
+    // NOTE: Box<E> only implements Error when E: Error + Sized, which means we can't pass a
+    // Box<dyn Error> to request_value.
+    //assert_eq!(request_value::<String>(&obj).unwrap(), "bye");
+}
+
+// Test the Error.provide and request mechanisms with a concrete object.
+#[test]
+fn test_error_generic_member_access_concrete() {
+    let obj = SomeConcreteType { some_string: "hello".to_owned() };
+
+    assert_eq!(request_ref::<String>(&obj).unwrap(), "hello");
+    assert_eq!(request_value::<String>(&obj).unwrap(), "bye");
+    assert_eq!(request_value::<u8>(&obj), None);
+}
diff --git a/library/core/tests/iter/adapters/map_windows.rs b/library/core/tests/iter/adapters/map_windows.rs
new file mode 100644
index 00000000000..7fb2408f8ac
--- /dev/null
+++ b/library/core/tests/iter/adapters/map_windows.rs
@@ -0,0 +1,283 @@
+use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+
+#[cfg(not(panic = "abort"))]
+mod drop_checks {
+    //! These tests mainly make sure the elements are correctly dropped.
+    use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst};
+
+    #[derive(Debug)]
+    struct DropInfo {
+        dropped_twice: AtomicBool,
+        alive_count: AtomicUsize,
+    }
+
+    impl DropInfo {
+        const fn new() -> Self {
+            Self { dropped_twice: AtomicBool::new(false), alive_count: AtomicUsize::new(0) }
+        }
+
+        #[track_caller]
+        fn check(&self) {
+            assert!(!self.dropped_twice.load(SeqCst), "a value was dropped twice");
+            assert_eq!(self.alive_count.load(SeqCst), 0);
+        }
+    }
+
+    #[derive(Debug)]
+    struct DropCheck<'a> {
+        info: &'a DropInfo,
+        was_dropped: bool,
+    }
+
+    impl<'a> DropCheck<'a> {
+        fn new(info: &'a DropInfo) -> Self {
+            info.alive_count.fetch_add(1, SeqCst);
+
+            Self { info, was_dropped: false }
+        }
+    }
+
+    impl Drop for DropCheck<'_> {
+        fn drop(&mut self) {
+            if self.was_dropped {
+                self.info.dropped_twice.store(true, SeqCst);
+            }
+            self.was_dropped = true;
+
+            self.info.alive_count.fetch_sub(1, SeqCst);
+        }
+    }
+
+    fn iter(info: &DropInfo, len: usize, panic_at: usize) -> impl Iterator<Item = DropCheck<'_>> {
+        (0..len).map(move |i| {
+            if i == panic_at {
+                panic!("intended panic");
+            }
+            DropCheck::new(info)
+        })
+    }
+
+    #[track_caller]
+    fn check<const N: usize>(len: usize, panic_at: usize) {
+        check_drops(|info| {
+            iter(info, len, panic_at).map_windows(|_: &[_; N]| {}).last();
+        });
+    }
+
+    #[track_caller]
+    fn check_drops(f: impl FnOnce(&DropInfo)) {
+        let info = DropInfo::new();
+        let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
+            f(&info);
+        }));
+        info.check();
+    }
+
+    #[test]
+    fn no_iter_panic_n1() {
+        check::<1>(0, 100);
+        check::<1>(1, 100);
+        check::<1>(2, 100);
+        check::<1>(13, 100);
+    }
+
+    #[test]
+    fn no_iter_panic_n2() {
+        check::<2>(0, 100);
+        check::<2>(1, 100);
+        check::<2>(2, 100);
+        check::<2>(3, 100);
+        check::<2>(13, 100);
+    }
+
+    #[test]
+    fn no_iter_panic_n5() {
+        check::<5>(0, 100);
+        check::<5>(1, 100);
+        check::<5>(2, 100);
+        check::<5>(13, 100);
+        check::<5>(30, 100);
+    }
+
+    #[test]
+    fn panic_in_first_batch() {
+        check::<1>(7, 0);
+
+        check::<2>(7, 0);
+        check::<2>(7, 1);
+
+        check::<3>(7, 0);
+        check::<3>(7, 1);
+        check::<3>(7, 2);
+    }
+
+    #[test]
+    fn panic_in_middle() {
+        check::<1>(7, 1);
+        check::<1>(7, 5);
+        check::<1>(7, 6);
+
+        check::<2>(7, 2);
+        check::<2>(7, 5);
+        check::<2>(7, 6);
+
+        check::<5>(13, 5);
+        check::<5>(13, 8);
+        check::<5>(13, 12);
+    }
+
+    #[test]
+    fn len_equals_n() {
+        check::<1>(1, 100);
+        check::<1>(1, 0);
+
+        check::<2>(2, 100);
+        check::<2>(2, 0);
+        check::<2>(2, 1);
+
+        check::<5>(5, 100);
+        check::<5>(5, 0);
+        check::<5>(5, 1);
+        check::<5>(5, 4);
+    }
+}
+
+#[test]
+fn output_n1() {
+    assert_eq!("".chars().map_windows(|[c]| *c).collect::<Vec<_>>(), vec![]);
+    assert_eq!("x".chars().map_windows(|[c]| *c).collect::<Vec<_>>(), vec!['x']);
+    assert_eq!("abcd".chars().map_windows(|[c]| *c).collect::<Vec<_>>(), vec!['a', 'b', 'c', 'd']);
+}
+
+#[test]
+fn output_n2() {
+    assert_eq!(
+        "".chars().map_windows(|a: &[_; 2]| *a).collect::<Vec<_>>(),
+        <Vec<[char; 2]>>::new(),
+    );
+    assert_eq!("ab".chars().map_windows(|a: &[_; 2]| *a).collect::<Vec<_>>(), vec![['a', 'b']]);
+    assert_eq!(
+        "abcd".chars().map_windows(|a: &[_; 2]| *a).collect::<Vec<_>>(),
+        vec![['a', 'b'], ['b', 'c'], ['c', 'd']],
+    );
+}
+
+#[test]
+fn test_case_from_pr_82413_comment() {
+    for () in std::iter::repeat("0".to_owned()).map_windows(|_: &[_; 3]| {}).take(4) {}
+}
+
+#[test]
+#[should_panic = "array in `Iterator::map_windows` must contain more than 0 elements"]
+fn check_zero_window() {
+    let _ = std::iter::repeat(0).map_windows(|_: &[_; 0]| ());
+}
+
+#[test]
+fn test_zero_sized_type() {
+    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+    struct Data;
+    let data: Vec<_> =
+        std::iter::repeat(Data).take(10).map_windows(|arr: &[Data; 5]| *arr).collect();
+    assert_eq!(data, [[Data; 5]; 6]);
+}
+
+#[test]
+#[should_panic = "array size of `Iterator::map_windows` is too large"]
+fn test_too_large_array_size() {
+    let _ = std::iter::repeat(()).map_windows(|arr: &[(); usize::MAX]| *arr);
+}
+
+#[test]
+fn test_laziness() {
+    let counter = AtomicUsize::new(0);
+    let mut iter = (0..5)
+        .inspect(|_| {
+            counter.fetch_add(1, SeqCst);
+        })
+        .map_windows(|arr: &[i32; 2]| *arr);
+    assert_eq!(counter.load(SeqCst), 0);
+
+    assert_eq!(iter.next(), Some([0, 1]));
+    // The first iteration consumes N items (N = 2).
+    assert_eq!(counter.load(SeqCst), 2);
+
+    assert_eq!(iter.next(), Some([1, 2]));
+    assert_eq!(counter.load(SeqCst), 3);
+
+    assert_eq!(iter.next(), Some([2, 3]));
+    assert_eq!(counter.load(SeqCst), 4);
+
+    assert_eq!(iter.next(), Some([3, 4]));
+    assert_eq!(counter.load(SeqCst), 5);
+
+    assert_eq!(iter.next(), None);
+    assert_eq!(counter.load(SeqCst), 5);
+}
+
+#[test]
+fn test_size_hint() {
+    struct SizeHintCheckHelper((usize, Option<usize>));
+
+    impl Iterator for SizeHintCheckHelper {
+        type Item = i32;
+
+        fn next(&mut self) -> Option<i32> {
+            let (ref mut lo, ref mut hi) = self.0;
+            let next = (*hi != Some(0)).then_some(0);
+            *lo = lo.saturating_sub(1);
+            if let Some(hi) = hi {
+                *hi = hi.saturating_sub(1);
+            }
+            next
+        }
+
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            self.0
+        }
+    }
+
+    fn check_size_hint<const N: usize>(
+        size_hint: (usize, Option<usize>),
+        mut mapped_size_hint: (usize, Option<usize>),
+    ) {
+        let mut iter = SizeHintCheckHelper(size_hint);
+        let mut mapped_iter = iter.by_ref().map_windows(|_: &[_; N]| ());
+        while mapped_iter.size_hint().0 > 0 {
+            assert_eq!(mapped_iter.size_hint(), mapped_size_hint);
+            assert!(mapped_iter.next().is_some());
+            mapped_size_hint.0 -= 1;
+            mapped_size_hint.1 = mapped_size_hint.1.map(|hi| hi.saturating_sub(1));
+        }
+    }
+
+    check_size_hint::<1>((0, None), (0, None));
+    check_size_hint::<1>((0, Some(0)), (0, Some(0)));
+    check_size_hint::<1>((0, Some(2)), (0, Some(2)));
+    check_size_hint::<1>((1, None), (1, None));
+    check_size_hint::<1>((1, Some(1)), (1, Some(1)));
+    check_size_hint::<1>((1, Some(4)), (1, Some(4)));
+    check_size_hint::<1>((5, None), (5, None));
+    check_size_hint::<1>((5, Some(5)), (5, Some(5)));
+    check_size_hint::<1>((5, Some(10)), (5, Some(10)));
+
+    check_size_hint::<2>((0, None), (0, None));
+    check_size_hint::<2>((0, Some(0)), (0, Some(0)));
+    check_size_hint::<2>((0, Some(2)), (0, Some(1)));
+    check_size_hint::<2>((1, None), (0, None));
+    check_size_hint::<2>((1, Some(1)), (0, Some(0)));
+    check_size_hint::<2>((1, Some(4)), (0, Some(3)));
+    check_size_hint::<2>((5, None), (4, None));
+    check_size_hint::<2>((5, Some(5)), (4, Some(4)));
+    check_size_hint::<2>((5, Some(10)), (4, Some(9)));
+
+    check_size_hint::<5>((0, None), (0, None));
+    check_size_hint::<5>((0, Some(0)), (0, Some(0)));
+    check_size_hint::<5>((0, Some(2)), (0, Some(0)));
+    check_size_hint::<5>((1, None), (0, None));
+    check_size_hint::<5>((1, Some(1)), (0, Some(0)));
+    check_size_hint::<5>((1, Some(4)), (0, Some(0)));
+    check_size_hint::<5>((5, None), (1, None));
+    check_size_hint::<5>((5, Some(5)), (1, Some(1)));
+    check_size_hint::<5>((5, Some(10)), (1, Some(6)));
+}
diff --git a/library/core/tests/iter/adapters/mod.rs b/library/core/tests/iter/adapters/mod.rs
index ca3463aa7f7..dedb4c0a9dd 100644
--- a/library/core/tests/iter/adapters/mod.rs
+++ b/library/core/tests/iter/adapters/mod.rs
@@ -13,6 +13,7 @@ mod fuse;
 mod inspect;
 mod intersperse;
 mod map;
+mod map_windows;
 mod peekable;
 mod scan;
 mod skip;
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 897a5e9b870..7a6def37a55 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -105,11 +105,14 @@
 #![feature(const_slice_from_ref)]
 #![feature(waker_getters)]
 #![feature(slice_flatten)]
-#![feature(provide_any)]
+#![feature(error_generic_member_access)]
+#![feature(error_in_core)]
+#![feature(trait_upcasting)]
 #![feature(utf8_chunks)]
 #![feature(is_ascii_octdigit)]
 #![feature(get_many_mut)]
 #![feature(offset_of)]
+#![feature(iter_map_windows)]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(fuzzy_provenance_casts)]
 
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index be89afa32b3..b641e73f4f8 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -24,7 +24,6 @@
 #![feature(staged_api)]
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
-#![feature(local_key_cell_methods)]
 #![feature(maybe_uninit_write_slice)]
 #![feature(negative_impls)]
 #![feature(new_uninit)]
diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs
index 1b1f11798d7..d14d0b82229 100644
--- a/library/profiler_builtins/build.rs
+++ b/library/profiler_builtins/build.rs
@@ -6,6 +6,12 @@ use std::env;
 use std::path::Path;
 
 fn main() {
+    println!("cargo:rerun-if-env-changed=LLVM_PROFILER_RT_LIB");
+    if let Ok(rt) = env::var("LLVM_PROFILER_RT_LIB") {
+        println!("cargo:rustc-link-lib=static:+verbatim={rt}");
+        return;
+    }
+
     let target = env::var("TARGET").expect("TARGET was not set");
     let cfg = &mut cc::Build::new();
 
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 5b213555394..33c9c6e63c1 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -29,8 +29,8 @@ rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] }
 
 [target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies]
 miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
-addr2line = { version = "0.20.0", optional = true, default-features = false }
-object = { version = "0.31.1", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] }
+addr2line = { version = "0.21.0", optional = true, default-features = false }
+object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] }
 
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index d372fa64065..f67f6034d34 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -178,7 +178,8 @@ impl Iterator for Vars {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Vars {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Vars").finish_non_exhaustive()
+        let Self { inner: VarsOs { inner } } = self;
+        f.debug_struct("Vars").field("inner", &inner.str_debug()).finish()
     }
 }
 
@@ -196,7 +197,8 @@ impl Iterator for VarsOs {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for VarsOs {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("VarOs").finish_non_exhaustive()
+        let Self { inner } = self;
+        f.debug_struct("VarsOs").field("inner", inner).finish()
     }
 }
 
@@ -829,7 +831,8 @@ impl DoubleEndedIterator for Args {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Args {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Args").field("inner", &self.inner.inner).finish()
+        let Self { inner: ArgsOs { inner } } = self;
+        f.debug_struct("Args").field("inner", inner).finish()
     }
 }
 
@@ -870,7 +873,8 @@ impl DoubleEndedIterator for ArgsOs {
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for ArgsOs {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("ArgsOs").field("inner", &self.inner).finish()
+        let Self { inner } = self;
+        f.debug_struct("ArgsOs").field("inner", inner).finish()
     }
 }
 
@@ -890,6 +894,7 @@ pub mod consts {
     /// - aarch64
     /// - loongarch64
     /// - m68k
+    /// - csky
     /// - mips
     /// - mips64
     /// - powerpc
diff --git a/library/std/src/env/tests.rs b/library/std/src/env/tests.rs
index 94cace03af6..55869229581 100644
--- a/library/std/src/env/tests.rs
+++ b/library/std/src/env/tests.rs
@@ -95,8 +95,28 @@ fn args_debug() {
         format!("Args {{ inner: {:?} }}", args().collect::<Vec<_>>()),
         format!("{:?}", args())
     );
+}
+
+#[test]
+fn args_os_debug() {
     assert_eq!(
         format!("ArgsOs {{ inner: {:?} }}", args_os().collect::<Vec<_>>()),
         format!("{:?}", args_os())
     );
 }
+
+#[test]
+fn vars_debug() {
+    assert_eq!(
+        format!("Vars {{ inner: {:?} }}", vars().collect::<Vec<_>>()),
+        format!("{:?}", vars())
+    );
+}
+
+#[test]
+fn vars_os_debug() {
+    assert_eq!(
+        format!("VarsOs {{ inner: {:?} }}", vars_os().collect::<Vec<_>>()),
+        format!("{:?}", vars_os())
+    );
+}
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index ee5eddebfaf..7bc3af1793e 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -9,6 +9,8 @@ use crate::fmt::{self, Write};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::error::Error;
+#[unstable(feature = "error_generic_member_access", issue = "99301")]
+pub use core::error::{request_ref, Request};
 
 mod private {
     // This is a hack to prevent `type_id` from being overridden by `Error`
@@ -371,11 +373,10 @@ impl<E> Report<E> {
     ///
     /// ```rust
     /// #![feature(error_reporter)]
-    /// #![feature(provide_any)]
     /// #![feature(error_generic_member_access)]
     /// # use std::error::Error;
     /// # use std::fmt;
-    /// use std::any::Demand;
+    /// use std::error::Request;
     /// use std::error::Report;
     /// use std::backtrace::Backtrace;
     ///
@@ -405,8 +406,8 @@ impl<E> Report<E> {
     /// }
     ///
     /// impl Error for SuperErrorSideKick {
-    ///     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
-    ///         demand.provide_ref::<Backtrace>(&self.backtrace);
+    ///     fn provide<'a>(&'a self, request: &mut Request<'a>) {
+    ///         request.provide_ref::<Backtrace>(&self.backtrace);
     ///     }
     /// }
     ///
@@ -459,11 +460,11 @@ where
     fn backtrace(&self) -> Option<&Backtrace> {
         // have to grab the backtrace on the first error directly since that error may not be
         // 'static
-        let backtrace = (&self.error as &dyn Error).request_ref();
+        let backtrace = request_ref(&self.error);
         let backtrace = backtrace.or_else(|| {
             self.error
                 .source()
-                .map(|source| source.sources().find_map(|source| source.request_ref()))
+                .map(|source| source.sources().find_map(|source| request_ref(source)))
                 .flatten()
         });
         backtrace
diff --git a/library/std/src/error/tests.rs b/library/std/src/error/tests.rs
index ee999bd65c3..ed070a26b0c 100644
--- a/library/std/src/error/tests.rs
+++ b/library/std/src/error/tests.rs
@@ -1,6 +1,6 @@
 use super::Error;
 use crate::fmt;
-use core::any::Demand;
+use core::error::Request;
 
 #[derive(Debug, PartialEq)]
 struct A;
@@ -199,7 +199,7 @@ where
         self.source.as_deref()
     }
 
-    fn provide<'a>(&'a self, req: &mut Demand<'a>) {
+    fn provide<'a>(&'a self, req: &mut Request<'a>) {
         self.backtrace.as_ref().map(|bt| req.provide_ref::<Backtrace>(bt));
     }
 }
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 67e58fd1b86..43cecb19b14 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -110,12 +110,12 @@ impl crate::sealed::Sealed for OsString {}
 /// [conversions]: super#conversions
 #[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
 #[stable(feature = "rust1", since = "1.0.0")]
-// FIXME:
 // `OsStr::from_inner` current implementation relies
 // on `OsStr` being layout-compatible with `Slice`.
-// When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`.
-// Anyway, `OsStr` representation and layout are considered implementation details, are
-// not documented and must not be relied upon.
+// However, `OsStr` layout is considered an implementation detail and must not be relied upon. We
+// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
+// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
+#[cfg_attr(not(doc), repr(transparent))]
 pub struct OsStr {
     inner: Slice,
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 9038e8fa9d7..c07aa5cd91f 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -293,7 +293,6 @@
 #![feature(float_next_up_down)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
-#![feature(int_roundings)]
 #![feature(ip)]
 #![feature(ip_in_core)]
 #![feature(maybe_uninit_slice)]
@@ -307,7 +306,6 @@
 #![feature(pointer_is_aligned)]
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
-#![feature(provide_any)]
 #![feature(ptr_as_uninit)]
 #![feature(raw_os_nonzero)]
 #![feature(round_ties_even)]
diff --git a/library/std/src/os/l4re/raw.rs b/library/std/src/os/l4re/raw.rs
index b3f7439f8cd..12c0293285a 100644
--- a/library/std/src/os/l4re/raw.rs
+++ b/library/std/src/os/l4re/raw.rs
@@ -27,6 +27,7 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t};
 #[cfg(any(
     target_arch = "x86",
     target_arch = "m68k",
+    target_arch = "csky",
     target_arch = "powerpc",
     target_arch = "sparc",
     target_arch = "arm",
diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs
index 7c55e92502f..a568f9b26ba 100644
--- a/library/std/src/os/linux/raw.rs
+++ b/library/std/src/os/linux/raw.rs
@@ -27,6 +27,7 @@ pub use self::arch::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t};
 #[cfg(any(
     target_arch = "x86",
     target_arch = "m68k",
+    target_arch = "csky",
     target_arch = "powerpc",
     target_arch = "sparc",
     target_arch = "arm",
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 99f7a60f8ab..5842c096f1a 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1158,12 +1158,12 @@ impl FusedIterator for Ancestors<'_> {}
 /// Which method works best depends on what kind of situation you're in.
 #[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
 #[stable(feature = "rust1", since = "1.0.0")]
-// FIXME:
 // `PathBuf::as_mut_vec` current implementation relies
 // on `PathBuf` being layout-compatible with `Vec<u8>`.
-// When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`.
-// Anyway, `PathBuf` representation and layout are considered implementation detail, are
-// not documented and must not be relied upon.
+// However, `PathBuf` layout is considered an implementation detail and must not be relied upon. We
+// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
+// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
+#[cfg_attr(not(doc), repr(transparent))]
 pub struct PathBuf {
     inner: OsString,
 }
@@ -1983,12 +1983,12 @@ impl AsRef<OsStr> for PathBuf {
 /// ```
 #[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
 #[stable(feature = "rust1", since = "1.0.0")]
-// FIXME:
 // `Path::new` current implementation relies
 // on `Path` being layout-compatible with `OsStr`.
-// When attribute privacy is implemented, `Path` should be annotated as `#[repr(transparent)]`.
-// Anyway, `Path` representation and layout are considered implementation detail, are
-// not documented and must not be relied upon.
+// However, `Path` layout is considered an implementation detail and must not be relied upon. We
+// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
+// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
+#[cfg_attr(not(doc), repr(transparent))]
 pub struct Path {
     inner: OsStr,
 }
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f25ad2ece71..f54d5934175 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1530,10 +1530,19 @@ impl From<fs::File> for Stdio {
 // vs `_exit`.  Naming of Unix system calls is not standardised across Unices, so terminology is a
 // matter of convention and tradition.  For clarity we usually speak of `exit`, even when we might
 // mean an underlying system call such as `_exit`.
-#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(imp::ExitStatus);
 
+/// The default value is one which indicates successful completion.
+#[stable(feature = "process-exitcode-default", since = "CURRENT_RUSTC_VERSION")]
+impl Default for ExitStatus {
+    fn default() -> Self {
+        // Ideally this would be done by ExitCode::default().into() but that is complicated.
+        ExitStatus::from_inner(imp::ExitStatus::default())
+    }
+}
+
 /// Allows extension traits within `std`.
 #[unstable(feature = "sealed", issue = "none")]
 impl crate::sealed::Sealed for ExitStatus {}
diff --git a/library/std/src/sys/common/alloc.rs b/library/std/src/sys/common/alloc.rs
index 3ccea3ce0e3..d58aa6c27b8 100644
--- a/library/std/src/sys/common/alloc.rs
+++ b/library/std/src/sys/common/alloc.rs
@@ -8,6 +8,7 @@ use crate::ptr;
     target_arch = "x86",
     target_arch = "arm",
     target_arch = "m68k",
+    target_arch = "csky",
     target_arch = "mips",
     target_arch = "mips32r6",
     target_arch = "powerpc",
diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs
index e53dbae6119..c79197a9ad1 100644
--- a/library/std/src/sys/hermit/os.rs
+++ b/library/std/src/sys/hermit/os.rs
@@ -112,6 +112,34 @@ pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
 }
 
+// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+pub struct EnvStrDebug<'a> {
+    slice: &'a [(OsString, OsString)],
+}
+
+impl fmt::Debug for EnvStrDebug<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { slice } = self;
+        f.debug_list()
+            .entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
+            .finish()
+    }
+}
+
+impl Env {
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self { iter } = self;
+        EnvStrDebug { slice: iter.as_slice() }
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { iter } = self;
+        f.debug_list().entries(iter.as_slice()).finish()
+    }
+}
+
 impl !Send for Env {}
 impl !Sync for Env {}
 
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index dc9636ac8c9..e477a0cd7ab 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -67,6 +67,9 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // D0, D1
 ))]
 const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1
 
+#[cfg(target_arch = "csky")]
+const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1
+
 #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
 const UNWIND_DATA_REG: (i32, i32) = (3, 4); // R3, R4 / X3, X4
 
diff --git a/library/std/src/sys/sgx/os.rs b/library/std/src/sys/sgx/os.rs
index 5da0257f35d..86f4c7d3d56 100644
--- a/library/std/src/sys/sgx/os.rs
+++ b/library/std/src/sys/sgx/os.rs
@@ -96,14 +96,61 @@ fn create_env_store() -> &'static EnvStore {
     unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) }
 }
 
-pub type Env = vec::IntoIter<(OsString, OsString)>;
+pub struct Env {
+    iter: vec::IntoIter<(OsString, OsString)>,
+}
+
+// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+pub struct EnvStrDebug<'a> {
+    slice: &'a [(OsString, OsString)],
+}
+
+impl fmt::Debug for EnvStrDebug<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { slice } = self;
+        f.debug_list()
+            .entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
+            .finish()
+    }
+}
+
+impl Env {
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self { iter } = self;
+        EnvStrDebug { slice: iter.as_slice() }
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { iter } = self;
+        f.debug_list().entries(iter.as_slice()).finish()
+    }
+}
+
+impl !Send for Env {}
+impl !Sync for Env {}
+
+impl Iterator for Env {
+    type Item = (OsString, OsString);
+    fn next(&mut self) -> Option<(OsString, OsString)> {
+        self.iter.next()
+    }
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
 
 pub fn env() -> Env {
     let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
         map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
     };
 
-    get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default().into_iter()
+    let iter = get_env_store()
+        .map(|env| clone_to_vec(&env.lock().unwrap()))
+        .unwrap_or_default()
+        .into_iter();
+    Env { iter }
 }
 
 pub fn getenv(k: &OsStr) -> Option<OsString> {
diff --git a/library/std/src/sys/solid/os.rs b/library/std/src/sys/solid/os.rs
index 6135921f0b5..717c08434a8 100644
--- a/library/std/src/sys/solid/os.rs
+++ b/library/std/src/sys/solid/os.rs
@@ -85,6 +85,34 @@ pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
 }
 
+// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+pub struct EnvStrDebug<'a> {
+    slice: &'a [(OsString, OsString)],
+}
+
+impl fmt::Debug for EnvStrDebug<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { slice } = self;
+        f.debug_list()
+            .entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
+            .finish()
+    }
+}
+
+impl Env {
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self { iter } = self;
+        EnvStrDebug { slice: iter.as_slice() }
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { iter } = self;
+        f.debug_list().entries(iter.as_slice()).finish()
+    }
+}
+
 impl !Send for Env {}
 impl !Sync for Env {}
 
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index a68c14758ff..215f63d04f7 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -495,6 +495,34 @@ pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
 }
 
+// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+pub struct EnvStrDebug<'a> {
+    slice: &'a [(OsString, OsString)],
+}
+
+impl fmt::Debug for EnvStrDebug<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { slice } = self;
+        f.debug_list()
+            .entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
+            .finish()
+    }
+}
+
+impl Env {
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self { iter } = self;
+        EnvStrDebug { slice: iter.as_slice() }
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { iter } = self;
+        f.debug_list().entries(iter.as_slice()).finish()
+    }
+}
+
 impl !Send for Env {}
 impl !Sync for Env {}
 
diff --git a/library/std/src/sys/unsupported/os.rs b/library/std/src/sys/unsupported/os.rs
index e150ae143ad..248b34829f2 100644
--- a/library/std/src/sys/unsupported/os.rs
+++ b/library/std/src/sys/unsupported/os.rs
@@ -65,10 +65,26 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 pub struct Env(!);
 
+impl Env {
+    // FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self(inner) = self;
+        match *inner {}
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self(inner) = self;
+        match *inner {}
+    }
+}
+
 impl Iterator for Env {
     type Item = (OsString, OsString);
     fn next(&mut self) -> Option<(OsString, OsString)> {
-        self.0
+        let Self(inner) = self;
+        match *inner {}
     }
 }
 
diff --git a/library/std/src/sys/wasi/fd.rs b/library/std/src/sys/wasi/fd.rs
index 1b50c2ea6dd..d7295a799da 100644
--- a/library/std/src/sys/wasi/fd.rs
+++ b/library/std/src/sys/wasi/fd.rs
@@ -16,14 +16,20 @@ pub struct WasiFd {
 fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
     assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
     assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
-    // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
+    // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout.
+    // We decorate our `IoSliceMut` with `repr(transparent)` (see `io.rs`), and
+    // `crate::io::IoSliceMut` is a `repr(transparent)` wrapper around our type, so this is
+    // guaranteed.
     unsafe { mem::transmute(a) }
 }
 
 fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
     assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
     assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
-    // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
+    // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout.
+    // We decorate our `IoSlice` with `repr(transparent)` (see `io.rs`), and
+    // `crate::io::IoSlice` is a `repr(transparent)` wrapper around our type, so this is
+    // guaranteed.
     unsafe { mem::transmute(a) }
 }
 
diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs
index 197bdeda4fb..e0de284c5e2 100644
--- a/library/std/src/sys/wasi/os.rs
+++ b/library/std/src/sys/wasi/os.rs
@@ -142,10 +142,39 @@ impl StdError for JoinPathsError {
 pub fn current_exe() -> io::Result<PathBuf> {
     unsupported()
 }
+
 pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
 }
 
+// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+pub struct EnvStrDebug<'a> {
+    slice: &'a [(OsString, OsString)],
+}
+
+impl fmt::Debug for EnvStrDebug<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { slice } = self;
+        f.debug_list()
+            .entries(slice.iter().map(|(a, b)| (a.to_str().unwrap(), b.to_str().unwrap())))
+            .finish()
+    }
+}
+
+impl Env {
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self { iter } = self;
+        EnvStrDebug { slice: iter.as_slice() }
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { iter } = self;
+        f.debug_list().entries(iter.as_slice()).finish()
+    }
+}
+
 impl !Send for Env {}
 impl !Sync for Env {}
 
diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs
index d27b7a2e0f5..dbad425976a 100644
--- a/library/std/src/sys/wasi/thread.rs
+++ b/library/std/src/sys/wasi/thread.rs
@@ -20,9 +20,9 @@ cfg_if::cfg_if! {
             // https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108
             #[repr(C)]
             union pthread_attr_union {
-                __i: [ffi::c_int; if mem::size_of::<ffi::c_int>() == 8 { 14 } else { 9 }],
-                __vi: [ffi::c_int; if mem::size_of::<ffi::c_int>() == 8 { 14 } else { 9 }],
-                __s: [ffi::c_ulong; if mem::size_of::<ffi::c_int>() == 8 { 7 } else { 9 }],
+                __i: [ffi::c_int; if mem::size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
+                __vi: [ffi::c_int; if mem::size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
+                __s: [ffi::c_ulong; if mem::size_of::<ffi::c_long>() == 8 { 7 } else { 9 }],
             }
 
             #[repr(C)]
diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs
index d7adeb266ed..2329426ad1d 100644
--- a/library/std/src/sys/windows/os.rs
+++ b/library/std/src/sys/windows/os.rs
@@ -85,25 +85,69 @@ pub fn error_string(mut errnum: i32) -> String {
 
 pub struct Env {
     base: c::LPWCH,
-    cur: c::LPWCH,
+    iter: EnvIterator,
+}
+
+// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+pub struct EnvStrDebug<'a> {
+    iter: &'a EnvIterator,
+}
+
+impl fmt::Debug for EnvStrDebug<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { iter } = self;
+        let iter: EnvIterator = (*iter).clone();
+        let mut list = f.debug_list();
+        for (a, b) in iter {
+            list.entry(&(a.to_str().unwrap(), b.to_str().unwrap()));
+        }
+        list.finish()
+    }
+}
+
+impl Env {
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self { base: _, iter } = self;
+        EnvStrDebug { iter }
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self { base: _, iter } = self;
+        f.debug_list().entries(iter.clone()).finish()
+    }
 }
 
 impl Iterator for Env {
     type Item = (OsString, OsString);
 
     fn next(&mut self) -> Option<(OsString, OsString)> {
+        let Self { base: _, iter } = self;
+        iter.next()
+    }
+}
+
+#[derive(Clone)]
+struct EnvIterator(c::LPWCH);
+
+impl Iterator for EnvIterator {
+    type Item = (OsString, OsString);
+
+    fn next(&mut self) -> Option<(OsString, OsString)> {
+        let Self(cur) = self;
         loop {
             unsafe {
-                if *self.cur == 0 {
+                if **cur == 0 {
                     return None;
                 }
-                let p = self.cur as *const u16;
+                let p = *cur as *const u16;
                 let mut len = 0;
                 while *p.add(len) != 0 {
                     len += 1;
                 }
                 let s = slice::from_raw_parts(p, len);
-                self.cur = self.cur.add(len + 1);
+                *cur = cur.add(len + 1);
 
                 // Windows allows environment variables to start with an equals
                 // symbol (in any other position, this is the separator between
@@ -137,7 +181,7 @@ pub fn env() -> Env {
         if ch.is_null() {
             panic!("failure getting env string from OS: {}", io::Error::last_os_error());
         }
-        Env { base: ch, cur: ch }
+        Env { base: ch, iter: EnvIterator(ch) }
     }
 }
 
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 195d175cc9b..67db5ebd89c 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -459,6 +459,7 @@ impl Wtf8Buf {
     /// Converts this `Wtf8Buf` into a boxed `Wtf8`.
     #[inline]
     pub fn into_box(self) -> Box<Wtf8> {
+        // SAFETY: relies on `Wtf8` being `repr(transparent)`.
         unsafe { mem::transmute(self.bytes.into_boxed_slice()) }
     }
 
@@ -511,6 +512,7 @@ impl Extend<CodePoint> for Wtf8Buf {
 /// Similar to `&str`, but can additionally contain surrogate code points
 /// if they’re not in a surrogate pair.
 #[derive(Eq, Ord, PartialEq, PartialOrd)]
+#[repr(transparent)]
 pub struct Wtf8 {
     bytes: [u8],
 }
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 1b86d898cc7..21515adc6c4 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -313,7 +313,6 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::Cell;
     ///
     /// thread_local! {
@@ -326,7 +325,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     ///
     /// assert_eq!(X.get(), 123);
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn set(&'static self, value: T) {
         self.initialize_with(Cell::new(value), |value, cell| {
             if let Some(value) = value {
@@ -351,7 +350,6 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::Cell;
     ///
     /// thread_local! {
@@ -360,7 +358,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     ///
     /// assert_eq!(X.get(), 1);
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn get(&'static self) -> T
     where
         T: Copy,
@@ -381,7 +379,6 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::Cell;
     ///
     /// thread_local! {
@@ -391,7 +388,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// assert_eq!(X.take(), Some(1));
     /// assert_eq!(X.take(), None);
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn take(&'static self) -> T
     where
         T: Default,
@@ -412,7 +409,6 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::Cell;
     ///
     /// thread_local! {
@@ -422,7 +418,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
     /// assert_eq!(X.replace(2), 1);
     /// assert_eq!(X.replace(3), 2);
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn replace(&'static self, value: T) -> T {
         self.with(|cell| cell.replace(value))
     }
@@ -444,7 +440,6 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// # Example
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::RefCell;
     ///
     /// thread_local! {
@@ -453,7 +448,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert!(v.is_empty()));
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn with_borrow<F, R>(&'static self, f: F) -> R
     where
         F: FnOnce(&T) -> R,
@@ -476,7 +471,6 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// # Example
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::RefCell;
     ///
     /// thread_local! {
@@ -487,7 +481,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert_eq!(*v, vec![1]));
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn with_borrow_mut<F, R>(&'static self, f: F) -> R
     where
         F: FnOnce(&mut T) -> R,
@@ -511,7 +505,6 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::RefCell;
     ///
     /// thread_local! {
@@ -524,7 +517,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert_eq!(*v, vec![1, 2, 3]));
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn set(&'static self, value: T) {
         self.initialize_with(RefCell::new(value), |value, cell| {
             if let Some(value) = value {
@@ -551,7 +544,6 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::RefCell;
     ///
     /// thread_local! {
@@ -566,7 +558,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert!(v.is_empty()));
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn take(&'static self) -> T
     where
         T: Default,
@@ -586,7 +578,6 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(local_key_cell_methods)]
     /// use std::cell::RefCell;
     ///
     /// thread_local! {
@@ -598,7 +589,7 @@ impl<T: 'static> LocalKey<RefCell<T>> {
     ///
     /// X.with_borrow(|v| assert_eq!(*v, vec![1, 2, 3]));
     /// ```
-    #[unstable(feature = "local_key_cell_methods", issue = "92122")]
+    #[stable(feature = "local_key_cell_methods", since = "CURRENT_RUSTC_VERSION")]
     pub fn replace(&'static self, value: T) -> T {
         self.with(|cell| cell.replace(value))
     }
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index 521da6c4589..a2bfa8e96dd 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -54,6 +54,9 @@ pub const unwinder_private_data_size: usize = 2;
 #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))]
 pub const unwinder_private_data_size: usize = 2;
 
+#[cfg(target_arch = "csky")]
+pub const unwinder_private_data_size: usize = 2;
+
 #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))]
 pub const unwinder_private_data_size: usize = 2;
 
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 66d97a2a0d0..ecb58a0e9a5 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -479,9 +479,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.31.1"
+version = "0.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
+checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
 dependencies = [
  "memchr",
 ]
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 85eb543e48e..74b9a23fa4e 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -36,7 +36,7 @@ filetime = "0.2"
 cc = "1.0.69"
 libc = "0.2"
 hex = "0.4"
-object = { version = "0.31.1", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] }
+object = { version = "0.32.0", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] }
 serde = "1.0.137"
 # Directly use serde_derive rather than through the derive feature of serde to allow building both
 # in parallel and to allow serde_json and toml to start building as soon as serde has been built.
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 70079106689..f44a05a6b28 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -332,6 +332,7 @@ def default_build_triple(verbose):
         'i786': 'i686',
         'loongarch64': 'loongarch64',
         'm68k': 'm68k',
+        'csky': 'csky',
         'powerpc': 'powerpc',
         'powerpc64': 'powerpc64',
         'powerpc64le': 'powerpc64le',
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index cad370ad756..9c68e5a78d8 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -325,6 +325,10 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
         cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
     }
 
+    if let Some(path) = builder.config.profiler_path(target) {
+        cargo.env("LLVM_PROFILER_RT_LIB", path);
+    }
+
     // Determine if we're going to compile in optimized C intrinsics to
     // the `compiler-builtins` crate. These intrinsics live in LLVM's
     // `compiler-rt` repository, but our `src/llvm-project` submodule isn't
@@ -1384,6 +1388,16 @@ impl Step for Sysroot {
         let _ = fs::remove_dir_all(&sysroot);
         t!(fs::create_dir_all(&sysroot));
 
+        // In some cases(see https://github.com/rust-lang/rust/issues/109314), when the stage0
+        // compiler relies on more recent version of LLVM than the beta compiler, it may not
+        // be able to locate the correct LLVM in the sysroot. This situation typically occurs
+        // when we upgrade LLVM version while the beta compiler continues to use an older version.
+        //
+        // Make sure to add the correct version of LLVM into the stage0 sysroot.
+        if compiler.stage == 0 {
+            dist::maybe_install_llvm_target(builder, compiler.host, &sysroot);
+        }
+
         // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0.
         if builder.download_rustc() && compiler.stage != 0 {
             assert_eq!(
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 830c1a3b846..4821d20a898 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -534,7 +534,7 @@ pub struct Target {
     pub linker: Option<PathBuf>,
     pub ndk: Option<PathBuf>,
     pub sanitizers: Option<bool>,
-    pub profiler: Option<bool>,
+    pub profiler: Option<StringOrBool>,
     pub rpath: Option<bool>,
     pub crt_static: Option<bool>,
     pub musl_root: Option<PathBuf>,
@@ -863,9 +863,9 @@ define_config! {
     }
 }
 
-#[derive(Debug, Deserialize)]
+#[derive(Clone, Debug, Deserialize)]
 #[serde(untagged)]
-enum StringOrBool {
+pub enum StringOrBool {
     String(String),
     Bool(bool),
 }
@@ -876,6 +876,12 @@ impl Default for StringOrBool {
     }
 }
 
+impl StringOrBool {
+    fn is_string_or_true(&self) -> bool {
+        matches!(self, Self::String(_) | Self::Bool(true))
+    }
+}
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum RustOptimize {
     String(String),
@@ -1038,7 +1044,7 @@ define_config! {
         llvm_libunwind: Option<String> = "llvm-libunwind",
         android_ndk: Option<String> = "android-ndk",
         sanitizers: Option<bool> = "sanitizers",
-        profiler: Option<bool> = "profiler",
+        profiler: Option<StringOrBool> = "profiler",
         rpath: Option<bool> = "rpath",
         crt_static: Option<bool> = "crt-static",
         musl_root: Option<String> = "musl-root",
@@ -1957,12 +1963,24 @@ impl Config {
         self.target_config.values().any(|t| t.sanitizers == Some(true)) || self.sanitizers
     }
 
+    pub fn profiler_path(&self, target: TargetSelection) -> Option<&str> {
+        match self.target_config.get(&target)?.profiler.as_ref()? {
+            StringOrBool::String(s) => Some(s),
+            StringOrBool::Bool(_) => None,
+        }
+    }
+
     pub fn profiler_enabled(&self, target: TargetSelection) -> bool {
-        self.target_config.get(&target).map(|t| t.profiler).flatten().unwrap_or(self.profiler)
+        self.target_config
+            .get(&target)
+            .and_then(|t| t.profiler.as_ref())
+            .map(StringOrBool::is_string_or_true)
+            .unwrap_or(self.profiler)
     }
 
     pub fn any_profiler_enabled(&self) -> bool {
-        self.target_config.values().any(|t| t.profiler == Some(true)) || self.profiler
+        self.target_config.values().any(|t| matches!(&t.profiler, Some(p) if p.is_string_or_true()))
+            || self.profiler
     }
 
     pub fn rpath_enabled(&self, target: TargetSelection) -> bool {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index e3a9434a164..4396bbc51a3 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -138,7 +138,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
     (
         Some(Mode::Std),
         "target_arch",
-        Some(&["asmjs", "spirv", "nvptx", "xtensa", "mips32r6", "mips64r6"]),
+        Some(&["asmjs", "spirv", "nvptx", "xtensa", "mips32r6", "mips64r6", "csky"]),
     ),
     /* Extra names used by dependencies */
     // FIXME: Used by serde_json, but we should not be triggering on external dependencies.
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 4943f93fa9a..c841cb34036 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -299,7 +299,7 @@ impl Step for Llvm {
 
         let llvm_exp_targets = match builder.config.llvm_experimental_targets {
             Some(ref s) => s,
-            None => "AVR;M68k",
+            None => "AVR;M68k;CSKY",
         };
 
         let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" };
@@ -374,12 +374,12 @@ impl Step for Llvm {
             cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
         }
 
-        if target.starts_with("riscv")
+        if (target.starts_with("riscv") || target.starts_with("csky"))
             && !target.contains("freebsd")
             && !target.contains("openbsd")
             && !target.contains("netbsd")
         {
-            // RISC-V GCC erroneously requires linking against
+            // RISC-V and CSKY GCC erroneously requires linking against
             // `libatomic` when using 1-byte and 2-byte C++
             // atomics but the LLVM build system check cannot
             // detect this. Therefore it is set manually here.
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 87db964a15f..8bd8beb873b 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -63,6 +63,11 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
       uname -m >> $hash_key
 
       docker --version >> $hash_key
+
+      # Include cache version. Currently it is needed to bust Docker
+      # cache key after opting in into the old Docker build backend.
+      echo "1" >> $hash_key
+
       cksum=$(sha512sum $hash_key | \
         awk '{print $1}')
 
@@ -90,6 +95,12 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
         context="$script_dir"
     fi
     echo "::group::Building docker image for $image"
+
+    # As of August 2023, Github Actions have updated Docker to 23.X,
+    # which uses the BuildKit by default. It currently throws aways all
+    # intermediate layers, which breaks our usage of S3 layer caching.
+    # Therefore we opt-in to the old build backend for now.
+    export DOCKER_BUILDKIT=0
     retry docker \
       build \
       --rm \
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index f900a5eb576..2cc0bfd9db9 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -316,10 +316,10 @@ jobs:
       matrix:
         include:
           - name: mingw-check
-            <<: *job-linux-16c
+            <<: *job-linux-4c
 
           - name: mingw-check-tidy
-            <<: *job-linux-16c
+            <<: *job-linux-4c
 
           - name: x86_64-gnu-llvm-15
             <<: *job-linux-16c
diff --git a/src/doc/book b/src/doc/book
-Subproject 668c64760b5c7ea654facb4ba5fe9faddfda27c
+Subproject 72187f5cd0beaaa9c6f584156bcd88f921871e8
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 1e5556dd1b864109985d5871616ae6b9164bcea
+Subproject 99ad2847b865e96d8ae7b333d3ee96963557e62
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 302b995bcb24b70fd883980fd174738c3a10b70
+Subproject 388750b081c0893c275044d37203f97709e058b
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 9cd5c5a6ccbd4c07c65ab5c69a53286280308c9
+Subproject d43038932adeb16ada80e206d4c073d85129810
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 24eebb6df96d037aad285e4f7793bd0393a6687
+Subproject b123ab4754127d822ffb38349ce0fbf561f1b2f
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 817abbfaf26..94605e2a217 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -32,6 +32,7 @@
     - [\*-esp-espidf](platform-support/esp-idf.md)
     - [\*-unknown-fuchsia](platform-support/fuchsia.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
+    - [csky-unknown-linux-gnuabiv2](platform-support/csky-unknown-linux-gnuabiv2.md)
     - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md)
     - [loongarch\*-unknown-none\*](platform-support/loongarch-none.md)
     - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 4622148e869..f882a31de5a 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -584,7 +584,7 @@ See the [Symbol Mangling] chapter for details on symbol mangling and the manglin
 This instructs `rustc` to generate code specifically for a particular processor.
 
 You can run `rustc --print target-cpus` to see the valid options to pass
-and the default target CPU for the current buid target.
+and the default target CPU for the current build target.
 Each target has a default base CPU. Special values include:
 
 * `native` can be passed to use the processor of the host machine.
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 393719e7115..371ee378d1a 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -259,6 +259,7 @@ target | std | host | notes
 `avr-unknown-gnu-atmega328` | * |  | AVR. Requires `-Z build-std=core`
 `bpfeb-unknown-none` | * |  | BPF (big endian)
 `bpfel-unknown-none` | * |  | BPF (little endian)
+`csky-unknown-linux-gnuabiv2` | ✓ |  | C-SKY abiv2 Linux(little endian)
 `hexagon-unknown-linux-musl` | ? |  |
 `i386-apple-ios` | ✓ |  | 32-bit x86 iOS
 [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * |  | 32-bit x86 QNX Neutrino 7.0 RTOS |
diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
index 8fc5e6dd92b..8bc9381342d 100644
--- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
+++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
@@ -10,7 +10,7 @@ It's very small that there is no RwLock, no network, no stdin, and no file syste
 Some abbreviation:
 | Abbreviation | The full text | Description |
 |  ----  | ----  | ---- |
-| TEE | Trusted Execution Environment | ARM TrustZone devide the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. |
+| TEE | Trusted Execution Environment | ARM TrustZone divides the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. |
 | REE | Rich Execution Environment | The normal world. for example, Linux for Android phone is in REE side. |
 | TA | Trusted Application | The app run in TEE side system. |
 | CA | Client Application | The progress run in REE side system. |
diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
new file mode 100644
index 00000000000..e73598be0d9
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
@@ -0,0 +1,70 @@
+# `csky-unknown-linux-gnuabiv2`
+
+**Tier: 3**
+
+This target supports [C-SKY](https://github.com/c-sky) CPUs with `abi` v2 and `glibc`.
+
+https://c-sky.github.io/
+https://gitlab.com/c-sky/
+
+## Target maintainers
+
+* [@Dirreke](https://github.com/Dirreke)
+
+## Requirements
+
+
+## Building the target
+
+### Get a C toolchain
+
+Compiling rust for this target has been tested on `x86_64` linux hosts.  Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.
+
+If you don't already have a suitable toolchain, you can download from [here](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1619528643136/csky-linux-gnuabiv2-tools-x86_64-glibc-linux-4.9.56-20210423.tar.gz), and unpack it into a directory.
+
+### Configure rust
+
+The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`:
+
+```toml
+[build]
+target = ["x86_64-unknown-linux-gnu", "csky-unknown-linux-gnuabiv2"]
+stage = 2
+
+[target.csky-unknown-linux-gnuabiv2]
+# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
+cc = "${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc"
+
+### Build
+
+```sh
+# in rust dir
+./x.py build --stage 2
+```
+
+## Building and Running Rust programs
+
+To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-cskyv2`. This avoids having a full emulated ARM system by doing dynamic binary translation and dynamic system call translation.  It lets you run CSKY programs directly on your `x86_64` kernel.  It's very convenient!
+
+To use:
+
+* Install `qemu-cskyv2` (If you don't already have a qemu, you can download from [here](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1689324918932/xuantie-qemu-x86_64-Ubuntu-18.04-20230714-0202.tar.gz"), and unpack it into a directory.)
+* Link your built toolchain via:
+  * `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2`
+* Create a test program
+
+```sh
+cargo new hello_world
+cd hello_world
+```
+
+* Build and run
+
+```sh
+CARGO_TARGET_CSKY_UNKNOWN_LINUX_GNUABIV2_RUNNER=${QEMU_PATH}/bin/qemu-cskyv2 -L ${TOOLCHAIN_PATH}/csky-linux-gnuabiv2/libc \
+CARGO_TARGET_CSKY_UNKNOWN_LINUX_GNUABIV2_LINKER=${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc \
+RUSTFLAGS="-C target-features=+crt-static" \
+cargo +stage2 run --target csky-unknown-linux-gnuabiv2
+```
+
+Attention: The dynamic-linked program may nor be run by `qemu-cskyv2` but can be run on the target.
diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md
index 17e85590f2c..e8f55b8bfce 100644
--- a/src/doc/rustc/src/platform-support/loongarch-linux.md
+++ b/src/doc/rustc/src/platform-support/loongarch-linux.md
@@ -71,7 +71,7 @@ CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-
 AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \
 CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \
 # SET TARGET SYSTEM LIBRARY PATH
-CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRAY_PATH" \
+CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRARY_PATH" \
 cargo run --target loongarch64-unknown-linux-gnu --release
 ```
 Tested on x86 architecture, other architectures not tested.
diff --git a/src/doc/rustc/src/platform-support/netbsd.md b/src/doc/rustc/src/platform-support/netbsd.md
index 23f4488de6e..3891d6d3148 100644
--- a/src/doc/rustc/src/platform-support/netbsd.md
+++ b/src/doc/rustc/src/platform-support/netbsd.md
@@ -86,7 +86,7 @@ The Rust testsuite could presumably be run natively.
 
 For the systems where the maintainer can build natively, the rust
 compiler itself is re-built natively.  This involves the rust compiler
-being re-built with the newly self-built rust compiler, so excercises
+being re-built with the newly self-built rust compiler, so exercises
 the result quite extensively.
 
 Additionally, for some systems we build `librsvg`, and for the more
diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md
index 1a6f7bb834c..0fe9d4edaca 100644
--- a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md
+++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md
@@ -20,7 +20,7 @@ will fail to load on machines that do not support this.
 
 It should support the full standard library (`std` and `alloc` either with
 default or user-defined allocators). This target is probably most useful when
-targetted via cross-compilation (including from `x86_64-apple-darwin`), but if
+targeted via cross-compilation (including from `x86_64-apple-darwin`), but if
 built manually, the host tools work.
 
 It is similar to `x86_64-apple-darwin` in nearly all respects, although the
@@ -49,7 +49,7 @@ suite seems to work.
 
 Cross-compilation to this target from Apple hosts should generally work without
 much configuration, so long as XCode and the CommandLineTools are installed.
-Targetting it from non-Apple hosts is difficult, but no moreso than targetting
+Targeting it from non-Apple hosts is difficult, but no more so than targeting
 `x86_64-apple-darwin`.
 
 When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM
diff --git a/src/doc/unstable-book/src/compiler-flags/path-options.md b/src/doc/unstable-book/src/compiler-flags/path-options.md
index 0f2437020dd..0786ef1f166 100644
--- a/src/doc/unstable-book/src/compiler-flags/path-options.md
+++ b/src/doc/unstable-book/src/compiler-flags/path-options.md
@@ -1,6 +1,6 @@
 # `--print` Options
 
-The behavior of the `--print` flag can be modified by optionally be specifiying a filepath
+The behavior of the `--print` flag can be modified by optionally be specifying a filepath
 for each requested information kind, in the format `--print KIND=PATH`, just like for
 `--emit`. When a path is specified, information will be written there instead of to stdout.
 
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index c634dc50d6d..968c9bb4ebb 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -17,6 +17,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 - AVR
 - MSP430
 - M68k
+- CSKY
 - s390x
 
 ## Register classes
@@ -46,6 +47,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | M68k         | `reg`          | `d[0-7]`, `a[0-7]`                 | `r`                  |
 | M68k         | `reg_data`     | `d[0-7]`                           | `d`                  |
 | M68k         | `reg_addr`     | `a[0-3]`                           | `a`                  |
+| CSKY         | `reg`          | `r[0-31]`                          | `r`                  |
+| CSKY         | `freg`         | `f[0-31]`                          | `f`                  |
 | s390x        | `reg`          | `r[0-10]`, `r[12-14]`              | `r`                  |
 | s390x        | `freg`         | `f[0-15]`                          | `f`                  |
 
@@ -79,6 +82,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | MSP430       | `reg`                           | None           | `i8`, `i16`                             |
 | M68k         | `reg`, `reg_addr`               | None           | `i16`, `i32`                            |
 | M68k         | `reg_data`                      | None           | `i8`, `i16`, `i32`                      |
+| CSKY         | `reg`                           | None           | `i8`, `i16`, `i32`                      |
+| CSKY         | `freg`                          | None           | `f32`,                                  |
 | s390x        | `reg`                           | None           | `i8`, `i16`, `i32`, `i64`               |
 | s390x        | `freg`                          | None           | `f32`, `f64`                            |
 
@@ -102,6 +107,17 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | M68k         | `a5`          | `bp`      |
 | M68k         | `a6`          | `fp`      |
 | M68k         | `a7`          | `sp`, `usp`, `ssp`, `isp` |
+| CSKY         | `r[0-3]`      | `a[0-3]`  |
+| CSKY         | `r[4-11]`     | `l[0-7]`  |
+| CSKY         | `r[12-13]`    | `t[0-1]`  |
+| CSKY         | `r14`         | `sp`      |
+| CSKY         | `r15`         | `lr`      |
+| CSKY         | `r[16-17]`    | `l[8-9]`  |
+| CSKY         | `r[18-25]`    | `t[2-9]`  |
+| CSKY         | `r28`         | `rgb`     |
+| CSKY         | `r29`         | `rtb`     |
+| CSKY         | `r30`         | `svbr`    |
+| CSKY         | `r31`         | `tls`     |
 
 > **Notes**:
 > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed
@@ -123,6 +139,13 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | AVR          | `r0`, `r1`, `r1r0`                      | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs.  If modified, they must be restored to their original values before the end of the block. |
 |MSP430        | `r0`, `r2`, `r3`                        | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to.                          |
 | M68k         | `a4`, `a5`                              | Used internally by LLVM for the base pointer and global base pointer. |
+| CSKY         | `r7`, `r28`                             | Used internally by LLVM for the base pointer and global base pointer. |
+| CSKY         | `r8`                                    | Used internally by LLVM for the frame pointer. |
+| CSKY         | `r14`                                   | Used internally by LLVM for the stack pointer. |
+| CSKY         | `r15`                                   | This is the link register. |
+| CSKY         | `r[26-30]`                              | Reserved by its ABI.       |
+| CSKY         | `r31`                                   | This is the TLS register.  |
+
 
 ## Template modifiers
 
@@ -139,6 +162,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | PowerPC      | `freg`         | None     | `0`            | None          |
 | s390x        | `reg`          | None     | `%r0`          | None          |
 | s390x        | `freg`         | None     | `%f0`          | None          |
+| CSKY         | `reg`          | None     | `r0`           | None          |
+| CSKY         | `freg`         | None     | `f0`           | None          |
 
 # Flags covered by `preserves_flags`
 
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 83886dd42aa..7652f27e51c 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -519,6 +519,7 @@ impl<'a> fmt::Display for Display<'a> {
                         "asmjs" => "JavaScript",
                         "loongarch64" => "LoongArch LA64",
                         "m68k" => "M68k",
+                        "csky" => "CSKY",
                         "mips" => "MIPS",
                         "mips32r6" => "MIPS Release 6",
                         "mips64" => "MIPS-64",
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 384010034e6..2456e8818eb 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -9,7 +9,7 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, DefIdSet, LocalDefId};
+use rustc_hir::def_id::{DefId, DefIdSet, LocalModDefId};
 use rustc_hir::Mutability;
 use rustc_metadata::creader::{CStore, LoadedMacro};
 use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -138,7 +138,7 @@ pub(crate) fn try_inline(
 pub(crate) fn try_inline_glob(
     cx: &mut DocContext<'_>,
     res: Res,
-    current_mod: LocalDefId,
+    current_mod: LocalModDefId,
     visited: &mut DefIdSet,
     inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
     import: &hir::Item<'_>,
@@ -154,7 +154,7 @@ pub(crate) fn try_inline_glob(
             // reexported by the glob, e.g. because they are shadowed by something else.
             let reexports = cx
                 .tcx
-                .module_children_local(current_mod)
+                .module_children_local(current_mod.to_local_def_id())
                 .iter()
                 .filter(|child| !child.reexport_chain.is_empty())
                 .filter_map(|child| child.res.opt_def_id())
@@ -200,7 +200,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
     let fqn = if let ItemType::Macro = kind {
         // Check to see if it is a macro 2.0 or built-in macro
         if matches!(
-            CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.sess()),
+            CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.tcx),
             LoadedMacro::MacroDef(def, _)
                 if matches!(&def.kind, ast::ItemKind::MacroDef(ast_def)
                     if !ast_def.macro_rules)
@@ -680,7 +680,7 @@ fn build_macro(
     import_def_id: Option<DefId>,
     macro_kind: MacroKind,
 ) -> clean::ItemKind {
-    match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
+    match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
         LoadedMacro::MacroDef(item_def, _) => match macro_kind {
             MacroKind::Bang => {
                 if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index b6ba4c853d4..624f1620f2c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1551,7 +1551,7 @@ fn first_non_private<'tcx>(
         }
         [parent, leaf] if parent.ident.name == kw::Super => {
             let parent_mod = cx.tcx.parent_module(hir_id);
-            if let Some(super_parent) = cx.tcx.opt_local_parent(parent_mod) {
+            if let Some(super_parent) = cx.tcx.opt_local_parent(parent_mod.to_local_def_id()) {
                 (super_parent, leaf.ident)
             } else {
                 // If we can't find the parent of the parent, then the parent is already the crate.
@@ -2828,7 +2828,7 @@ fn clean_use_statement_inner<'tcx>(
     // The parent of the module in which this import resides. This
     // is the same as `current_mod` if that's already the top
     // level module.
-    let parent_mod = cx.tcx.parent_module_from_def_id(current_mod);
+    let parent_mod = cx.tcx.parent_module_from_def_id(current_mod.to_local_def_id());
 
     // This checks if the import can be seen from a higher level module.
     // In other words, it checks if the visibility is the equivalent of
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index eb5d3c88570..58022046294 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -604,7 +604,7 @@ fn generate_macro_def_id_path(
     }
     // Check to see if it is a macro 2.0 or built-in macro.
     // More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
-    let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx.sess) {
+    let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx) {
         LoadedMacro::MacroDef(def, _) => {
             // If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
             matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 88f8770029e..778609da062 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -100,6 +100,7 @@ static TARGETS: &[&str] = &[
     "i686-unknown-uefi",
     "loongarch64-unknown-linux-gnu",
     "m68k-unknown-linux-gnu",
+    "csky-unknown-linux-gnuabiv2",
     "mips-unknown-linux-gnu",
     "mips-unknown-linux-musl",
     "mips64-unknown-linux-gnuabi64",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject d78bbf4bde3c6b95caca7512f537c6f9721426f
+Subproject 7c3904d6c3ed54e8a413023519b55a536ad44d5
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index bc011a6c354..58c27855000 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -802,7 +802,8 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
         match parent.kind {
             ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
                 if child.hir_id == e.hir_id => true,
-            ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true,
+            ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar)
+                | ExprKind::Field(_, _) => true,
             _ => false,
         }
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 6d16d188754..930386a60aa 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -1038,7 +1038,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                 wild_in_or_pats::check(cx, arms);
             }
 
-            if source == MatchSource::TryDesugar {
+            if let MatchSource::TryDesugar(_) = source {
                 try_err::check(cx, expr, ex);
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/try_err.rs b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
index 99a748489b4..0fd6f533db0 100644
--- a/src/tools/clippy/clippy_lints/src/matches/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
@@ -80,7 +80,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
 
 /// Finds function return type by examining return expressions in match arms.
 fn find_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> Option<Ty<'tcx>> {
-    if let ExprKind::Match(_, arms, MatchSource::TryDesugar) = expr {
+    if let ExprKind::Match(_, arms, MatchSource::TryDesugar(_)) = expr {
         for arm in *arms {
             if let ExprKind::Ret(Some(ret)) = arm.body.kind {
                 return Some(cx.typeck_results().expr_ty(ret));
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
index 7eb325ee7b5..eb4f003d38a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
@@ -64,7 +64,7 @@ pub(super) fn check(
                     ExprKind::Path(QPath::LangItem(rustc_hir::LangItem::TryTraitBranch, _, _))
                 ),
                 ExprKind::MethodCall(_, self_arg, ..) if expr.hir_id == self_arg.hir_id => true,
-                ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
+                ExprKind::Match(_, _, MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar)
                 | ExprKind::Field(..)
                 | ExprKind::Index(..) => true,
                 _ => false,
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 41986551da4..7016ad0a80f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -236,7 +236,7 @@ fn indirect_usage<'tcx>(
             !matches!(
                 node,
                 Node::Expr(Expr {
-                    kind: ExprKind::Match(.., MatchSource::TryDesugar),
+                    kind: ExprKind::Match(.., MatchSource::TryDesugar(_)),
                     ..
                 })
             )
diff --git a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
index e2a7ba02a04..7b0f7eaf1f0 100644
--- a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
@@ -122,7 +122,7 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
         } else {
             return;
         };
-        if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar) = &arg.kind;
+        if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar(_)) = &arg.kind;
         if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind;
         if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)) = &called.kind;
         if expr.span.ctxt() == inner_expr.span.ctxt();
diff --git a/src/tools/clippy/clippy_lints/src/question_mark_used.rs b/src/tools/clippy/clippy_lints/src/question_mark_used.rs
index ff66b8a0095..d0de33e3c4f 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark_used.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark_used.rs
@@ -34,7 +34,7 @@ declare_lint_pass!(QuestionMarkUsed => [QUESTION_MARK_USED]);
 
 impl<'tcx> LateLintPass<'tcx> for QuestionMarkUsed {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let ExprKind::Match(_, _, MatchSource::TryDesugar) = expr.kind {
+        if let ExprKind::Match(_, _, MatchSource::TryDesugar(_)) = expr.kind {
             if !span_is_local(expr.span) {
                 return;
             }
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index 4e3efe97b8c..fc49b58e0a7 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -52,7 +52,7 @@ impl ReturnVisitor {
 
 impl<'tcx> Visitor<'tcx> for ReturnVisitor {
     fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
-        if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar) = ex.kind {
+        if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
             self.found_return = true;
         } else {
             hir_visit::walk_expr(self, ex);
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 351bacf5691..d6b9a49d2fe 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
         if !in_external_macro(cx.sess(), stmt.span)
             && let StmtKind::Semi(expr) = stmt.kind
             && let ExprKind::Ret(Some(ret)) = expr.kind
-            && let ExprKind::Match(.., MatchSource::TryDesugar) = ret.kind
+            && let ExprKind::Match(.., MatchSource::TryDesugar(_)) = ret.kind
             // Ensure this is not the final stmt, otherwise removing it would cause a compile error
             && let OwnerNode::Item(item) = cx.tcx.hir().owner(cx.tcx.hir().get_parent_item(expr.hir_id))
             && let ItemKind::Fn(_, _, body) = item.kind
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
index dd120599c04..462b1aa8153 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
@@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
             if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) {
                 !matches!(
                     &arg.kind,
-                    ExprKind::Match(.., MatchSource::TryDesugar) | ExprKind::Path(..)
+                    ExprKind::Match(.., MatchSource::TryDesugar(_)) | ExprKind::Path(..)
                 )
             } else {
                 false
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 92b694d3076..bd4dc07a42b 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
         }
 
         match e.kind {
-            ExprKind::Match(_, arms, MatchSource::TryDesugar) => {
+            ExprKind::Match(_, arms, MatchSource::TryDesugar(_)) => {
                 let (ExprKind::Ret(Some(e)) | ExprKind::Break(_, Some(e))) = arms[0].body.kind else {
                     return;
                 };
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 60fab1ec41a..6be8b8bb916 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -149,7 +149,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
             (Pat::Str("for"), Pat::Str("}"))
         },
         ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str("match"), Pat::Str("}")),
-        ExprKind::Match(e, _, MatchSource::TryDesugar) => (expr_search_pat(tcx, e).0, Pat::Str("?")),
+        ExprKind::Match(e, _, MatchSource::TryDesugar(_)) => (expr_search_pat(tcx, e).0, Pat::Str("?")),
         ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {
             (expr_search_pat(tcx, e).0, Pat::Str("await"))
         },
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 171b7faf219..6c4cec59524 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -83,7 +83,7 @@ use rustc_ast::Attribute;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
 use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
@@ -1765,7 +1765,7 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
 
     if let ExprKind::Match(_, arms, ref source) = expr.kind {
         // desugared from a `?` operator
-        if *source == MatchSource::TryDesugar {
+        if let MatchSource::TryDesugar(_) = *source {
             return Some(expr);
         }
 
@@ -2370,11 +2370,11 @@ pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
     false
 }
 
-static TEST_ITEM_NAMES_CACHE: OnceLock<Mutex<FxHashMap<LocalDefId, Vec<Symbol>>>> = OnceLock::new();
+static TEST_ITEM_NAMES_CACHE: OnceLock<Mutex<FxHashMap<LocalModDefId, Vec<Symbol>>>> = OnceLock::new();
 
-fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalDefId, f: impl Fn(&[Symbol]) -> bool) -> bool {
+fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Symbol]) -> bool) -> bool {
     let cache = TEST_ITEM_NAMES_CACHE.get_or_init(|| Mutex::new(FxHashMap::default()));
-    let mut map: MutexGuard<'_, FxHashMap<LocalDefId, Vec<Symbol>>> = cache.lock().unwrap();
+    let mut map: MutexGuard<'_, FxHashMap<LocalModDefId, Vec<Symbol>>> = cache.lock().unwrap();
     let value = map.entry(module);
     match value {
         Entry::Occupied(entry) => f(entry.get()),
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 4c695cb9b6e..139e31bc528 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -415,7 +415,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
 
         if !matches!(
             impl_src,
-            ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(ty::BoundConstness::ConstIfConst, _)
+            ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(_)
         ) {
             return false;
         }
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index f83988a6e32..3b47a451345 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -161,7 +161,7 @@ pub fn for_each_expr_with_closures<'tcx, B, C: Continue>(
 /// returns `true` if expr contains match expr desugared from try
 fn contains_try(expr: &hir::Expr<'_>) -> bool {
     for_each_expr(expr, |e| {
-        if matches!(e.kind, hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar)) {
+        if matches!(e.kind, hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) {
             ControlFlow::Break(())
         } else {
             ControlFlow::Continue(())
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs
index 0b171f21d0c..c545434efe5 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.rs
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs
@@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
     };
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
+        // FIXME: should emit "this `if` has identical blocks"
         Ok("foo")?;
     } else {
         Ok("foo")?;
diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
index 56e5f3e45b2..37fe787d1de 100644
--- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr
+++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr
@@ -83,25 +83,6 @@ LL | |     };
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:100:13
-   |
-LL |       if true {
-   |  _____________^
-LL | |
-LL | |         Ok("foo")?;
-LL | |     } else {
-   | |_____^
-   |
-note: same as this
-  --> $DIR/if_same_then_else2.rs:103:12
-   |
-LL |       } else {
-   |  ____________^
-LL | |         Ok("foo")?;
-LL | |     }
-   | |_____^
-
-error: this `if` has identical blocks
   --> $DIR/if_same_then_else2.rs:124:20
    |
 LL |       } else if true {
@@ -122,5 +103,5 @@ LL | |         return Ok(&foo[0..]);
 LL | |     }
    | |_____^
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 0e50618ad9e..d57da574315 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -7,7 +7,6 @@
 #![feature(variant_count)]
 #![feature(yeet_expr)]
 #![feature(nonzero_ops)]
-#![feature(local_key_cell_methods)]
 #![feature(round_ties_even)]
 #![feature(os_str_bytes)]
 #![feature(lint_reasons)]
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index f8806794979..a2b263cf2d8 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1196,9 +1196,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.31.1"
+version = "0.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
+checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
 dependencies = [
  "memchr",
 ]
@@ -1337,7 +1337,7 @@ name = "proc-macro-api"
 version = "0.0.0"
 dependencies = [
  "memmap2",
- "object 0.31.1",
+ "object 0.32.0",
  "paths",
  "profile",
  "serde",
@@ -1357,7 +1357,7 @@ dependencies = [
  "libloading",
  "mbe",
  "memmap2",
- "object 0.31.1",
+ "object 0.32.0",
  "paths",
  "proc-macro-api",
  "proc-macro-test",
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs
index 19bfd294b25..62bdb6ee688 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs
@@ -42,10 +42,11 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
     };
 }
 
-const KNOWN_ARCH: [&str; 19] = [
+const KNOWN_ARCH: [&str; 20] = [
     "aarch64",
     "arm",
     "avr",
+    "csky",
     "hexagon",
     "mips",
     "mips64",
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
index 4e39167136b..4229f289130 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
@@ -12,7 +12,7 @@ rust-version.workspace = true
 doctest = false
 
 [dependencies]
-object = { version = "0.31.0", default-features = false, features = [
+object = { version = "0.32.0", default-features = false, features = [
     "std",
     "read_core",
     "elf",
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index ecc6aaa0ac7..99993f16e27 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -12,7 +12,7 @@ rust-version.workspace = true
 doctest = false
 
 [dependencies]
-object = { version = "0.31.0", default-features = false, features = [
+object = { version = "0.32.0", default-features = false, features = [
     "std",
     "read_core",
     "elf",
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index a9ab696cdf4..410852b6a31 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -258,6 +258,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "termize",
     "thin-vec",
     "thiserror",
+    "thiserror-core",
+    "thiserror-core-impl",
     "thiserror-impl",
     "thorin-dwp",
     "thread_local",
diff --git a/tests/rustdoc-gui/search-tab.goml b/tests/rustdoc-gui/search-tab.goml
index 2223598f029..7bbde3ec23d 100644
--- a/tests/rustdoc-gui/search-tab.goml
+++ b/tests/rustdoc-gui/search-tab.goml
@@ -40,37 +40,37 @@ define-function: (
 
 call-function: ("check-colors", {
     "theme": "ayu",
-    "background": "rgba(0, 0, 0, 0)",
-    "background_selected": "rgb(20, 25, 32)",
-    "background_hover": "rgba(0, 0, 0, 0)",
-    "border_bottom": "0px none rgb(197, 197, 197)",
-    "border_bottom_selected": "1px solid rgb(255, 180, 76)",
+    "background": "transparent",
+    "background_selected": "#141920",
+    "background_hover": "transparent",
+    "border_bottom": "0px none #c5c5c5",
+    "border_bottom_selected": "1px solid #ffb44c",
     "border_bottom_hover": "1px solid rgba(242, 151, 24, 0.3)",
-    "border_top": "0px none rgb(197, 197, 197)",
-    "border_top_selected": "0px none rgb(197, 197, 197)",
-    "border_top_hover": "0px none rgb(197, 197, 197)",
+    "border_top": "0px none #c5c5c5",
+    "border_top_selected": "0px none #c5c5c5",
+    "border_top_hover": "0px none #c5c5c5",
 })
 call-function: ("check-colors", {
     "theme": "dark",
-    "background": "rgb(37, 37, 37)",
-    "background_selected": "rgb(53, 53, 53)",
-    "background_hover": "rgb(53, 53, 53)",
-    "border_bottom": "0px none rgb(221, 221, 221)",
-    "border_bottom_selected": "0px none rgb(221, 221, 221)",
-    "border_bottom_hover": "0px none rgb(221, 221, 221)",
-    "border_top": "2px solid rgb(37, 37, 37)",
-    "border_top_selected": "2px solid rgb(0, 137, 255)",
-    "border_top_hover": "2px solid rgb(0, 137, 255)",
+    "background": "#252525",
+    "background_selected": "#353535",
+    "background_hover": "#353535",
+    "border_bottom": "0px none #ddd",
+    "border_bottom_selected": "0px none #ddd",
+    "border_bottom_hover": "0px none #ddd",
+    "border_top": "2px solid #252525",
+    "border_top_selected": "2px solid #0089ff",
+    "border_top_hover": "2px solid #0089ff",
 })
 call-function: ("check-colors", {
     "theme": "light",
-    "background": "rgb(230, 230, 230)",
-    "background_selected": "rgb(255, 255, 255)",
-    "background_hover": "rgb(255, 255, 255)",
-    "border_bottom": "0px none rgb(0, 0, 0)",
-    "border_bottom_selected": "0px none rgb(0, 0, 0)",
-    "border_bottom_hover": "0px none rgb(0, 0, 0)",
-    "border_top": "2px solid rgb(230, 230, 230)",
-    "border_top_selected": "2px solid rgb(0, 137, 255)",
-    "border_top_hover": "2px solid rgb(0, 137, 255)",
+    "background": "#e6e6e6",
+    "background_selected": "#fff",
+    "background_hover": "#fff",
+    "border_bottom": "0px none #000",
+    "border_bottom_selected": "0px none #000",
+    "border_bottom_hover": "0px none #000",
+    "border_top": "2px solid #e6e6e6",
+    "border_top_selected": "2px solid #0089ff",
+    "border_top_hover": "2px solid #0089ff",
 })
diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml
index cec1a799926..079d582a567 100644
--- a/tests/rustdoc-gui/sidebar-links-color.goml
+++ b/tests/rustdoc-gui/sidebar-links-color.goml
@@ -92,80 +92,80 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "struct": "rgb(83, 177, 219)",
-        "struct_hover": "rgb(255, 180, 76)",
-        "struct_hover_background": "rgba(0, 0, 0, 0)",
-        "enum": "rgb(83, 177, 219)",
-        "enum_hover": "rgb(255, 180, 76)",
-        "enum_hover_background": "rgba(0, 0, 0, 0)",
-        "union": "rgb(83, 177, 219)",
-        "union_hover": "rgb(255, 180, 76)",
-        "union_hover_background": "rgba(0, 0, 0, 0)",
-        "trait": "rgb(83, 177, 219)",
-        "trait_hover": "rgb(255, 180, 76)",
-        "trait_hover_background": "rgba(0, 0, 0, 0)",
-        "fn": "rgb(83, 177, 219)",
-        "fn_hover": "rgb(255, 180, 76)",
-        "fn_hover_background": "rgba(0, 0, 0, 0)",
-        "type": "rgb(83, 177, 219)",
-        "type_hover": "rgb(255, 180, 76)",
-        "type_hover_background": "rgba(0, 0, 0, 0)",
-        "keyword": "rgb(83, 177, 219)",
-        "keyword_hover": "rgb(255, 180, 76)",
-        "keyword_hover_background": "rgba(0, 0, 0, 0)",
+        "struct": "#53b1db",
+        "struct_hover": "#ffb44c",
+        "struct_hover_background": "transparent",
+        "enum": "#53b1db",
+        "enum_hover": "#ffb44c",
+        "enum_hover_background": "transparent",
+        "union": "#53b1db",
+        "union_hover": "#ffb44c",
+        "union_hover_background": "transparent",
+        "trait": "#53b1db",
+        "trait_hover": "#ffb44c",
+        "trait_hover_background": "transparent",
+        "fn": "#53b1db",
+        "fn_hover": "#ffb44c",
+        "fn_hover_background": "transparent",
+        "type": "#53b1db",
+        "type_hover": "#ffb44c",
+        "type_hover_background": "transparent",
+        "keyword": "#53b1db",
+        "keyword_hover": "#ffb44c",
+        "keyword_hover_background": "transparent",
     }
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "struct": "rgb(253, 191, 53)",
-        "struct_hover": "rgb(253, 191, 53)",
-        "struct_hover_background": "rgb(68, 68, 68)",
-        "enum": "rgb(253, 191, 53)",
-        "enum_hover": "rgb(253, 191, 53)",
-        "enum_hover_background": "rgb(68, 68, 68)",
-        "union": "rgb(253, 191, 53)",
-        "union_hover": "rgb(253, 191, 53)",
-        "union_hover_background": "rgb(68, 68, 68)",
-        "trait": "rgb(253, 191, 53)",
-        "trait_hover": "rgb(253, 191, 53)",
-        "trait_hover_background": "rgb(68, 68, 68)",
-        "fn": "rgb(253, 191, 53)",
-        "fn_hover": "rgb(253, 191, 53)",
-        "fn_hover_background": "rgb(68, 68, 68)",
-        "type": "rgb(253, 191, 53)",
-        "type_hover": "rgb(253, 191, 53)",
-        "type_hover_background": "rgb(68, 68, 68)",
-        "keyword": "rgb(253, 191, 53)",
-        "keyword_hover": "rgb(253, 191, 53)",
-        "keyword_hover_background": "rgb(68, 68, 68)",
+        "struct": "#fdbf35",
+        "struct_hover": "#fdbf35",
+        "struct_hover_background": "#444",
+        "enum": "#fdbf35",
+        "enum_hover": "#fdbf35",
+        "enum_hover_background": "#444",
+        "union": "#fdbf35",
+        "union_hover": "#fdbf35",
+        "union_hover_background": "#444",
+        "trait": "#fdbf35",
+        "trait_hover": "#fdbf35",
+        "trait_hover_background": "#444",
+        "fn": "#fdbf35",
+        "fn_hover": "#fdbf35",
+        "fn_hover_background": "#444",
+        "type": "#fdbf35",
+        "type_hover": "#fdbf35",
+        "type_hover_background": "#444",
+        "keyword": "#fdbf35",
+        "keyword_hover": "#fdbf35",
+        "keyword_hover_background": "#444",
     }
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "struct": "rgb(53, 109, 164)",
-        "struct_hover": "rgb(53, 109, 164)",
-        "struct_hover_background": "rgb(255, 255, 255)",
-        "enum": "rgb(53, 109, 164)",
-        "enum_hover": "rgb(53, 109, 164)",
-        "enum_hover_background": "rgb(255, 255, 255)",
-        "union": "rgb(53, 109, 164)",
-        "union_hover": "rgb(53, 109, 164)",
-        "union_hover_background": "rgb(255, 255, 255)",
-        "trait": "rgb(53, 109, 164)",
-        "trait_hover": "rgb(53, 109, 164)",
-        "trait_hover_background": "rgb(255, 255, 255)",
-        "fn": "rgb(53, 109, 164)",
-        "fn_hover": "rgb(53, 109, 164)",
-        "fn_hover_background": "rgb(255, 255, 255)",
-        "type": "rgb(53, 109, 164)",
-        "type_hover": "rgb(53, 109, 164)",
-        "type_hover_background": "rgb(255, 255, 255)",
-        "keyword": "rgb(53, 109, 164)",
-        "keyword_hover": "rgb(53, 109, 164)",
-        "keyword_hover_background": "rgb(255, 255, 255)",
+        "struct": "#356da4",
+        "struct_hover": "#356da4",
+        "struct_hover_background": "#fff",
+        "enum": "#356da4",
+        "enum_hover": "#356da4",
+        "enum_hover_background": "#fff",
+        "union": "#356da4",
+        "union_hover": "#356da4",
+        "union_hover_background": "#fff",
+        "trait": "#356da4",
+        "trait_hover": "#356da4",
+        "trait_hover_background": "#fff",
+        "fn": "#356da4",
+        "fn_hover": "#356da4",
+        "fn_hover_background": "#fff",
+        "type": "#356da4",
+        "type_hover": "#356da4",
+        "type_hover_background": "#fff",
+        "keyword": "#356da4",
+        "keyword_hover": "#356da4",
+        "keyword_hover_background": "#fff",
     }
 )
diff --git a/tests/rustdoc-gui/unsafe-fn.goml b/tests/rustdoc-gui/unsafe-fn.goml
index 51007b653d9..8d26f15f37f 100644
--- a/tests/rustdoc-gui/unsafe-fn.goml
+++ b/tests/rustdoc-gui/unsafe-fn.goml
@@ -23,6 +23,6 @@ define-function: (
     },
 )
 
-call-function: ("sup-check", ("dark", "rgb(221, 221, 221)"))
-call-function: ("sup-check", ("ayu", "rgb(197, 197, 197)"))
-call-function: ("sup-check", ("light", "rgb(0, 0, 0)"))
+call-function: ("sup-check", ("ayu", "#c5c5c5"))
+call-function: ("sup-check", ("dark", "#ddd"))
+call-function: ("sup-check", ("light", "black"))
diff --git a/tests/ui/asm/issue-113788.rs b/tests/ui/asm/issue-113788.rs
new file mode 100644
index 00000000000..903b444767f
--- /dev/null
+++ b/tests/ui/asm/issue-113788.rs
@@ -0,0 +1,7 @@
+// test that "error: arguments for inline assembly must be copyable" doesn't show up in this code
+// needs-asm-support
+// only-x86_64
+fn main() {
+    let peb: *const PEB; //~ ERROR cannot find type `PEB` in this scope [E0412]
+    unsafe { std::arch::asm!("mov {0}, fs:[0x30]", out(reg) peb); }
+}
diff --git a/tests/ui/asm/issue-113788.stderr b/tests/ui/asm/issue-113788.stderr
new file mode 100644
index 00000000000..f8e65b6f538
--- /dev/null
+++ b/tests/ui/asm/issue-113788.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `PEB` in this scope
+  --> $DIR/issue-113788.rs:5:21
+   |
+LL |     let peb: *const PEB;
+   |                     ^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
index 554ac673d51..ab675d0a1a6 100644
--- a/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
+++ b/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
@@ -49,13 +49,11 @@ async fn foo8() -> Result<(), ()> {
     Ok(())
 }
 fn foo9() -> Result<(), ()> {
-    let _ = await bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
+    let _ = await bar(); //~ ERROR incorrect use of `await`
     Ok(())
 }
 fn foo10() -> Result<(), ()> {
-    let _ = await? bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
+    let _ = await? bar(); //~ ERROR incorrect use of `await`
     Ok(())
 }
 fn foo11() -> Result<(), ()> {
@@ -63,8 +61,7 @@ fn foo11() -> Result<(), ()> {
     Ok(())
 }
 fn foo12() -> Result<(), ()> {
-    let _ = (await bar())?; //~ ERROR `await` is only allowed inside `async` functions and blocks
-    //~^ ERROR incorrect use of `await`
+    let _ = (await bar())?; //~ ERROR incorrect use of `await`
     Ok(())
 }
 fn foo13() -> Result<(), ()> {
@@ -111,7 +108,6 @@ async fn foo27() -> Result<(), ()> {
 fn foo28() -> Result<(), ()> {
     fn foo() -> Result<(), ()> {
         let _ = await!(bar())?; //~ ERROR incorrect use of `await`
-        //~^ ERROR `await` is only allowed inside `async` functions
         Ok(())
     }
     foo()
@@ -119,7 +115,6 @@ fn foo28() -> Result<(), ()> {
 fn foo29() -> Result<(), ()> {
     let foo = || {
         let _ = await!(bar())?; //~ ERROR incorrect use of `await`
-        //~^ ERROR `await` is only allowed inside `async` functions
         Ok(())
     };
     foo()
diff --git a/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
index 7b03e56662a..928eb0b821d 100644
--- a/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
+++ b/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
@@ -59,61 +59,61 @@ LL |     let _ = await bar();
    |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:57:13
+  --> $DIR/incorrect-syntax-suggestions.rs:56:13
    |
 LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:62:13
+  --> $DIR/incorrect-syntax-suggestions.rs:60:13
    |
 LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:66:14
+  --> $DIR/incorrect-syntax-suggestions.rs:64:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:71:24
+  --> $DIR/incorrect-syntax-suggestions.rs:68:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:76:24
+  --> $DIR/incorrect-syntax-suggestions.rs:73:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:104:13
+  --> $DIR/incorrect-syntax-suggestions.rs:101:13
    |
 LL |     let _ = await!(bar());
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:108:13
+  --> $DIR/incorrect-syntax-suggestions.rs:105:13
    |
 LL |     let _ = await!(bar())?;
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:113:17
+  --> $DIR/incorrect-syntax-suggestions.rs:110:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:121:17
+  --> $DIR/incorrect-syntax-suggestions.rs:117:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: expected expression, found `=>`
-  --> $DIR/incorrect-syntax-suggestions.rs:129:25
+  --> $DIR/incorrect-syntax-suggestions.rs:124:25
    |
 LL |     match await { await => () }
    |                   ----- ^^ expected expression
@@ -121,13 +121,13 @@ LL |     match await { await => () }
    |                   while parsing this incorrect await expression
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:129:11
+  --> $DIR/incorrect-syntax-suggestions.rs:124:11
    |
 LL |     match await { await => () }
    |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
 
 error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/incorrect-syntax-suggestions.rs:132:1
+  --> $DIR/incorrect-syntax-suggestions.rs:127:1
    |
 LL |     match await { await => () }
    |     -----                      - expected one of `.`, `?`, `{`, or an operator
@@ -138,31 +138,7 @@ LL | }
    | ^ unexpected token
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:52:13
-   |
-LL | fn foo9() -> Result<(), ()> {
-   |    ---- this is not `async`
-LL |     let _ = await bar();
-   |             ^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:57:13
-   |
-LL | fn foo10() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = await? bar();
-   |             ^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:66:14
-   |
-LL | fn foo12() -> Result<(), ()> {
-   |    ----- this is not `async`
-LL |     let _ = (await bar())?;
-   |              ^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:71:19
+  --> $DIR/incorrect-syntax-suggestions.rs:68:19
    |
 LL | fn foo13() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -170,7 +146,7 @@ LL |     let _ = bar().await();
    |                   ^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:76:19
+  --> $DIR/incorrect-syntax-suggestions.rs:73:19
    |
 LL | fn foo14() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -178,7 +154,7 @@ LL |     let _ = bar().await()?;
    |                   ^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:81:19
+  --> $DIR/incorrect-syntax-suggestions.rs:78:19
    |
 LL | fn foo15() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -186,7 +162,7 @@ LL |     let _ = bar().await;
    |                   ^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:85:19
+  --> $DIR/incorrect-syntax-suggestions.rs:82:19
    |
 LL | fn foo16() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -194,7 +170,7 @@ LL |     let _ = bar().await?;
    |                   ^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:90:23
+  --> $DIR/incorrect-syntax-suggestions.rs:87:23
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -202,29 +178,13 @@ LL |         let _ = bar().await?;
    |                       ^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:97:23
+  --> $DIR/incorrect-syntax-suggestions.rs:94:23
    |
 LL |     let foo = || {
    |               -- this is not `async`
 LL |         let _ = bar().await?;
    |                       ^^^^^ only allowed inside `async` functions and blocks
 
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:113:17
-   |
-LL |     fn foo() -> Result<(), ()> {
-   |        --- this is not `async`
-LL |         let _ = await!(bar())?;
-   |                 ^^^^^ only allowed inside `async` functions and blocks
-
-error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:121:17
-   |
-LL |     let foo = || {
-   |               -- this is not `async`
-LL |         let _ = await!(bar())?;
-   |                 ^^^^^ only allowed inside `async` functions and blocks
-
-error: aborting due to 33 previous errors
+error: aborting due to 28 previous errors
 
 For more information about this error, try `rustc --explain E0728`.
diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr
index 5f8dbbdb05c..b7269a652ea 100644
--- a/tests/ui/check-cfg/compact-values.stderr
+++ b/tests/ui/check-cfg/compact-values.stderr
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value
 LL | #[cfg(target(os = "linux", arch = "X"))]
    |                            ^^^^^^^^^^
    |
-   = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
+   = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs
new file mode 100644
index 00000000000..01f7d6ce901
--- /dev/null
+++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs
@@ -0,0 +1,35 @@
+#![deny(coinductive_overlap_in_coherence)]
+
+use std::borrow::Borrow;
+use std::cmp::Ordering;
+use std::marker::PhantomData;
+
+#[derive(PartialEq, Default)]
+pub(crate) struct Interval<T>(PhantomData<T>);
+
+// This impl overlaps with the `derive` unless we reject the nested
+// `Interval<?1>: PartialOrd<Interval<?1>>` candidate which results
+// in a - currently inductive - cycle.
+impl<T, Q> PartialEq<Q> for Interval<T>
+//~^ ERROR implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
+//~| WARN this was previously accepted by the compiler but is being phased out
+where
+    T: Borrow<Q>,
+    Q: ?Sized + PartialOrd,
+{
+    fn eq(&self, _: &Q) -> bool {
+        true
+    }
+}
+
+impl<T, Q> PartialOrd<Q> for Interval<T>
+where
+    T: Borrow<Q>,
+    Q: ?Sized + PartialOrd,
+{
+    fn partial_cmp(&self, _: &Q) -> Option<Ordering> {
+        None
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
new file mode 100644
index 00000000000..f315ba82130
--- /dev/null
+++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr
@@ -0,0 +1,23 @@
+error: implementations of `PartialEq<Interval<_>>` for `Interval<_>` will conflict in the future
+  --> $DIR/warn-when-cycle-is-error-in-coherence.rs:13:1
+   |
+LL | #[derive(PartialEq, Default)]
+   |          --------- the second impl is here
+...
+LL | impl<T, Q> PartialEq<Q> for Interval<T>
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the first impl is here
+...
+LL |     Q: ?Sized + PartialOrd,
+   |                 ---------- `Interval<_>: PartialOrd` may be considered to hold in future releases, causing the impls to overlap
+   |
+   = 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 #114040 <https://github.com/rust-lang/rust/issues/114040>
+   = note: impls that are not considered to overlap may be considered to overlap in the future
+note: the lint level is defined here
+  --> $DIR/warn-when-cycle-is-error-in-coherence.rs:1:9
+   |
+LL | #![deny(coinductive_overlap_in_coherence)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/did_you_mean/compatible-variants.stderr b/tests/ui/did_you_mean/compatible-variants.stderr
index 7b88d93ead1..f2bbd8ced8f 100644
--- a/tests/ui/did_you_mean/compatible-variants.stderr
+++ b/tests/ui/did_you_mean/compatible-variants.stderr
@@ -61,6 +61,8 @@ LL +     Some(())
 error[E0308]: `?` operator has incompatible types
   --> $DIR/compatible-variants.rs:35:5
    |
+LL | fn d() -> Option<()> {
+   |           ---------- expected `Option<()>` because of return type
 LL |     c()?
    |     ^^^^ expected `Option<()>`, found `()`
    |
diff --git a/tests/ui/generic-associated-types/issue-102114.stderr b/tests/ui/generic-associated-types/issue-102114.current.stderr
index 8e41dee54d7..6e7a0b1f67f 100644
--- a/tests/ui/generic-associated-types/issue-102114.stderr
+++ b/tests/ui/generic-associated-types/issue-102114.current.stderr
@@ -1,5 +1,5 @@
 error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
-  --> $DIR/issue-102114.rs:11:12
+  --> $DIR/issue-102114.rs:14:12
    |
 LL |     type B<'b>;
    |            -- expected 0 type parameters
diff --git a/tests/ui/generic-associated-types/issue-102114.next.stderr b/tests/ui/generic-associated-types/issue-102114.next.stderr
new file mode 100644
index 00000000000..6e7a0b1f67f
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-102114.next.stderr
@@ -0,0 +1,12 @@
+error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/issue-102114.rs:14:12
+   |
+LL |     type B<'b>;
+   |            -- expected 0 type parameters
+...
+LL |     type B<T> = Wrapper<T>;
+   |            ^ found 1 type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/generic-associated-types/issue-102114.rs b/tests/ui/generic-associated-types/issue-102114.rs
index de31737efef..bb6622c0a5f 100644
--- a/tests/ui/generic-associated-types/issue-102114.rs
+++ b/tests/ui/generic-associated-types/issue-102114.rs
@@ -1,3 +1,6 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
 trait A {
     type B<'b>;
     fn a() -> Self::B<'static>;
diff --git a/tests/ui/generic-associated-types/issue-86218.rs b/tests/ui/generic-associated-types/issue-86218.rs
index 61cfdd35a89..397a0f2c649 100644
--- a/tests/ui/generic-associated-types/issue-86218.rs
+++ b/tests/ui/generic-associated-types/issue-86218.rs
@@ -17,7 +17,6 @@ trait Yay<AdditionalValue> {
 
 impl<'a> Yay<&'a ()> for () {
     type InnerStream<'s> = impl Stream<Item = i32> + 's;
-    //^ ERROR does not fulfill the required lifetime
     fn foo<'s>() -> Self::InnerStream<'s> {
         ()
     }
diff --git a/tests/ui/generic-associated-types/issue-90014-tait.rs b/tests/ui/generic-associated-types/issue-90014-tait.rs
index bc3a4e12965..1ce5cd31987 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait.rs
+++ b/tests/ui/generic-associated-types/issue-90014-tait.rs
@@ -13,7 +13,6 @@ struct Foo<'a>(&'a mut ());
 
 impl Foo<'_> {
     type Fut<'a> = impl Future<Output = ()>;
-    //^ ERROR: the type `&mut ()` does not fulfill the required lifetime
 
     fn make_fut<'a>(&'a self) -> Self::Fut<'a> {
         async { () }
diff --git a/tests/ui/generic-associated-types/issue-90014-tait.stderr b/tests/ui/generic-associated-types/issue-90014-tait.stderr
index 8330a387ecd..1dec7edce50 100644
--- a/tests/ui/generic-associated-types/issue-90014-tait.stderr
+++ b/tests/ui/generic-associated-types/issue-90014-tait.stderr
@@ -1,18 +1,18 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-90014-tait.rs:19:9
+  --> $DIR/issue-90014-tait.rs:18:9
    |
 LL |     type Fut<'a> = impl Future<Output = ()>;
    |                    ------------------------ the expected future
-...
+LL |
 LL |     fn make_fut<'a>(&'a self) -> Self::Fut<'a> {
    |                                  ------------- expected `Foo<'_>::Fut<'a>` because of return type
 LL |         async { () }
    |         ^^^^^^^^^^^^ expected future, found `async` block
    |
    = note: expected opaque type `Foo<'_>::Fut<'a>`
-            found `async` block `[async block@$DIR/issue-90014-tait.rs:19:9: 19:21]`
+            found `async` block `[async block@$DIR/issue-90014-tait.rs:18:9: 18:21]`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/issue-90014-tait.rs:18:8
+  --> $DIR/issue-90014-tait.rs:17:8
    |
 LL |     fn make_fut<'a>(&'a self) -> Self::Fut<'a> {
    |        ^^^^^^^^
diff --git a/tests/ui/generic-const-items/reference-outlives-referent.rs b/tests/ui/generic-const-items/reference-outlives-referent.rs
new file mode 100644
index 00000000000..13e4eaac39f
--- /dev/null
+++ b/tests/ui/generic-const-items/reference-outlives-referent.rs
@@ -0,0 +1,9 @@
+// Test that we catch that the reference outlives the referent and we
+// successfully emit a diagnostic. Regression test for issue #114714.
+
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+const Q<'a, 'b>: &'a &'b () = &&(); //~ ERROR reference has a longer lifetime than the data it references
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/reference-outlives-referent.stderr b/tests/ui/generic-const-items/reference-outlives-referent.stderr
new file mode 100644
index 00000000000..2b57713b5c1
--- /dev/null
+++ b/tests/ui/generic-const-items/reference-outlives-referent.stderr
@@ -0,0 +1,20 @@
+error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+  --> $DIR/reference-outlives-referent.rs:7:18
+   |
+LL | const Q<'a, 'b>: &'a &'b () = &&();
+   |                  ^^^^^^^^^^
+   |
+note: the pointer is valid for the lifetime `'a` as defined here
+  --> $DIR/reference-outlives-referent.rs:7:9
+   |
+LL | const Q<'a, 'b>: &'a &'b () = &&();
+   |         ^^
+note: but the referenced data is only valid for the lifetime `'b` as defined here
+  --> $DIR/reference-outlives-referent.rs:7:13
+   |
+LL | const Q<'a, 'b>: &'a &'b () = &&();
+   |             ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
index 73b0a317364..5241b475d5c 100644
--- a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
+++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/placeholder-pattern-fail.rs:9:47
    |
 LL |     let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub;
-   |                                               ^^^ one type is more general than the other
+   |            --------------------------------   ^^^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)`
               found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)`
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr
index 9914783d976..db5fc4bf1ba 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/hrtb-exists-forall-fn.rs:17:34
    |
 LL |     let _: for<'b> fn(&'b u32) = foo();
-   |                                  ^^^^^ one type is more general than the other
+   |            -------------------   ^^^^^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'b> fn(&'b u32)`
               found fn pointer `fn(&u32)`
diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs
new file mode 100644
index 00000000000..57d68849251
--- /dev/null
+++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs
@@ -0,0 +1,22 @@
+// edition:2015
+// check-pass
+// issue: 114664
+
+fn ice() -> impl AsRef<Fn(&())> {
+    //~^ WARN trait objects without an explicit `dyn` are deprecated
+    //~| WARN trait objects without an explicit `dyn` are deprecated
+    //~| 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!
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    Foo
+}
+
+struct Foo;
+impl AsRef<dyn Fn(&())> for Foo {
+    fn as_ref(&self) -> &(dyn for<'a> Fn(&'a ()) + 'static) {
+        todo!()
+    }
+}
+
+pub fn main() {}
diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
new file mode 100644
index 00000000000..fad0b812d43
--- /dev/null
+++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
@@ -0,0 +1,42 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
+   |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+   |                        ^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
+help: use `dyn`
+   |
+LL | fn ice() -> impl AsRef<dyn Fn(&())> {
+   |                        +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
+   |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+   |                        ^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+   |
+LL | fn ice() -> impl AsRef<dyn Fn(&())> {
+   |                        +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
+   |
+LL | fn ice() -> impl AsRef<Fn(&())> {
+   |                        ^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+   |
+LL | fn ice() -> impl AsRef<dyn Fn(&())> {
+   |                        +++
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/impl-trait/issue-99073-2.rs b/tests/ui/impl-trait/issue-99073-2.rs
index 14ac688806b..37ea211bec3 100644
--- a/tests/ui/impl-trait/issue-99073-2.rs
+++ b/tests/ui/impl-trait/issue-99073-2.rs
@@ -8,6 +8,7 @@ fn test<T: Display>(t: T, recurse: bool) -> impl Display {
     let f = || {
         let i: u32 = test::<i32>(-1, false);
         //~^ ERROR concrete type differs from previous defining opaque type use
+        //~| ERROR expected generic type parameter, found `i32`
         println!("{i}");
     };
     if recurse {
diff --git a/tests/ui/impl-trait/issue-99073-2.stderr b/tests/ui/impl-trait/issue-99073-2.stderr
index 913bc8f5674..06b2b84569f 100644
--- a/tests/ui/impl-trait/issue-99073-2.stderr
+++ b/tests/ui/impl-trait/issue-99073-2.stderr
@@ -1,3 +1,12 @@
+error[E0792]: expected generic type parameter, found `i32`
+  --> $DIR/issue-99073-2.rs:9:22
+   |
+LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display {
+   |         - this generic parameter must be used with a generic type parameter
+LL |     let f = || {
+LL |         let i: u32 = test::<i32>(-1, false);
+   |                      ^^^^^^^^^^^^^^^^^^^^^^
+
 error: concrete type differs from previous defining opaque type use
   --> $DIR/issue-99073-2.rs:9:22
    |
@@ -5,10 +14,11 @@ LL |         let i: u32 = test::<i32>(-1, false);
    |                      ^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `u32`
    |
 note: previous use here
-  --> $DIR/issue-99073-2.rs:16:5
+  --> $DIR/issue-99073-2.rs:7:45
    |
-LL |     t
-   |     ^
+LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display {
+   |                                             ^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/issue-99073.rs b/tests/ui/impl-trait/issue-99073.rs
index 7798e247df0..b4ef3e66f96 100644
--- a/tests/ui/impl-trait/issue-99073.rs
+++ b/tests/ui/impl-trait/issue-99073.rs
@@ -5,4 +5,5 @@ fn main() {
 fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
   move || f(fix(&f))
   //~^ ERROR concrete type differs from previous defining opaque type use
+  //~| ERROR expected generic type parameter, found `&F`
 }
diff --git a/tests/ui/impl-trait/issue-99073.stderr b/tests/ui/impl-trait/issue-99073.stderr
index 54636795349..a8400080e5a 100644
--- a/tests/ui/impl-trait/issue-99073.stderr
+++ b/tests/ui/impl-trait/issue-99073.stderr
@@ -1,14 +1,23 @@
-error: concrete type differs from previous defining opaque type use
+error[E0792]: expected generic type parameter, found `&F`
   --> $DIR/issue-99073.rs:6:11
    |
+LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
+   |        - this generic parameter must be used with a generic type parameter
+LL |   move || f(fix(&f))
+   |           ^^^^^^^^^^
+
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/issue-99073.rs:6:13
+   |
 LL |   move || f(fix(&f))
-   |           ^^^^^^^^^^ expected `[closure@$DIR/issue-99073.rs:6:3: 6:10]`, got `G`
+   |             ^^^^^^^ expected `[closure@$DIR/issue-99073.rs:6:3: 6:10]`, got `G`
    |
 note: previous use here
-  --> $DIR/issue-99073.rs:6:3
+  --> $DIR/issue-99073.rs:5:36
    |
-LL |   move || f(fix(&f))
-   |   ^^^^^^^^^^^^^^^^^^
+LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
+   |                                    ^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/impl-trait/rpit/equal-lifetime-params-ok.rs b/tests/ui/impl-trait/rpit/equal-lifetime-params-ok.rs
new file mode 100644
index 00000000000..6207381c745
--- /dev/null
+++ b/tests/ui/impl-trait/rpit/equal-lifetime-params-ok.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+// related to #113916, check that using RPITs in functions with lifetime params
+// which are constrained to be equal compiles.
+
+trait Trait<'a, 'b> {}
+impl Trait<'_, '_> for () {}
+fn pass<'a: 'b, 'b: 'a>() -> impl Trait<'a, 'b> {
+    (|| {})()
+}
+
+struct Foo<'a>(&'a ());
+impl<'a> Foo<'a> {
+    fn bar<'b: 'a>(&'b self) -> impl Trait<'a, 'b> {
+        let _: &'a &'b &'a ();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/rpit/non-defining-use.rs b/tests/ui/impl-trait/rpit/non-defining-use.rs
new file mode 100644
index 00000000000..255a8929a87
--- /dev/null
+++ b/tests/ui/impl-trait/rpit/non-defining-use.rs
@@ -0,0 +1,14 @@
+// Regression test for #111935 that non-defining uses of RPIT result in errors
+#![allow(unconditional_recursion)]
+fn foo<T>() -> impl Sized {
+    let _: () = foo::<u8>(); //~ ERROR expected generic type parameter, found `u8`
+}
+
+fn bar<T>(val: T) -> impl Sized {
+    let _: u8 = bar(0u8);
+    //~^ ERROR concrete type differs from previous defining opaque type use
+    //~| ERROR expected generic type parameter, found `u8`
+    val
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/rpit/non-defining-use.stderr b/tests/ui/impl-trait/rpit/non-defining-use.stderr
new file mode 100644
index 00000000000..19987d47672
--- /dev/null
+++ b/tests/ui/impl-trait/rpit/non-defining-use.stderr
@@ -0,0 +1,31 @@
+error[E0792]: expected generic type parameter, found `u8`
+  --> $DIR/non-defining-use.rs:4:12
+   |
+LL | fn foo<T>() -> impl Sized {
+   |        - this generic parameter must be used with a generic type parameter
+LL |     let _: () = foo::<u8>();
+   |            ^^
+
+error[E0792]: expected generic type parameter, found `u8`
+  --> $DIR/non-defining-use.rs:8:12
+   |
+LL | fn bar<T>(val: T) -> impl Sized {
+   |        - this generic parameter must be used with a generic type parameter
+LL |     let _: u8 = bar(0u8);
+   |            ^^
+
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/non-defining-use.rs:8:17
+   |
+LL |     let _: u8 = bar(0u8);
+   |                 ^^^^^^^^ expected `T`, got `u8`
+   |
+note: previous use here
+  --> $DIR/non-defining-use.rs:7:22
+   |
+LL | fn bar<T>(val: T) -> impl Sized {
+   |                      ^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs
new file mode 100644
index 00000000000..9b793642d07
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-1.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+pub trait Foo {
+    type Error: Error;
+
+    fn foo(&self, stream: &<Self::Error as Error>::Span);
+}
+
+pub struct Wrapper<Inner>(Inner);
+
+impl<E: Error, Inner> Foo for Wrapper<Inner>
+where
+    Inner: Foo<Error = E>,
+{
+    type Error = E;
+
+    fn foo(&self, stream: &<Self::Error as Error>::Span) {
+        todo!()
+    }
+}
+
+pub trait Error {
+    type Span;
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs
new file mode 100644
index 00000000000..86b10a56c9d
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-entailment-wf-vars-issue-114783-2.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+trait AsBufferView {
+    type Device;
+}
+
+trait Error {
+    type Span;
+}
+
+trait Foo {
+    type Error: Error;
+    fn foo(&self) -> &<Self::Error as Error>::Span;
+}
+
+impl<D: Error, VBuf0> Foo for VBuf0
+where
+    VBuf0: AsBufferView<Device = D>,
+{
+    type Error = D;
+    fn foo(&self) -> &<Self::Error as Error>::Span {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/inline-const/pat-match-fndef.rs b/tests/ui/inline-const/pat-match-fndef.rs
new file mode 100644
index 00000000000..fbd4dc66c3a
--- /dev/null
+++ b/tests/ui/inline-const/pat-match-fndef.rs
@@ -0,0 +1,13 @@
+#![feature(inline_const_pat)]
+//~^ WARN the feature `inline_const_pat` is incomplete
+
+fn uwu() {}
+
+fn main() {
+    let x = [];
+    match x[123] {
+        const { uwu } => {}
+        //~^ ERROR `fn() {uwu}` cannot be used in patterns
+        _ => {}
+    }
+}
diff --git a/tests/ui/inline-const/pat-match-fndef.stderr b/tests/ui/inline-const/pat-match-fndef.stderr
new file mode 100644
index 00000000000..c94782b17ce
--- /dev/null
+++ b/tests/ui/inline-const/pat-match-fndef.stderr
@@ -0,0 +1,17 @@
+warning: the feature `inline_const_pat` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/pat-match-fndef.rs:1:12
+   |
+LL | #![feature(inline_const_pat)]
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: `fn() {uwu}` cannot be used in patterns
+  --> $DIR/pat-match-fndef.rs:9:9
+   |
+LL |         const { uwu } => {}
+   |         ^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/tests/ui/internal/internal-unstable.rs b/tests/ui/internal/internal-unstable.rs
index b8987d3e13c..1eb27fbdc3a 100644
--- a/tests/ui/internal/internal-unstable.rs
+++ b/tests/ui/internal/internal-unstable.rs
@@ -8,7 +8,6 @@ extern crate internal_unstable;
 
 struct Baz {
     #[allow_internal_unstable]
-    //^ WARN `#[allow_internal_unstable]` is ignored on struct fields and match arms
     baz: u8,
 }
 
@@ -50,7 +49,6 @@ fn main() {
 
     match true {
         #[allow_internal_unstable]
-        //^ WARN `#[allow_internal_unstable]` is ignored on struct fields and match arms
         _ => {}
     }
 }
diff --git a/tests/ui/internal/internal-unstable.stderr b/tests/ui/internal/internal-unstable.stderr
index f0f9bfb8d23..b7c47365c2d 100644
--- a/tests/ui/internal/internal-unstable.stderr
+++ b/tests/ui/internal/internal-unstable.stderr
@@ -1,5 +1,5 @@
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:41:25
+  --> $DIR/internal-unstable.rs:40:25
    |
 LL |     pass_through_allow!(internal_unstable::unstable());
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     pass_through_allow!(internal_unstable::unstable());
    = help: add `#![feature(function)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:43:27
+  --> $DIR/internal-unstable.rs:42:27
    |
 LL |     pass_through_noallow!(internal_unstable::unstable());
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL |     pass_through_noallow!(internal_unstable::unstable());
    = help: add `#![feature(function)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:47:22
+  --> $DIR/internal-unstable.rs:46:22
    |
 LL |     println!("{:?}", internal_unstable::unstable());
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     println!("{:?}", internal_unstable::unstable());
    = help: add `#![feature(function)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:49:10
+  --> $DIR/internal-unstable.rs:48:10
    |
 LL |     bar!(internal_unstable::unstable());
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -31,7 +31,7 @@ LL |     bar!(internal_unstable::unstable());
    = help: add `#![feature(function)]` to the crate attributes to enable
 
 error[E0658]: use of unstable library feature 'function'
-  --> $DIR/internal-unstable.rs:19:9
+  --> $DIR/internal-unstable.rs:18:9
    |
 LL |         internal_unstable::unstable();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr b/tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr
index 7180a3d2426..c92da53dbc4 100644
--- a/tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr
+++ b/tests/ui/issues/issue-51632-try-desugar-incompatible-types.stderr
@@ -1,6 +1,8 @@
 error[E0308]: `?` operator has incompatible types
   --> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
    |
+LL | fn forbidden_narratives() -> Result<isize, ()> {
+   |                              ----------------- expected `Result<isize, ()>` because of return type
 LL |     missing_discourses()?
    |     ^^^^^^^^^^^^^^^^^^^^^ expected `Result<isize, ()>`, found `isize`
    |
diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs
new file mode 100644
index 00000000000..b71bcd0fab5
--- /dev/null
+++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+// this test checks that the `dead_code` lint is *NOT* being emited
+// for `foo` as `foo` is being used by `main`, and so the `#[expect]`
+// is unfulfilled
+//
+// it also checks that the `dead_code` lint is also *NOT* emited
+// for `bar` as it's suppresed by the `#[expect]` on `bar`
+
+#![feature(lint_reasons)]
+#![warn(dead_code)] // to override compiletest
+
+fn bar() {}
+
+#[expect(dead_code)]
+//~^ WARN this lint expectation is unfulfilled
+fn foo() { bar() }
+
+fn main() { foo() }
diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.stderr b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.stderr
new file mode 100644
index 00000000000..d5c4dabed01
--- /dev/null
+++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-2.stderr
@@ -0,0 +1,10 @@
+warning: this lint expectation is unfulfilled
+  --> $DIR/allow-or-expect-dead_code-114557-2.rs:15:10
+   |
+LL | #[expect(dead_code)]
+   |          ^^^^^^^^^
+   |
+   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs
new file mode 100644
index 00000000000..f8a5d31a0f2
--- /dev/null
+++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// this test makes sure that the `unfulfilled_lint_expectations` lint
+// is being emited for `foo` as foo is not dead code, it's pub
+
+#![feature(lint_reasons)]
+#![warn(dead_code)] // to override compiletest
+
+#[expect(dead_code)]
+//~^ WARN this lint expectation is unfulfilled
+pub fn foo() {}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.stderr b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.stderr
new file mode 100644
index 00000000000..c954a75b394
--- /dev/null
+++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557-3.stderr
@@ -0,0 +1,10 @@
+warning: this lint expectation is unfulfilled
+  --> $DIR/allow-or-expect-dead_code-114557-3.rs:9:10
+   |
+LL | #[expect(dead_code)]
+   |          ^^^^^^^^^
+   |
+   = note: `#[warn(unfulfilled_lint_expectations)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs
new file mode 100644
index 00000000000..24fafa3d1b8
--- /dev/null
+++ b/tests/ui/lint/dead-code/allow-or-expect-dead_code-114557.rs
@@ -0,0 +1,18 @@
+// check-pass
+// revisions: allow expect
+
+// this test checks that no matter if we put #[allow(dead_code)]
+// or #[expect(dead_code)], no warning is being emited
+
+#![feature(lint_reasons)]
+#![warn(dead_code)] // to override compiletest
+
+fn f() {}
+
+#[cfg_attr(allow, allow(dead_code))]
+#[cfg_attr(expect, expect(dead_code))]
+fn g() {
+    f();
+}
+
+fn main() {}
diff --git a/tests/ui/lint/lint-struct-necessary.rs b/tests/ui/lint/lint-struct-necessary.rs
new file mode 100644
index 00000000000..8bc3c12054a
--- /dev/null
+++ b/tests/ui/lint/lint-struct-necessary.rs
@@ -0,0 +1,31 @@
+#![allow(dead_code)]
+#![deny(unused_parens)]
+
+enum State {
+    Waiting { start_at: u64 }
+}
+struct Foo {}
+
+fn main() {
+    let e = &mut State::Waiting { start_at: 0u64 };
+    match (&mut State::Waiting { start_at: 0u64 }) {
+        _ => {}
+    }
+
+    match (e) {
+        //~^ ERROR unnecessary parentheses around `match` scrutinee expression
+        _ => {}
+    }
+
+    match &(State::Waiting { start_at: 0u64 }) {
+        _ => {}
+    }
+
+    match (State::Waiting { start_at: 0u64 }) {
+        _ => {}
+    }
+
+    match (&&Foo {}) {
+        _ => {}
+    }
+}
diff --git a/tests/ui/lint/lint-struct-necessary.stderr b/tests/ui/lint/lint-struct-necessary.stderr
new file mode 100644
index 00000000000..eb65a9e98c6
--- /dev/null
+++ b/tests/ui/lint/lint-struct-necessary.stderr
@@ -0,0 +1,19 @@
+error: unnecessary parentheses around `match` scrutinee expression
+  --> $DIR/lint-struct-necessary.rs:15:11
+   |
+LL |     match (e) {
+   |           ^ ^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-struct-necessary.rs:2:9
+   |
+LL | #![deny(unused_parens)]
+   |         ^^^^^^^^^^^^^
+help: remove these parentheses
+   |
+LL -     match (e) {
+LL +     match e {
+   |
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index 6e70626ef99..f4e463b67c0 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -24,6 +24,8 @@ unsafe fn ref_to_mut() {
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+    let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
+    //~^ ERROR casting `&T` to `&mut T` is undefined behavior
 
     let deferred = num as *const i32 as *mut i32;
     let _num = &mut *deferred;
@@ -47,6 +49,9 @@ unsafe fn assign_to_ref() {
     //~^ ERROR assigning to `&T` is undefined behavior
     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
     //~^ ERROR assigning to `&T` is undefined behavior
+    *std::mem::transmute::<_, *mut i32>(num) += 1;
+    //~^ ERROR assigning to `&T` is undefined behavior
+
     let value = num as *const i32 as *mut i32;
     *value = 1;
     //~^ ERROR assigning to `&T` is undefined behavior
diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr
index 02b23600557..e8bb0557ca8 100644
--- a/tests/ui/lint/reference_casting.stderr
+++ b/tests/ui/lint/reference_casting.stderr
@@ -37,7 +37,13 @@ LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:29:16
+  --> $DIR/reference_casting.rs:27:16
+   |
+LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:31:16
    |
 LL |     let deferred = num as *const i32 as *mut i32;
    |                    ----------------------------- casting happend here
@@ -45,48 +51,54 @@ LL |     let _num = &mut *deferred;
    |                ^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:38:5
+  --> $DIR/reference_casting.rs:40:5
    |
 LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:40:5
+  --> $DIR/reference_casting.rs:42:5
    |
 LL |     *(a as *const _ as *mut String) += " world";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:42:5
+  --> $DIR/reference_casting.rs:44:5
    |
 LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:44:5
+  --> $DIR/reference_casting.rs:46:5
    |
 LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:46:5
+  --> $DIR/reference_casting.rs:48:5
    |
 LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:48:5
+  --> $DIR/reference_casting.rs:50:5
    |
 LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:51:5
+  --> $DIR/reference_casting.rs:52:5
+   |
+LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:56:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
 LL |     *value = 1;
    |     ^^^^^^^^^^
 
-error: aborting due to 14 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/tests/ui/lint/unknown-lints/allow-in-other-module.rs b/tests/ui/lint/unknown-lints/allow-in-other-module.rs
new file mode 100644
index 00000000000..20bf0d7af03
--- /dev/null
+++ b/tests/ui/lint/unknown-lints/allow-in-other-module.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+// Tests that the unknown_lints lint doesn't fire for an unknown lint loaded from a separate file.
+// The key part is that the stderr output should be empty.
+// Reported in https://github.com/rust-lang/rust/issues/84936
+// Fixed incidentally by https://github.com/rust-lang/rust/pull/97266
+
+// This `allow` should apply to submodules, whether they are inline or loaded from a file.
+#![allow(unknown_lints)]
+#![allow(dead_code)]
+// no warning
+#![allow(not_a_real_lint)]
+
+mod other;
+
+// no warning
+#[allow(not_a_real_lint)]
+fn m() {}
+
+mod mm {
+    // no warning
+    #[allow(not_a_real_lint)]
+    fn m() {}
+}
+
+fn main() {}
diff --git a/tests/ui/lint/unknown-lints/other.rs b/tests/ui/lint/unknown-lints/other.rs
new file mode 100644
index 00000000000..a5111c00a3e
--- /dev/null
+++ b/tests/ui/lint/unknown-lints/other.rs
@@ -0,0 +1,10 @@
+// ignore-test
+
+// Companion to allow-in-other-module.rs
+
+// This should not warn.
+#![allow(not_a_real_lint)]
+
+// This should not warn, either.
+#[allow(not_a_real_lint)]
+fn m() {}
diff --git a/tests/ui/macros/assert-eq-macro-msg.rs b/tests/ui/macros/assert-eq-macro-msg.rs
index cb21d5e7ed6..3d921f40072 100644
--- a/tests/ui/macros/assert-eq-macro-msg.rs
+++ b/tests/ui/macros/assert-eq-macro-msg.rs
@@ -1,7 +1,7 @@
 // run-fail
-// error-pattern:assertion failed: `(left == right)`
-// error-pattern: left: `2`
-// error-pattern:right: `3`: 1 + 1 definitely should be 3
+// error-pattern:assertion `left == right` failed: 1 + 1 definitely should be 3
+// error-pattern:  left: 2
+// error-pattern: right: 3
 // ignore-emscripten no processes
 
 fn main() {
diff --git a/tests/ui/macros/assert-eq-macro-panic.rs b/tests/ui/macros/assert-eq-macro-panic.rs
index 5e505c30b35..6745290cbfc 100644
--- a/tests/ui/macros/assert-eq-macro-panic.rs
+++ b/tests/ui/macros/assert-eq-macro-panic.rs
@@ -1,7 +1,7 @@
 // run-fail
-// error-pattern:assertion failed: `(left == right)`
-// error-pattern: left: `14`
-// error-pattern:right: `15`
+// error-pattern:assertion `left == right` failed
+// error-pattern:  left: 14
+// error-pattern: right: 15
 // ignore-emscripten no processes
 
 fn main() {
diff --git a/tests/ui/macros/assert-matches-macro-msg.rs b/tests/ui/macros/assert-matches-macro-msg.rs
index 0f63de6cfff..7af6a077843 100644
--- a/tests/ui/macros/assert-matches-macro-msg.rs
+++ b/tests/ui/macros/assert-matches-macro-msg.rs
@@ -1,7 +1,7 @@
 // run-fail
-// error-pattern:assertion failed: `(left matches right)`
-// error-pattern: left: `2`
-// error-pattern:right: `3`: 1 + 1 definitely should be 3
+// error-pattern:assertion `left matches right` failed: 1 + 1 definitely should be 3
+// error-pattern:  left: 2
+// error-pattern: right: 3
 // ignore-emscripten no processes
 
 #![feature(assert_matches)]
diff --git a/tests/ui/macros/assert-ne-macro-msg.rs b/tests/ui/macros/assert-ne-macro-msg.rs
index 7e390d24a23..adda0af88f2 100644
--- a/tests/ui/macros/assert-ne-macro-msg.rs
+++ b/tests/ui/macros/assert-ne-macro-msg.rs
@@ -1,7 +1,7 @@
 // run-fail
-// error-pattern:assertion failed: `(left != right)`
-// error-pattern: left: `2`
-// error-pattern:right: `2`: 1 + 1 definitely should not be 2
+// error-pattern:assertion `left != right` failed: 1 + 1 definitely should not be 2
+// error-pattern:  left: 2
+// error-pattern: right: 2
 // ignore-emscripten no processes
 
 fn main() {
diff --git a/tests/ui/macros/assert-ne-macro-panic.rs b/tests/ui/macros/assert-ne-macro-panic.rs
index 4f507d7b54d..d977473a2de 100644
--- a/tests/ui/macros/assert-ne-macro-panic.rs
+++ b/tests/ui/macros/assert-ne-macro-panic.rs
@@ -1,7 +1,7 @@
 // run-fail
-// error-pattern:assertion failed: `(left != right)`
-// error-pattern: left: `14`
-// error-pattern:right: `14`
+// error-pattern:assertion `left != right` failed
+// error-pattern:  left: 14
+// error-pattern: right: 14
 // ignore-emscripten no processes
 
 fn main() {
diff --git a/tests/ui/match/non-first-arm-doesnt-match-expected-return-type.rs b/tests/ui/match/non-first-arm-doesnt-match-expected-return-type.rs
new file mode 100644
index 00000000000..85b1ef7555e
--- /dev/null
+++ b/tests/ui/match/non-first-arm-doesnt-match-expected-return-type.rs
@@ -0,0 +1,21 @@
+#![allow(unused)]
+
+fn test(shouldwe: Option<u32>, shouldwe2: Option<u32>) -> u32 {
+    //~^ NOTE expected `u32` because of return type
+    match shouldwe {
+        Some(val) => {
+            match shouldwe2 {
+                Some(val) => {
+                    return val;
+                }
+                None => (), //~ ERROR mismatched types
+                //~^ NOTE expected `u32`, found `()`
+            }
+        }
+        None => return 12,
+    }
+}
+
+fn main() {
+    println!("returned {}", test(None, Some(5)));
+}
diff --git a/tests/ui/match/non-first-arm-doesnt-match-expected-return-type.stderr b/tests/ui/match/non-first-arm-doesnt-match-expected-return-type.stderr
new file mode 100644
index 00000000000..e6d93b8b5f5
--- /dev/null
+++ b/tests/ui/match/non-first-arm-doesnt-match-expected-return-type.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/non-first-arm-doesnt-match-expected-return-type.rs:11:25
+   |
+LL | fn test(shouldwe: Option<u32>, shouldwe2: Option<u32>) -> u32 {
+   |                                                           --- expected `u32` because of return type
+...
+LL |                 None => (),
+   |                         ^^ expected `u32`, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/parser/issues/issue-113203.rs b/tests/ui/parser/issues/issue-113203.rs
new file mode 100644
index 00000000000..1103251c140
--- /dev/null
+++ b/tests/ui/parser/issues/issue-113203.rs
@@ -0,0 +1,7 @@
+// Checks what happens when we attempt to use the await keyword as a prefix. Span
+// incorrectly emitted an `.await` in E0277 which does not exist
+// edition:2018
+fn main() {
+    await {}()
+    //~^ ERROR incorrect use of `await`
+}
diff --git a/tests/ui/parser/issues/issue-113203.stderr b/tests/ui/parser/issues/issue-113203.stderr
new file mode 100644
index 00000000000..97304a89c9e
--- /dev/null
+++ b/tests/ui/parser/issues/issue-113203.stderr
@@ -0,0 +1,8 @@
+error: incorrect use of `await`
+  --> $DIR/issue-113203.rs:5:5
+   |
+LL |     await {}()
+   |     ^^^^^^^^ help: `await` is a postfix operation: `{}.await`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/parser/issues/issue-70583-block-is-empty-2.rs b/tests/ui/parser/issues/issue-70583-block-is-empty-2.rs
index 80f53338a68..92ff0ef643e 100644
--- a/tests/ui/parser/issues/issue-70583-block-is-empty-2.rs
+++ b/tests/ui/parser/issues/issue-70583-block-is-empty-2.rs
@@ -6,9 +6,13 @@ pub enum ErrorHandled {
 impl ErrorHandled {
     pub fn assert_reported(self) {
         match self {
+            //~^ NOTE this delimiter might not be properly closed...
             ErrorHandled::Reported => {}}
-                                     //^~ ERROR block is empty, you might have not meant to close it
+                                     //~^ NOTE block is empty, you might have not meant to close it
+                                     //~| NOTE as it matches this but it has different indentation
             ErrorHandled::TooGeneric => panic!(),
         }
     }
-} //~ ERROR unexpected closing delimiter: `}`
+}
+//~^ ERROR unexpected closing delimiter: `}`
+//~| NOTE unexpected closing delimiter
diff --git a/tests/ui/parser/issues/issue-70583-block-is-empty-2.stderr b/tests/ui/parser/issues/issue-70583-block-is-empty-2.stderr
index 9ae94c70186..c590e04bb3d 100644
--- a/tests/ui/parser/issues/issue-70583-block-is-empty-2.stderr
+++ b/tests/ui/parser/issues/issue-70583-block-is-empty-2.stderr
@@ -1,8 +1,9 @@
 error: unexpected closing delimiter: `}`
-  --> $DIR/issue-70583-block-is-empty-2.rs:14:1
+  --> $DIR/issue-70583-block-is-empty-2.rs:16:1
    |
 LL |         match self {
    |                    - this delimiter might not be properly closed...
+LL |
 LL |             ErrorHandled::Reported => {}}
    |                                       --- ...as it matches this but it has different indentation
    |                                       |
diff --git a/tests/ui/regions/higher-ranked-implied.stderr b/tests/ui/regions/higher-ranked-implied.stderr
index 9d80eacd7c3..8fa65f11667 100644
--- a/tests/ui/regions/higher-ranked-implied.stderr
+++ b/tests/ui/regions/higher-ranked-implied.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/higher-ranked-implied.rs:12:16
    |
 LL |     let y: B = x;
-   |                ^ one type is more general than the other
+   |            -   ^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
               found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
@@ -11,7 +13,9 @@ error[E0308]: mismatched types
   --> $DIR/higher-ranked-implied.rs:13:16
    |
 LL |     let _: A = y;
-   |                ^ one type is more general than the other
+   |            -   ^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
               found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
diff --git a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
index bb5bc6f66a5..f2328cf3b24 100644
--- a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
+++ b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
    |
 LL |     let _: fn(&mut &isize, &mut &isize) = a;
-   |                                           ^ one type is more general than the other
+   |            ----------------------------   ^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
                  found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
diff --git a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
index dbe9e9b1a2e..9c5004981d5 100644
--- a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
+++ b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
    |
 LL |     let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
-   |                                                        ^ one type is more general than the other
+   |            -----------------------------------------   ^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)`
                  found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}`
diff --git a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
index df0fd069edc..2fab2986567 100644
--- a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
+++ b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43
    |
 LL |     let _: fn(&mut &isize, &mut &isize) = a;
-   |                                           ^ one type is more general than the other
+   |            ----------------------------   ^ one type is more general than the other
+   |            |
+   |            expected due to this
    |
    = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
                  found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
index 721890db4fb..c27e8c4b019 100644
--- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
+++ b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
@@ -1,5 +1,7 @@
 // Check that we can manually implement an object-unsafe trait for its trait object.
 
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 // run-pass
 
 #![feature(object_safe_for_dispatch)]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs
index a70ef31fed1..f41c1051fce 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.rs
@@ -1,6 +1,6 @@
 // known-bug: #110395
 // FIXME check-pass
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
index 6d7980a9736..4fcfe9d4769 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
@@ -1,11 +1,14 @@
-error[E0015]: cannot call non-const fn `<<T as Foo>::Assoc as Foo>::foo` in constant functions
+error[E0277]: the trait bound `T: Foo` is not satisfied
   --> $DIR/assoc-type-const-bound-usage.rs:12:5
    |
 LL |     <T as Foo>::Assoc::foo();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: consider further restricting this bound
+   |
+LL | const fn foo<T: ~const Foo + Foo>() {
+   |                            +++++
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs
index fe1abbf4207..53778b3af3d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs
@@ -1,5 +1,6 @@
-// known-bug: #110395
-#![feature(const_trait_impl)]
+// FIXME(effects)
+// check-pass
+#![feature(const_trait_impl, effects)]
 
 pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
     *t == *t
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr
deleted file mode 100644
index d50100d033e..00000000000
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0015]: cannot call non-const operator in constant functions
-  --> $DIR/call-generic-method-fail.rs:5:5
-   |
-LL |     *t == *t
-   |     ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-help: consider further restricting this bound
-   |
-LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool {
-   |                                       ++++++++++++++++++++++++++++
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
index 307d5a37bb0..b6cb24d15fe 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
@@ -1,10 +1,9 @@
 // Tests that a const default trait impl can be specialized by another const
 // trait impl and that the specializing impl will be used during const-eval.
 
-// known-bug: #110395
-// FIXME run-pass
+// run-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(min_specialization)]
 
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr
deleted file mode 100644
index 6dad82b03b5..00000000000
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0015]: cannot call non-const fn `<T as Value>::value` in constant functions
-  --> $DIR/const-default-const-specialized.rs:16:5
-   |
-LL |     T::value()
-   |     ^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
index f1fbbb512e3..84c7926f415 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
@@ -3,7 +3,7 @@
 // known-bug: #110395
 // FIXME run-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(min_specialization)]
 
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
index 5ba4f2d52c5..4734cee7f9a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr
@@ -1,11 +1,12 @@
-error[E0015]: cannot call non-const fn `<T as Value>::value` in constant functions
-  --> $DIR/non-const-default-const-specialized.rs:15:5
+error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo`
+  --> $DIR/non-const-default-const-specialized.rs:27:1
    |
-LL |     T::value()
-   |     ^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL | impl<T> Value for T {
+   | ------------------- first implementation here
+...
+LL | impl const Value for FortyTwo {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `FortyTwo`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs
index 79cba548fd5..92becf7c4af 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs
@@ -1,6 +1,5 @@
-// known-bug: #110395
-// FIXME check-pass
-#![feature(const_trait_impl)]
+// check-pass
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr
deleted file mode 100644
index 03d7b0549a6..00000000000
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
-  --> $DIR/super-traits.rs:21:7
-   |
-LL |     t.a();
-   |       ^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
index 7338fb245b3..89d74cecfdb 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(generic_arg_infer)]
 #![feature(generic_const_exprs)]
 #![allow(incomplete_features)]
@@ -6,9 +6,10 @@
 struct Foo<const N: usize>;
 
 impl<const N: usize> Foo<N> {
-   fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
-      Foo
-   }
+    fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
+        //~^ ERROR mismatched types
+        Foo
+    }
 }
 
 #[const_trait]
@@ -24,7 +25,7 @@ impl const Add42 for () {
 
 fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
     //~^ ERROR `~const` is not allowed here
-    //~| ERROR cannot call
+    //~| ERROR mismatched types
     Foo
 }
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
index 2a17ee3f372..ec5d21d33c6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
@@ -1,23 +1,33 @@
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-and-const-params.rs:25:11
+  --> $DIR/tilde-const-and-const-params.rs:26:11
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |           ^^^^^^^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
-  --> $DIR/tilde-const-and-const-params.rs:25:4
+  --> $DIR/tilde-const-and-const-params.rs:26:4
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |    ^^^
 
-error[E0015]: cannot call non-const fn `<A as Add42>::add` in constants
-  --> $DIR/tilde-const-and-const-params.rs:25:61
+error[E0308]: mismatched types
+  --> $DIR/tilde-const-and-const-params.rs:26:61
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
-   |                                                             ^^^^^^^^^
+   |                                                             ^^^^^^^^^ expected `false`, found `true`
    |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = note: expected constant `false`
+              found constant `true`
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/tilde-const-and-const-params.rs:9:44
+   |
+LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
+   |                                            ^^^^^^^^^ expected `false`, found `true`
+   |
+   = note: expected constant `false`
+              found constant `true`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs
index 411f4b2f68c..fbdc3a4f370 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.rs
@@ -1,6 +1,6 @@
 // known-bug: #110395
 // FIXME check-pass
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr
index 4b852b65b0c..f77672f3e71 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde_const_on_impl_bound.stderr
@@ -1,11 +1,12 @@
-error[E0015]: cannot call non-const fn `<T as Foo>::foo` in constant functions
-  --> $DIR/tilde_const_on_impl_bound.rs:14:16
+error[E0308]: mismatched types
+  --> $DIR/tilde_const_on_impl_bound.rs:14:9
    |
 LL |         self.0.foo()
-   |                ^^^^^
+   |         ^^^^^^^^^^^^ expected `host`, found `true`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: expected constant `host`
+              found constant `true`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs
index 47f7806e453..94be3ff46ac 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs
@@ -4,7 +4,7 @@
 // test is not enough.
 // known-bug: #110395
 // FIXME check-pass
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Bar {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
index 54537231b61..e8d0eec020f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr
@@ -1,51 +1,35 @@
-error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
-  --> $DIR/trait-where-clause-const.rs:20:5
-   |
-LL |     T::a();
-   |     ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const fn `<T as Foo>::b` in constant functions
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
   --> $DIR/trait-where-clause-const.rs:21:5
    |
 LL |     T::b();
-   |     ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const fn `<T as Foo>::c::<T>` in constant functions
-  --> $DIR/trait-where-clause-const.rs:23:5
-   |
-LL |     T::c::<T>();
-   |     ^^^^^^^^^^^
+   |     ^^^^ the trait `Bar` is not implemented for `T`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
-  --> $DIR/trait-where-clause-const.rs:28:5
+note: required by a bound in `Foo::b`
+  --> $DIR/trait-where-clause-const.rs:15:24
    |
-LL |     T::a();
-   |     ^^^^^^
+LL |     fn b() where Self: ~const Bar;
+   |                        ^^^^^^^^^^ required by this bound in `Foo::b`
+help: consider further restricting this bound
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL | const fn test1<T: ~const Foo + Bar + Bar>() {
+   |                                    +++++
 
-error[E0015]: cannot call non-const fn `<T as Foo>::b` in constant functions
-  --> $DIR/trait-where-clause-const.rs:29:5
+error[E0277]: the trait bound `T: ~const Bar` is not satisfied
+  --> $DIR/trait-where-clause-const.rs:23:12
    |
-LL |     T::b();
-   |     ^^^^^^
+LL |     T::c::<T>();
+   |            ^ the trait `Bar` is not implemented for `T`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const fn `<T as Foo>::c::<T>` in constant functions
-  --> $DIR/trait-where-clause-const.rs:30:5
+note: required by a bound in `Foo::c`
+  --> $DIR/trait-where-clause-const.rs:16:13
    |
-LL |     T::c::<T>();
-   |     ^^^^^^^^^^^
+LL |     fn c<T: ~const Bar>();
+   |             ^^^^^^^^^^ required by this bound in `Foo::c`
+help: consider further restricting this bound
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+LL | const fn test1<T: ~const Foo + Bar + Bar>() {
+   |                                    +++++
 
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
index 6e1074035b7..5439f859a03 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs
@@ -1,5 +1,4 @@
-// known-bug: #110395
-// FIXME run-pass
+// run-pass
 
 #![feature(const_trait_impl, effects)]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr
deleted file mode 100644
index b353c622b55..00000000000
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0015]: cannot call non-const fn `<Self as Bar>::bar` in constant functions
-  --> $DIR/trait-where-clause-run.rs:14:9
-   |
-LL |         <Self as Bar>::bar() * 6
-   |         ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
index 32ebe03435d..c578813b846 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs
@@ -1,7 +1,6 @@
-// known-bug: #110395
-// FIXME check-pass
+// check-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr
deleted file mode 100644
index 7356fbd9267..00000000000
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0015]: cannot call non-const fn `<T as Foo>::bar` in constant functions
-  --> $DIR/trait-where-clause-self-referential.rs:22:5
-   |
-LL |     T::bar();
-   |     ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/std/slice-from-array-issue-113238.rs b/tests/ui/std/slice-from-array-issue-113238.rs
new file mode 100644
index 00000000000..e9e1bfb8db3
--- /dev/null
+++ b/tests/ui/std/slice-from-array-issue-113238.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+// This intends to use the unsizing coercion from array to slice, but it only
+// works if we resolve `<&[u8]>::from` as the reflexive `From<T> for T`. In
+// #113238, we found that gimli had added its own `From<EndianSlice> for &[u8]`
+// that affected all `std/backtrace` users.
+fn main() {
+    let _ = <&[u8]>::from(&[]);
+}
diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
index 004f1c1622b..80be252a0a5 100644
--- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr
+++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
@@ -13,7 +13,7 @@ LL |     let _: &[i8] = data.into();
              <[T; 4] as From<(T, T, T, T)>>
              <[T; 5] as From<(T, T, T, T, T)>>
              <[T; 6] as From<(T, T, T, T, T, T)>>
-           and 7 others
+           and 6 others
    = note: required for `&[u8]` to implement `Into<&[i8]>`
 
 error: aborting due to previous error
diff --git a/tests/ui/suggestions/remove-question-symbol-with-paren.stderr b/tests/ui/suggestions/remove-question-symbol-with-paren.stderr
index 39e35f733a1..40b9cf2dcd4 100644
--- a/tests/ui/suggestions/remove-question-symbol-with-paren.stderr
+++ b/tests/ui/suggestions/remove-question-symbol-with-paren.stderr
@@ -1,6 +1,9 @@
 error[E0308]: `?` operator has incompatible types
   --> $DIR/remove-question-symbol-with-paren.rs:5:6
    |
+LL | fn foo() -> Option<()> {
+   |             ---------- expected `Option<()>` because of return type
+LL |     let x = Some(());
 LL |     (x?)
    |      ^^ expected `Option<()>`, found `()`
    |
diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs
index 3ebd2dbceaa..782444417a8 100644
--- a/tests/ui/target-feature/gate.rs
+++ b/tests/ui/target-feature/gate.rs
@@ -17,6 +17,7 @@
 // gate-test-ermsb_target_feature
 // gate-test-bpf_target_feature
 // gate-test-aarch64_ver_target_feature
+// gate-test-csky_target_feature
 
 #[target_feature(enable = "avx512bw")]
 //~^ ERROR: currently unstable
diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr
index 896212e42fc..f56efb3bb83 100644
--- a/tests/ui/target-feature/gate.stderr
+++ b/tests/ui/target-feature/gate.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the target feature `avx512bw` is currently unstable
-  --> $DIR/gate.rs:21:18
+  --> $DIR/gate.rs:22:18
    |
 LL | #[target_feature(enable = "avx512bw")]
    |                  ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
index 8c3f5a07f56..6997833834d 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
@@ -1,11 +1,11 @@
 thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:33:5:
-assertion failed: `(left == right)`
-  left: `2`,
- right: `4`
+assertion `left == right` failed
+  left: 2
+ right: 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:27:5:
-assertion failed: `(left == right)`
-  left: `2`,
- right: `4`
+assertion `left == right` failed
+  left: 2
+ right: 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 testing321
diff --git a/tests/ui/test-attrs/test-panic-abort.run.stdout b/tests/ui/test-attrs/test-panic-abort.run.stdout
index 785407dfa0b..0e27f6fb655 100644
--- a/tests/ui/test-attrs/test-panic-abort.run.stdout
+++ b/tests/ui/test-attrs/test-panic-abort.run.stdout
@@ -18,9 +18,9 @@ testing123
 ---- it_fails stderr ----
 testing321
 thread 'main' panicked at $DIR/test-panic-abort.rs:38:5:
-assertion failed: `(left == right)`
-  left: `2`,
- right: `5`
+assertion `left == right` failed
+  left: 2
+ right: 5
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 
diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs
index 74c7afd6b9e..bb2b13664ba 100644
--- a/tests/ui/traits/issue-105231.rs
+++ b/tests/ui/traits/issue-105231.rs
@@ -1,9 +1,9 @@
-//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
 struct A<T>(B<T>);
 //~^ ERROR recursive types `A` and `B` have infinite size
 struct B<T>(A<A<T>>);
 trait Foo {}
 impl<T> Foo for T where T: Send {}
+//~^ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
 impl Foo for B<u8> {}
 
 fn main() {}
diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr
index fe20c47c57a..76a71067353 100644
--- a/tests/ui/traits/issue-105231.stderr
+++ b/tests/ui/traits/issue-105231.stderr
@@ -1,5 +1,5 @@
 error[E0072]: recursive types `A` and `B` have infinite size
-  --> $DIR/issue-105231.rs:2:1
+  --> $DIR/issue-105231.rs:1:1
    |
 LL | struct A<T>(B<T>);
    | ^^^^^^^^^^^ ---- recursive without indirection
@@ -15,10 +15,14 @@ LL ~ struct B<T>(Box<A<A<T>>>);
    |
 
 error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
+  --> $DIR/issue-105231.rs:5:28
+   |
+LL | impl<T> Foo for T where T: Send {}
+   |                            ^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
 note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
-  --> $DIR/issue-105231.rs:4:8
+  --> $DIR/issue-105231.rs:3:8
    |
 LL | struct B<T>(A<A<T>>);
    |        ^
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
new file mode 100644
index 00000000000..b39ae0333ad
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Ztrait-solver=next
+
+// Coherence should handle overflow while normalizing for
+// `trait_ref_is_knowable` correctly.
+
+trait Overflow {
+    type Assoc;
+}
+impl<T> Overflow for T {
+    type Assoc = <T as Overflow>::Assoc;
+}
+
+
+trait Trait {}
+impl<T: Copy> Trait for T {}
+struct LocalTy;
+impl Trait for <LocalTy as Overflow>::Assoc {}
+//~^ ERROR conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
new file mode 100644
index 00000000000..5d5f325e4b4
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
+  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:17:1
+   |
+LL | impl<T: Copy> Trait for T {}
+   | ------------------------- first implementation here
+LL | struct LocalTy;
+LL | impl Trait for <LocalTy as Overflow>::Assoc {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<LocalTy as Overflow>::Assoc`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs
new file mode 100644
index 00000000000..c38e3baf5b4
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Id {
+    type Assoc;
+}
+impl<T> Id for T {
+    type Assoc = T;
+}
+
+
+// Coherence should be able to reason that `<LocalTy as Id>::Assoc: Copy`
+// does not hold.
+//
+// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
+// for more details.
+trait Trait {}
+impl<T: Copy> Trait for T {}
+struct LocalTy;
+impl Trait for <LocalTy as Id>::Assoc {}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs
new file mode 100644
index 00000000000..2d53266db09
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs
@@ -0,0 +1,25 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+use std::future::{Future, IntoFuture};
+use std::pin::Pin;
+
+// We check that this does not overlap with the following impl from std:
+//     impl<P> Future for Pin<P> where P: DerefMut, <P as Deref>::Target: Future { .. }
+// This should fail because we know ` <&mut Value as Deref>::Target: Future` not to hold.
+// For this to work we have to normalize in the `trait_ref_is_knowable` check as we
+// otherwise add an ambiguous candidate here.
+//
+// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
+// for more details.
+struct Value;
+impl<'a> IntoFuture for Pin<&'a mut Value> {
+    type Output = ();
+    type IntoFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
+
+    fn into_future(self) -> Self::IntoFuture {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs
new file mode 100644
index 00000000000..2f27de4e4f4
--- /dev/null
+++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs
@@ -0,0 +1,24 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Id {
+    type Assoc;
+}
+impl<T> Id for T {
+    type Assoc = T;
+}
+
+
+// Coherence should be able to reason that `(): PartialEq<<T as Id>::Assoc>>`
+// does not hold.
+//
+// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
+// for more details.
+trait Trait {}
+impl<T> Trait for T
+where
+    (): PartialEq<T> {}
+struct LocalTy;
+impl Trait for <LocalTy as Id>::Assoc {}
+
+fn main() {}
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
index d37943b929a..206ab07898b 100644
--- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
@@ -1,4 +1,3 @@
-//~ ERROR overflow
 // A regression test for #111729 checking that we correctly
 // track recursion depth for obligations returned by confirmation.
 use std::panic::RefUnwindSafe;
@@ -15,6 +14,7 @@ struct RootDatabase {
 }
 
 impl<T: RefUnwindSafe> Database for T {
+    //~^ ERROR overflow
     type Storage = SalsaStorage;
 }
 impl Database for RootDatabase {
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
index 8f9ce3ef1e9..4123a8199a0 100644
--- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
@@ -1,13 +1,17 @@
 error[E0275]: overflow evaluating the requirement `Runtime<RootDatabase>: RefUnwindSafe`
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:16:9
+   |
+LL | impl<T: RefUnwindSafe> Database for T {
+   |         ^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_via_builtin_auto_trait_impl`)
 note: required because it appears within the type `RootDatabase`
-  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:13:8
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:12:8
    |
 LL | struct RootDatabase {
    |        ^^^^^^^^^^^^
 note: required for `RootDatabase` to implement `Database`
-  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:17:24
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:16:24
    |
 LL | impl<T: RefUnwindSafe> Database for T {
    |         -------------  ^^^^^^^^     ^
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
index 82b4e9bd72a..d48d9b89d1d 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.current.stderr
@@ -1,5 +1,5 @@
 error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
-  --> $DIR/type-checking-test-1.rs:16:13
+  --> $DIR/type-checking-test-1.rs:19:13
    |
 LL |     let _ = x as &dyn Bar<_>; // Ambiguous
    |             ^^^^^^^^^^^^^^^^ invalid cast
@@ -10,7 +10,7 @@ LL |     let _ = &x as &dyn Bar<_>; // Ambiguous
    |             +
 
 error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
-  --> $DIR/type-checking-test-1.rs:16:13
+  --> $DIR/type-checking-test-1.rs:19:13
    |
 LL |     let _ = x as &dyn Bar<_>; // Ambiguous
    |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr
new file mode 100644
index 00000000000..b612005fcb0
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.next.stderr
@@ -0,0 +1,9 @@
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
+  --> $DIR/type-checking-test-1.rs:19:13
+   |
+LL |     let _ = x as &dyn Bar<_>; // Ambiguous
+   |             ^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
index 6bc9f4a75d3..7c7beec0809 100644
--- a/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
+++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -1,3 +1,6 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
 #![feature(trait_upcasting)]
 
 trait Foo: Bar<i32> + Bar<u32> {}
@@ -15,7 +18,7 @@ fn test_specific(x: &dyn Foo) {
 fn test_unknown_version(x: &dyn Foo) {
     let _ = x as &dyn Bar<_>; // Ambiguous
                               //~^ ERROR non-primitive cast
-                              //~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
+                              //[current]~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
 }
 
 fn test_infer_version(x: &dyn Foo) {
diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs
index 077a31494a9..1700c800e31 100644
--- a/tests/ui/type-alias-impl-trait/coherence.rs
+++ b/tests/ui/type-alias-impl-trait/coherence.rs
@@ -11,7 +11,7 @@ fn use_alias<T>(val: T) -> AliasOfForeignType<T> {
     foreign_crate::ForeignType(val)
 }
 
-impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
+impl foreign_crate::ForeignTrait for AliasOfForeignType<()> {}
 //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.stderr
index c923eb08ab3..36bbb985ef0 100644
--- a/tests/ui/type-alias-impl-trait/coherence.stderr
+++ b/tests/ui/type-alias-impl-trait/coherence.stderr
@@ -1,10 +1,10 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
   --> $DIR/coherence.rs:14:1
    |
-LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------
-   | |                                       |
-   | |                                       `AliasOfForeignType<T>` is not defined in the current crate
+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
diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.rs b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
index 679b2b0f188..1ec8877eaeb 100644
--- a/tests/ui/type-alias-impl-trait/coherence_generalization.rs
+++ b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
@@ -2,6 +2,7 @@
 
 // FIXME(type_alias_impl_trait): What does this test? This needs a comment
 // explaining what we're worried about here.
+
 #![feature(type_alias_impl_trait)]
 trait Trait {}
 type Opaque<T> = impl Sized;
@@ -9,7 +10,7 @@ fn foo<T>() -> Opaque<T> {
     ()
 }
 
-impl<T, V> Trait for (T, V, V, u32) {}
-impl<U, V> Trait for (Opaque<U>, V, i32, V) {}
+impl<T, U, V> Trait for (T, U, V, V, u32) {}
+impl<U, V> Trait for (Opaque<U>, U, V, i32, V) {}
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs
new file mode 100644
index 00000000000..b3510067047
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Display;
+
+type Opaque<X> = impl Sized + 'static;
+fn define<X>() -> Opaque<X> {}
+
+trait Trait {
+    type Assoc: Display;
+}
+impl<'a> Trait for Opaque<&'a str> {
+    //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+    type Assoc = &'a str;
+}
+
+// ======= Exploit =======
+
+fn extend<T: Trait + 'static>(s: T::Assoc) -> Box<dyn Display> {
+    Box::new(s)
+}
+
+fn main() {
+    let val = extend::<Opaque<&'_ str>>(&String::from("blah blah blah"));
+    println!("{}", val);
+}
diff --git a/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr
new file mode 100644
index 00000000000..65139307f8e
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/unconstrained-impl-param.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/unconstrained-impl-param.rs:11:6
+   |
+LL | impl<'a> Trait for Opaque<&'a str> {
+   |      ^^ unconstrained lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/unsized/issue-75899.rs b/tests/ui/unsized/issue-75899.rs
index abff17e11b5..71943103291 100644
--- a/tests/ui/unsized/issue-75899.rs
+++ b/tests/ui/unsized/issue-75899.rs
@@ -1,3 +1,5 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 // check-pass
 
 trait Trait {}
diff --git a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
index cf7d06b6179..ea60fa70876 100644
--- a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
+++ b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
@@ -14,7 +14,6 @@ trait Trait {
 
 impl Trait for bool {
     fn a<T: Bound>(&self, _: T) {}
-    //^~ This gets rejected but should be accepted
     fn b<T>(&self, _: T) where T: Bound {}
     fn c<T: Bound>(&self, _: T) {}
     fn d<T>(&self, _: T) where T: Bound {}
diff --git a/triagebot.toml b/triagebot.toml
index c513dce3f40..b2ea206a8a2 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -490,7 +490,7 @@ cc = ["@nnethercote"]
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
-users_on_vacation = ["jyn514", "WaffleLapkin", "clubby789"]
+users_on_vacation = ["jyn514", "WaffleLapkin", "clubby789", "oli-obk"]
 
 [assign.adhoc_groups]
 compiler-team = [