about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-08-10 19:07:11 +0200
committerRalf Jung <post@ralfj.de>2023-08-10 19:07:11 +0200
commit2e14f25c9b7ede9519ebb99eb8424511aab48371 (patch)
tree168e6eec8c0d01a0d5f8b9e5805ba0f98f9511f1
parenta549de1588f114a0400e21911806a124cd69fcc8 (diff)
parent9fa6bdd764a1f7bdf69eccceeace6d13f38cb2e1 (diff)
downloadrust-2e14f25c9b7ede9519ebb99eb8424511aab48371.tar.gz
rust-2e14f25c9b7ede9519ebb99eb8424511aab48371.zip
Merge from rustc
-rw-r--r--.github/ISSUE_TEMPLATE/tracking_issue.md3
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_ast/src/ast.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs17
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs96
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs101
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/audit.yml19
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs10
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/bench.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_backend.rs16
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs35
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/main.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/path.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs14
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/shared_utils.rs26
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs36
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/usage.txt2
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/utils.rs19
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Allow-internal-features.patch24
-rw-r--r--compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml4
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs63
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh8
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs43
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs25
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs140
-rw-r--r--compiler/rustc_const_eval/src/errors.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs16
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs10
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs11
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs7
-rw-r--r--compiler/rustc_data_structures/src/base_n.rs5
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs16
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs3
-rw-r--r--compiler/rustc_hir/src/intravisit.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs152
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs70
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs94
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs3
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs79
-rw-r--r--compiler/rustc_interface/src/passes.rs47
-rw-r--r--compiler/rustc_interface/src/queries.rs163
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp17
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp19
-rw-r--r--compiler/rustc_metadata/src/creader.rs8
-rw-r--r--compiler/rustc_metadata/src/locator.rs13
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs2
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs19
-rw-r--r--compiler/rustc_middle/src/ty/context.rs82
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs11
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs6
-rw-r--r--compiler/rustc_passes/src/stability.rs10
-rw-r--r--compiler/rustc_session/messages.ftl4
-rw-r--r--compiler/rustc_session/src/errors.rs4
-rw-r--r--compiler/rustc_session/src/session.rs12
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs61
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs149
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs25
-rw-r--r--compiler/rustc_target/src/abi/mod.rs7
-rw-r--r--compiler/rustc_target/src/json.rs5
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs16
-rw-r--r--compiler/rustc_target/src/spec/abi.rs30
-rw-r--r--compiler/rustc_target/src/spec/abi/tests.rs6
-rw-r--r--compiler/rustc_target/src/spec/mod.rs6
-rw-r--r--compiler/rustc_target/src/spec/teeos_base.rs29
-rw-r--r--compiler/rustc_trait_selection/messages.ftl9
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs36
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs71
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs6
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs3
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs35
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs65
-rw-r--r--library/core/src/ascii/ascii_char.rs4
-rw-r--r--library/core/src/escape.rs4
-rw-r--r--library/core/src/marker.rs10
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/f32.rs42
-rw-r--r--library/std/src/f32/tests.rs32
-rw-r--r--library/std/src/f64.rs42
-rw-r--r--library/std/src/f64/tests.rs32
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/sys/unix/cmath.rs4
-rw-r--r--library/std/src/sys/unix/process/process_fuchsia.rs2
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs223
-rw-r--r--library/std/src/sys/unix/process/process_unix/tests.rs25
-rw-r--r--library/std/src/sys/unix/process/process_unsupported.rs2
-rw-r--r--library/std/src/sys/unix/process/process_vxworks.rs2
-rw-r--r--library/std/src/sys/unsupported/process.rs37
-rw-r--r--library/std/src/sys/windows/cmath.rs6
-rw-r--r--library/std/src/sys/windows/process.rs2
-rw-r--r--library/test/src/term/terminfo/searcher/tests.rs12
-rw-r--r--src/bootstrap/bootstrap.py4
-rw-r--r--src/bootstrap/bootstrap_test.py19
-rw-r--r--src/bootstrap/builder.rs10
-rw-r--r--src/bootstrap/builder/tests.rs6
-rw-r--r--src/bootstrap/compile.rs37
-rw-r--r--src/bootstrap/config.rs4
-rw-r--r--src/bootstrap/doc.rs2
-rw-r--r--src/bootstrap/flags.rs18
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/bootstrap/llvm.rs20
-rw-r--r--src/bootstrap/mk/Makefile.in4
-rw-r--r--src/bootstrap/test.rs15
-rw-r--r--src/ci/docker/host-x86_64/i686-gnu/Dockerfile10
-rw-r--r--src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile6
-rw-r--r--src/ci/docker/host-x86_64/wasm32/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh4
-rwxr-xr-xsrc/ci/docker/scripts/fuchsia-test-runner.py6
-rw-r--r--src/ci/github-actions/ci.yml4
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md100
-rw-r--r--src/doc/rustc/src/platform-support/android.md2
-rw-r--r--src/etc/completions/x.py.fish17
-rw-r--r--src/etc/completions/x.py.ps115
-rw-r--r--src/etc/completions/x.py.sh90
-rw-r--r--src/tools/compiletest/src/runtest.rs2
-rw-r--r--src/tools/opt-dist/src/bolt.rs7
-rw-r--r--src/tools/opt-dist/src/main.rs2
-rw-r--r--src/tools/opt-dist/src/tests.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs2
-rw-r--r--src/tools/tidy/config/black.toml15
-rw-r--r--src/tools/tidy/config/requirements.in10
-rw-r--r--src/tools/tidy/config/requirements.txt117
-rw-r--r--src/tools/tidy/config/ruff.toml41
-rw-r--r--src/tools/tidy/src/ext_tool_checks.rs435
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs13
-rw-r--r--tests/run-make/optimization-remarks-dir-pgo/Makefile20
-rw-r--r--tests/run-make/optimization-remarks-dir-pgo/foo.rs6
-rw-r--r--tests/rustdoc-gui/links-color.goml72
-rw-r--r--tests/rustdoc-json/enums/field_order.rs40
-rw-r--r--tests/rustdoc-json/enums/variant_order.rs38
-rw-r--r--tests/rustdoc-json/structs/field_order.rs38
-rw-r--r--tests/rustdoc-json/unions/field_order.rs38
-rw-r--r--tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr27
-rw-r--r--tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr27
-rw-r--r--tests/ui/abi/riscv-discoverability-guidance.rs27
-rw-r--r--tests/ui/abi/unsupported.aarch64.stderr26
-rw-r--r--tests/ui/abi/unsupported.arm.stderr24
-rw-r--r--tests/ui/abi/unsupported.i686.stderr20
-rw-r--r--tests/ui/abi/unsupported.riscv32.stderr61
-rw-r--r--tests/ui/abi/unsupported.riscv64.stderr61
-rw-r--r--tests/ui/abi/unsupported.rs40
-rw-r--r--tests/ui/abi/unsupported.x64.stderr24
-rw-r--r--tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr2
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr1
-rw-r--r--tests/ui/async-await/async-await-let-else.drop_tracking.stderr4
-rw-r--r--tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr4
-rw-r--r--tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr4
-rw-r--r--tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr2
-rw-r--r--tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr2
-rw-r--r--tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr5
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr17
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr17
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr11
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr11
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr11
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr11
-rw-r--r--tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr37
-rw-r--r--tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr37
-rw-r--r--tests/ui/async-await/in-trait/async-generics.current.stderr37
-rw-r--r--tests/ui/async-await/in-trait/async-generics.next.stderr37
-rw-r--r--tests/ui/async-await/in-trait/async-recursive-generic.current.stderr12
-rw-r--r--tests/ui/async-await/in-trait/async-recursive-generic.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/async-recursive.current.stderr12
-rw-r--r--tests/ui/async-await/in-trait/async-recursive.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/bad-signatures.current.stderr17
-rw-r--r--tests/ui/async-await/in-trait/bad-signatures.next.stderr17
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr10
-rw-r--r--tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr25
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr12
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.current.stderr16
-rw-r--r--tests/ui/async-await/in-trait/generics-mismatch.next.stderr16
-rw-r--r--tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr12
-rw-r--r--tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.current.stderr30
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.next.stderr30
-rw-r--r--tests/ui/async-await/in-trait/missing-send-bound.current.stderr20
-rw-r--r--tests/ui/async-await/in-trait/missing-send-bound.next.stderr20
-rw-r--r--tests/ui/async-await/in-trait/missing-send-bound.stderr1
-rw-r--r--tests/ui/async-await/in-trait/object-safety.current.stderr18
-rw-r--r--tests/ui/async-await/in-trait/object-safety.next.stderr18
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr39
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr39
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr9
-rw-r--r--tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr9
-rw-r--r--tests/ui/async-await/in-trait/return-type-suggestion.current.stderr14
-rw-r--r--tests/ui/async-await/in-trait/return-type-suggestion.next.stderr14
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-64130-non-send-future-diags.stderr1
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-70818.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-70818.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/issue-70818.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-71137.stderr1
-rw-r--r--tests/ui/async-await/issue-86507.drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issue-86507.drop_tracking_mir.stderr1
-rw-r--r--tests/ui/async-await/issue-86507.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr1
-rw-r--r--tests/ui/async-await/issues/issue-67893.stderr1
-rw-r--r--tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr5
-rw-r--r--tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr5
-rw-r--r--tests/ui/async-await/partial-drop-partial-reinit.rs1
-rw-r--r--tests/ui/auto-traits/issue-83857-ub.stderr1
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr2
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr1
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr1
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr1
-rw-r--r--tests/ui/check-cfg/values-target-json.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr2
-rw-r--r--tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr1
-rw-r--r--tests/ui/closures/closure-bounds-subtype.stderr1
-rw-r--r--tests/ui/closures/closure-move-sync.stderr1
-rw-r--r--tests/ui/const-generics/const_trait_fn-issue-88433.rs2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.rs8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.stderr75
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr42
-rw-r--r--tests/ui/const-generics/slice-const-param.rs21
-rw-r--r--tests/ui/consts/const-try.stderr33
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.rs2
-rw-r--r--tests/ui/consts/rustc-impl-const-stability.stderr12
-rw-r--r--tests/ui/error-codes/E0277-2.stderr1
-rw-r--r--tests/ui/extern/extern-type-diag-not-similar.stderr1
-rw-r--r--tests/ui/extern/extern-types-not-sync-send.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs33
-rw-r--r--tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr57
-rw-r--r--tests/ui/fmt/send-sync.stderr2
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr3
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr3
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr8
-rw-r--r--tests/ui/generator/drop-yield-twice.stderr1
-rw-r--r--tests/ui/generator/issue-57017.no_drop_tracking.stderr6
-rw-r--r--tests/ui/generator/issue-57478.no_drop_tracking.stderr1
-rw-r--r--tests/ui/generator/not-send-sync.drop_tracking.stderr2
-rw-r--r--tests/ui/generator/not-send-sync.drop_tracking_mir.stderr2
-rw-r--r--tests/ui/generator/not-send-sync.no_drop_tracking.stderr2
-rw-r--r--tests/ui/generator/parent-expression.drop_tracking.stderr3
-rw-r--r--tests/ui/generator/parent-expression.drop_tracking_mir.stderr3
-rw-r--r--tests/ui/generator/parent-expression.no_drop_tracking.stderr8
-rw-r--r--tests/ui/generator/partial-drop.drop_tracking.stderr2
-rw-r--r--tests/ui/generator/partial-drop.no_drop_tracking.stderr2
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr2
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr2
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr2
-rw-r--r--tests/ui/generator/ref-upvar-not-send.rs2
-rw-r--r--tests/ui/generator/ref-upvar-not-send.stderr12
-rw-r--r--tests/ui/generic-associated-types/streaming_iterator.rs3
-rw-r--r--tests/ui/impl-trait/auto-trait-leak2.rs2
-rw-r--r--tests/ui/impl-trait/auto-trait-leak2.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr1
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match.current.stderr15
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match.next.stderr15
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr11
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr11
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr24
-rw-r--r--tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr24
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.current.stderr33
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.next.stderr29
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102571.current.stderr14
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102571.next.stderr14
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.current.stderr49
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.next.stderr49
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs11
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr61
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr61
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-broken.current.stderr31
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-broken.next.stderr31
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr9
-rw-r--r--tests/ui/impl-trait/in-trait/wf-bounds.current.stderr57
-rw-r--r--tests/ui/impl-trait/in-trait/wf-bounds.next.stderr57
-rw-r--r--tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs15
-rw-r--r--tests/ui/inline-const/instance-doesnt-depend-on-type.rs10
-rw-r--r--tests/ui/issues/issue-21763.stderr1
-rw-r--r--tests/ui/issues/issue-24446.stderr1
-rw-r--r--tests/ui/issues/issue-40827.stderr2
-rw-r--r--tests/ui/kindck/kindck-impl-type-params.stderr2
-rw-r--r--tests/ui/kindck/kindck-nonsendable-1.stderr1
-rw-r--r--tests/ui/kindck/kindck-send-object.stderr2
-rw-r--r--tests/ui/kindck/kindck-send-object1.stderr2
-rw-r--r--tests/ui/kindck/kindck-send-object2.stderr2
-rw-r--r--tests/ui/kindck/kindck-send-owned.stderr1
-rw-r--r--tests/ui/kindck/kindck-send-unsafe.stderr2
-rw-r--r--tests/ui/lto/issue-100772.rs4
-rw-r--r--tests/ui/mut/mutable-enum-indirect.stderr1
-rw-r--r--tests/ui/no-send-res-ports.stderr1
-rw-r--r--tests/ui/no_send-enum.stderr1
-rw-r--r--tests/ui/no_send-rc.stderr1
-rw-r--r--tests/ui/no_share-enum.stderr1
-rw-r--r--tests/ui/no_share-struct.stderr1
-rw-r--r--tests/ui/phantom-auto-trait.stderr2
-rw-r--r--tests/ui/proc-macro/auxiliary/exports_no_mangle.rs11
-rw-r--r--tests/ui/proc-macro/meta-macro-hygiene.rs4
-rw-r--r--tests/ui/proc-macro/meta-macro-hygiene.stdout8
-rw-r--r--tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs22
-rw-r--r--tests/ui/proc-macro/nonterminal-token-hygiene.rs3
-rw-r--r--tests/ui/proc-macro/nonterminal-token-hygiene.stdout13
-rw-r--r--tests/ui/recursion/recursive-requirements.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr28
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr11
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr27
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs7
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr23
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr13
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs1
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr40
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs6
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr17
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr33
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs2
-rw-r--r--tests/ui/sanitize/issue-111184-generator-witness.rs4
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-requires-lto.rs2
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr2
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs8
-rw-r--r--tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr4
-rw-r--r--tests/ui/self/arbitrary_self_type_mut_difference.rs13
-rw-r--r--tests/ui/self/arbitrary_self_type_mut_difference.stderr27
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed17
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs17
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr43
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed12
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_mut_pin.rs12
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr20
-rw-r--r--tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs13
-rw-r--r--tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr33
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.rs2
-rw-r--r--tests/ui/statics/issue-17718-static-sync.stderr1
-rw-r--r--tests/ui/stdlib-unit-tests/not-sync.stderr3
-rw-r--r--tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr2
-rw-r--r--tests/ui/suggestions/issue-84973-blacklist.stderr1
-rw-r--r--tests/ui/suggestions/restrict-type-argument.stderr6
-rw-r--r--tests/ui/traits/alias/cross-crate.stderr2
-rw-r--r--tests/ui/traits/bad-method-typaram-kind.stderr1
-rw-r--r--tests/ui/traits/inductive-overflow/two-traits.stderr1
-rw-r--r--tests/ui/traits/issue-7013.stderr1
-rw-r--r--tests/ui/traits/negative-impls/negated-auto-traits-error.stderr6
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr1
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs46
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr29
-rw-r--r--tests/ui/traits/no_send-struct.stderr1
-rw-r--r--tests/ui/traits/non_lifetime_binders/fail.stderr1
-rw-r--r--tests/ui/traits/unsend-future.stderr1
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr1
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs19
-rw-r--r--tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr1
-rw-r--r--tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr1
-rw-r--r--tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr3
-rw-r--r--tests/ui/typeck/typeck-default-trait-impl-send-param.stderr1
-rw-r--r--tests/ui/typeck/typeck-unsafe-always-share.stderr4
-rwxr-xr-xx.py2
435 files changed, 4197 insertions, 3021 deletions
diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md
index 00659605071..5f17f30b3b0 100644
--- a/.github/ISSUE_TEMPLATE/tracking_issue.md
+++ b/.github/ISSUE_TEMPLATE/tracking_issue.md
@@ -39,10 +39,13 @@ for larger features an implementation could be broken up into multiple PRs.
 - [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring
       instructions?)
 - [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
+- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure])
 - [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide])
 
 [stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
 [doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs
+[nightly-style-procedure]: https://github.com/rust-lang/style-team/blob/master/nightly-style-procedure.md 
+[Style Guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide
 
 ### Unresolved Questions
 <!--
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4121e392ae8..6ff0f5e2736 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -336,7 +336,7 @@ jobs:
             os: macos-13
           - name: x86_64-apple-1
             env:
-              SCRIPT: "./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps"
+              SCRIPT: "./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps"
               RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
               MACOSX_DEPLOYMENT_TARGET: 10.8
diff --git a/Cargo.lock b/Cargo.lock
index 3b270c14bb5..de6258502a3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -641,9 +641,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.98"
+version = "0.1.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfbefa16407456e5cad1ad066c84dfcb980afe4437103a0007d1c2f136130210"
+checksum = "d6c0f24437059853f0fa64afc51f338f93647a3de4cf3358ba1bb4171a199775"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f2e90fd8eed..58725a08c7c 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -313,6 +313,16 @@ pub enum TraitBoundModifier {
     MaybeConstMaybe,
 }
 
+impl TraitBoundModifier {
+    pub fn to_constness(self) -> Const {
+        match self {
+            // FIXME(effects) span
+            Self::MaybeConst => Const::Yes(DUMMY_SP),
+            _ => Const::No,
+        }
+    }
+}
+
 /// The AST represents all type param bounds as types.
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index ab55c09465b..a1e62699680 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -207,6 +207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 &sym.path,
                                 ParamMode::Optional,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                                None,
                             );
                             hir::InlineAsmOperand::SymStatic { path, def_id }
                         } else {
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 72dc52a6329..a63bd4f8a02 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -31,9 +31,26 @@ pub struct InvalidAbi {
     pub abi: Symbol,
     pub command: String,
     #[subdiagnostic]
+    pub explain: Option<InvalidAbiReason>,
+    #[subdiagnostic]
     pub suggestion: Option<InvalidAbiSuggestion>,
 }
 
+pub struct InvalidAbiReason(pub &'static str);
+
+impl rustc_errors::AddToDiagnostic for InvalidAbiReason {
+    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
+    where
+        F: Fn(
+            &mut rustc_errors::Diagnostic,
+            rustc_errors::SubdiagnosticMessage,
+        ) -> rustc_errors::SubdiagnosticMessage,
+    {
+        #[allow(rustc::untranslatable_diagnostic)]
+        diag.note(self.0);
+    }
+}
+
 #[derive(Subdiagnostic)]
 #[suggestion(
     ast_lowering_invalid_abi_suggestion,
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 42d0998d162..b23cee14f75 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -100,6 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         ParamMode::Optional,
                         ParenthesizedGenericArgs::Err,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     ));
                     let receiver = self.lower_expr(receiver);
                     let args =
@@ -260,6 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     hir::ExprKind::Path(qpath)
                 }
@@ -307,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         )),
                         self.arena
                             .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@@ -1179,6 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a tuple struct.
                     let tuple_struct_pat = hir::PatKind::TupleStruct(
@@ -1198,6 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         path,
                         ParamMode::Optional,
                         &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        None,
                     );
                     // Destructure like a unit struct.
                     let unit_struct_pat = hir::PatKind::Path(qpath);
@@ -1222,6 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.path,
                     ParamMode::Optional,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 );
                 let fields_omitted = match &se.rest {
                     StructRest::Base(e) => {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index df73c721ade..a59c83de0f4 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1,4 +1,4 @@
-use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
+use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
 use super::ResolverAstLoweringExt;
 use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
 use super::{FnDeclKind, LoweringContext, ParamMode};
@@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
             allow_gen_future,
             generics_def_id_map: Default::default(),
+            host_param_id: None,
         };
         lctx.with_hir_id_owner(owner, |lctx| f(lctx));
 
@@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
             // This is used to track which lifetimes have already been defined,
             // and which need to be replicated when lowering an async fn.
 
-            if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind {
-                lctx.is_in_trait_impl = impl_.of_trait.is_some();
+            match parent_hir.node().expect_item().kind {
+                hir::ItemKind::Impl(impl_) => {
+                    lctx.is_in_trait_impl = impl_.of_trait.is_some();
+                }
+                hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => {
+                    lctx.host_param_id = generics
+                        .params
+                        .iter()
+                        .find(|param| {
+                            parent_hir
+                                .attrs
+                                .get(param.hir_id.local_id)
+                                .iter()
+                                .any(|attr| attr.has_name(sym::rustc_host))
+                        })
+                        .map(|param| param.def_id);
+                }
+                _ => {}
             }
 
             match ctxt {
@@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.lower_generics(ast_generics, *constness, id, &itctx, |this| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(
+                                *constness,
                                 trait_ref,
                                 &ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
                             )
@@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     polarity,
                     defaultness,
                     defaultness_span,
-                    constness: self.lower_constness(*constness),
                     generics,
                     of_trait: trait_ref,
                     self_ty: lowered_ty,
@@ -1254,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
-        abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
-            self.error_on_invalid_abi(abi);
+        abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| {
+            self.error_on_invalid_abi(abi, err);
             abi::Abi::Rust
         })
     }
@@ -1268,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    fn error_on_invalid_abi(&self, abi: StrLit) {
+    fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) {
         let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
             .iter()
             .map(|s| Symbol::intern(s))
@@ -1277,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         self.tcx.sess.emit_err(InvalidAbi {
             abi: abi.symbol_unescaped,
             span: abi.span,
+            explain: match err {
+                abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)),
+                _ => None,
+            },
             suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
                 span: abi.span,
                 suggestion: format!("\"{suggested_name}\""),
@@ -1363,6 +1384,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         }
 
+        // Desugar `~const` bound in generics into an additional `const host: bool` param
+        // if the effects feature is enabled. This needs to be done before we lower where
+        // clauses since where clauses need to bind to the DefId of the host param
+        let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects {
+            if let Some(param) = generics.params.iter().find(|x| {
+                x.attrs.iter().any(|x| x.has_name(sym::rustc_host))
+            }) {
+                // user has manually specified a `rustc_host` param, in this case, we set
+                // the param id so that lowering logic can use that. But we don't create
+                // another host param, so this gives `None`.
+                self.host_param_id = Some(self.local_def_id(param.id));
+                None
+            } else {
+                let param_node_id = self.next_node_id();
+                let hir_id = self.next_id();
+                let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
+                self.host_param_id = Some(def_id);
+                Some((span, hir_id, def_id))
+            }
+        } else {
+            None
+        };
+
         let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
         predicates.extend(generics.params.iter().filter_map(|param| {
             self.lower_generic_bound_predicate(
@@ -1410,22 +1454,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
         predicates.extend(impl_trait_bounds.into_iter());
 
-        // Desugar `~const` bound in generics into an additional `const host: bool` param
-        // if the effects feature is enabled.
-        if let Const::Yes(span) = constness && self.tcx.features().effects
-            // Do not add host param if it already has it (manually specified)
-            && !params.iter().any(|x| {
-                self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| {
-                    attrs.iter().any(|x| x.has_name(sym::rustc_host))
-                })
-            })
-        {
-            let param_node_id = self.next_node_id();
+        if let Some((span, hir_id, def_id)) = host_param_parts {
             let const_node_id = self.next_node_id();
-            let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span);
-            let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
+            let anon_const: LocalDefId =
+                self.create_def(def_id, const_node_id, DefPathData::AnonConst, span);
 
-            let hir_id = self.next_id();
             let const_id = self.next_id();
             let const_expr_id = self.next_id();
             let bool_id = self.next_id();
@@ -1435,14 +1468,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
 
-            let attrs = self.arena.alloc_from_iter([
-                Attribute {
-                    kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            let attrs = self.arena.alloc_from_iter([Attribute {
+                kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(
+                    sym::rustc_host,
                     span,
-                    id: attr_id,
-                    style: AttrStyle::Outer,
-                },
-            ]);
+                )))),
+                span,
+                id: attr_id,
+                style: AttrStyle::Outer,
+            }]);
             self.attrs.insert(hir_id.local_id, attrs);
 
             let const_body = self.lower_body(|this| {
@@ -1481,7 +1515,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             }),
                         )),
                     )),
-                    default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }),
+                    default: Some(hir::AnonConst {
+                        def_id: anon_const,
+                        hir_id: const_id,
+                        body: const_body,
+                    }),
                 },
                 colon_span: None,
                 pure_wrt_drop: false,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d29e9f9b3f6..0aeff22ca9f 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> {
     /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
     /// field from the original parameter 'a to the new parameter 'a1.
     generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
+
+    host_param_id: Option<LocalDefId>,
 }
 
 trait ResolverAstLoweringExt {
@@ -1262,6 +1264,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         span: t.span
                     },
                     itctx,
+                    ast::Const::No,
                 );
                 let bounds = this.arena.alloc_from_iter([bound]);
                 let lifetime_bound = this.elided_dyn_bound(t.span);
@@ -1272,7 +1275,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
 
         let id = self.lower_node_id(t.id);
-        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
+        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None);
         self.ty_path(id, t.span, qpath)
     }
 
@@ -1356,10 +1359,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
                             GenericBound::Trait(
                                 ty,
-                                TraitBoundModifier::None
+                                modifier @ (TraitBoundModifier::None
                                 | TraitBoundModifier::MaybeConst
-                                | TraitBoundModifier::Negative,
-                            ) => Some(this.lower_poly_trait_ref(ty, itctx)),
+                                | TraitBoundModifier::Negative),
+                            ) => {
+                                Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness()))
+                            }
                             // `~const ?Bound` will cause an error during AST validation
                             // anyways, so treat it like `?Bound` as compilation proceeds.
                             GenericBound::Trait(
@@ -1663,11 +1668,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             );
             debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
 
-            let lifetime_mapping = if in_trait {
-                Some(&*self.arena.alloc_slice(&synthesized_lifetime_args))
-            } else {
-                None
-            };
+            let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args);
 
             let opaque_ty_item = hir::OpaqueTy {
                 generics: this.arena.alloc(hir::Generics {
@@ -1956,7 +1957,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(p, itctx),
+                self.lower_poly_trait_ref(p, itctx, modifier.to_constness()),
                 self.lower_trait_bound_modifier(*modifier),
             ),
             GenericBound::Outlives(lifetime) => {
@@ -2099,8 +2100,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> {
-        let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
+    fn lower_trait_ref(
+        &mut self,
+        constness: ast::Const,
+        p: &TraitRef,
+        itctx: &ImplTraitContext,
+    ) -> hir::TraitRef<'hir> {
+        let path = match self.lower_qpath(
+            p.ref_id,
+            &None,
+            &p.path,
+            ParamMode::Explicit,
+            itctx,
+            Some(constness),
+        ) {
             hir::QPath::Resolved(None, path) => path,
             qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
         };
@@ -2112,10 +2125,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         p: &PolyTraitRef,
         itctx: &ImplTraitContext,
+        constness: ast::Const,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
             self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
-        let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx);
+        let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx);
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
     }
 
@@ -2469,6 +2483,67 @@ struct GenericArgsCtor<'hir> {
 }
 
 impl<'hir> GenericArgsCtor<'hir> {
+    fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) {
+        if !lcx.tcx.features().effects {
+            return;
+        }
+
+        // if bound is non-const, don't add host effect param
+        let ast::Const::Yes(span) = constness else { return };
+
+        let span = lcx.lower_span(span);
+
+        let id = lcx.next_node_id();
+        let hir_id = lcx.next_id();
+        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(
+                        span,
+                        hir::ExprKind::Lit(
+                            lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }),
+                        ),
+                    ),
+                },
+            )
+        });
+
+        let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id();
+        let attr = lcx.arena.alloc(Attribute {
+            kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))),
+            span,
+            id: attr_id,
+            style: AttrStyle::Outer,
+        });
+        lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr));
+
+        let def_id =
+            lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span);
+        lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
+        self.args.push(hir::GenericArg::Const(hir::ConstArg {
+            value: hir::AnonConst { def_id, hir_id, body },
+            span,
+        }))
+    }
+
     fn is_empty(&self) -> bool {
         self.args.is_empty()
             && self.bindings.is_empty()
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2509b705639..a30f264bc7d 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                         break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@@ -54,6 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
                         break hir::PatKind::Path(qpath);
                     }
@@ -64,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             path,
                             ParamMode::Optional,
                             &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            None,
                         );
 
                         let fs = self.arena.alloc_from_iter(fields.iter().map(|f| {
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 441282c05b4..899f92a9958 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -23,6 +23,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Path,
         param_mode: ParamMode,
         itctx: &ImplTraitContext,
+        // constness of the impl/bound if this is a trait path
+        constness: Option<ast::Const>,
     ) -> hir::QPath<'hir> {
         let qself_position = qself.as_ref().map(|q| q.position);
         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
@@ -73,6 +75,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         param_mode,
                         parenthesized_generic_args,
                         itctx,
+                        // if this is the last segment, add constness to the trait path
+                        if i == proj_start - 1 { constness } else { None },
                     )
                 },
             )),
@@ -119,6 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 param_mode,
                 ParenthesizedGenericArgs::Err,
                 itctx,
+                None,
             ));
             let qpath = hir::QPath::TypeRelative(ty, hir_segment);
 
@@ -159,6 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     param_mode,
                     ParenthesizedGenericArgs::Err,
                     &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    None,
                 )
             })),
             span: self.lower_span(p.span),
@@ -172,8 +178,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         param_mode: ParamMode,
         parenthesized_generic_args: ParenthesizedGenericArgs,
         itctx: &ImplTraitContext,
+        constness: Option<ast::Const>,
     ) -> hir::PathSegment<'hir> {
-        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
+        debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment);
         let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() {
             match generic_args {
                 GenericArgs::AngleBracketed(data) => {
@@ -231,6 +238,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             )
         };
 
+        if let Some(constness) = constness {
+            generic_args.push_constness(self, constness);
+        }
+
         let has_lifetimes =
             generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)));
 
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml
new file mode 100644
index 00000000000..3efdec41559
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml
@@ -0,0 +1,19 @@
+name: Security audit
+on:
+  workflow_dispatch:
+  schedule:
+    - cron: '0 10 * * 1' # every monday at 10:00 UTC
+permissions:
+  issues: write
+  checks: write
+jobs:
+  audit:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - run: |
+          sed -i 's/components.*/components = []/' rust-toolchain
+          echo 'profile = "minimal"' >> rust-toolchain
+      - uses: rustsec/audit-check@v1.4.1
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs
index 29c127bf50e..2e7ba1b2060 100644
--- a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs
@@ -1,8 +1,8 @@
-use super::build_sysroot;
-use super::path::Dirs;
-use super::prepare::GitRepo;
-use super::utils::{spawn_and_wait, CargoProject, Compiler};
-use super::{CodegenBackend, SysrootKind};
+use crate::build_sysroot;
+use crate::path::Dirs;
+use crate::prepare::GitRepo;
+use crate::utils::{spawn_and_wait, CargoProject, Compiler};
+use crate::{CodegenBackend, SysrootKind};
 
 static ABI_CAFE_REPO: GitRepo = GitRepo::github(
     "Gankra",
diff --git a/compiler/rustc_codegen_cranelift/build_system/bench.rs b/compiler/rustc_codegen_cranelift/build_system/bench.rs
index cec608ea042..6c64faaa256 100644
--- a/compiler/rustc_codegen_cranelift/build_system/bench.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/bench.rs
@@ -2,10 +2,10 @@ use std::env;
 use std::io::Write;
 use std::path::Path;
 
-use super::path::{Dirs, RelPath};
-use super::prepare::GitRepo;
-use super::rustc_info::get_file_name;
-use super::utils::{hyperfine_command, spawn_and_wait, Compiler};
+use crate::path::{Dirs, RelPath};
+use crate::prepare::GitRepo;
+use crate::rustc_info::get_file_name;
+use crate::utils::{hyperfine_command, spawn_and_wait, Compiler};
 
 static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
     "ebobby",
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
index 1c5db23299d..e434c36f992 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
@@ -1,9 +1,9 @@
-use std::env;
 use std::path::PathBuf;
 
-use super::path::{Dirs, RelPath};
-use super::rustc_info::get_file_name;
-use super::utils::{is_ci, is_ci_opt, maybe_incremental, CargoProject, Compiler, LogGroup};
+use crate::path::{Dirs, RelPath};
+use crate::rustc_info::get_file_name;
+use crate::shared_utils::{rustflags_from_env, rustflags_to_cmd_env};
+use crate::utils::{is_ci, is_ci_opt, maybe_incremental, CargoProject, Compiler, LogGroup};
 
 pub(crate) static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
 
@@ -18,11 +18,11 @@ pub(crate) fn build_backend(
     let mut cmd = CG_CLIF.build(&bootstrap_host_compiler, dirs);
     maybe_incremental(&mut cmd);
 
-    let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default();
+    let mut rustflags = rustflags_from_env("RUSTFLAGS");
 
     if is_ci() {
         // Deny warnings on CI
-        rustflags += " -Dwarnings";
+        rustflags.push("-Dwarnings".to_owned());
 
         if !is_ci_opt() {
             cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true");
@@ -42,10 +42,10 @@ pub(crate) fn build_backend(
         _ => unreachable!(),
     }
 
-    cmd.env("RUSTFLAGS", rustflags);
+    rustflags_to_cmd_env(&mut cmd, "RUSTFLAGS", &rustflags);
 
     eprintln!("[BUILD] rustc_codegen_cranelift");
-    super::utils::spawn_and_wait(cmd);
+    crate::utils::spawn_and_wait(cmd);
 
     CG_CLIF
         .target_dir(dirs)
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
index 04097936d03..31a4b209826 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
@@ -2,13 +2,13 @@ use std::fs;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-use super::path::{Dirs, RelPath};
-use super::rustc_info::get_file_name;
-use super::utils::{
+use crate::path::{Dirs, RelPath};
+use crate::rustc_info::get_file_name;
+use crate::utils::{
     maybe_incremental, remove_dir_if_exists, spawn_and_wait, try_hard_link, CargoProject, Compiler,
     LogGroup,
 };
-use super::{CodegenBackend, SysrootKind};
+use crate::{config, CodegenBackend, SysrootKind};
 
 static DIST_DIR: RelPath = RelPath::DIST;
 static BIN_DIR: RelPath = RelPath::DIST.join("bin");
@@ -128,8 +128,8 @@ pub(crate) fn build_sysroot(
             cargo: bootstrap_host_compiler.cargo.clone(),
             rustc: rustc_clif.clone(),
             rustdoc: rustdoc_clif.clone(),
-            rustflags: String::new(),
-            rustdocflags: String::new(),
+            rustflags: vec![],
+            rustdocflags: vec![],
             triple: target_triple,
             runner: vec![],
         }
@@ -185,7 +185,7 @@ fn build_sysroot_for_triple(
 
 #[must_use]
 fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget {
-    let default_sysroot = super::rustc_info::get_default_sysroot(&compiler.rustc);
+    let default_sysroot = crate::rustc_info::get_default_sysroot(&compiler.rustc);
 
     let mut target_libs = SysrootTarget { triple: compiler.triple, libs: vec![] };
 
@@ -234,32 +234,32 @@ fn build_clif_sysroot_for_triple(
 
     let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join(channel);
 
-    if !super::config::get_bool("keep_sysroot") {
+    if !config::get_bool("keep_sysroot") {
         // Cleanup the deps dir, but keep build scripts and the incremental cache for faster
         // recompilation as they are not affected by changes in cg_clif.
         remove_dir_if_exists(&build_dir.join("deps"));
     }
 
     // Build sysroot
-    let mut rustflags = " -Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
+    let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned(), "-Cpanic=abort".to_owned()];
     match cg_clif_dylib_path {
         CodegenBackend::Local(path) => {
-            rustflags.push_str(&format!(" -Zcodegen-backend={}", path.to_str().unwrap()));
+            rustflags.push(format!("-Zcodegen-backend={}", path.to_str().unwrap()));
         }
         CodegenBackend::Builtin(name) => {
-            rustflags.push_str(&format!(" -Zcodegen-backend={name}"));
+            rustflags.push(format!("-Zcodegen-backend={name}"));
         }
     };
     // Necessary for MinGW to find rsbegin.o and rsend.o
-    rustflags
-        .push_str(&format!(" --sysroot {}", RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap()));
+    rustflags.push("--sysroot".to_owned());
+    rustflags.push(RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap().to_owned());
     if channel == "release" {
         // Incremental compilation by default disables mir inlining. This leads to both a decent
         // compile perf and a significant runtime perf regression. As such forcefully enable mir
         // inlining.
-        rustflags.push_str(" -Zinline-mir");
+        rustflags.push("-Zinline-mir".to_owned());
     }
-    compiler.rustflags += &rustflags;
+    compiler.rustflags.extend(rustflags);
     let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs);
     maybe_incremental(&mut build_cmd);
     if channel == "release" {
@@ -289,8 +289,8 @@ fn build_clif_sysroot_for_triple(
 }
 
 fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option<SysrootTarget> {
-    if !super::config::get_bool("keep_sysroot") {
-        super::prepare::prepare_stdlib(dirs, &compiler.rustc);
+    if !config::get_bool("keep_sysroot") {
+        crate::prepare::prepare_stdlib(dirs, &compiler.rustc);
     }
 
     if !compiler.triple.ends_with("windows-gnu") {
@@ -306,6 +306,7 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option<SysrootTarget> {
         let obj = RTSTARTUP_SYSROOT.to_path(dirs).join(format!("{file}.o"));
         let mut build_rtstartup_cmd = Command::new(&compiler.rustc);
         build_rtstartup_cmd
+            .arg("-Ainternal_features") // Missing #[allow(internal_features)]
             .arg("--target")
             .arg(&compiler.triple)
             .arg("--emit=obj")
diff --git a/compiler/rustc_codegen_cranelift/build_system/main.rs b/compiler/rustc_codegen_cranelift/build_system/main.rs
index 3bc78d5db94..798ae9dbd50 100644
--- a/compiler/rustc_codegen_cranelift/build_system/main.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/main.rs
@@ -16,6 +16,7 @@ mod config;
 mod path;
 mod prepare;
 mod rustc_info;
+mod shared_utils;
 mod tests;
 mod utils;
 
@@ -169,8 +170,8 @@ fn main() {
             cargo,
             rustc,
             rustdoc,
-            rustflags: String::new(),
-            rustdocflags: String::new(),
+            rustflags: vec![],
+            rustdocflags: vec![],
             triple,
             runner: vec![],
         }
diff --git a/compiler/rustc_codegen_cranelift/build_system/path.rs b/compiler/rustc_codegen_cranelift/build_system/path.rs
index 4f86c0fd29d..8572815fc55 100644
--- a/compiler/rustc_codegen_cranelift/build_system/path.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/path.rs
@@ -1,7 +1,7 @@
 use std::fs;
 use std::path::PathBuf;
 
-use super::utils::remove_dir_if_exists;
+use crate::utils::remove_dir_if_exists;
 
 #[derive(Debug, Clone)]
 pub(crate) struct Dirs {
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index 3ee2e8f4a4e..165296cb4a9 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -3,18 +3,18 @@ use std::fs;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-use super::build_sysroot::STDLIB_SRC;
-use super::path::{Dirs, RelPath};
-use super::rustc_info::get_default_sysroot;
-use super::utils::{
+use crate::build_sysroot::STDLIB_SRC;
+use crate::path::{Dirs, RelPath};
+use crate::rustc_info::get_default_sysroot;
+use crate::utils::{
     copy_dir_recursively, git_command, remove_dir_if_exists, retry_spawn_and_wait, spawn_and_wait,
 };
 
 pub(crate) fn prepare(dirs: &Dirs) {
     RelPath::DOWNLOAD.ensure_exists(dirs);
-    super::tests::RAND_REPO.fetch(dirs);
-    super::tests::REGEX_REPO.fetch(dirs);
-    super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
+    crate::tests::RAND_REPO.fetch(dirs);
+    crate::tests::REGEX_REPO.fetch(dirs);
+    crate::tests::PORTABLE_SIMD_REPO.fetch(dirs);
 }
 
 pub(crate) fn prepare_stdlib(dirs: &Dirs, rustc: &Path) {
diff --git a/compiler/rustc_codegen_cranelift/build_system/shared_utils.rs b/compiler/rustc_codegen_cranelift/build_system/shared_utils.rs
new file mode 100644
index 00000000000..0aea545ff7d
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/build_system/shared_utils.rs
@@ -0,0 +1,26 @@
+// This file is used by both the build system as well as cargo-clif.rs
+
+// Adapted from https://github.com/rust-lang/cargo/blob/6dc1deaddf62c7748c9097c7ea88e9ec77ff1a1a/src/cargo/core/compiler/build_context/target_info.rs#L750-L77
+pub(crate) fn rustflags_from_env(kind: &str) -> Vec<String> {
+    // First try CARGO_ENCODED_RUSTFLAGS from the environment.
+    // Prefer this over RUSTFLAGS since it's less prone to encoding errors.
+    if let Ok(a) = std::env::var(format!("CARGO_ENCODED_{}", kind)) {
+        if a.is_empty() {
+            return Vec::new();
+        }
+        return a.split('\x1f').map(str::to_string).collect();
+    }
+
+    // Then try RUSTFLAGS from the environment
+    if let Ok(a) = std::env::var(kind) {
+        let args = a.split(' ').map(str::trim).filter(|s| !s.is_empty()).map(str::to_string);
+        return args.collect();
+    }
+
+    // No rustflags to be collected from the environment
+    Vec::new()
+}
+
+pub(crate) fn rustflags_to_cmd_env(cmd: &mut std::process::Command, kind: &str, flags: &[String]) {
+    cmd.env(format!("CARGO_ENCODED_{}", kind), flags.join("\x1f"));
+}
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index 0254d18cf7c..e7bd8b1278c 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -1,16 +1,17 @@
-use super::build_sysroot;
-use super::config;
-use super::path::{Dirs, RelPath};
-use super::prepare::{apply_patches, GitRepo};
-use super::rustc_info::get_default_sysroot;
-use super::utils::{spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler, LogGroup};
-use super::{CodegenBackend, SysrootKind};
-use std::env;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
 
+use crate::build_sysroot;
+use crate::config;
+use crate::path::{Dirs, RelPath};
+use crate::prepare::{apply_patches, GitRepo};
+use crate::rustc_info::get_default_sysroot;
+use crate::shared_utils::rustflags_from_env;
+use crate::utils::{spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler, LogGroup};
+use crate::{CodegenBackend, SysrootKind};
+
 static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example");
 
 struct TestCase {
@@ -306,7 +307,7 @@ pub(crate) fn run_tests(
         );
         // Rust's build system denies a couple of lints that trigger on several of the test
         // projects. Changing the code to fix them is not worth it, so just silence all lints.
-        target_compiler.rustflags += " --cap-lints=allow";
+        target_compiler.rustflags.push("--cap-lints=allow".to_owned());
 
         let runner = TestRunner::new(
             dirs.clone(),
@@ -350,18 +351,15 @@ impl<'a> TestRunner<'a> {
         is_native: bool,
         stdlib_source: PathBuf,
     ) -> Self {
-        if let Ok(rustflags) = env::var("RUSTFLAGS") {
-            target_compiler.rustflags.push(' ');
-            target_compiler.rustflags.push_str(&rustflags);
-        }
-        if let Ok(rustdocflags) = env::var("RUSTDOCFLAGS") {
-            target_compiler.rustdocflags.push(' ');
-            target_compiler.rustdocflags.push_str(&rustdocflags);
-        }
+        target_compiler.rustflags.extend(rustflags_from_env("RUSTFLAGS"));
+        target_compiler.rustdocflags.extend(rustflags_from_env("RUSTDOCFLAGS"));
 
         // FIXME fix `#[linkage = "extern_weak"]` without this
         if target_compiler.triple.contains("darwin") {
-            target_compiler.rustflags.push_str(" -Clink-arg=-undefined -Clink-arg=dynamic_lookup");
+            target_compiler.rustflags.extend([
+                "-Clink-arg=-undefined".to_owned(),
+                "-Clink-arg=dynamic_lookup".to_owned(),
+            ]);
         }
 
         let jit_supported = use_unstable_features
@@ -470,7 +468,7 @@ impl<'a> TestRunner<'a> {
         S: AsRef<OsStr>,
     {
         let mut cmd = Command::new(&self.target_compiler.rustc);
-        cmd.args(self.target_compiler.rustflags.split_whitespace());
+        cmd.args(&self.target_compiler.rustflags);
         cmd.arg("-L");
         cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
         cmd.arg("--out-dir");
diff --git a/compiler/rustc_codegen_cranelift/build_system/usage.txt b/compiler/rustc_codegen_cranelift/build_system/usage.txt
index 6d3b3a13d6e..f652599447b 100644
--- a/compiler/rustc_codegen_cranelift/build_system/usage.txt
+++ b/compiler/rustc_codegen_cranelift/build_system/usage.txt
@@ -43,7 +43,7 @@ REQUIREMENTS:
     * Rustup: By default rustup is used to install the right nightly version. If you don't want to
       use rustup, you can manually install the nightly version indicated by rust-toolchain.toml and
       point the CARGO, RUSTC and RUSTDOC env vars to the right executables.
-    * Git: `./y.sh prepare` uses git for applying patches and on Windows for downloading test repos.
+    * Git: Git is used for applying patches and on Windows for downloading test repos.
     * Curl and tar (non-Windows only): Used by `./y.sh prepare` to download a single commit for
       repos. Git will be used to clone the whole repo when using Windows.
     * [Hyperfine](https://github.com/sharkdp/hyperfine/): Used for benchmarking with `./y.sh bench`.
diff --git a/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs
index 97c82d501c5..24624cdeab1 100644
--- a/compiler/rustc_codegen_cranelift/build_system/utils.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/utils.rs
@@ -5,15 +5,16 @@ use std::path::{Path, PathBuf};
 use std::process::{self, Command, Stdio};
 use std::sync::atomic::{AtomicBool, Ordering};
 
-use super::path::{Dirs, RelPath};
+use crate::path::{Dirs, RelPath};
+use crate::shared_utils::rustflags_to_cmd_env;
 
 #[derive(Clone, Debug)]
 pub(crate) struct Compiler {
     pub(crate) cargo: PathBuf,
     pub(crate) rustc: PathBuf,
     pub(crate) rustdoc: PathBuf,
-    pub(crate) rustflags: String,
-    pub(crate) rustdocflags: String,
+    pub(crate) rustflags: Vec<String>,
+    pub(crate) rustdocflags: Vec<String>,
     pub(crate) triple: String,
     pub(crate) runner: Vec<String>,
 }
@@ -23,8 +24,8 @@ impl Compiler {
         match self.triple.as_str() {
             "aarch64-unknown-linux-gnu" => {
                 // We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
-                self.rustflags += " -Clinker=aarch64-linux-gnu-gcc";
-                self.rustdocflags += " -Clinker=aarch64-linux-gnu-gcc";
+                self.rustflags.push("-Clinker=aarch64-linux-gnu-gcc".to_owned());
+                self.rustdocflags.push("-Clinker=aarch64-linux-gnu-gcc".to_owned());
                 self.runner = vec![
                     "qemu-aarch64".to_owned(),
                     "-L".to_owned(),
@@ -33,8 +34,8 @@ impl Compiler {
             }
             "s390x-unknown-linux-gnu" => {
                 // We are cross-compiling for s390x. Use the correct linker and run tests in qemu.
-                self.rustflags += " -Clinker=s390x-linux-gnu-gcc";
-                self.rustdocflags += " -Clinker=s390x-linux-gnu-gcc";
+                self.rustflags.push("-Clinker=s390x-linux-gnu-gcc".to_owned());
+                self.rustdocflags.push("-Clinker=s390x-linux-gnu-gcc".to_owned());
                 self.runner = vec![
                     "qemu-s390x".to_owned(),
                     "-L".to_owned(),
@@ -100,8 +101,8 @@ impl CargoProject {
 
         cmd.env("RUSTC", &compiler.rustc);
         cmd.env("RUSTDOC", &compiler.rustdoc);
-        cmd.env("RUSTFLAGS", &compiler.rustflags);
-        cmd.env("RUSTDOCFLAGS", &compiler.rustdocflags);
+        rustflags_to_cmd_env(&mut cmd, "RUSTFLAGS", &compiler.rustflags);
+        rustflags_to_cmd_env(&mut cmd, "RUSTDOCFLAGS", &compiler.rustdocflags);
         if !compiler.runner.is_empty() {
             cmd.env(
                 format!("CARGO_TARGET_{}_RUNNER", compiler.triple.to_uppercase().replace('-', "_")),
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 9ecc4c5dd5b..34c7e44b288 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -11,7 +11,7 @@
     thread_local
 )]
 #![no_core]
-#![allow(dead_code)]
+#![allow(dead_code, internal_features)]
 
 #[lang = "sized"]
 pub trait Sized {}
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index d97fab9eb42..91de04d9770 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -1,6 +1,6 @@
 #![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)]
 #![no_core]
-#![allow(dead_code, non_camel_case_types)]
+#![allow(dead_code, non_camel_case_types, internal_features)]
 
 extern crate mini_core;
 
diff --git a/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Allow-internal-features.patch b/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Allow-internal-features.patch
new file mode 100644
index 00000000000..87252df1eab
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Allow-internal-features.patch
@@ -0,0 +1,24 @@
+From fcf75306d88e533b83eaff3f8d0ab9f307e8a84d Mon Sep 17 00:00:00 2001
+From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
+Date: Wed, 9 Aug 2023 10:01:17 +0000
+Subject: [PATCH] Allow internal features
+
+---
+ crates/core_simd/src/lib.rs | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
+index fde406b..b386116 100644
+--- a/crates/core_simd/src/lib.rs
++++ b/crates/core_simd/src/lib.rs
+@@ -19,6 +19,7 @@
+ #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really
+ #![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)]
+ #![unstable(feature = "portable_simd", issue = "86656")]
++#![allow(internal_features)]
+ //! Portable SIMD module.
+ 
+ #[path = "mod.rs"]
+-- 
+2.34.1
+
diff --git a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
index aea47bdfba2..fa175edcae6 100644
--- a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
+++ b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
@@ -74,9 +74,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.95"
+version = "0.1.100"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6866e0f3638013234db3c89ead7a14d278354338e7237257407500009012b23f"
+checksum = "d6c0f24437059853f0fa64afc51f338f93647a3de4cf3358ba1bb4171a199775"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 34514658359..5689bdee64d 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-07-22"
+channel = "nightly-2023-08-08"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
diff --git a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs
index f73b2012684..1e14f41d4a2 100644
--- a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs
@@ -3,6 +3,8 @@ use std::env;
 use std::os::unix::process::CommandExt;
 use std::process::Command;
 
+include!("../build_system/shared_utils.rs");
+
 fn main() {
     let current_exe = env::current_exe().unwrap();
     let mut sysroot = current_exe.parent().unwrap();
@@ -10,27 +12,19 @@ fn main() {
         sysroot = sysroot.parent().unwrap();
     }
 
-    let mut rustflags = String::new();
-    rustflags.push_str(" -Cpanic=abort -Zpanic-abort-tests -Zcodegen-backend=");
+    let mut rustflags = vec!["-Cpanic=abort".to_owned(), "-Zpanic-abort-tests".to_owned()];
     if let Some(name) = option_env!("BUILTIN_BACKEND") {
-        rustflags.push_str(name);
+        rustflags.push(format!("-Zcodegen-backend={name}"));
     } else {
-        rustflags.push_str(
-            sysroot
-                .join(if cfg!(windows) { "bin" } else { "lib" })
-                .join(
-                    env::consts::DLL_PREFIX.to_string()
-                        + "rustc_codegen_cranelift"
-                        + env::consts::DLL_SUFFIX,
-                )
-                .to_str()
-                .unwrap(),
+        let dylib = sysroot.join(if cfg!(windows) { "bin" } else { "lib" }).join(
+            env::consts::DLL_PREFIX.to_string()
+                + "rustc_codegen_cranelift"
+                + env::consts::DLL_SUFFIX,
         );
+        rustflags.push(format!("-Zcodegen-backend={}", dylib.to_str().unwrap()));
     }
-    rustflags.push_str(" --sysroot ");
-    rustflags.push_str(sysroot.to_str().unwrap());
-    env::set_var("RUSTFLAGS", env::var("RUSTFLAGS").unwrap_or(String::new()) + &rustflags);
-    env::set_var("RUSTDOCFLAGS", env::var("RUSTDOCFLAGS").unwrap_or(String::new()) + &rustflags);
+    rustflags.push("--sysroot".to_owned());
+    rustflags.push(sysroot.to_str().unwrap().to_owned());
 
     let cargo = if let Some(cargo) = option_env!("CARGO") {
         cargo
@@ -49,10 +43,7 @@ fn main() {
 
     let args: Vec<_> = match args.get(0).map(|arg| &**arg) {
         Some("jit") => {
-            env::set_var(
-                "RUSTFLAGS",
-                env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
-            );
+            rustflags.push("-Cprefer-dynamic".to_owned());
             args.remove(0);
             IntoIterator::into_iter(["rustc".to_string()])
                 .chain(args)
@@ -64,10 +55,7 @@ fn main() {
                 .collect()
         }
         Some("lazy-jit") => {
-            env::set_var(
-                "RUSTFLAGS",
-                env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
-            );
+            rustflags.push("-Cprefer-dynamic".to_owned());
             args.remove(0);
             IntoIterator::into_iter(["rustc".to_string()])
                 .chain(args)
@@ -81,11 +69,28 @@ fn main() {
         _ => args,
     };
 
+    let mut cmd = Command::new(cargo);
+    cmd.args(args);
+    rustflags_to_cmd_env(
+        &mut cmd,
+        "RUSTFLAGS",
+        &rustflags_from_env("RUSTFLAGS")
+            .into_iter()
+            .chain(rustflags.iter().map(|flag| flag.clone()))
+            .collect::<Vec<_>>(),
+    );
+    rustflags_to_cmd_env(
+        &mut cmd,
+        "RUSTDOCFLAGS",
+        &rustflags_from_env("RUSTDOCFLAGS")
+            .into_iter()
+            .chain(rustflags.iter().map(|flag| flag.clone()))
+            .collect::<Vec<_>>(),
+    );
+
     #[cfg(unix)]
-    panic!("Failed to spawn cargo: {}", Command::new(cargo).args(args).exec());
+    panic!("Failed to spawn cargo: {}", cmd.exec());
 
     #[cfg(not(unix))]
-    std::process::exit(
-        Command::new(cargo).args(args).spawn().unwrap().wait().unwrap().code().unwrap_or(1),
-    );
+    std::process::exit(cmd.spawn().unwrap().wait().unwrap().code().unwrap_or(1));
 }
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index 83cbe0db633..c163b854384 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -49,6 +49,8 @@ rm tests/ui/proc-macro/allowed-signatures.rs
 # vendor intrinsics
 rm tests/ui/sse2.rs # cpuid not supported, so sse2 not detected
 rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
+rm tests/ui/simd/intrinsic/generic-bswap-byte.rs # simd_bswap not yet implemented
+rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # many missing simd intrinsics
 
 # exotic linkages
 rm tests/ui/issues/issue-33992.rs # unsupported linkages
@@ -124,6 +126,8 @@ rm tests/ui/typeck/issue-46112.rs # same
 rm tests/ui/consts/const_cmp_type_id.rs # same
 rm tests/ui/consts/issue-73976-monomorphic.rs # same
 rm tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs # same
+rm tests/ui/consts/const-eval/nonnull_as_ref_ub.rs # same
+rm tests/ui/consts/issue-94675.rs # same
 
 # rustdoc-clif passes extra args, suppressing the help message when no args are passed
 rm -r tests/run-make/issue-88756-default-output
@@ -158,8 +162,6 @@ rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
 
 rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
 
-rm tests/ui/panic-handler/weak-lang-item-2.rs # Will be fixed by #113568
-
 cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist
 
 # prevent $(RUSTDOC) from picking up the sysroot built by x.py. It conflicts with the one used by
@@ -172,7 +174,7 @@ index ea06b620c4c..b969d0009c6 100644
 @@ -9,7 +9,7 @@ RUSTC_ORIGINAL := \$(RUSTC)
  BARE_RUSTC := \$(HOST_RPATH_ENV) '\$(RUSTC)'
  BARE_RUSTDOC := \$(HOST_RPATH_ENV) '\$(RUSTDOC)'
- RUSTC := \$(BARE_RUSTC) --out-dir \$(TMPDIR) -L \$(TMPDIR) \$(RUSTFLAGS)
+ RUSTC := \$(BARE_RUSTC) --out-dir \$(TMPDIR) -L \$(TMPDIR) \$(RUSTFLAGS) -Ainternal_features
 -RUSTDOC := \$(BARE_RUSTDOC) -L \$(TARGET_RPATH_DIR)
 +RUSTDOC := \$(BARE_RUSTDOC)
  ifdef RUSTC_LINKER
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 2c038f22ca9..b7f56a2986c 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -48,7 +48,9 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
             default_call_conv
         }
 
-        Conv::X86Intr => sess.fatal("x86-interrupt call conv not yet implemented"),
+        Conv::X86Intr | Conv::RiscvInterrupt { .. } => {
+            sess.fatal(format!("interrupt call conv {c:?} not yet implemented"))
+        }
 
         Conv::ArmAapcs => sess.fatal("aapcs call conv not yet implemented"),
         Conv::CCmseNonSecureCall => {
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index ebd153cb71d..d01ded8abaa 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -260,6 +260,13 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
     flags_builder.set("enable_verifier", enable_verifier).unwrap();
     flags_builder.set("regalloc_checker", enable_verifier).unwrap();
 
+    let preserve_frame_pointer = sess.target.options.frame_pointer
+        != rustc_target::spec::FramePointer::MayOmit
+        || matches!(sess.opts.cg.force_frame_pointers, Some(true));
+    if preserve_frame_pointer {
+        flags_builder.set("preserve_frame_pointers", "true").unwrap();
+    }
+
     let tls_model = match target_triple.binary_format {
         BinaryFormat::Elf => "elf_gd",
         BinaryFormat::Macho => "macho",
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index e02b457fd0b..c6a7dc95d77 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -383,13 +383,16 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
     }
 
     fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
-        let mut func_attrs = SmallVec::<[_; 2]>::new();
+        let mut func_attrs = SmallVec::<[_; 3]>::new();
         if self.ret.layout.abi.is_uninhabited() {
             func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx));
         }
         if !self.can_unwind {
             func_attrs.push(llvm::AttributeKind::NoUnwind.create_attr(cx.llcx));
         }
+        if let Conv::RiscvInterrupt { kind } = self.conv {
+            func_attrs.push(llvm::CreateAttrStringValue(cx.llcx, "interrupt", kind.as_str()));
+        }
         attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &{ func_attrs });
 
         let mut i = 0;
@@ -565,7 +568,9 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
 impl From<Conv> for llvm::CallConv {
     fn from(conv: Conv) -> Self {
         match conv {
-            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
+            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall | Conv::RiscvInterrupt { .. } => {
+                llvm::CCallConv
+            }
             Conv::RustCold => llvm::ColdCallConv,
             Conv::AmdGpuKernel => llvm::AmdGpuKernel,
             Conv::AvrInterrupt => llvm::AvrInterrupt,
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 46e6daed21f..47cc5bd52e2 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -320,6 +320,7 @@ impl<'a> DiagnosticHandlers<'a> {
             })
             .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok()));
 
+        let pgo_available = cgcx.opts.cg.profile_use.is_some();
         let data = Box::into_raw(Box::new((cgcx, handler)));
         unsafe {
             let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx);
@@ -333,6 +334,7 @@ impl<'a> DiagnosticHandlers<'a> {
                 // The `as_ref()` is important here, otherwise the `CString` will be dropped
                 // too soon!
                 remark_file.as_ref().map(|dir| dir.as_ptr()).unwrap_or(std::ptr::null()),
+                pgo_available,
             );
             DiagnosticHandlers { data, llcx, old_handler }
         }
@@ -470,6 +472,8 @@ pub(crate) unsafe fn llvm_optimize(
         Some(llvm::SanitizerOptions {
             sanitize_address: config.sanitizer.contains(SanitizerSet::ADDRESS),
             sanitize_address_recover: config.sanitizer_recover.contains(SanitizerSet::ADDRESS),
+            sanitize_cfi: config.sanitizer.contains(SanitizerSet::CFI),
+            sanitize_kcfi: config.sanitizer.contains(SanitizerSet::KCFI),
             sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY),
             sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
             sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
@@ -505,6 +509,7 @@ pub(crate) unsafe fn llvm_optimize(
         &*module.module_llvm.tm,
         to_pass_builder_opt_level(opt_level),
         opt_stage,
+        cgcx.opts.cg.linker_plugin_lto.enabled(),
         config.no_prepopulate_passes,
         config.verify_llvm_ir,
         using_thin_buffers,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 5408481df48..ac6d8f84142 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1512,9 +1512,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
     ) {
-        let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
-        if is_indirect_call && fn_abi.is_some() && self.tcx.sess.is_sanitizer_cfi_enabled() {
-            if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::CFI) {
+        let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
+        if self.tcx.sess.is_sanitizer_cfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call {
+            if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) {
                 return;
             }
 
@@ -1526,7 +1526,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
                 options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
             }
 
-            let typeid = typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options);
+            let typeid = typeid_for_fnabi(self.tcx, fn_abi, options);
             let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
 
             // Test whether the function pointer is associated with the type identifier.
@@ -1550,25 +1550,26 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
     ) -> Option<llvm::OperandBundleDef<'ll>> {
-        let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
-        let kcfi_bundle = if is_indirect_call && self.tcx.sess.is_sanitizer_kcfi_enabled() {
-            if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::KCFI) {
-                return None;
-            }
+        let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
+        let kcfi_bundle =
+            if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call {
+                if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) {
+                    return None;
+                }
 
-            let mut options = TypeIdOptions::empty();
-            if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() {
-                options.insert(TypeIdOptions::GENERALIZE_POINTERS);
-            }
-            if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() {
-                options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
-            }
+                let mut options = TypeIdOptions::empty();
+                if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() {
+                    options.insert(TypeIdOptions::GENERALIZE_POINTERS);
+                }
+                if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() {
+                    options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
+                }
 
-            let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options);
-            Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
-        } else {
-            None
-        };
+                let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
+                Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
+            } else {
+                None
+            };
         kcfi_bundle
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index b167facfb02..112b4a173a5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -475,6 +475,8 @@ pub enum OptStage {
 pub struct SanitizerOptions {
     pub sanitize_address: bool,
     pub sanitize_address_recover: bool,
+    pub sanitize_cfi: bool,
+    pub sanitize_kcfi: bool,
     pub sanitize_memory: bool,
     pub sanitize_memory_recover: bool,
     pub sanitize_memory_track_origins: c_int,
@@ -894,6 +896,7 @@ extern "C" {
     pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
     pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
     pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>;
+    pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
 
     // Operations on constants of any type
     pub fn LLVMConstNull(Ty: &Type) -> &Value;
@@ -2138,6 +2141,7 @@ extern "C" {
         TM: &'a TargetMachine,
         OptLevel: PassBuilderOptLevel,
         OptStage: OptStage,
+        IsLinkerPluginLTO: bool,
         NoPrepopulatePasses: bool,
         VerifyIR: bool,
         UseThinLTOBuffers: bool,
@@ -2332,6 +2336,7 @@ extern "C" {
         remark_passes: *const *const c_char,
         remark_passes_len: usize,
         remark_file: *const c_char,
+        pgo_available: bool,
     );
 
     #[allow(improper_ctypes)]
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 4c04fc60b98..a1e322f4b31 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -13,6 +13,7 @@ use std::{env, mem, str};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::find_native_static_library;
 use rustc_middle::middle::dependency_format::Linkage;
+use rustc_middle::middle::exported_symbols;
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
@@ -659,8 +660,6 @@ impl<'a> Linker for GccLinker<'a> {
             return;
         }
 
-        // FIXME(#99978) hide #[no_mangle] symbols for proc-macros
-
         let is_windows = self.sess.target.is_like_windows;
         let path = tmpdir.join(if is_windows { "list.def" } else { "list" });
 
@@ -1679,8 +1678,15 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
         return exports.iter().map(ToString::to_string).collect();
     }
 
-    let mut symbols = Vec::new();
+    if let CrateType::ProcMacro = crate_type {
+        exported_symbols_for_proc_macro_crate(tcx)
+    } else {
+        exported_symbols_for_non_proc_macro(tcx, crate_type)
+    }
+}
 
+fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
+    let mut symbols = Vec::new();
     let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
     for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
         if info.level.is_below_threshold(export_threshold) {
@@ -1691,6 +1697,19 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
     symbols
 }
 
+fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
+    // `exported_symbols` will be empty when !should_codegen.
+    if !tcx.sess.opts.output_types.should_codegen() {
+        return Vec::new();
+    }
+
+    let stable_crate_id = tcx.sess.local_stable_crate_id();
+    let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
+    let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
+
+    vec![proc_macro_decls_name, metadata_symbol_name]
+}
+
 pub(crate) fn linked_symbols(
     tcx: TyCtxt<'_>,
     crate_type: CrateType,
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 0b336109921..e5dd5729d89 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -303,8 +303,6 @@ const_eval_remainder_overflow =
     overflow in signed remainder (dividing MIN by -1)
 const_eval_scalar_size_mismatch =
     scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead
-const_eval_size_of_unsized =
-    size_of called on unsized type `{$ty}`
 const_eval_size_overflow =
     overflow computing total size of `{$name}`
 
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index cc39387c41f..4ee4ebbb9e4 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -40,7 +40,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
         | hir::Node::AnonConst(_)
         | hir::Node::ConstBlock(_)
         | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const,
-        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
+        hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const),
         hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
             // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
             // foreign items cannot be evaluated at compile-time.
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index f785bcfed6c..b15a65d67a3 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -7,9 +7,10 @@ use crate::interpret::{
     intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta,
     MemoryKind, Place, Projectable, Scalar,
 };
+use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
 use rustc_span::source_map::DUMMY_SP;
-use rustc_target::abi::{Align, FieldIdx, VariantIdx, FIRST_VARIANT};
+use rustc_target::abi::VariantIdx;
 
 #[instrument(skip(ecx), level = "debug")]
 fn branches<'tcx>(
@@ -154,52 +155,37 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
     }
 }
 
-#[instrument(skip(ecx), level = "debug")]
-fn create_mplace_from_layout<'tcx>(
-    ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
-    ty: Ty<'tcx>,
-) -> MPlaceTy<'tcx> {
-    let tcx = ecx.tcx;
-    let param_env = ecx.param_env;
-    let layout = tcx.layout_of(param_env.and(ty)).unwrap();
-    debug!(?layout);
-
-    ecx.allocate(layout, MemoryKind::Stack).unwrap()
-}
-
-// Walks custom DSTs and gets the type of the unsized field and the number of elements
-// in the unsized field.
-fn get_info_on_unsized_field<'tcx>(
-    ty: Ty<'tcx>,
+/// Valtrees don't store the `MemPlaceMeta` that all dynamically sized values have in the interpreter.
+/// This function reconstructs it.
+fn reconstruct_place_meta<'tcx>(
+    layout: TyAndLayout<'tcx>,
     valtree: ty::ValTree<'tcx>,
     tcx: TyCtxt<'tcx>,
-) -> (Ty<'tcx>, usize) {
+) -> MemPlaceMeta {
+    if layout.is_sized() {
+        return MemPlaceMeta::None;
+    }
+
     let mut last_valtree = valtree;
+    // Traverse the type, and update `last_valtree` as we go.
     let tail = tcx.struct_tail_with_normalize(
-        ty,
+        layout.ty,
         |ty| ty,
         || {
             let branches = last_valtree.unwrap_branch();
-            last_valtree = branches[branches.len() - 1];
+            last_valtree = *branches.last().unwrap();
             debug!(?branches, ?last_valtree);
         },
     );
-    let unsized_inner_ty = match tail.kind() {
-        ty::Slice(t) => *t,
-        ty::Str => tail,
-        _ => bug!("expected Slice or Str"),
-    };
-
-    // Have to adjust type for ty::Str
-    let unsized_inner_ty = match unsized_inner_ty.kind() {
-        ty::Str => tcx.types.u8,
-        _ => unsized_inner_ty,
+    // Sanity-check that we got a tail we support.
+    match tail.kind() {
+        ty::Slice(..) | ty::Str => {}
+        _ => bug!("unsized tail of a valtree must be Slice or Str"),
     };
 
-    // Get the number of elements in the unsized field
+    // Get the number of elements in the unsized field.
     let num_elems = last_valtree.unwrap_branch().len();
-
-    (unsized_inner_ty, num_elems)
+    MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx))
 }
 
 #[instrument(skip(ecx), level = "debug", ret)]
@@ -208,41 +194,9 @@ fn create_pointee_place<'tcx>(
     ty: Ty<'tcx>,
     valtree: ty::ValTree<'tcx>,
 ) -> MPlaceTy<'tcx> {
-    let tcx = ecx.tcx.tcx;
-
-    if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) {
-        // We need to create `Allocation`s for custom DSTs
-
-        let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx);
-        let unsized_inner_ty = match unsized_inner_ty.kind() {
-            ty::Str => tcx.types.u8,
-            _ => unsized_inner_ty,
-        };
-        let unsized_inner_ty_size =
-            tcx.layout_of(ty::ParamEnv::empty().and(unsized_inner_ty)).unwrap().layout.size();
-        debug!(?unsized_inner_ty, ?unsized_inner_ty_size, ?num_elems);
-
-        // for custom DSTs only the last field/element is unsized, but we need to also allocate
-        // space for the other fields/elements
-        let layout = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap();
-        let size_of_sized_part = layout.layout.size();
-
-        // Get the size of the memory behind the DST
-        let dst_size = unsized_inner_ty_size.checked_mul(num_elems as u64, &tcx).unwrap();
-
-        let size = size_of_sized_part.checked_add(dst_size, &tcx).unwrap();
-        let align = Align::from_bytes(size.bytes().next_power_of_two()).unwrap();
-        let ptr = ecx.allocate_ptr(size, align, MemoryKind::Stack).unwrap();
-        debug!(?ptr);
-
-        MPlaceTy::from_aligned_ptr_with_meta(
-            ptr.into(),
-            layout,
-            MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)),
-        )
-    } else {
-        create_mplace_from_layout(ecx, ty)
-    }
+    let layout = ecx.layout_of(ty).unwrap();
+    let meta = reconstruct_place_meta(layout, valtree, ecx.tcx.tcx);
+    ecx.allocate_dyn(layout, MemoryKind::Stack, meta).unwrap()
 }
 
 /// Converts a `ValTree` to a `ConstValue`, which is needed after mir
@@ -282,10 +236,13 @@ pub fn valtree_to_const_value<'tcx>(
         ty::Ref(_, _, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
             let place = match ty.kind() {
                 ty::Ref(_, inner_ty, _) => {
-                    // Need to create a place for the pointee to fill for Refs
+                    // Need to create a place for the pointee (the reference itself will be an immediate)
                     create_pointee_place(&mut ecx, *inner_ty, valtree)
                 }
-                _ => create_mplace_from_layout(&mut ecx, ty),
+                _ => {
+                    // Need to create a place for this valtree.
+                    create_pointee_place(&mut ecx, ty, valtree)
+                }
             };
             debug!(?place);
 
@@ -399,45 +356,8 @@ fn valtree_into_mplace<'tcx>(
                 debug!(?i, ?inner_valtree);
 
                 let place_inner = match ty.kind() {
-                    ty::Str | ty::Slice(_) => ecx.project_index(place, i as u64).unwrap(),
-                    _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty())
-                        && i == branches.len() - 1 =>
-                    {
-                        // Note: For custom DSTs we need to manually process the last unsized field.
-                        // We created a `Pointer` for the `Allocation` of the complete sized version of
-                        // the Adt in `create_pointee_place` and now we fill that `Allocation` with the
-                        // values in the ValTree. For the unsized field we have to additionally add the meta
-                        // data.
-
-                        let (unsized_inner_ty, num_elems) =
-                            get_info_on_unsized_field(ty, valtree, tcx);
-                        debug!(?unsized_inner_ty);
-
-                        let inner_ty = match ty.kind() {
-                            ty::Adt(def, args) => {
-                                let i = FieldIdx::from_usize(i);
-                                def.variant(FIRST_VARIANT).fields[i].ty(tcx, args)
-                            }
-                            ty::Tuple(inner_tys) => inner_tys[i],
-                            _ => bug!("unexpected unsized type {:?}", ty),
-                        };
-
-                        let inner_layout =
-                            tcx.layout_of(ty::ParamEnv::empty().and(inner_ty)).unwrap();
-                        debug!(?inner_layout);
-
-                        let offset = place_adjusted.layout.fields.offset(i);
-                        place
-                            .offset_with_meta(
-                                offset,
-                                MemPlaceMeta::Meta(Scalar::from_target_usize(
-                                    num_elems as u64,
-                                    &tcx,
-                                )),
-                                inner_layout,
-                                &tcx,
-                            )
-                            .unwrap()
+                    ty::Str | ty::Slice(_) | ty::Array(..) => {
+                        ecx.project_index(place, i as u64).unwrap()
                     }
                     _ => ecx.project_field(&place_adjusted, i).unwrap(),
                 };
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 3a4e2648b80..4362cae7ed7 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -862,7 +862,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
             InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
                 rustc_middle::error::middle_adjust_for_foreign_abi_error
             }
-            InvalidProgramInfo::SizeOfUnsizedType(_) => const_eval_size_of_unsized,
             InvalidProgramInfo::ConstPropNonsense => {
                 panic!("We had const-prop nonsense, this should never be printed")
             }
@@ -890,9 +889,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
                 builder.set_arg("arch", arch);
                 builder.set_arg("abi", abi.name());
             }
-            InvalidProgramInfo::SizeOfUnsizedType(ty) => {
-                builder.set_arg("ty", ty);
-            }
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index ec226808f1b..daadb758964 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -934,14 +934,26 @@ where
         Ok(MPlaceTy { mplace, layout: place.layout, align: place.align })
     }
 
+    pub fn allocate_dyn(
+        &mut self,
+        layout: TyAndLayout<'tcx>,
+        kind: MemoryKind<M::MemoryKind>,
+        meta: MemPlaceMeta<M::Provenance>,
+    ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
+        let Some((size, align)) = self.size_and_align_of(&meta, &layout)? else {
+            span_bug!(self.cur_span(), "cannot allocate space for `extern` type, size is not known")
+        };
+        let ptr = self.allocate_ptr(size, align, kind)?;
+        Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.into(), layout, meta))
+    }
+
     pub fn allocate(
         &mut self,
         layout: TyAndLayout<'tcx>,
         kind: MemoryKind<M::MemoryKind>,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
         assert!(layout.is_sized());
-        let ptr = self.allocate_ptr(layout.size, layout.align.abi, kind)?;
-        Ok(MPlaceTy::from_aligned_ptr(ptr.into(), layout))
+        self.allocate_dyn(layout, kind, MemPlaceMeta::None)
     }
 
     /// Returns a wide MPlace of type `&'static [mut] str` to a new 1-aligned allocation.
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index f04c73105d2..0740894a4ff 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -269,13 +269,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
                 let layout = self.layout_of(ty)?;
                 if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() {
-                    // FIXME: This should be a span_bug, but const generics can run MIR
-                    // that is not properly type-checked yet (#97477).
-                    self.tcx.sess.delay_span_bug(
+                    span_bug!(
                         self.frame().current_span(),
-                        format!("{null_op:?} MIR operator called for unsized type {ty}"),
+                        "{null_op:?} MIR operator called for unsized type {ty}",
                     );
-                    throw_inval!(SizeOfUnsizedType(ty));
                 }
                 let val = match null_op {
                     mir::NullOp::SizeOf => layout.size.bytes(),
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 1bd21473182..3c03172bbef 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -393,15 +393,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             ));
             assert_eq!(dest_offset, None);
             // Allocate enough memory to hold `src`.
-            let Some((size, align)) = self.size_and_align_of_mplace(&src)? else {
-                span_bug!(
-                    self.cur_span(),
-                    "unsized fn arg with `extern` type tail should not be allowed"
-                )
-            };
-            let ptr = self.allocate_ptr(size, align, MemoryKind::Stack)?;
-            let dest_place =
-                MPlaceTy::from_aligned_ptr_with_meta(ptr.into(), callee_arg.layout, src.meta);
+            let dest_place = self.allocate_dyn(src.layout, MemoryKind::Stack, src.meta)?;
             // Update the local to be that new place.
             *M::access_local_mut(self, dest_frame, dest_local)? = Operand::Indirect(*dest_place);
         }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index e77fb4ea2a2..e51082e1ec0 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -127,15 +127,8 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let hir_id = tcx.local_def_id_to_hir_id(local_def_id);
 
     let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false };
-    let parent_def = tcx.hir().get(parent);
-
-    if !matches!(
-        parent_def,
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
-            ..
-        })
-    ) {
+
+    if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) {
         return false;
     }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index e785196c744..1f3cda35c2b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -145,8 +145,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                     let implsrc = selcx.select(&obligation);
 
                     if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
-                        let span = tcx.def_span(data.impl_def_id);
-                        err.subdiagnostic(errors::NonConstImplNote { span });
+                        // FIXME(effects) revisit this
+                        if !tcx.is_const_trait_impl_raw(data.impl_def_id) {
+                            let span = tcx.def_span(data.impl_def_id);
+                            err.subdiagnostic(errors::NonConstImplNote { span });
+                        }
                     }
                 }
                 _ => {}
diff --git a/compiler/rustc_data_structures/src/base_n.rs b/compiler/rustc_data_structures/src/base_n.rs
index 58704350706..a3eb2b9c416 100644
--- a/compiler/rustc_data_structures/src/base_n.rs
+++ b/compiler/rustc_data_structures/src/base_n.rs
@@ -30,7 +30,10 @@ pub fn push_str(mut n: u128, base: usize, output: &mut String) {
         }
     }
 
-    output.push_str(str::from_utf8(&s[index..]).unwrap());
+    output.push_str(unsafe {
+        // SAFETY: `s` is populated using only valid utf8 characters from `BASE_64`
+        str::from_utf8_unchecked(&s[index..])
+    });
 }
 
 #[inline]
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 60dc9b20077..ec77569d4b8 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -32,7 +32,7 @@ use rustc_feature::find_gated_cfg;
 use rustc_fluent_macro::fluent_messages;
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
-use rustc_lint::LintStore;
+use rustc_lint::{unerased_lint_store, LintStore};
 use rustc_metadata::locator;
 use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS};
 use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths};
@@ -411,15 +411,11 @@ fn run_compiler(
                 return early_exit();
             }
 
-            {
-                let plugins = queries.register_plugins()?;
-                let (.., lint_store) = &*plugins.borrow();
-
-                // Lint plugins are registered; now we can process command line flags.
-                if sess.opts.describe_lints {
-                    describe_lints(sess, lint_store, true);
-                    return early_exit();
-                }
+            if sess.opts.describe_lints {
+                queries
+                    .global_ctxt()?
+                    .enter(|tcx| describe_lints(sess, unerased_lint_store(tcx), true));
+                return early_exit();
             }
 
             // Make sure name resolution and macro expansion is run.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index ede3570510a..898f5fd3b70 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -313,6 +313,8 @@ declare_features! (
     (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
     /// Allows `extern "ptx-*" fn()`.
     (active, abi_ptx, "1.15.0", Some(38788), None),
+    /// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
+    (active, abi_riscv_interrupt, "CURRENT_RUSTC_VERSION", Some(111889), None),
     /// Allows `extern "x86-interrupt" fn()`.
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
     /// Allows additional const parameter types, such as `&'static str` or user defined types
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index c6f8d1e211d..92a91766d91 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2675,7 +2675,7 @@ pub struct OpaqueTy<'hir> {
     ///
     /// This mapping associated a captured lifetime (first parameter) with the new
     /// early-bound lifetime that was generated for the opaque.
-    pub lifetime_mapping: Option<&'hir [(&'hir Lifetime, LocalDefId)]>,
+    pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)],
     /// Whether the opaque is a return-position impl trait (or async future)
     /// originating from a trait method. This makes it so that the opaque is
     /// lowered as an associated type.
@@ -3359,7 +3359,6 @@ pub struct Impl<'hir> {
     // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
     // decoding as `Span`s cannot be decoded when a `Session` is not available.
     pub defaultness_span: Option<Span>,
-    pub constness: Constness,
     pub generics: &'hir Generics<'hir>,
 
     /// The trait being implemented, if any.
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9d1d899eef0..172f557f8e2 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -522,7 +522,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
             unsafety: _,
             defaultness: _,
             polarity: _,
-            constness: _,
             defaultness_span: _,
             ref generics,
             ref of_trait,
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 319573c85b4..668763f9bf6 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -532,6 +532,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         if let Err(guar) = ty.error_reported() {
                             return ty::Const::new_error(tcx, guar, ty).into();
                         }
+                        // FIXME(effects) see if we should special case effect params here
                         if !infer_args && has_default {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, args.unwrap())
@@ -659,7 +660,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         trait_ref: &hir::TraitRef<'_>,
         self_ty: Ty<'tcx>,
-        constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
 
@@ -669,7 +669,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             self_ty,
             trait_ref.path.segments.last().unwrap(),
             true,
-            constness,
+            ty::BoundConstness::NotConst,
         )
     }
 
@@ -849,6 +849,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         self_ty: Ty<'tcx>,
         trait_segment: &hir::PathSegment<'_>,
         is_impl: bool,
+        // FIXME(effects) move all host param things in astconv to hir lowering
         constness: ty::BoundConstness,
     ) -> ty::TraitRef<'tcx> {
         let (generic_args, _) = self.create_args_for_ast_trait_ref(
@@ -2714,11 +2715,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         };
         let i = hir.get_parent(fn_hir_id).expect_item().expect_impl();
 
-        let trait_ref = self.instantiate_mono_trait_ref(
-            i.of_trait.as_ref()?,
-            self.ast_ty_to_ty(i.self_ty),
-            ty::BoundConstness::NotConst,
-        );
+        let trait_ref =
+            self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
 
         let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
             tcx,
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 49307d96cc2..8a5099804ed 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -407,7 +407,17 @@ fn check_opaque_meets_bounds<'tcx>(
         .build();
     let ocx = ObligationCtxt::new(&infcx);
 
-    let args = GenericArgs::identity_for_item(tcx, def_id.to_def_id());
+    let args = match *origin {
+        hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
+            GenericArgs::identity_for_item(tcx, parent).extend_to(
+                tcx,
+                def_id.to_def_id(),
+                |param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
+            )
+        }
+        hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
+    };
+
     let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
 
     // `ReErased` regions appear in the "parent_args" of closures/generators.
@@ -468,9 +478,10 @@ fn check_opaque_meets_bounds<'tcx>(
         }
     }
     // Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
-    for (key, mut ty) in infcx.take_opaque_types() {
+    for (mut key, mut ty) in infcx.take_opaque_types() {
         ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty);
-        sanity_check_found_hidden_type(tcx, key, ty.hidden_type, defining_use_anchor, origin)?;
+        key = infcx.resolve_vars_if_possible(key);
+        sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?;
     }
     Ok(())
 }
@@ -479,8 +490,6 @@ fn sanity_check_found_hidden_type<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::OpaqueTypeKey<'tcx>,
     mut ty: ty::OpaqueHiddenType<'tcx>,
-    defining_use_anchor: LocalDefId,
-    origin: &hir::OpaqueTyOrigin,
 ) -> Result<(), ErrorGuaranteed> {
     if ty.ty.is_ty_var() {
         // Nothing was actually constrained.
@@ -493,29 +502,23 @@ fn sanity_check_found_hidden_type<'tcx>(
             return Ok(());
         }
     }
+    let strip_vars = |ty: Ty<'tcx>| {
+        ty.fold_with(&mut BottomUpFolder {
+            tcx,
+            ty_op: |t| t,
+            ct_op: |c| c,
+            lt_op: |l| match l.kind() {
+                RegionKind::ReVar(_) => tcx.lifetimes.re_erased,
+                _ => l,
+            },
+        })
+    };
     // Closures frequently end up containing erased lifetimes in their final representation.
     // These correspond to lifetime variables that never got resolved, so we patch this up here.
-    ty.ty = ty.ty.fold_with(&mut BottomUpFolder {
-        tcx,
-        ty_op: |t| t,
-        ct_op: |c| c,
-        lt_op: |l| match l.kind() {
-            RegionKind::ReVar(_) => tcx.lifetimes.re_erased,
-            _ => l,
-        },
-    });
+    ty.ty = strip_vars(ty.ty);
     // Get the hidden type.
-    let mut hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args);
-    if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin {
-        if hidden_ty != ty.ty {
-            hidden_ty = find_and_apply_rpit_args(
-                tcx,
-                hidden_ty,
-                defining_use_anchor.to_def_id(),
-                key.def_id.to_def_id(),
-            )?;
-        }
-    }
+    let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args);
+    let hidden_ty = strip_vars(hidden_ty);
 
     // If the hidden types differ, emit a type mismatch diagnostic.
     if hidden_ty == ty.ty {
@@ -527,105 +530,6 @@ fn sanity_check_found_hidden_type<'tcx>(
     }
 }
 
-/// In case it is in a nested opaque type, find that opaque type's
-/// usage in the function signature and use the generic arguments from the usage site.
-/// We need to do because RPITs ignore the lifetimes of the function,
-/// as they have their own copies of all the lifetimes they capture.
-/// So the only way to get the lifetimes represented in terms of the function,
-/// is to look how they are used in the function signature (or do some other fancy
-/// recording of this mapping at ast -> hir lowering time).
-///
-/// As an example:
-/// ```text
-/// trait Id {
-///     type Assoc;
-/// }
-/// impl<'a> Id for &'a () {
-///     type Assoc = &'a ();
-/// }
-/// fn func<'a>(x: &'a ()) -> impl Id<Assoc = impl Sized + 'a> { x }
-/// // desugared to
-/// fn func<'a>(x: &'a () -> Outer<'a> where <Outer<'a> as Id>::Assoc = Inner<'a> {
-///     // Note that in contrast to other nested items, RPIT type aliases can
-///     // access their parents' generics.
-///
-///     // hidden type is `&'aDupOuter ()`
-///     // During wfcheck the hidden type of `Inner<'aDupOuter>` is `&'a ()`, but
-///     // `typeof(Inner<'aDupOuter>) = &'aDupOuter ()`.
-///     // So we walk the signature of `func` to find the use of `Inner<'a>`
-///     // and then use that to replace the lifetimes in the hidden type, obtaining
-///     // `&'a ()`.
-///     type Outer<'aDupOuter> = impl Id<Assoc = Inner<'aDupOuter>>;
-///
-///     // hidden type is `&'aDupInner ()`
-///     type Inner<'aDupInner> = impl Sized + 'aDupInner;
-///
-///     x
-/// }
-/// ```
-fn find_and_apply_rpit_args<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mut hidden_ty: Ty<'tcx>,
-    function: DefId,
-    opaque: DefId,
-) -> Result<Ty<'tcx>, ErrorGuaranteed> {
-    // Find use of the RPIT in the function signature and thus find the right args to
-    // convert it into the parameter space of the function signature. This is needed,
-    // because that's what `type_of` returns, against which we compare later.
-    let ret = tcx.fn_sig(function).instantiate_identity().output();
-    struct Visitor<'tcx> {
-        tcx: TyCtxt<'tcx>,
-        opaque: DefId,
-        seen: FxHashSet<DefId>,
-    }
-    impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for Visitor<'tcx> {
-        type BreakTy = GenericArgsRef<'tcx>;
-
-        #[instrument(level = "trace", skip(self), ret)]
-        fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-            trace!("{:#?}", t.kind());
-            match t.kind() {
-                ty::Alias(ty::Opaque, alias) => {
-                    trace!(?alias.def_id);
-                    if alias.def_id == self.opaque {
-                        return ControlFlow::Break(alias.args);
-                    } else if self.seen.insert(alias.def_id) {
-                        for clause in self
-                            .tcx
-                            .explicit_item_bounds(alias.def_id)
-                            .iter_instantiated_copied(self.tcx, alias.args)
-                        {
-                            trace!(?clause);
-                            clause.visit_with(self)?;
-                        }
-                    }
-                }
-                ty::Alias(ty::Weak, alias) => {
-                    self.tcx
-                        .type_of(alias.def_id)
-                        .instantiate(self.tcx, alias.args)
-                        .visit_with(self)?;
-                }
-                _ => (),
-            }
-
-            t.super_visit_with(self)
-        }
-    }
-    if let ControlFlow::Break(args) =
-        ret.visit_with(&mut Visitor { tcx, opaque, seen: Default::default() })
-    {
-        trace!(?args);
-        trace!("expected: {hidden_ty:#?}");
-        hidden_ty = ty::EarlyBinder::bind(hidden_ty).instantiate(tcx, args);
-        trace!("expected: {hidden_ty:#?}");
-    } else {
-        tcx.sess
-            .delay_span_bug(tcx.def_span(function), format!("{ret:?} does not contain {opaque:?}"));
-    }
-    Ok(hidden_ty)
-}
-
 fn is_enum_of_nonnullable_ptr<'tcx>(
     tcx: TyCtxt<'tcx>,
     adt_def: AdtDef<'tcx>,
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index f568b751951..02a5d28b1e2 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1359,38 +1359,60 @@ fn impl_trait_ref(
         .as_ref()
         .map(|ast_trait_ref| {
             let selfty = tcx.type_of(def_id).instantiate_identity();
-            icx.astconv().instantiate_mono_trait_ref(
-                ast_trait_ref,
-                selfty,
-                check_impl_constness(tcx, impl_.constness, ast_trait_ref),
-            )
+
+            if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
+                tcx,
+                tcx.is_const_trait_impl_raw(def_id.to_def_id()),
+                &ast_trait_ref,
+            ) {
+                // we have a const impl, but for a trait without `#[const_trait]`, so
+                // without the host param. If we continue with the HIR trait ref, we get
+                // ICEs for generic arg count mismatch. We do a little HIR editing to
+                // make astconv happy.
+                let mut path_segments = ast_trait_ref.path.segments.to_vec();
+                let last_segment = path_segments.len() - 1;
+                let mut args = path_segments[last_segment].args().clone();
+                let last_arg = args.args.len() - 1;
+                assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host)));
+                args.args = &args.args[..args.args.len() - 1];
+                path_segments[last_segment].args = Some(&args);
+                let path = hir::Path {
+                    span: ast_trait_ref.path.span,
+                    res: ast_trait_ref.path.res,
+                    segments: &path_segments,
+                };
+                let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id };
+                icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty)
+            } else {
+                icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty)
+            }
         })
         .map(ty::EarlyBinder::bind)
 }
 
 fn check_impl_constness(
     tcx: TyCtxt<'_>,
-    constness: hir::Constness,
+    is_const: bool,
     ast_trait_ref: &hir::TraitRef<'_>,
-) -> ty::BoundConstness {
-    match constness {
-        hir::Constness::Const => {
-            if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
-                let trait_name = tcx.item_name(trait_def_id).to_string();
-                tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
-                    trait_ref_span: ast_trait_ref.path.span,
-                    trait_name,
-                    local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
-                    marking: (),
-                    adding: (),
-                });
-                ty::BoundConstness::NotConst
-            } else {
-                ty::BoundConstness::ConstIfConst
-            }
-        },
-        hir::Constness::NotConst => ty::BoundConstness::NotConst,
+) -> Option<ErrorGuaranteed> {
+    if !is_const {
+        return None;
     }
+
+    let trait_def_id = ast_trait_ref.trait_def_id()?;
+    if tcx.has_attr(trait_def_id, sym::const_trait) {
+        return None;
+    }
+
+    let trait_name = tcx.item_name(trait_def_id).to_string();
+    Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
+        trait_ref_span: ast_trait_ref.path.span,
+        trait_name,
+        local_trait_span:
+            trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
+        marking: (),
+        adding: (),
+    }))
 }
 
 fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity {
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 6e1762c54f2..4842008279a 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
                 }
 
-                host_effect_index = Some(parent_count + index as usize);
+                host_effect_index = Some(index as usize);
             }
 
             Some(ty::GenericParamDef {
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 83220be6883..495e663666c 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -2,16 +2,16 @@ use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
 use crate::bounds::Bounds;
 use crate::collect::ItemCtxt;
 use crate::constrained_generic_params as cgp;
-use hir::{HirId, Lifetime, Node};
+use hir::{HirId, Node};
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
+use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate};
 use rustc_span::symbol::Ident;
-use rustc_span::{Span, Symbol, DUMMY_SP};
+use rustc_span::{Span, DUMMY_SP};
 
 /// Returns a list of all type predicates (explicit and implicit) for the definition with
 /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
@@ -55,17 +55,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     use rustc_hir::*;
 
     match tcx.opt_rpitit_info(def_id.to_def_id()) {
-        Some(ImplTraitInTraitData::Trait { opaque_def_id, fn_def_id }) => {
-            let opaque_ty_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id.expect_local());
-            let opaque_ty_node = tcx.hir().get(opaque_ty_id);
-            let Node::Item(&Item {
-                kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping: Some(lifetime_mapping), .. }),
-                ..
-            }) = opaque_ty_node
-            else {
-                bug!("unexpected {opaque_ty_node:?}")
-            };
-
+        Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => {
             let mut predicates = Vec::new();
 
             // RPITITs should inherit the predicates of their parent. This is
@@ -78,13 +68,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
 
             // We also install bidirectional outlives predicates for the RPITIT
             // to keep the duplicates lifetimes from opaque lowering in sync.
+            // We only need to compute bidirectional outlives for the duplicated
+            // opaque lifetimes, which explains the slicing below.
             compute_bidirectional_outlives_predicates(
                 tcx,
-                def_id,
-                lifetime_mapping.iter().map(|(lifetime, def_id)| {
-                    (**lifetime, (*def_id, lifetime.ident.name, lifetime.ident.span))
-                }),
-                tcx.generics_of(def_id.to_def_id()),
+                &tcx.generics_of(def_id.to_def_id()).params
+                    [tcx.generics_of(fn_def_id).params.len()..],
                 &mut predicates,
             );
 
@@ -351,21 +340,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
         };
         debug!(?lifetimes);
 
-        let lifetime_mapping = std::iter::zip(lifetimes, ast_generics.params)
-            .map(|(arg, dup)| {
-                let hir::GenericArg::Lifetime(arg) = arg else { bug!() };
-                (**arg, dup)
-            })
-            .filter(|(_, dup)| matches!(dup.kind, hir::GenericParamKind::Lifetime { .. }))
-            .map(|(lifetime, dup)| (lifetime, (dup.def_id, dup.name.ident().name, dup.span)));
-
-        compute_bidirectional_outlives_predicates(
-            tcx,
-            def_id,
-            lifetime_mapping,
-            generics,
-            &mut predicates,
-        );
+        compute_bidirectional_outlives_predicates(tcx, &generics.params, &mut predicates);
         debug!(?predicates);
     }
 
@@ -379,41 +354,28 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
 /// enforce that these lifetimes stay in sync.
 fn compute_bidirectional_outlives_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    item_def_id: LocalDefId,
-    lifetime_mapping: impl Iterator<Item = (Lifetime, (LocalDefId, Symbol, Span))>,
-    generics: &Generics,
+    opaque_own_params: &[ty::GenericParamDef],
     predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
 ) {
-    let icx = ItemCtxt::new(tcx, item_def_id);
-
-    for (arg, (dup_def, name, span)) in lifetime_mapping {
-        let orig_region = icx.astconv().ast_region_to_region(&arg, None);
-        if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) {
-            // There is no late-bound lifetime to actually match up here, since the lifetime doesn't
-            // show up in the opaque's parent's args.
-            continue;
+    for param in opaque_own_params {
+        let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+        if let ty::ReEarlyBound(..) = *orig_lifetime {
+            let dup_lifetime = ty::Region::new_early_bound(
+                tcx,
+                ty::EarlyBoundRegion { def_id: param.def_id, index: param.index, name: param.name },
+            );
+            let span = tcx.def_span(param.def_id);
+            predicates.push((
+                ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_lifetime, dup_lifetime))
+                    .to_predicate(tcx),
+                span,
+            ));
+            predicates.push((
+                ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_lifetime, orig_lifetime))
+                    .to_predicate(tcx),
+                span,
+            ));
         }
-
-        let Some(dup_index) = generics.param_def_id_to_index(icx.tcx, dup_def.to_def_id()) else {
-            bug!()
-        };
-
-        let dup_region = ty::Region::new_early_bound(
-            tcx,
-            ty::EarlyBoundRegion { def_id: dup_def.to_def_id(), index: dup_index, name },
-        );
-
-        predicates.push((
-            ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region))
-                .to_predicate(tcx),
-            span,
-        ));
-
-        predicates.push((
-            ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region))
-                .to_predicate(tcx),
-            span,
-        ));
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 6be8d72aed2..61b182b1be7 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -578,6 +578,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             MissingTypesOrConsts { .. } => {
                 self.suggest_adding_type_and_const_args(err);
             }
+            ExcessTypesOrConsts { .. } => {
+                // this can happen with `~const T` where T isn't a const_trait.
+            }
             _ => unreachable!(),
         }
     }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index fda46798708..89efdc269c4 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -626,7 +626,6 @@ impl<'a> State<'a> {
                 unsafety,
                 polarity,
                 defaultness,
-                constness,
                 defaultness_span: _,
                 generics,
                 ref of_trait,
@@ -643,10 +642,6 @@ impl<'a> State<'a> {
                     self.space();
                 }
 
-                if constness == hir::Constness::Const {
-                    self.word_nbsp("const");
-                }
-
                 if let hir::ImplPolarity::Negative(_) = polarity {
                     self.word("!");
                 }
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index c68f2d94f35..ba00954db91 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -767,9 +767,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let tcx = self.tcx;
 
-        if !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you {
-            return;
-        }
+        // fast-reject if callee doesn't have the host effect param (non-const)
+        let generics = tcx.generics_of(callee_did);
+        let Some(host_effect_index) = generics.host_effect_index else { return };
+
+        // if the callee does have the param, we need to equate the param to some const
+        // value no matter whether the effects feature is enabled in the local crate,
+        // because inference will fail if we don't.
+        let mut host_always_on =
+            !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you;
 
         // Compute the constness required by the context.
         let context = tcx.hir().enclosing_body_owner(call_expr_hir);
@@ -780,10 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if tcx.has_attr(context.to_def_id(), sym::rustc_do_not_const_check) {
             trace!("do not const check this context");
-            return;
+            host_always_on = true;
         }
 
         let effect = match const_context {
+            _ if host_always_on => tcx.consts.true_,
             Some(hir::ConstContext::Static(_) | hir::ConstContext::Const) => tcx.consts.false_,
             Some(hir::ConstContext::ConstFn) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, context);
@@ -792,21 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             None => tcx.consts.true_,
         };
 
-        let generics = tcx.generics_of(callee_did);
-
         trace!(?effect, ?generics, ?callee_args);
 
-        if let Some(idx) = generics.host_effect_index {
-            let param = callee_args.const_at(idx);
-            let cause = self.misc(span);
-            match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
-                Ok(infer::InferOk { obligations, value: () }) => {
-                    self.register_predicates(obligations);
-                }
-                Err(e) => {
-                    // FIXME(effects): better diagnostic
-                    self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
-                }
+        let param = callee_args.const_at(host_effect_index);
+        let cause = self.misc(span);
+        match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
+            Ok(infer::InferOk { obligations, value: () }) => {
+                self.register_predicates(obligations);
+            }
+            Err(e) => {
+                // FIXME(effects): better diagnostic
+                self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit();
             }
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index b2b3f435505..d9b17a2e2b7 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1007,15 +1007,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         expr: &hir::Expr<'_>,
         expr_ty: Ty<'tcx>,
-        target: Ty<'tcx>,
+        mut target: Ty<'tcx>,
         allow_two_phase: AllowTwoPhase,
         cause: Option<ObligationCause<'tcx>>,
     ) -> RelateResult<'tcx, Ty<'tcx>> {
         let source = self.try_structurally_resolve_type(expr.span, expr_ty);
-        let target = self.try_structurally_resolve_type(
-            cause.as_ref().map_or(expr.span, |cause| cause.span),
-            target,
-        );
+        if self.next_trait_solver() {
+            target = self.try_structurally_resolve_type(
+                cause.as_ref().map_or(expr.span, |cause| cause.span),
+                target,
+            );
+        }
         debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
 
         let cause =
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 2af8648455b..7cea40fdd64 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -13,7 +13,7 @@ use crate::errors::{
     YieldExprOutsideOfGenerator,
 };
 use crate::fatally_break_rust;
-use crate::method::SelfSource;
+use crate::method::{MethodCallComponents, SelfSource};
 use crate::type_error_struct;
 use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
 use crate::{
@@ -1281,7 +1281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         segment.ident,
                         SelfSource::MethodCall(rcvr),
                         error,
-                        Some((rcvr, args)),
+                        Some(MethodCallComponents { receiver: rcvr, args, full_expr: expr }),
                         expected,
                         false,
                     ) {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 322d726a89d..8fad0a6c9e4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1349,7 +1349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                     GenericParamDefKind::Const { has_default } => {
-                        if !infer_args && has_default {
+                        if !infer_args
+                            && has_default
+                            && !tcx.has_attr(param.def_id, sym::rustc_host)
+                        {
                             tcx.const_param_default(param.def_id)
                                 .instantiate(tcx, args.unwrap())
                                 .into()
diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs
index 597696843c4..6dd131aa283 100644
--- a/compiler/rustc_hir_typeck/src/method/mod.rs
+++ b/compiler/rustc_hir_typeck/src/method/mod.rs
@@ -7,7 +7,7 @@ mod prelude2021;
 pub mod probe;
 mod suggest;
 
-pub use self::suggest::SelfSource;
+pub use self::suggest::{MethodCallComponents, SelfSource};
 pub use self::MethodError::*;
 
 use crate::errors::OpMethodGenericParams;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index b9d8c5a7540..2d64c5667a8 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -50,6 +50,15 @@ use rustc_hir::intravisit::Visitor;
 use std::cmp::{self, Ordering};
 use std::iter;
 
+/// After identifying that `full_expr` is a method call, we use this type to keep the expression's
+/// components readily available to us to point at the right place in diagnostics.
+#[derive(Debug, Clone, Copy)]
+pub struct MethodCallComponents<'tcx> {
+    pub receiver: &'tcx hir::Expr<'tcx>,
+    pub args: &'tcx [hir::Expr<'tcx>],
+    pub full_expr: &'tcx hir::Expr<'tcx>,
+}
+
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
         let tcx = self.tcx;
@@ -115,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         item_name: Ident,
         source: SelfSource<'tcx>,
         error: MethodError<'tcx>,
-        args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
+        args: Option<MethodCallComponents<'tcx>>,
         expected: Expectation<'tcx>,
         trait_missing_method: bool,
     ) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
@@ -257,18 +266,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn suggest_missing_writer(
         &self,
         rcvr_ty: Ty<'tcx>,
-        args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]),
+        args: MethodCallComponents<'tcx>,
     ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
         let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
-        let mut err =
-            struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str);
+        let mut err = struct_span_err!(
+            self.tcx.sess,
+            args.receiver.span,
+            E0599,
+            "cannot write into `{}`",
+            ty_str
+        );
         err.span_note(
-            args.0.span,
+            args.receiver.span,
             "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
         );
-        if let ExprKind::Lit(_) = args.0.kind {
+        if let ExprKind::Lit(_) = args.receiver.kind {
             err.span_help(
-                args.0.span.shrink_to_lo(),
+                args.receiver.span.shrink_to_lo(),
                 "a writer is needed before this format string",
             );
         };
@@ -282,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         rcvr_ty: Ty<'tcx>,
         item_name: Ident,
         source: SelfSource<'tcx>,
-        args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
+        args: Option<MethodCallComponents<'tcx>>,
         sugg_span: Span,
         no_match_data: &mut NoMatchData<'tcx>,
         expected: Expectation<'tcx>,
@@ -953,6 +967,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 unsatisfied_bounds = true;
             }
+        } else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some(args) = args {
+            // This is useful for methods on arbitrary self types that might have a simple
+            // mutability difference, like calling a method on `Pin<&mut Self>` that is on
+            // `Pin<&Self>`.
+            if targs.len() == 1 {
+                let mut item_segment = hir::PathSegment::invalid();
+                item_segment.ident = item_name;
+                for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] {
+                    let new_args = tcx.mk_args_from_iter(
+                        targs
+                            .iter()
+                            .map(|arg| match arg.as_type() {
+                                Some(ty) => ty::GenericArg::from(
+                                    t(tcx, tcx.lifetimes.re_erased, ty.peel_refs()),
+                                ),
+                                _ => arg,
+                            })
+                    );
+                    let rcvr_ty = Ty::new_adt(tcx, *def, new_args);
+                    if let Ok(method) = self.lookup_method_for_diagnostic(
+                        rcvr_ty,
+                        &item_segment,
+                        span,
+                        args.full_expr,
+                        args.receiver,
+                    ) {
+                        err.span_note(
+                            tcx.def_span(method.def_id),
+                            format!("{item_kind} is available for `{rcvr_ty}`"),
+                        );
+                    }
+                }
+            }
         }
 
         let label_span_not_found = |err: &mut Diagnostic| {
@@ -1111,7 +1158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 span,
                 rcvr_ty,
                 item_name,
-                args.map(|(_, args)| args.len() + 1),
+                args.map(|MethodCallComponents { args, .. }| args.len() + 1),
                 source,
                 no_match_data.out_of_scope_traits.clone(),
                 &unsatisfied_predicates,
@@ -1192,7 +1239,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         rcvr_ty: Ty<'tcx>,
         item_name: Ident,
-        args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
+        args: Option<MethodCallComponents<'tcx>>,
         span: Span,
         err: &mut Diagnostic,
         sources: &mut Vec<CandidateSource>,
@@ -1343,7 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         rcvr_ty: Ty<'tcx>,
         source: SelfSource<'tcx>,
         item_name: Ident,
-        args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>])>,
+        args: Option<MethodCallComponents<'tcx>>,
         sugg_span: Span,
     ) {
         let mut has_unsuggestable_args = false;
@@ -1415,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 None
             };
             let mut applicability = Applicability::MachineApplicable;
-            let args = if let Some((receiver, args)) = args {
+            let args = if let Some(MethodCallComponents { receiver, args, .. }) = args {
                 // The first arg is the same kind as the receiver
                 let explicit_args = if first_arg.is_some() {
                     std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
@@ -2995,7 +3042,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
 
 fn print_disambiguation_help<'tcx>(
     item_name: Ident,
-    args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
+    args: Option<MethodCallComponents<'tcx>>,
     err: &mut Diagnostic,
     trait_name: String,
     rcvr_ty: Ty<'_>,
@@ -3007,7 +3054,11 @@ fn print_disambiguation_help<'tcx>(
     fn_has_self_parameter: bool,
 ) {
     let mut applicability = Applicability::MachineApplicable;
-    let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
+    let (span, sugg) = if let (
+        ty::AssocKind::Fn,
+        Some(MethodCallComponents { receiver, args, .. }),
+    ) = (kind, args)
+    {
         let args = format!(
             "({}{})",
             rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index a34fdf4ecc9..07c559354c0 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -12,7 +12,7 @@ use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
 use rustc_errors::PResult;
 use rustc_expand::base::{ExtCtxt, LintStoreExpand};
 use rustc_fs_util::try_canonicalize;
-use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
+use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore};
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
@@ -72,43 +72,16 @@ fn count_nodes(krate: &ast::Crate) -> usize {
     counter.count
 }
 
-pub fn register_plugins<'a>(
-    sess: &'a Session,
-    metadata_loader: &'a dyn MetadataLoader,
-    register_lints: impl Fn(&Session, &mut LintStore),
+pub(crate) fn create_lint_store(
+    sess: &Session,
+    metadata_loader: &dyn MetadataLoader,
+    register_lints: Option<impl Fn(&Session, &mut LintStore)>,
     pre_configured_attrs: &[ast::Attribute],
-    crate_name: Symbol,
-) -> Result<LintStore> {
-    // these need to be set "early" so that expansion sees `quote` if enabled.
-    let features = rustc_expand::config::features(sess, pre_configured_attrs);
-    sess.init_features(features);
-
-    let crate_types = util::collect_crate_types(sess, pre_configured_attrs);
-    sess.init_crate_types(crate_types);
-
-    let stable_crate_id = StableCrateId::new(
-        crate_name,
-        sess.crate_types().contains(&CrateType::Executable),
-        sess.opts.cg.metadata.clone(),
-        sess.cfg_version,
-    );
-    sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
-    rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
-
-    if sess.opts.incremental.is_some() {
-        sess.time("incr_comp_garbage_collect_session_directories", || {
-            if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
-                warn!(
-                    "Error while trying to garbage collect incremental \
-                     compilation cache directory: {}",
-                    e
-                );
-            }
-        });
-    }
-
+) -> LintStore {
     let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
-    register_lints(sess, &mut lint_store);
+    if let Some(register_lints) = register_lints {
+        register_lints(sess, &mut lint_store);
+    }
 
     let registrars = sess.time("plugin_loading", || {
         plugin::load::load_plugins(sess, metadata_loader, pre_configured_attrs)
@@ -120,7 +93,7 @@ pub fn register_plugins<'a>(
         }
     });
 
-    Ok(lint_store)
+    lint_store
 }
 
 fn pre_expansion_lint<'a>(
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 8c4cdc6696a..b805ff09ee4 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -1,6 +1,6 @@
 use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
 use crate::interface::{Compiler, Result};
-use crate::passes;
+use crate::{passes, util};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
@@ -9,15 +9,14 @@ 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};
-use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_incremental::DepGraphFuture;
-use rustc_lint::LintStore;
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
 use rustc_middle::ty::{GlobalCtxt, TyCtxt};
-use rustc_session::config::{self, OutputFilenames, OutputType};
+use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::{output::find_crate_name, Session};
 use rustc_span::symbol::sym;
@@ -85,12 +84,11 @@ pub struct Queries<'tcx> {
     arena: WorkerLocal<Arena<'tcx>>,
     hir_arena: WorkerLocal<rustc_hir::Arena<'tcx>>,
 
-    dep_graph_future: Query<Option<DepGraphFuture>>,
     parse: Query<ast::Crate>,
     pre_configure: Query<(ast::Crate, ast::AttrVec)>,
     crate_name: Query<Symbol>,
-    register_plugins: Query<(ast::Crate, ast::AttrVec, Lrc<LintStore>)>,
-    dep_graph: Query<DepGraph>,
+    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,12 +100,11 @@ impl<'tcx> Queries<'tcx> {
             gcx_cell: OnceCell::new(),
             arena: WorkerLocal::new(|_| Arena::default()),
             hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
-            dep_graph_future: Default::default(),
             parse: Default::default(),
             pre_configure: Default::default(),
             crate_name: Default::default(),
-            register_plugins: Default::default(),
-            dep_graph: Default::default(),
+            crate_types: Default::default(),
+            stable_crate_id: Default::default(),
             gcx: Default::default(),
         }
     }
@@ -119,13 +116,6 @@ impl<'tcx> Queries<'tcx> {
         self.compiler.codegen_backend()
     }
 
-    fn dep_graph_future(&self) -> Result<QueryResult<'_, Option<DepGraphFuture>>> {
-        self.dep_graph_future.compute(|| {
-            let sess = self.session();
-            Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess)))
-        })
-    }
-
     pub fn parse(&self) -> Result<QueryResult<'_, ast::Crate>> {
         self.parse
             .compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit()))
@@ -148,84 +138,111 @@ impl<'tcx> Queries<'tcx> {
         })
     }
 
-    pub fn register_plugins(
-        &self,
-    ) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec, Lrc<LintStore>)>> {
-        self.register_plugins.compute(|| {
-            let crate_name = *self.crate_name()?.borrow();
-            let (krate, pre_configured_attrs) = self.pre_configure()?.steal();
-
-            let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {};
-            let lint_store = passes::register_plugins(
-                self.session(),
-                &*self.codegen_backend().metadata_loader(),
-                self.compiler.register_lints.as_deref().unwrap_or_else(|| empty),
-                &pre_configured_attrs,
-                crate_name,
-            )?;
-
-            // 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, but it also can't happen
-            // until after rustc_incremental::prepare_session_directory() is
-            // called, which happens within passes::register_plugins().
-            self.dep_graph_future().ok();
-
-            Ok((krate, pre_configured_attrs, Lrc::new(lint_store)))
+    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_name(&self) -> Result<QueryResult<'_, Symbol>> {
-        self.crate_name.compute(|| {
-            Ok({
-                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.
-                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 dep_graph(&self) -> Result<QueryResult<'_, DepGraph>> {
-        self.dep_graph.compute(|| {
+    fn stable_crate_id(&self) -> Result<QueryResult<'_, StableCrateId>> {
+        self.stable_crate_id.compute(|| {
             let sess = self.session();
-            let future_opt = self.dep_graph_future()?.steal();
-            let dep_graph = future_opt
-                .and_then(|future| {
-                    let (prev_graph, mut 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);
-            Ok(dep_graph)
+            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>> {
+        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)?;
+        let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
+
+        if sess.opts.incremental.is_some() {
+            sess.time("incr_comp_garbage_collect_session_directories", || {
+                if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
+                    warn!(
+                        "Error while trying to garbage collect incremental \
+                         compilation cache directory: {}",
+                        e
+                    );
+                }
+            });
+        }
+
+        Ok(res)
+    }
+
+    fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
+        dep_graph_future
+            .and_then(|future| {
+                let sess = self.session();
+                let (prev_graph, mut 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)
+    }
+
     pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
-            let crate_name = *self.crate_name()?.borrow();
-            let (krate, pre_configured_attrs, lint_store) = self.register_plugins()?.steal();
+            // 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 sess = self.session();
+            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 cstore = RwLock::new(Box::new(CStore::new(sess)) as _);
-            let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id()));
+            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 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 these fields from session to tcx and make them immutable.
+            sess.init_crate_types(crate_types);
+            sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized");
+            sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs));
+
             let qcx = passes::create_global_ctxt(
                 self.compiler,
                 lint_store,
-                self.dep_graph()?.steal(),
+                self.dep_graph(dep_graph_future),
                 untracked,
                 &self.gcx_cell,
                 &self.arena,
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index ea045462845..3f2bf2c9b44 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -15,7 +15,6 @@
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/JSON.h"
-#include "llvm/Support/Host.h"
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 48b5fd6e283..b3371dbe834 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -25,11 +25,11 @@
 #if LLVM_VERSION_GE(17, 0)
 #include "llvm/Support/VirtualFileSystem.h"
 #endif
-#include "llvm/Support/Host.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
 #include "llvm/Transforms/IPO/Internalize.h"
+#include "llvm/Transforms/IPO/LowerTypeTests.h"
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Utils/AddDiscriminators.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
@@ -609,6 +609,8 @@ enum class LLVMRustOptStage {
 struct LLVMRustSanitizerOptions {
   bool SanitizeAddress;
   bool SanitizeAddressRecover;
+  bool SanitizeCFI;
+  bool SanitizeKCFI;
   bool SanitizeMemory;
   bool SanitizeMemoryRecover;
   int  SanitizeMemoryTrackOrigins;
@@ -625,6 +627,7 @@ LLVMRustOptimize(
     LLVMTargetMachineRef TMRef,
     LLVMRustPassBuilderOptLevel OptLevelRust,
     LLVMRustOptStage OptStage,
+    bool IsLinkerPluginLTO,
     bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
     bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
     bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
@@ -736,6 +739,18 @@ LLVMRustOptimize(
   std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
       OptimizerLastEPCallbacks;
 
+  if (!IsLinkerPluginLTO
+      && SanitizerOptions && SanitizerOptions->SanitizeCFI
+      && !NoPrepopulatePasses) {
+    PipelineStartEPCallbacks.push_back(
+      [](ModulePassManager &MPM, OptimizationLevel Level) {
+        MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
+                                       /*ImportSummary=*/nullptr,
+                                       /*DropTypeTests=*/false));
+      }
+    );
+  }
+
   if (VerifyIR) {
     PipelineStartEPCallbacks.push_back(
       [VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) {
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 8ef39a6c866..70cdf3d6d23 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1869,7 +1869,8 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
     LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback,
     void *DiagnosticHandlerContext, bool RemarkAllPasses,
     const char * const * RemarkPasses, size_t RemarkPassesLen,
-    const char * RemarkFilePath
+    const char * RemarkFilePath,
+    bool PGOAvailable
 ) {
 
   class RustDiagnosticHandler final : public DiagnosticHandler {
@@ -1967,6 +1968,11 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
   std::unique_ptr<LLVMRemarkStreamer> LlvmRemarkStreamer;
 
   if (RemarkFilePath != nullptr) {
+    if (PGOAvailable) {
+      // Enable PGO hotness data for remarks, if available
+      unwrap(C)->setDiagnosticsHotnessRequested(true);
+    }
+
     std::error_code EC;
     RemarkFile = std::make_unique<ToolOutputFile>(
       RemarkFilePath,
@@ -2027,3 +2033,14 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) {
 extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) {
   return identify_magic(StringRef(ptr, len)) == file_magic::bitcode;
 }
+
+extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) {
+  if (unwrap<Value>(V)->getType()->isPointerTy()) {
+    if (auto *GV = dyn_cast<GlobalValue>(unwrap<Value>(V))) {
+      if (GV->getValueType()->isFunctionTy())
+        return false;
+    }
+    return true;
+  }
+  return false;
+}
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 571af82d13a..7c9aaeb5762 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -20,7 +20,6 @@ use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate};
 use rustc_session::lint;
 use rustc_session::output::validate_crate_name;
 use rustc_session::search_paths::PathKind;
-use rustc_session::Session;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{Span, DUMMY_SP};
@@ -262,9 +261,9 @@ impl CStore {
         }
     }
 
-    pub fn new(sess: &Session) -> CStore {
+    pub fn new(local_stable_crate_id: StableCrateId) -> CStore {
         let mut stable_crate_ids = StableCrateIdMap::default();
-        stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
+        stable_crate_ids.insert(local_stable_crate_id, LOCAL_CRATE);
         CStore {
             // We add an empty entry for LOCAL_CRATE (which maps to zero) in
             // order to make array indices in `metas` match with the
@@ -544,6 +543,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
                 self.sess,
                 &**metadata_loader,
                 name,
+                // The all loop is because `--crate-type=rlib --crate-type=rlib` is
+                // legal and produces both inside this type.
+                self.sess.crate_types().iter().all(|c| *c == CrateType::Rlib),
                 hash,
                 extra_filename,
                 false, // is_host
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index a0c552f5fd6..bf6004ba864 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -222,7 +222,7 @@ use rustc_data_structures::owned_slice::slice_owned;
 use rustc_data_structures::svh::Svh;
 use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
 use rustc_fs_util::try_canonicalize;
-use rustc_session::config::{self, CrateType};
+use rustc_session::config;
 use rustc_session::cstore::{CrateSource, MetadataLoader};
 use rustc_session::filesearch::FileSearch;
 use rustc_session::search_paths::PathKind;
@@ -305,14 +305,12 @@ impl<'a> CrateLocator<'a> {
         sess: &'a Session,
         metadata_loader: &'a dyn MetadataLoader,
         crate_name: Symbol,
+        is_rlib: bool,
         hash: Option<Svh>,
         extra_filename: Option<&'a str>,
         is_host: bool,
         path_kind: PathKind,
     ) -> CrateLocator<'a> {
-        // The all loop is because `--crate-type=rlib --crate-type=rlib` is
-        // legal and produces both inside this type.
-        let is_rlib = sess.crate_types().iter().all(|c| *c == CrateType::Rlib);
         let needs_object_code = sess.opts.output_types.should_codegen();
         // If we're producing an rlib, then we don't need object code.
         // Or, if we're not producing object code, then we don't need it either
@@ -883,9 +881,10 @@ fn find_plugin_registrar_impl<'a>(
         sess,
         metadata_loader,
         name,
-        None, // hash
-        None, // extra_filename
-        true, // is_host
+        false, // is_rlib
+        None,  // hash
+        None,  // extra_filename
+        true,  // is_host
         PathKind::Crate,
     );
 
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 2567170f39a..c787481bfbe 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -329,6 +329,9 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
 
     /// Try to create an Allocation of `size` bytes, panics if there is not enough memory
     /// available to the compiler to do so.
+    ///
+    /// Example use case: To obtain an Allocation filled with specific data,
+    /// first call this function and then call write_scalar to fill in the right data.
     pub fn uninit(size: Size, align: Align) -> Self {
         match Self::uninit_inner(size, align, || {
             panic!("Allocation::uninit called with panic_on_fail had allocation failure");
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 2e46bfc1a38..e6ef5a41ee0 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -184,8 +184,6 @@ pub enum InvalidProgramInfo<'tcx> {
     /// (which unfortunately typeck does not reject).
     /// Not using `FnAbiError` as that contains a nested `LayoutError`.
     FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
-    /// SizeOf of unsized type was requested.
-    SizeOfUnsizedType(Ty<'tcx>),
     /// We are runnning into a nonsense situation due to ConstProp violating our invariants.
     ConstPropNonsense,
 }
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 2e5c6a44579..74bdd07a1c9 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -7,6 +7,7 @@ use std::fmt::Write;
 
 use crate::query::Providers;
 use rustc_data_structures::fx::FxIndexMap;
+use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{self as hir, LangItem};
 use rustc_span::def_id::LocalDefIdMap;
@@ -89,10 +90,18 @@ pub enum ClosureKind {
     FnOnce,
 }
 
-impl<'tcx> ClosureKind {
+impl ClosureKind {
     /// This is the initial value used when doing upvar inference.
     pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
 
+    pub const fn as_str(self) -> &'static str {
+        match self {
+            ClosureKind::Fn => "Fn",
+            ClosureKind::FnMut => "FnMut",
+            ClosureKind::FnOnce => "FnOnce",
+        }
+    }
+
     /// Returns `true` if a type that impls this closure kind
     /// must also implement `other`.
     pub fn extends(self, other: ty::ClosureKind) -> bool {
@@ -115,7 +124,7 @@ impl<'tcx> ClosureKind {
 
     /// Returns the representative scalar type for this closure kind.
     /// See `Ty::to_opt_closure_kind` for more details.
-    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self {
             ClosureKind::Fn => tcx.types.i8,
             ClosureKind::FnMut => tcx.types.i16,
@@ -124,6 +133,12 @@ impl<'tcx> ClosureKind {
     }
 }
 
+impl IntoDiagnosticArg for ClosureKind {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(self.as_str().into())
+    }
+}
+
 /// A composite describing a `Place` that is captured by a closure.
 #[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 0b2d95506bf..8ac1d02ce50 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1931,6 +1931,84 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
+    /// Given the def-id of an early-bound lifetime on an RPIT corresponding to
+    /// a duplicated captured lifetime, map it back to the early- or late-bound
+    /// lifetime of the function from which it originally as captured. If it is
+    /// a late-bound lifetime, this will represent the liberated (`ReFree`) lifetime
+    /// of the signature.
+    // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
+    // re-use the generics of the opaque, this function will need to be tweaked slightly.
+    pub fn map_rpit_lifetime_to_fn_lifetime(
+        self,
+        mut rpit_lifetime_param_def_id: LocalDefId,
+    ) -> ty::Region<'tcx> {
+        debug_assert!(
+            matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam),
+            "{rpit_lifetime_param_def_id:?} is a {}",
+            self.def_descr(rpit_lifetime_param_def_id.to_def_id())
+        );
+
+        loop {
+            let parent = self.local_parent(rpit_lifetime_param_def_id);
+            let hir::OpaqueTy { lifetime_mapping, .. } =
+                self.hir().get_by_def_id(parent).expect_item().expect_opaque_ty();
+
+            let Some((lifetime, _)) = lifetime_mapping
+                .iter()
+                .find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id)
+            else {
+                bug!("duplicated lifetime param should be present");
+            };
+
+            match self.named_bound_var(lifetime.hir_id) {
+                Some(resolve_bound_vars::ResolvedArg::EarlyBound(ebv)) => {
+                    let new_parent = self.parent(ebv);
+
+                    // If we map to another opaque, then it should be a parent
+                    // of the opaque we mapped from. Continue mapping.
+                    if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
+                        debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
+                        rpit_lifetime_param_def_id = ebv.expect_local();
+                        continue;
+                    }
+
+                    let generics = self.generics_of(new_parent);
+                    return ty::Region::new_early_bound(
+                        self,
+                        ty::EarlyBoundRegion {
+                            def_id: ebv,
+                            index: generics
+                                .param_def_id_to_index(self, ebv)
+                                .expect("early-bound var should be present in fn generics"),
+                            name: self.hir().name(self.local_def_id_to_hir_id(ebv.expect_local())),
+                        },
+                    );
+                }
+                Some(resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv)) => {
+                    let new_parent = self.parent(lbv);
+                    return ty::Region::new_free(
+                        self,
+                        new_parent,
+                        ty::BoundRegionKind::BrNamed(
+                            lbv,
+                            self.hir().name(self.local_def_id_to_hir_id(lbv.expect_local())),
+                        ),
+                    );
+                }
+                Some(resolve_bound_vars::ResolvedArg::Error(guar)) => {
+                    return ty::Region::new_error(self, guar);
+                }
+                _ => {
+                    return ty::Region::new_error_with_message(
+                        self,
+                        lifetime.ident.span,
+                        "cannot resolve lifetime",
+                    );
+                }
+            }
+        }
+    }
+
     /// Whether the `def_id` counts as const fn in the current crate, considering all active
     /// feature gates
     pub fn is_const_fn(self, def_id: DefId) -> bool {
@@ -1963,9 +2041,9 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(
             node,
             hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
+                kind: hir::ItemKind::Impl(hir::Impl { generics, .. }),
                 ..
-            })
+            }) if generics.params.iter().any(|p| self.has_attr(p.def_id, sym::rustc_host))
         )
     }
 
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index df39103bc19..e362b3477c9 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1239,6 +1239,8 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
         | EfiApi
         | AvrInterrupt
         | AvrNonBlockingInterrupt
+        | RiscvInterruptM
+        | RiscvInterruptS
         | CCmseNonSecureCall
         | Wasm
         | PlatformIntrinsic
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 27ade16739d..bb6513363c9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2841,6 +2841,11 @@ define_print_and_forward_display! {
 
     ty::TraitPredicate<'tcx> {
         p!(print(self.trait_ref.self_ty()), ": ");
+        if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index {
+            if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ {
+                p!("~const ");
+            }
+        }
         // FIXME(effects) print `~const` here
         if let ty::ImplPolarity::Negative = self.polarity {
             p!("!");
@@ -2870,11 +2875,7 @@ define_print_and_forward_display! {
     }
 
     ty::ClosureKind {
-        match *self {
-            ty::ClosureKind::Fn => p!("Fn"),
-            ty::ClosureKind::FnMut => p!("FnMut"),
-            ty::ClosureKind::FnOnce => p!("FnOnce"),
-        }
+        p!(write("{}", self.as_str()))
     }
 
     ty::Predicate<'tcx> {
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 58cc161ddcc..d202860840c 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -30,6 +30,8 @@ fn abi_can_unwind(abi: Abi) -> bool {
         | EfiApi
         | AvrInterrupt
         | AvrNonBlockingInterrupt
+        | RiscvInterruptM
+        | RiscvInterruptS
         | CCmseNonSecureCall
         | Wasm
         | RustIntrinsic
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index f99a51fea0b..bf798adee19 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -75,7 +75,7 @@ mod errors;
 mod ffi_unwind_calls;
 mod function_item_references;
 mod generator;
-mod inline;
+pub mod inline;
 mod instsimplify;
 mod large_enums;
 mod lower_intrinsics;
@@ -431,7 +431,9 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
     tcx.alloc_steal_mir(body)
 }
 
-fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden
+// by custom rustc drivers, running all the steps by themselves.
+pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
     let did = body.source.def_id();
 
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 25a3d38c144..3950ac9dd31 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -732,13 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
             // For implementations of traits, check the stability of each item
             // individually as it's possible to have a stable trait with unstable
             // items.
-            hir::ItemKind::Impl(hir::Impl {
-                of_trait: Some(ref t),
-                self_ty,
-                items,
-                constness,
-                ..
-            }) => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
                 let features = self.tcx.features();
                 if features.staged_api {
                     let attrs = self.tcx.hir().attrs(item.hir_id());
@@ -769,7 +763,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                     // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
                     // needs to have an error emitted.
                     if features.const_trait_impl
-                        && *constness == hir::Constness::Const
+                        && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id())
                         && const_stab.is_some_and(|(stab, _)| stab.is_const_stable())
                     {
                         self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span });
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index d4042a2e61a..b07c6db599e 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -89,7 +89,9 @@ session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-genera
 
 session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
 
-session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`
+session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
+
+session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
 
 session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
 
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 1ffee01b2f1..78940462b2c 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -115,6 +115,10 @@ pub struct CannotEnableCrtStaticLinux;
 pub struct SanitizerCfiRequiresLto;
 
 #[derive(Diagnostic)]
+#[diag(session_sanitizer_cfi_requires_single_codegen_unit)]
+pub struct SanitizerCfiRequiresSingleCodegenUnit;
+
+#[derive(Diagnostic)]
 #[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)]
 pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi;
 
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index ac745d16161..b25a6299125 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1619,13 +1619,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
 
     // LLVM CFI requires LTO.
     if sess.is_sanitizer_cfi_enabled()
-        && !(sess.lto() == config::Lto::Fat
-            || sess.lto() == config::Lto::Thin
-            || sess.opts.cg.linker_plugin_lto.enabled())
+        && !(sess.lto() == config::Lto::Fat || sess.opts.cg.linker_plugin_lto.enabled())
     {
         sess.emit_err(errors::SanitizerCfiRequiresLto);
     }
 
+    // LLVM CFI using rustc LTO requires a single codegen unit.
+    if sess.is_sanitizer_cfi_enabled()
+        && sess.lto() == config::Lto::Fat
+        && !(sess.codegen_units().as_usize() == 1)
+    {
+        sess.emit_err(errors::SanitizerCfiRequiresSingleCodegenUnit);
+    }
+
     // LLVM CFI is incompatible with LLVM KCFI.
     if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
         sess.emit_err(errors::CannotMixAndMatchSanitizers {
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 39541c845b3..0d9157940f8 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -112,6 +112,10 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::TraitDef(self.create_def_id(did))
     }
 
+    pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
+        stable_mir::ty::ConstDef(self.create_def_id(did))
+    }
+
     fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
         // FIXME: this becomes inefficient when we have too many ids
         for (i, &d) in self.def_ids.iter().enumerate() {
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index d12de92db8a..f782138f870 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -9,11 +9,14 @@
 
 use crate::rustc_internal::{self, opaque};
 use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
-use crate::stable_mir::ty::{FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy};
+use crate::stable_mir::ty::{
+    allocation_filter, new_allocation, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
+};
 use crate::stable_mir::{self, Context};
 use rustc_hir as hir;
 use rustc_middle::mir::coverage::CodeRegion;
-use rustc_middle::mir::{self};
+use rustc_middle::mir::interpret::alloc_range;
+use rustc_middle::mir::{self, ConstantKind};
 use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
 use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_target::abi::FieldIdx;
@@ -877,6 +880,8 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
                 abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic,
                 abi::Abi::Unadjusted => Abi::Unadjusted,
                 abi::Abi::RustCold => Abi::RustCold,
+                abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM,
+                abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS,
             },
         }
     }
@@ -1080,30 +1085,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
     type T = stable_mir::ty::Allocation;
 
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        let size = self.size();
-        let mut bytes: Vec<Option<u8>> = self
-            .inspect_with_uninit_and_ptr_outside_interpreter(0..size.bytes_usize())
-            .iter()
-            .copied()
-            .map(Some)
-            .collect();
-        for (i, b) in bytes.iter_mut().enumerate() {
-            if !self.init_mask().get(rustc_target::abi::Size::from_bytes(i)) {
-                *b = None;
-            }
-        }
-        stable_mir::ty::Allocation {
-            bytes: bytes,
-            provenance: {
-                let mut ptrs = Vec::new();
-                for (size, prov) in self.provenance().ptrs().iter() {
-                    ptrs.push((size.bytes_usize(), opaque(prov)));
-                }
-                stable_mir::ty::ProvenanceMap { ptrs }
-            },
-            align: self.align.bytes(),
-            mutability: self.mutability.stable(tables),
-        }
+        allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables)
     }
 }
 
@@ -1145,3 +1127,30 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
         }
     }
 }
+
+impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> {
+    type T = stable_mir::ty::ConstantKind;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        match self {
+            ConstantKind::Ty(c) => match c.kind() {
+                ty::Value(val) => {
+                    let const_val = tables.tcx.valtree_to_const_val((c.ty(), val));
+                    stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables))
+                }
+                _ => todo!(),
+            },
+            ConstantKind::Unevaluated(unev_const, ty) => {
+                stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst {
+                    ty: tables.intern_ty(*ty),
+                    def: tables.const_def(unev_const.def),
+                    args: unev_const.args.stable(tables),
+                    promoted: unev_const.promoted.map(|u| u.as_u32()),
+                })
+            }
+            ConstantKind::Val(val, _) => {
+                stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables))
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index c487db5b732..e83ca88da1b 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -1,5 +1,10 @@
+use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer};
+
 use super::{mir::Mutability, mir::Safety, with, DefId};
-use crate::rustc_internal::Opaque;
+use crate::{
+    rustc_internal::{opaque, Opaque},
+    rustc_smir::{Stable, Tables},
+};
 
 #[derive(Copy, Clone, Debug)]
 pub struct Ty(pub usize);
@@ -105,6 +110,9 @@ pub struct AliasDef(pub(crate) DefId);
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct TraitDef(pub(crate) DefId);
 
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct ConstDef(pub(crate) DefId);
+
 impl TraitDef {
     pub fn trait_decl(&self) -> TraitDecl {
         with(|cx| cx.trait_decl(self))
@@ -178,6 +186,8 @@ pub enum Abi {
     PlatformIntrinsic,
     Unadjusted,
     RustCold,
+    RiscvInterruptM,
+    RiscvInterruptS,
 }
 
 #[derive(Clone, Debug)]
@@ -248,6 +258,7 @@ pub type Bytes = Vec<Option<u8>>;
 pub type Size = usize;
 pub type Prov = Opaque;
 pub type Align = u64;
+pub type Promoted = u32;
 pub type InitMaskMaterialized = Vec<u64>;
 
 /// Stores the provenance information of pointers stored in memory.
@@ -266,6 +277,142 @@ pub struct Allocation {
     pub mutability: Mutability,
 }
 
+impl Allocation {
+    /// Creates new empty `Allocation` from given `Align`.
+    fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
+        Allocation {
+            bytes: Vec::new(),
+            provenance: ProvenanceMap { ptrs: Vec::new() },
+            align: align.bytes(),
+            mutability: Mutability::Not,
+        }
+    }
+}
+
+// We need this method instead of a Stable implementation
+// because we need to get `Ty` of the const we are trying to create, to do that
+// we need to have access to `ConstantKind` but we can't access that inside Stable impl.
+pub fn new_allocation<'tcx>(
+    const_kind: &rustc_middle::mir::ConstantKind<'tcx>,
+    const_value: ConstValue<'tcx>,
+    tables: &mut Tables<'tcx>,
+) -> Allocation {
+    match const_value {
+        ConstValue::Scalar(scalar) => {
+            let size = scalar.size();
+            let align = tables
+                .tcx
+                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
+                .unwrap()
+                .align;
+            let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi);
+            allocation
+                .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar)
+                .unwrap();
+            allocation.stable(tables)
+        }
+        ConstValue::ZeroSized => {
+            let align = tables
+                .tcx
+                .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty()))
+                .unwrap()
+                .align;
+            Allocation::new_empty_allocation(align.abi)
+        }
+        ConstValue::Slice { data, start, end } => {
+            let alloc_id = tables.tcx.create_memory_alloc(data);
+            let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start));
+            let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx);
+            let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize(
+                (end - start) as u64,
+                &tables.tcx,
+            );
+            let layout = tables
+                .tcx
+                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
+                .unwrap();
+            let mut allocation =
+                rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi);
+            allocation
+                .write_scalar(
+                    &tables.tcx,
+                    alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size),
+                    scalar_ptr,
+                )
+                .unwrap();
+            allocation
+                .write_scalar(
+                    &tables.tcx,
+                    alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()),
+                    scalar_len,
+                )
+                .unwrap();
+            allocation.stable(tables)
+        }
+        ConstValue::ByRef { alloc, offset } => {
+            let ty_size = tables
+                .tcx
+                .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty()))
+                .unwrap()
+                .size;
+            allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables)
+        }
+    }
+}
+
+/// Creates an `Allocation` only from information within the `AllocRange`.
+pub fn allocation_filter<'tcx>(
+    alloc: &rustc_middle::mir::interpret::Allocation,
+    alloc_range: AllocRange,
+    tables: &mut Tables<'tcx>,
+) -> Allocation {
+    let mut bytes: Vec<Option<u8>> = alloc
+        .inspect_with_uninit_and_ptr_outside_interpreter(
+            alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(),
+        )
+        .iter()
+        .copied()
+        .map(Some)
+        .collect();
+    for (i, b) in bytes.iter_mut().enumerate() {
+        if !alloc
+            .init_mask()
+            .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize()))
+        {
+            *b = None;
+        }
+    }
+    let mut ptrs = Vec::new();
+    for (offset, prov) in alloc
+        .provenance()
+        .ptrs()
+        .iter()
+        .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end())
+    {
+        ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov)));
+    }
+    Allocation {
+        bytes: bytes,
+        provenance: ProvenanceMap { ptrs },
+        align: alloc.align.bytes(),
+        mutability: alloc.mutability.stable(tables),
+    }
+}
+
+#[derive(Clone, Debug)]
+pub enum ConstantKind {
+    Allocated(Allocation),
+    Unevaluated(UnevaluatedConst),
+}
+
+#[derive(Clone, Debug)]
+pub struct UnevaluatedConst {
+    pub ty: Ty,
+    pub def: ConstDef,
+    pub args: GenericArgs,
+    pub promoted: Option<Promoted>,
+}
+
 pub enum TraitSpecializationKind {
     None,
     Marker,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9ea9efb047c..745a3590720 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -326,6 +326,7 @@ symbols! {
         abi_efiapi,
         abi_msp430_interrupt,
         abi_ptx,
+        abi_riscv_interrupt,
         abi_sysv64,
         abi_thiscall,
         abi_unadjusted,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 3d2ea017d8f..e4989bdfbcd 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -603,6 +603,25 @@ pub enum Conv {
     AmdGpuKernel,
     AvrInterrupt,
     AvrNonBlockingInterrupt,
+
+    RiscvInterrupt {
+        kind: RiscvInterruptKind,
+    },
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)]
+pub enum RiscvInterruptKind {
+    Machine,
+    Supervisor,
+}
+
+impl RiscvInterruptKind {
+    pub fn as_str(&self) -> &'static str {
+        match self {
+            Self::Machine => "machine",
+            Self::Supervisor => "supervisor",
+        }
+    }
 }
 
 /// Metadata describing how the arguments to a native function
@@ -753,6 +772,12 @@ impl FromStr for Conv {
             "AmdGpuKernel" => Ok(Conv::AmdGpuKernel),
             "AvrInterrupt" => Ok(Conv::AvrInterrupt),
             "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
+            "RiscvInterrupt(machine)" => {
+                Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine })
+            }
+            "RiscvInterrupt(supervisor)" => {
+                Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor })
+            }
             _ => Err(format!("'{s}' is not a valid value for entry function call convention.")),
         }
     }
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index 084c917cc31..dd435dbb0a3 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -39,7 +39,7 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
 
 /// Trait that needs to be implemented by the higher-level type representation
 /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality.
-pub trait TyAbiInterface<'a, C>: Sized {
+pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug {
     fn ty_and_layout_for_variant(
         this: TyAndLayout<'a, Self>,
         cx: &C,
@@ -135,6 +135,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
         for index in indices {
             offset += layout.fields.offset(index);
             layout = layout.field(cx, index);
+            assert!(
+                layout.is_sized(),
+                "offset of unsized field (type {:?}) cannot be computed statically",
+                layout.ty
+            );
         }
 
         offset
diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs
index 75bb76a9de0..af455b6432f 100644
--- a/compiler/rustc_target/src/json.rs
+++ b/compiler/rustc_target/src/json.rs
@@ -92,6 +92,7 @@ impl<A: ToJson> ToJson for Option<A> {
 
 impl ToJson for crate::abi::call::Conv {
     fn to_json(&self) -> Json {
+        let buf: String;
         let s = match self {
             Self::C => "C",
             Self::Rust => "Rust",
@@ -110,6 +111,10 @@ impl ToJson for crate::abi::call::Conv {
             Self::AmdGpuKernel => "AmdGpuKernel",
             Self::AvrInterrupt => "AvrInterrupt",
             Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
+            Self::RiscvInterrupt { kind } => {
+                buf = format!("RiscvInterrupt({})", kind.as_str());
+                &buf
+            }
         };
         Json::String(s.to_owned())
     }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs
new file mode 100644
index 00000000000..64a7dc681c8
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs
@@ -0,0 +1,16 @@
+use crate::spec::Target;
+
+pub fn target() -> Target {
+    let mut base = super::teeos_base::opts();
+    base.features = "+strict-align,+neon,+fp-armv8".into();
+    base.max_atomic_width = Some(128);
+    base.linker = Some("aarch64-linux-gnu-ld".into());
+
+    Target {
+        llvm_target: "aarch64-unknown-none".into(),
+        pointer_width: 64,
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: base,
+    }
+}
diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index dc233121f66..550cdf6bda6 100644
--- a/compiler/rustc_target/src/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
@@ -38,6 +38,8 @@ pub enum Abi {
     PlatformIntrinsic,
     Unadjusted,
     RustCold,
+    RiscvInterruptM,
+    RiscvInterruptS,
 }
 
 impl Abi {
@@ -107,11 +109,29 @@ const AbiDatas: &[AbiData] = &[
     AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" },
     AbiData { abi: Abi::Unadjusted, name: "unadjusted" },
     AbiData { abi: Abi::RustCold, name: "rust-cold" },
+    AbiData { abi: Abi::RiscvInterruptM, name: "riscv-interrupt-m" },
+    AbiData { abi: Abi::RiscvInterruptS, name: "riscv-interrupt-s" },
 ];
 
+#[derive(Copy, Clone, Debug)]
+pub enum AbiUnsupported {
+    Unrecognized,
+    Reason { explain: &'static str },
+}
+
 /// Returns the ABI with the given name (if any).
-pub fn lookup(name: &str) -> Option<Abi> {
-    AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
+pub fn lookup(name: &str) -> Result<Abi, AbiUnsupported> {
+    AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi).ok_or_else(|| match name {
+        "riscv-interrupt" => AbiUnsupported::Reason {
+            explain: "please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively",
+        },
+        "riscv-interrupt-u" => AbiUnsupported::Reason {
+            explain: "user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314",
+        },
+
+        _ => AbiUnsupported::Unrecognized,
+
+    })
 }
 
 pub fn all_names() -> Vec<&'static str> {
@@ -200,6 +220,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
             feature: sym::abi_avr_interrupt,
             explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
         }),
+        "riscv-interrupt-m" | "riscv-interrupt-s" => Err(AbiDisabled::Unstable {
+            feature: sym::abi_riscv_interrupt,
+            explain: "riscv-interrupt ABIs are experimental and subject to change",
+        }),
         "C-cmse-nonsecure-call" => Err(AbiDisabled::Unstable {
             feature: sym::abi_c_cmse_nonsecure_call,
             explain: "C-cmse-nonsecure-call ABI is experimental and subject to change",
@@ -260,6 +284,8 @@ impl Abi {
             PlatformIntrinsic => 32,
             Unadjusted => 33,
             RustCold => 34,
+            RiscvInterruptM => 35,
+            RiscvInterruptS => 36,
         };
         debug_assert!(
             AbiDatas
diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_target/src/spec/abi/tests.rs
index 8bea5e5efe3..251a12fe7aa 100644
--- a/compiler/rustc_target/src/spec/abi/tests.rs
+++ b/compiler/rustc_target/src/spec/abi/tests.rs
@@ -4,19 +4,19 @@ use super::*;
 #[test]
 fn lookup_Rust() {
     let abi = lookup("Rust");
-    assert!(abi.is_some() && abi.unwrap().data().name == "Rust");
+    assert!(abi.is_ok() && abi.unwrap().data().name == "Rust");
 }
 
 #[test]
 fn lookup_cdecl() {
     let abi = lookup("cdecl");
-    assert!(abi.is_some() && abi.unwrap().data().name == "cdecl");
+    assert!(abi.is_ok() && abi.unwrap().data().name == "cdecl");
 }
 
 #[test]
 fn lookup_baz() {
     let abi = lookup("baz");
-    assert!(abi.is_none());
+    assert!(matches!(abi, Err(AbiUnsupported::Unrecognized)))
 }
 
 #[test]
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index c215a7c4b6e..1871239d7de 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -83,6 +83,7 @@ mod openbsd_base;
 mod redox_base;
 mod solaris_base;
 mod solid_base;
+mod teeos_base;
 mod thumb_base;
 mod uefi_msvc_base;
 mod unikraft_linux_musl_base;
@@ -1494,6 +1495,8 @@ supported_targets! {
 
     ("x86_64-unknown-none", x86_64_unknown_none),
 
+    ("aarch64-unknown-teeos", aarch64_unknown_teeos),
+
     ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl),
 
     ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710),
@@ -2267,6 +2270,7 @@ impl Target {
             PtxKernel => self.arch == "nvptx64",
             Msp430Interrupt => self.arch == "msp430",
             AmdGpuKernel => self.arch == "amdgcn",
+            RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]),
             AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
             Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]),
             Thiscall { .. } => self.arch == "x86",
@@ -2698,7 +2702,7 @@ impl Target {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
                     match lookup_abi(s) {
-                        Some(abi) => base.$key_name = Some(abi),
+                        Ok(abi) => base.$key_name = Some(abi),
                         _ => return Some(Err(format!("'{}' is not a valid value for abi", s))),
                     }
                     Some(Ok(()))
diff --git a/compiler/rustc_target/src/spec/teeos_base.rs b/compiler/rustc_target/src/spec/teeos_base.rs
new file mode 100644
index 00000000000..1bc71bab016
--- /dev/null
+++ b/compiler/rustc_target/src/spec/teeos_base.rs
@@ -0,0 +1,29 @@
+use super::{Cc, LinkerFlavor, Lld, PanicStrategy};
+use crate::spec::{RelroLevel, TargetOptions};
+
+pub fn opts() -> TargetOptions {
+    let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"];
+    let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"];
+
+    let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args);
+    super::add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args);
+
+    TargetOptions {
+        os: "teeos".into(),
+        vendor: "unknown".into(),
+        dynamic_linking: true,
+        linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+        // rpath hardcodes -Wl, so it can't be used together with ld.lld.
+        // C TAs also don't support rpath, so this is fine.
+        has_rpath: false,
+        // Note: Setting has_thread_local to true causes an error when
+        // loading / dyn-linking the TA
+        has_thread_local: false,
+        position_independent_executables: true,
+        relro_level: RelroLevel::Full,
+        crt_static_respected: true,
+        pre_link_args,
+        panic_strategy: PanicStrategy::Abort,
+        ..Default::default()
+    }
+}
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index f57f1bad15d..f4c9dfa3488 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -8,6 +8,15 @@ trait_selection_adjust_signature_remove_borrow = consider adjusting the signatur
         *[other] arguments
     }
 
+trait_selection_closure_fn_mut_label = closure is `FnMut` because it mutates the variable `{$place}` here
+
+trait_selection_closure_fn_once_label = closure is `FnOnce` because it moves the variable `{$place}` out of its environment
+
+trait_selection_closure_kind_mismatch = expected a closure that implements the `{$expected}` trait, but this closure only implements `{$found}`
+    .label = this closure implements `{$found}`, not `{$expected}`
+
+trait_selection_closure_kind_requirement = the requirement to implement `{$expected}` derives from here
+
 trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
 
 trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index dde9e9c9ac6..c1fb287d63e 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -4,7 +4,7 @@ use rustc_errors::{
     SubdiagnosticMessage,
 };
 use rustc_macros::Diagnostic;
-use rustc_middle::ty::{self, PolyTraitRef, Ty};
+use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
 use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
@@ -131,3 +131,37 @@ impl AddToDiagnostic for AdjustSignatureBorrow {
         }
     }
 }
+
+#[derive(Diagnostic)]
+#[diag(trait_selection_closure_kind_mismatch, code = "E0525")]
+pub struct ClosureKindMismatch {
+    #[primary_span]
+    #[label]
+    pub closure_span: Span,
+    pub expected: ClosureKind,
+    pub found: ClosureKind,
+    #[label(trait_selection_closure_kind_requirement)]
+    pub cause_span: Span,
+
+    #[subdiagnostic]
+    pub fn_once_label: Option<ClosureFnOnceLabel>,
+
+    #[subdiagnostic]
+    pub fn_mut_label: Option<ClosureFnMutLabel>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(trait_selection_closure_fn_once_label)]
+pub struct ClosureFnOnceLabel {
+    #[primary_span]
+    pub span: Span,
+    pub place: String,
+}
+
+#[derive(Subdiagnostic)]
+#[label(trait_selection_closure_fn_mut_label)]
+pub struct ClosureFnMutLabel {
+    #[primary_span]
+    pub span: Span,
+    pub place: String,
+}
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 4d85e2b6089..457d5420ca3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -7,6 +7,7 @@ use super::{
     ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
     PredicateObligation, SelectionError, TraitNotObjectSafe,
 };
+use crate::errors::{ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch};
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt};
@@ -3110,27 +3111,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> UnsatisfiedConst {
         let unsatisfied_const = UnsatisfiedConst(false);
         // FIXME(effects)
-        /* if trait_predicate.is_const_if_const() {
-            let non_const_predicate = trait_ref.without_const();
-            let non_const_obligation = Obligation {
-                cause: obligation.cause.clone(),
-                param_env: obligation.param_env,
-                predicate: non_const_predicate.to_predicate(self.tcx),
-                recursion_depth: obligation.recursion_depth,
-            };
-            if self.predicate_may_hold(&non_const_obligation) {
-                unsatisfied_const = UnsatisfiedConst(true);
-                err.span_note(
-                    span,
-                    format!(
-                        "the trait `{}` is implemented for `{}`, \
-                        but that implementation is not `const`",
-                        non_const_predicate.print_modifiers_and_trait_path(),
-                        trait_ref.skip_binder().self_ty(),
-                    ),
-                );
-            }
-        } */
         unsatisfied_const
     }
 
@@ -3142,24 +3122,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         kind: ty::ClosureKind,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let closure_span = self.tcx.def_span(closure_def_id);
-        let mut err = struct_span_err!(
-            self.tcx.sess,
-            closure_span,
-            E0525,
-            "expected a closure that implements the `{}` trait, \
-                but this closure only implements `{}`",
-            kind,
-            found_kind
-        );
 
-        err.span_label(
+        let mut err = ClosureKindMismatch {
             closure_span,
-            format!("this closure implements `{found_kind}`, not `{kind}`"),
-        );
-        err.span_label(
-            obligation.cause.span,
-            format!("the requirement to implement `{kind}` derives from here"),
-        );
+            expected: kind,
+            found: found_kind,
+            cause_span: obligation.cause.span,
+            fn_once_label: None,
+            fn_mut_label: None,
+        };
 
         // Additional context information explaining why the closure only implements
         // a particular trait.
@@ -3167,30 +3138,22 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             let hir_id = self.tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local());
             match (found_kind, typeck_results.closure_kind_origins().get(hir_id)) {
                 (ty::ClosureKind::FnOnce, Some((span, place))) => {
-                    err.span_label(
-                        *span,
-                        format!(
-                            "closure is `FnOnce` because it moves the \
-                            variable `{}` out of its environment",
-                            ty::place_to_string_for_capture(self.tcx, place)
-                        ),
-                    );
+                    err.fn_once_label = Some(ClosureFnOnceLabel {
+                        span: *span,
+                        place: ty::place_to_string_for_capture(self.tcx, &place),
+                    })
                 }
                 (ty::ClosureKind::FnMut, Some((span, place))) => {
-                    err.span_label(
-                        *span,
-                        format!(
-                            "closure is `FnMut` because it mutates the \
-                            variable `{}` here",
-                            ty::place_to_string_for_capture(self.tcx, place)
-                        ),
-                    );
+                    err.fn_mut_label = Some(ClosureFnMutLabel {
+                        span: *span,
+                        place: ty::place_to_string_for_capture(self.tcx, &place),
+                    })
                 }
                 _ => {}
             }
         }
 
-        err
+        self.tcx.sess.create_err(err)
     }
 
     fn report_type_parameter_mismatch_cyclic_type_error(
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 2b8571796df..d071cf76fd3 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2743,6 +2743,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             ObligationCauseCode::BindingObligation(item_def_id, span)
             | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => {
+                if self.tcx.is_diagnostic_item(sym::Send, item_def_id)
+                    || self.tcx.lang_items().sync_trait() == Some(item_def_id)
+                {
+                    return;
+                }
+
                 let item_name = tcx.def_path_str(item_def_id);
                 let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
                 let mut multispan = MultiSpan::from(span);
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index d0a7414b4ff..4d0b847533b 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -9,6 +9,7 @@ use rustc_session::config::OptLevel;
 use rustc_span::def_id::DefId;
 use rustc_target::abi::call::{
     ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind,
+    RiscvInterruptKind,
 };
 use rustc_target::abi::*;
 use rustc_target::spec::abi::Abi as SpecAbi;
@@ -193,6 +194,8 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
         AmdGpuKernel => Conv::AmdGpuKernel,
         AvrInterrupt => Conv::AvrInterrupt,
         AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
+        RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine },
+        RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor },
         Wasm => Conv::C,
 
         // These API constants ought to be more specific...
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index aa49a5561d1..436f10a4f7b 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -2,7 +2,6 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
-use rustc_middle::middle::resolve_bound_vars as rbv;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
@@ -52,9 +51,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
             tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap())))
         }
         DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => match data {
-            ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => {
-                let hir::OpaqueTy { lifetime_mapping, .. } =
-                    *tcx.hir().expect_item(opaque_def_id.expect_local()).expect_opaque_ty();
+            ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => {
                 // We need to remap all of the late-bound lifetimes in theassumed wf types
                 // of the fn (which are represented as ReFree) to the early-bound lifetimes
                 // of the RPITIT (which are represented by ReEarlyBound owned by the opaque).
@@ -66,28 +63,22 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
                 // predicates we insert in the `explicit_predicates_of` query for RPITITs.
                 let mut mapping = FxHashMap::default();
                 let generics = tcx.generics_of(def_id);
-                for &(lifetime, new_early_bound_def_id) in
-                    lifetime_mapping.expect("expected lifetime mapping for RPITIT")
-                {
-                    if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) =
-                        tcx.named_bound_var(lifetime.hir_id)
-                    {
-                        let name = tcx.hir().name(lifetime.hir_id);
-                        let index = generics
-                            .param_def_id_to_index(tcx, new_early_bound_def_id.to_def_id())
-                            .unwrap();
+
+                // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case,
+                // since it has been liberated), map it back to the early-bound lifetime of
+                // the GAT. Since RPITITs also have all of the fn's generics, we slice only
+                // the end of the list corresponding to the opaque's generics.
+                for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
+                    let orig_lt = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+                    if matches!(*orig_lt, ty::ReFree(..)) {
                         mapping.insert(
-                            ty::Region::new_free(
-                                tcx,
-                                fn_def_id,
-                                ty::BoundRegionKind::BrNamed(def_id, name),
-                            ),
+                            orig_lt,
                             ty::Region::new_early_bound(
                                 tcx,
                                 ty::EarlyBoundRegion {
-                                    def_id: new_early_bound_def_id.to_def_id(),
-                                    index,
-                                    name,
+                                    def_id: param.def_id,
+                                    index: param.index,
+                                    name: param.name,
                                 },
                             ),
                         );
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index a21b5ef05e6..e1a15b5cf9f 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -1,4 +1,5 @@
 use rustc_errors::ErrorGuaranteed;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::query::Providers;
@@ -15,54 +16,48 @@ fn resolve_instance<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>,
 ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
-    let (param_env, (def, args)) = key.into_parts();
+    let (param_env, (def_id, args)) = key.into_parts();
 
-    let result = if let Some(trait_def_id) = tcx.trait_of_item(def) {
+    let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
         debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
         resolve_associated_item(
             tcx,
-            def,
+            def_id,
             param_env,
             trait_def_id,
             tcx.normalize_erasing_regions(param_env, args),
         )
     } else {
-        let ty = tcx.type_of(def);
-        let item_type = tcx.subst_and_normalize_erasing_regions(args, param_env, ty);
+        let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) {
+            debug!(" => intrinsic");
+            ty::InstanceDef::Intrinsic(def_id)
+        } else if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
+            let ty = args.type_at(0);
 
-        let def = match *item_type.kind() {
-            ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
-                debug!(" => intrinsic");
-                ty::InstanceDef::Intrinsic(def)
-            }
-            ty::FnDef(def_id, args) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => {
-                let ty = args.type_at(0);
-
-                if ty.needs_drop(tcx, param_env) {
-                    debug!(" => nontrivial drop glue");
-                    match *ty.kind() {
-                        ty::Closure(..)
-                        | ty::Generator(..)
-                        | ty::Tuple(..)
-                        | ty::Adt(..)
-                        | ty::Dynamic(..)
-                        | ty::Array(..)
-                        | ty::Slice(..) => {}
-                        // Drop shims can only be built from ADTs.
-                        _ => return Ok(None),
-                    }
-
-                    ty::InstanceDef::DropGlue(def_id, Some(ty))
-                } else {
-                    debug!(" => trivial drop glue");
-                    ty::InstanceDef::DropGlue(def_id, None)
+            if ty.needs_drop(tcx, param_env) {
+                debug!(" => nontrivial drop glue");
+                match *ty.kind() {
+                    ty::Closure(..)
+                    | ty::Generator(..)
+                    | ty::Tuple(..)
+                    | ty::Adt(..)
+                    | ty::Dynamic(..)
+                    | ty::Array(..)
+                    | ty::Slice(..) => {}
+                    // Drop shims can only be built from ADTs.
+                    _ => return Ok(None),
                 }
+
+                ty::InstanceDef::DropGlue(def_id, Some(ty))
+            } else {
+                debug!(" => trivial drop glue");
+                ty::InstanceDef::DropGlue(def_id, None)
             }
-            _ => {
-                debug!(" => free item");
-                ty::InstanceDef::Item(def)
-            }
+        } else {
+            debug!(" => free item");
+            ty::InstanceDef::Item(def_id)
         };
+
         Ok(Some(Instance { def, args }))
     };
     debug!("inner_resolve_instance: result={:?}", result);
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index f093a0990d1..5378b210e67 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -518,14 +518,14 @@ impl AsciiChar {
     /// Gets this ASCII character as a byte.
     #[unstable(feature = "ascii_char", issue = "110998")]
     #[inline]
-    pub const fn as_u8(self) -> u8 {
+    pub const fn to_u8(self) -> u8 {
         self as u8
     }
 
     /// Gets this ASCII character as a `char` Unicode Scalar Value.
     #[unstable(feature = "ascii_char", issue = "110998")]
     #[inline]
-    pub const fn as_char(self) -> char {
+    pub const fn to_char(self) -> char {
         self as u8 as char
     }
 
diff --git a/library/core/src/escape.rs b/library/core/src/escape.rs
index 3d471419bb8..24bb9ad1ad1 100644
--- a/library/core/src/escape.rs
+++ b/library/core/src/escape.rs
@@ -95,11 +95,11 @@ impl<const N: usize> EscapeIterInner<N> {
     }
 
     pub fn next(&mut self) -> Option<u8> {
-        self.alive.next().map(|i| self.data[usize::from(i)].as_u8())
+        self.alive.next().map(|i| self.data[usize::from(i)].to_u8())
     }
 
     pub fn next_back(&mut self) -> Option<u8> {
-        self.alive.next_back().map(|i| self.data[usize::from(i)].as_u8())
+        self.alive.next_back().map(|i| self.data[usize::from(i)].to_u8())
     }
 
     pub fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5ec751e5168..aec287226a0 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -76,8 +76,11 @@ macro marker_impls {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "Send")]
 #[rustc_on_unimplemented(
+    on(_Self = "std::rc::Rc<T, A>", note = "use `std::sync::Arc` instead of `std::rc::Rc`"),
     message = "`{Self}` cannot be sent between threads safely",
-    label = "`{Self}` cannot be sent between threads safely"
+    label = "`{Self}` cannot be sent between threads safely",
+    note = "consider using `std::sync::Arc<{Self}>`; for more information visit \
+            <https://doc.rust-lang.org/book/ch16-03-shared-state.html>"
 )]
 pub unsafe auto trait Send {
     // empty.
@@ -628,8 +631,11 @@ impl<T: ?Sized> Copy for &T {}
         any(_Self = "core::cell::RefCell<T>", _Self = "std::cell::RefCell<T>"),
         note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead",
     ),
+    on(_Self = "std::rc::Rc<T, A>", note = "use `std::sync::Arc` instead of `std::rc::Rc`"),
     message = "`{Self}` cannot be shared between threads safely",
-    label = "`{Self}` cannot be shared between threads safely"
+    label = "`{Self}` cannot be shared between threads safely",
+    note = "consider using `std::sync::Arc<{Self}>`; for more information visit \
+            <https://doc.rust-lang.org/book/ch16-03-shared-state.html>"
 )]
 pub unsafe auto trait Sync {
     // FIXME(estebank): once support to add notes in `rustc_on_unimplemented`
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index ddcd35b1ac7..b871be733b8 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
 libc = { version = "0.2.146", default-features = false, features = ['rustc-dep-of-std'], public = true }
-compiler_builtins = { version = "0.1.98" }
+compiler_builtins = { version = "0.1.100" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] }
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index bc532990e94..a53b8535213 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -957,4 +957,46 @@ impl f32 {
     pub fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
+
+    /// Gamma function.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_gamma)]
+    /// let x = 5.0f32;
+    ///
+    /// let abs_difference = (x.gamma() - 24.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[rustc_allow_incoherent_impl]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_gamma", issue = "99842")]
+    #[inline]
+    pub fn gamma(self) -> f32 {
+        unsafe { cmath::tgammaf(self) }
+    }
+
+    /// Returns the natural logarithm of the gamma function.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_gamma)]
+    /// let x = 2.0f32;
+    ///
+    /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[rustc_allow_incoherent_impl]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_gamma", issue = "99842")]
+    #[inline]
+    pub fn ln_gamma(self) -> (f32, i32) {
+        let mut signgamp: i32 = 0;
+        let x = unsafe { cmath::lgammaf_r(self, &mut signgamp) };
+        (x, signgamp)
+    }
 }
diff --git a/library/std/src/f32/tests.rs b/library/std/src/f32/tests.rs
index e949def00bb..9ca4e8f2f45 100644
--- a/library/std/src/f32/tests.rs
+++ b/library/std/src/f32/tests.rs
@@ -653,6 +653,38 @@ fn test_atanh() {
 }
 
 #[test]
+fn test_gamma() {
+    // precision can differ between platforms
+    assert_approx_eq!(1.0f32.gamma(), 1.0f32);
+    assert_approx_eq!(2.0f32.gamma(), 1.0f32);
+    assert_approx_eq!(3.0f32.gamma(), 2.0f32);
+    assert_approx_eq!(4.0f32.gamma(), 6.0f32);
+    assert_approx_eq!(5.0f32.gamma(), 24.0f32);
+    assert_approx_eq!(0.5f32.gamma(), consts::PI.sqrt());
+    assert_approx_eq!((-0.5f32).gamma(), -2.0 * consts::PI.sqrt());
+    assert_eq!(0.0f32.gamma(), f32::INFINITY);
+    assert_eq!((-0.0f32).gamma(), f32::NEG_INFINITY);
+    assert!((-1.0f32).gamma().is_nan());
+    assert!((-2.0f32).gamma().is_nan());
+    assert!(f32::NAN.gamma().is_nan());
+    assert!(f32::NEG_INFINITY.gamma().is_nan());
+    assert_eq!(f32::INFINITY.gamma(), f32::INFINITY);
+    assert_eq!(171.71f32.gamma(), f32::INFINITY);
+}
+
+#[test]
+fn test_ln_gamma() {
+    assert_approx_eq!(1.0f32.ln_gamma().0, 0.0f32);
+    assert_eq!(1.0f32.ln_gamma().1, 1);
+    assert_approx_eq!(2.0f32.ln_gamma().0, 0.0f32);
+    assert_eq!(2.0f32.ln_gamma().1, 1);
+    assert_approx_eq!(3.0f32.ln_gamma().0, 2.0f32.ln());
+    assert_eq!(3.0f32.ln_gamma().1, 1);
+    assert_approx_eq!((-0.5f32).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
+    assert_eq!((-0.5f32).ln_gamma().1, -1);
+}
+
+#[test]
 fn test_real_consts() {
     use super::consts;
 
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 5af9f8bcb23..a1cec22c97a 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -957,4 +957,46 @@ impl f64 {
     pub fn atanh(self) -> f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
+
+    /// Gamma function.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_gamma)]
+    /// let x = 5.0f64;
+    ///
+    /// let abs_difference = (x.gamma() - 24.0).abs();
+    ///
+    /// assert!(abs_difference <= f64::EPSILON);
+    /// ```
+    #[rustc_allow_incoherent_impl]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_gamma", issue = "99842")]
+    #[inline]
+    pub fn gamma(self) -> f64 {
+        unsafe { cmath::tgamma(self) }
+    }
+
+    /// Returns the natural logarithm of the gamma function.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_gamma)]
+    /// let x = 2.0f64;
+    ///
+    /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
+    ///
+    /// assert!(abs_difference <= f64::EPSILON);
+    /// ```
+    #[rustc_allow_incoherent_impl]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[unstable(feature = "float_gamma", issue = "99842")]
+    #[inline]
+    pub fn ln_gamma(self) -> (f64, i32) {
+        let mut signgamp: i32 = 0;
+        let x = unsafe { cmath::lgamma_r(self, &mut signgamp) };
+        (x, signgamp)
+    }
 }
diff --git a/library/std/src/f64/tests.rs b/library/std/src/f64/tests.rs
index 53d351cceef..f88d01593b5 100644
--- a/library/std/src/f64/tests.rs
+++ b/library/std/src/f64/tests.rs
@@ -636,6 +636,38 @@ fn test_atanh() {
 }
 
 #[test]
+fn test_gamma() {
+    // precision can differ between platforms
+    assert_approx_eq!(1.0f64.gamma(), 1.0f64);
+    assert_approx_eq!(2.0f64.gamma(), 1.0f64);
+    assert_approx_eq!(3.0f64.gamma(), 2.0f64);
+    assert_approx_eq!(4.0f64.gamma(), 6.0f64);
+    assert_approx_eq!(5.0f64.gamma(), 24.0f64);
+    assert_approx_eq!(0.5f64.gamma(), consts::PI.sqrt());
+    assert_approx_eq!((-0.5f64).gamma(), -2.0 * consts::PI.sqrt());
+    assert_eq!(0.0f64.gamma(), f64::INFINITY);
+    assert_eq!((-0.0f64).gamma(), f64::NEG_INFINITY);
+    assert!((-1.0f64).gamma().is_nan());
+    assert!((-2.0f64).gamma().is_nan());
+    assert!(f64::NAN.gamma().is_nan());
+    assert!(f64::NEG_INFINITY.gamma().is_nan());
+    assert_eq!(f64::INFINITY.gamma(), f64::INFINITY);
+    assert_eq!(171.71f64.gamma(), f64::INFINITY);
+}
+
+#[test]
+fn test_ln_gamma() {
+    assert_approx_eq!(1.0f64.ln_gamma().0, 0.0f64);
+    assert_eq!(1.0f64.ln_gamma().1, 1);
+    assert_approx_eq!(2.0f64.ln_gamma().0, 0.0f64);
+    assert_eq!(2.0f64.ln_gamma().1, 1);
+    assert_approx_eq!(3.0f64.ln_gamma().0, 2.0f64.ln());
+    assert_eq!(3.0f64.ln_gamma().1, 1);
+    assert_approx_eq!((-0.5f64).ln_gamma().0, (2.0 * consts::PI.sqrt()).ln());
+    assert_eq!((-0.5f64).ln_gamma().1, -1);
+}
+
+#[test]
 fn test_real_consts() {
     use super::consts;
     let pi: f64 = consts::PI;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 31481de8495..f08ffa75700 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -288,6 +288,7 @@
 #![feature(exact_size_is_empty)]
 #![feature(exclusive_wrapper)]
 #![feature(extend_one)]
+#![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(float_next_up_down)]
 #![feature(hasher_prefixfree_extras)]
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index f9cb755b01a..f1305dee146 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1528,7 +1528,7 @@ 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)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(imp::ExitStatus);
 
diff --git a/library/std/src/sys/unix/cmath.rs b/library/std/src/sys/unix/cmath.rs
index 2bf80d7a4cb..5346d229116 100644
--- a/library/std/src/sys/unix/cmath.rs
+++ b/library/std/src/sys/unix/cmath.rs
@@ -30,4 +30,8 @@ extern "C" {
     pub fn tanf(n: f32) -> f32;
     pub fn tanh(n: f64) -> f64;
     pub fn tanhf(n: f32) -> f32;
+    pub fn tgamma(n: f64) -> f64;
+    pub fn tgammaf(n: f32) -> f32;
+    pub fn lgamma_r(n: f64, s: &mut i32) -> f64;
+    pub fn lgammaf_r(n: f32, s: &mut i32) -> f32;
 }
diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs
index e45c380a0bb..9931c2af2f1 100644
--- a/library/std/src/sys/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/unix/process/process_fuchsia.rs
@@ -235,7 +235,7 @@ impl Process {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(i64);
 
 impl ExitStatus {
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 0ce93af66ac..3963e7f52d5 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -10,9 +10,6 @@ use core::ffi::NonZero_c_int;
 #[cfg(target_os = "linux")]
 use crate::os::linux::process::PidFd;
 
-#[cfg(target_os = "linux")]
-use crate::sys::weak::raw_syscall;
-
 #[cfg(any(
     target_os = "macos",
     target_os = "watchos",
@@ -91,6 +88,11 @@ impl Command {
         if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? {
             return Ok((ret, ours));
         }
+
+        #[cfg(target_os = "linux")]
+        let (input, output) = sys::net::Socket::new_pair(libc::AF_UNIX, libc::SOCK_SEQPACKET)?;
+
+        #[cfg(not(target_os = "linux"))]
         let (input, output) = sys::pipe::anon_pipe()?;
 
         // Whatever happens after the fork is almost for sure going to touch or
@@ -104,12 +106,16 @@ impl Command {
         // The child calls `mem::forget` to leak the lock, which is crucial because
         // releasing a lock is not async-signal-safe.
         let env_lock = sys::os::env_read_lock();
-        let (pid, pidfd) = unsafe { self.do_fork()? };
+        let pid = unsafe { self.do_fork()? };
 
         if pid == 0 {
             crate::panic::always_abort();
             mem::forget(env_lock); // avoid non-async-signal-safe unlocking
             drop(input);
+            #[cfg(target_os = "linux")]
+            if self.get_create_pidfd() {
+                self.send_pidfd(&output);
+            }
             let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
             let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
             let errno = errno.to_be_bytes();
@@ -133,6 +139,12 @@ impl Command {
         drop(env_lock);
         drop(output);
 
+        #[cfg(target_os = "linux")]
+        let pidfd = if self.get_create_pidfd() { self.recv_pidfd(&input) } else { -1 };
+
+        #[cfg(not(target_os = "linux"))]
+        let pidfd = -1;
+
         // Safety: We obtained the pidfd from calling `clone3` with
         // `CLONE_PIDFD` so it's valid an otherwise unowned.
         let mut p = unsafe { Process::new(pid, pidfd) };
@@ -160,6 +172,7 @@ impl Command {
                 }
                 Ok(..) => {
                     // pipe I/O up to PIPE_BUF bytes should be atomic
+                    // similarly SOCK_SEQPACKET messages should arrive whole
                     assert!(p.wait().is_ok(), "wait() should either return Ok or panic");
                     panic!("short read on the CLOEXEC pipe")
                 }
@@ -185,20 +198,19 @@ impl Command {
     );
 
     #[cfg(any(target_os = "tvos", target_os = "watchos"))]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
+    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
         return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC);
     }
 
     // Attempts to fork the process. If successful, returns Ok((0, -1))
     // in the child, and Ok((child_pid, -1)) in the parent.
     #[cfg(not(any(
-        target_os = "linux",
         target_os = "watchos",
         target_os = "tvos",
         all(target_os = "nto", target_env = "nto71"),
     )))]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
-        cvt(libc::fork()).map(|res| (res, -1))
+    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
+        cvt(libc::fork())
     }
 
     // On QNX Neutrino, fork can fail with EBADF in case "another thread might have opened
@@ -206,7 +218,7 @@ impl Command {
     // Documentation says "... or try calling fork() again". This is what we do here.
     // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
     #[cfg(all(target_os = "nto", target_env = "nto71"))]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
+    unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
         use crate::sys::os::errno;
 
         let mut delay = MIN_FORKSPAWN_SLEEP;
@@ -229,91 +241,11 @@ impl Command {
                 delay *= 2;
                 continue;
             } else {
-                return cvt(r).map(|res| (res, -1));
+                return cvt(r);
             }
         }
     }
 
-    // Attempts to fork the process. If successful, returns Ok((0, -1))
-    // in the child, and Ok((child_pid, child_pidfd)) in the parent.
-    #[cfg(target_os = "linux")]
-    unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> {
-        use crate::sync::atomic::{AtomicBool, Ordering};
-
-        static HAS_CLONE3: AtomicBool = AtomicBool::new(true);
-        const CLONE_PIDFD: u64 = 0x00001000;
-
-        #[repr(C)]
-        struct clone_args {
-            flags: u64,
-            pidfd: u64,
-            child_tid: u64,
-            parent_tid: u64,
-            exit_signal: u64,
-            stack: u64,
-            stack_size: u64,
-            tls: u64,
-            set_tid: u64,
-            set_tid_size: u64,
-            cgroup: u64,
-        }
-
-        raw_syscall! {
-            fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
-        }
-
-        // Bypassing libc for `clone3` can make further libc calls unsafe,
-        // so we use it sparingly for now. See #89522 for details.
-        // Some tools (e.g. sandboxing tools) may also expect `fork`
-        // rather than `clone3`.
-        let want_clone3_pidfd = self.get_create_pidfd();
-
-        // If we fail to create a pidfd for any reason, this will
-        // stay as -1, which indicates an error.
-        let mut pidfd: pid_t = -1;
-
-        // Attempt to use the `clone3` syscall, which supports more arguments
-        // (in particular, the ability to create a pidfd). If this fails,
-        // we will fall through this block to a call to `fork()`
-        if want_clone3_pidfd && HAS_CLONE3.load(Ordering::Relaxed) {
-            let mut args = clone_args {
-                flags: CLONE_PIDFD,
-                pidfd: &mut pidfd as *mut pid_t as u64,
-                child_tid: 0,
-                parent_tid: 0,
-                exit_signal: libc::SIGCHLD as u64,
-                stack: 0,
-                stack_size: 0,
-                tls: 0,
-                set_tid: 0,
-                set_tid_size: 0,
-                cgroup: 0,
-            };
-
-            let args_ptr = &mut args as *mut clone_args;
-            let args_size = crate::mem::size_of::<clone_args>();
-
-            let res = cvt(clone3(args_ptr, args_size));
-            match res {
-                Ok(n) => return Ok((n as pid_t, pidfd)),
-                Err(e) => match e.raw_os_error() {
-                    // Multiple threads can race to execute this store,
-                    // but that's fine - that just means that multiple threads
-                    // will have tried and failed to execute the same syscall,
-                    // with no other side effects.
-                    Some(libc::ENOSYS) => HAS_CLONE3.store(false, Ordering::Relaxed),
-                    // Fallback to fork if `EPERM` is returned. (e.g. blocked by seccomp)
-                    Some(libc::EPERM) => {}
-                    _ => return Err(e),
-                },
-            }
-        }
-
-        // Generally, we just call `fork`. If we get here after wanting `clone3`,
-        // then the syscall does not exist or we do not have permission to call it.
-        cvt(libc::fork()).map(|res| (res, pidfd))
-    }
-
     pub fn exec(&mut self, default: Stdio) -> io::Error {
         let envp = self.capture_env();
 
@@ -722,6 +654,115 @@ impl Command {
             Ok(Some(p))
         }
     }
+
+    #[cfg(target_os = "linux")]
+    fn send_pidfd(&self, sock: &crate::sys::net::Socket) {
+        use crate::io::IoSlice;
+        use crate::os::fd::RawFd;
+        use crate::sys::cvt_r;
+        use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET};
+
+        unsafe {
+            let child_pid = libc::getpid();
+            // pidfd_open sets CLOEXEC by default
+            let pidfd = libc::syscall(libc::SYS_pidfd_open, child_pid, 0);
+
+            let fds: [c_int; 1] = [pidfd as RawFd];
+
+            const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>();
+
+            #[repr(C)]
+            union Cmsg {
+                buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }],
+                _align: libc::cmsghdr,
+            }
+
+            let mut cmsg: Cmsg = mem::zeroed();
+
+            // 0-length message to send through the socket so we can pass along the fd
+            let mut iov = [IoSlice::new(b"")];
+            let mut msg: libc::msghdr = mem::zeroed();
+
+            msg.msg_iov = &mut iov as *mut _ as *mut _;
+            msg.msg_iovlen = 1;
+            msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _;
+            msg.msg_control = &mut cmsg.buf as *mut _ as *mut _;
+
+            // only attach cmsg if we successfully acquired the pidfd
+            if pidfd >= 0 {
+                let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _);
+                (*hdr).cmsg_level = SOL_SOCKET;
+                (*hdr).cmsg_type = SCM_RIGHTS;
+                (*hdr).cmsg_len = CMSG_LEN(SCM_MSG_LEN as _) as _;
+                let data = CMSG_DATA(hdr);
+                crate::ptr::copy_nonoverlapping(
+                    fds.as_ptr().cast::<u8>(),
+                    data as *mut _,
+                    SCM_MSG_LEN,
+                );
+            }
+
+            // we send the 0-length message even if we failed to acquire the pidfd
+            // so we get a consistent SEQPACKET order
+            match cvt_r(|| libc::sendmsg(sock.as_raw(), &msg, 0)) {
+                Ok(0) => {}
+                _ => rtabort!("failed to communicate with parent process"),
+            }
+        }
+    }
+
+    #[cfg(target_os = "linux")]
+    fn recv_pidfd(&self, sock: &crate::sys::net::Socket) -> pid_t {
+        use crate::io::IoSliceMut;
+        use crate::sys::cvt_r;
+
+        use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET};
+
+        unsafe {
+            const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>();
+
+            #[repr(C)]
+            union Cmsg {
+                _buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }],
+                _align: libc::cmsghdr,
+            }
+            let mut cmsg: Cmsg = mem::zeroed();
+            // 0-length read to get the fd
+            let mut iov = [IoSliceMut::new(&mut [])];
+
+            let mut msg: libc::msghdr = mem::zeroed();
+
+            msg.msg_iov = &mut iov as *mut _ as *mut _;
+            msg.msg_iovlen = 1;
+            msg.msg_controllen = mem::size_of::<Cmsg>() as _;
+            msg.msg_control = &mut cmsg as *mut _ as *mut _;
+
+            match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, 0)) {
+                Err(_) => return -1,
+                Ok(_) => {}
+            }
+
+            let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _);
+            if hdr.is_null()
+                || (*hdr).cmsg_level != SOL_SOCKET
+                || (*hdr).cmsg_type != SCM_RIGHTS
+                || (*hdr).cmsg_len != CMSG_LEN(SCM_MSG_LEN as _) as _
+            {
+                return -1;
+            }
+            let data = CMSG_DATA(hdr);
+
+            let mut fds = [-1 as c_int];
+
+            crate::ptr::copy_nonoverlapping(
+                data as *const _,
+                fds.as_mut_ptr().cast::<u8>(),
+                SCM_MSG_LEN,
+            );
+
+            fds[0]
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -800,7 +841,7 @@ impl Process {
 //
 // This is not actually an "exit status" in Unix terminology.  Rather, it is a "wait status".
 // See the discussion in comments and doc comments for `std::process::ExitStatus`.
-#[derive(PartialEq, Eq, Clone, Copy)]
+#[derive(PartialEq, Eq, Clone, Copy, Default)]
 pub struct ExitStatus(c_int);
 
 impl fmt::Debug for ExitStatus {
diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs
index e5e1f956bc3..6aa79e7f9e7 100644
--- a/library/std/src/sys/unix/process/process_unix/tests.rs
+++ b/library/std/src/sys/unix/process/process_unix/tests.rs
@@ -60,3 +60,28 @@ fn test_command_fork_no_unwind() {
             || signal == libc::SIGSEGV
     );
 }
+
+#[test]
+#[cfg(target_os = "linux")]
+fn test_command_pidfd() {
+    use crate::os::fd::RawFd;
+    use crate::os::linux::process::{ChildExt, CommandExt};
+    use crate::process::Command;
+
+    let our_pid = crate::process::id();
+    let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) };
+    let pidfd_open_available = if pidfd >= 0 {
+        unsafe { libc::close(pidfd as RawFd) };
+        true
+    } else {
+        false
+    };
+
+    // always exercise creation attempts
+    let child = Command::new("echo").create_pidfd(true).spawn().unwrap();
+
+    // but only check if we know that the kernel supports pidfds
+    if pidfd_open_available {
+        assert!(child.pidfd().is_ok())
+    }
+}
diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs
index f28ca58d020..8e0b971af73 100644
--- a/library/std/src/sys/unix/process/process_unsupported.rs
+++ b/library/std/src/sys/unix/process/process_unsupported.rs
@@ -55,7 +55,7 @@ impl Process {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(c_int);
 
 impl ExitStatus {
diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs
index f70d3cb396b..1ff2b2fb383 100644
--- a/library/std/src/sys/unix/process/process_vxworks.rs
+++ b/library/std/src/sys/unix/process/process_vxworks.rs
@@ -179,7 +179,7 @@ impl Process {
 }
 
 /// Unix exit statuses
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(c_int);
 
 impl ExitStatus {
diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs
index a494f2d6b4c..77b675aaa4e 100644
--- a/library/std/src/sys/unsupported/process.rs
+++ b/library/std/src/sys/unsupported/process.rs
@@ -99,58 +99,59 @@ impl fmt::Debug for Command {
     }
 }
 
-pub struct ExitStatus(!);
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
+#[non_exhaustive]
+pub struct ExitStatus();
 
 impl ExitStatus {
     pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
-        self.0
+        Ok(())
     }
 
     pub fn code(&self) -> Option<i32> {
-        self.0
+        Some(0)
     }
 }
 
-impl Clone for ExitStatus {
-    fn clone(&self) -> ExitStatus {
-        self.0
+impl fmt::Display for ExitStatus {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "<dummy exit status>")
     }
 }
 
-impl Copy for ExitStatus {}
+pub struct ExitStatusError(!);
 
-impl PartialEq for ExitStatus {
-    fn eq(&self, _other: &ExitStatus) -> bool {
+impl Clone for ExitStatusError {
+    fn clone(&self) -> ExitStatusError {
         self.0
     }
 }
 
-impl Eq for ExitStatus {}
+impl Copy for ExitStatusError {}
 
-impl fmt::Debug for ExitStatus {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+impl PartialEq for ExitStatusError {
+    fn eq(&self, _other: &ExitStatusError) -> bool {
         self.0
     }
 }
 
-impl fmt::Display for ExitStatus {
+impl Eq for ExitStatusError {}
+
+impl fmt::Debug for ExitStatusError {
     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatusError(ExitStatus);
-
 impl Into<ExitStatus> for ExitStatusError {
     fn into(self) -> ExitStatus {
-        self.0.0
+        self.0
     }
 }
 
 impl ExitStatusError {
     pub fn code(self) -> Option<NonZeroI32> {
-        self.0.0
+        self.0
     }
 }
 
diff --git a/library/std/src/sys/windows/cmath.rs b/library/std/src/sys/windows/cmath.rs
index 43ab8c7ee65..1b2a86f3c0e 100644
--- a/library/std/src/sys/windows/cmath.rs
+++ b/library/std/src/sys/windows/cmath.rs
@@ -1,6 +1,6 @@
 #![cfg(not(test))]
 
-use libc::{c_double, c_float};
+use libc::{c_double, c_float, c_int};
 
 extern "C" {
     pub fn acos(n: c_double) -> c_double;
@@ -23,6 +23,10 @@ extern "C" {
     pub fn sinh(n: c_double) -> c_double;
     pub fn tan(n: c_double) -> c_double;
     pub fn tanh(n: c_double) -> c_double;
+    pub fn tgamma(n: c_double) -> c_double;
+    pub fn tgammaf(n: c_float) -> c_float;
+    pub fn lgamma_r(n: c_double, s: &mut c_int) -> c_double;
+    pub fn lgammaf_r(n: c_float, s: &mut c_int) -> c_float;
 }
 
 pub use self::shims::*;
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index e3493cbb850..2dd0c67acdb 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -652,7 +652,7 @@ impl Process {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
 pub struct ExitStatus(c::DWORD);
 
 impl ExitStatus {
diff --git a/library/test/src/term/terminfo/searcher/tests.rs b/library/test/src/term/terminfo/searcher/tests.rs
index 4227a585e2f..e1edd3b25cf 100644
--- a/library/test/src/term/terminfo/searcher/tests.rs
+++ b/library/test/src/term/terminfo/searcher/tests.rs
@@ -6,14 +6,12 @@ fn test_get_dbpath_for_term() {
     // woefully inadequate test coverage
     // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
     use std::env;
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    fn x(t: &str) -> String {
-        let p = get_dbpath_for_term(t).expect("no terminfo entry found");
-        p.to_str().unwrap().to_string()
+    fn x(t: &str) -> PathBuf {
+        get_dbpath_for_term(t).expect(&format!("no terminfo entry found for {t:?}"))
     }
-    assert!(x("screen") == "/usr/share/terminfo/s/screen");
-    assert!(get_dbpath_for_term("") == None);
+    assert_eq!(x("screen"), PathBuf::from("/usr/share/terminfo/s/screen"));
+    assert_eq!(get_dbpath_for_term(""), None);
     env::set_var("TERMINFO_DIRS", ":");
-    assert!(x("screen") == "/usr/share/terminfo/s/screen");
+    assert_eq!(x("screen"), PathBuf::from("/usr/share/terminfo/s/screen"));
     env::remove_var("TERMINFO_DIRS");
 }
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index fe66b1d41bf..70079106689 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -472,7 +472,9 @@ class FakeArgs:
 
 class RustBuild(object):
     """Provide all the methods required to build Rust"""
-    def __init__(self, config_toml="", args=FakeArgs()):
+    def __init__(self, config_toml="", args=None):
+        if args is None:
+            args = FakeArgs()
         self.git_version = None
         self.nix_deps_dir = None
         self._should_fix_bins_and_dylibs = None
diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py
index 3c91e403df3..dc06a4c9734 100644
--- a/src/bootstrap/bootstrap_test.py
+++ b/src/bootstrap/bootstrap_test.py
@@ -4,7 +4,6 @@ Run these with `x test bootstrap`, or `python -m unittest src/bootstrap/bootstra
 
 from __future__ import absolute_import, division, print_function
 import os
-import doctest
 import unittest
 import tempfile
 import hashlib
@@ -16,12 +15,15 @@ from shutil import rmtree
 bootstrap_dir = os.path.dirname(os.path.abspath(__file__))
 # For the import below, have Python search in src/bootstrap first.
 sys.path.insert(0, bootstrap_dir)
-import bootstrap
-import configure
+import bootstrap # noqa: E402
+import configure # noqa: E402
 
-def serialize_and_parse(configure_args, bootstrap_args=bootstrap.FakeArgs()):
+def serialize_and_parse(configure_args, bootstrap_args=None):
     from io import StringIO
 
+    if bootstrap_args is None:
+        bootstrap_args = bootstrap.FakeArgs()
+
     section_order, sections, targets = configure.parse_args(configure_args)
     buffer = StringIO()
     configure.write_config_toml(buffer, section_order, targets, sections)
@@ -129,7 +131,14 @@ class GenerateAndParseConfig(unittest.TestCase):
 class BuildBootstrap(unittest.TestCase):
     """Test that we generate the appropriate arguments when building bootstrap"""
 
-    def build_args(self, configure_args=[], args=[], env={}):
+    def build_args(self, configure_args=None, args=None, env=None):
+        if configure_args is None:
+            configure_args = []
+        if args is None:
+            args = []
+        if env is None:
+            env = {}
+
         env = env.copy()
         env["PATH"] = os.environ["PATH"]
 
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index d369e8eeda9..b3666192853 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -317,19 +317,17 @@ impl StepDescription {
     }
 
     fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
-        if builder.config.exclude.iter().any(|e| pathset.has(&e, builder.kind)) {
+        if builder.config.skip.iter().any(|e| pathset.has(&e, builder.kind)) {
             if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
                 println!("Skipping {pathset:?} because it is excluded");
             }
             return true;
         }
 
-        if !builder.config.exclude.is_empty()
-            && !matches!(builder.config.dry_run, DryRun::SelfCheck)
-        {
+        if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
             builder.verbose(&format!(
                 "{:?} not skipped for {:?} -- not in {:?}",
-                pathset, self.name, builder.config.exclude
+                pathset, self.name, builder.config.skip
             ));
         }
         false
@@ -2129,7 +2127,7 @@ impl<'a> Builder<'a> {
         let desc = StepDescription::from::<S>(kind);
         let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind));
 
-        // Avoid running steps contained in --exclude
+        // Avoid running steps contained in --skip
         for pathset in &should_run.paths {
             if desc.is_excluded(self, pathset) {
                 return None;
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index 65b8f7fd3b7..43b4a34fe5b 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -119,7 +119,7 @@ fn test_intersection() {
 #[test]
 fn test_exclude() {
     let mut config = configure("test", &["A"], &["A"]);
-    config.exclude = vec!["src/tools/tidy".into()];
+    config.skip = vec!["src/tools/tidy".into()];
     let cache = run_build(&[], config);
 
     // Ensure we have really excluded tidy
@@ -137,7 +137,7 @@ fn test_exclude_kind() {
     // Ensure our test is valid, and `test::Rustc` would be run without the exclude.
     assert!(run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
     // Ensure tests for rustc are skipped.
-    config.exclude = vec![path.clone()];
+    config.skip = vec![path.clone()];
     assert!(!run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
     // Ensure builds for rustc are not skipped.
     assert!(run_build(&[], config).contains::<compile::Rustc>());
@@ -587,6 +587,7 @@ mod dist {
             run: None,
             only_modified: false,
             skip: vec![],
+            extra_checks: None,
         };
 
         let build = Build::new(config);
@@ -658,6 +659,7 @@ mod dist {
             pass: None,
             run: None,
             only_modified: false,
+            extra_checks: None,
         };
         // Make sure rustfmt binary not being found isn't an error.
         config.channel = "beta".to_string();
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 2c63ec80c3e..62c7b96b5be 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -31,6 +31,7 @@ use crate::util::get_clang_cl_resource_dir;
 use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date};
 use crate::LLVM_TOOLS;
 use crate::{CLang, Compiler, DependencyType, GitRepo, Mode};
+use filetime::FileTime;
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Std {
@@ -904,19 +905,12 @@ impl Step for Rustc {
         // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with
         // debuginfo (via the debuginfo level of the executables using it): strip this debuginfo
         // away after the fact.
-        // FIXME: to make things simpler for now, limit this to the host and target where we know
-        // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
-        // cross-compiling. Expand this to other appropriate targets in the future.
         if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None
             && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None
-            && target == "x86_64-unknown-linux-gnu"
-            && target == builder.config.build
         {
             let target_root_dir = stamp.parent().unwrap();
             let rustc_driver = target_root_dir.join("librustc_driver.so");
-            if rustc_driver.exists() {
-                output(Command::new("strip").arg("--strip-debug").arg(rustc_driver));
-            }
+            strip_debug(builder, target, &rustc_driver);
         }
 
         builder.ensure(RustcLink::from_rustc(
@@ -1974,3 +1968,30 @@ pub enum CargoMessage<'a> {
         success: bool,
     },
 }
+
+pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) {
+    // FIXME: to make things simpler for now, limit this to the host and target where we know
+    // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
+    // cross-compiling. Expand this to other appropriate targets in the future.
+    if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() {
+        return;
+    }
+
+    let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap());
+    // Note: `output` will propagate any errors here.
+    output(Command::new("strip").arg("--strip-debug").arg(path));
+
+    // After running `strip`, we have to set the file modification time to what it was before,
+    // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time
+    // bootstrap is invoked.
+    //
+    // An example of this is if we run this on librustc_driver.so. In the first invocation:
+    // - Cargo will build librustc_driver.so (mtime of 1)
+    // - Cargo will build rustc-main (mtime of 2)
+    // - Bootstrap will strip librustc_driver.so (changing the mtime to 3).
+    //
+    // In the second invocation of bootstrap, Cargo will see that the mtime of librustc_driver.so
+    // is greater than the mtime of rustc-main, and will rebuild rustc-main. That will then cause
+    // everything else (standard library, future stages...) to be rebuilt.
+    t!(filetime::set_file_mtime(path, previous_mtime));
+}
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index da60166b84d..cdb34f99164 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -130,7 +130,7 @@ pub struct Config {
     pub sanitizers: bool,
     pub profiler: bool,
     pub omit_git_hash: bool,
-    pub exclude: Vec<PathBuf>,
+    pub skip: Vec<PathBuf>,
     pub include_default_paths: bool,
     pub rustc_error_format: Option<String>,
     pub json_output: bool,
@@ -1112,7 +1112,7 @@ impl Config {
 
         // Set flags.
         config.paths = std::mem::take(&mut flags.paths);
-        config.exclude = flags.exclude;
+        config.skip = flags.skip.into_iter().chain(flags.exclude).collect();
         config.include_default_paths = flags.include_default_paths;
         config.rustc_error_format = flags.rustc_error_format;
         config.json_output = flags.json_output;
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 9cb3546ba0a..505f06ed12d 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -570,7 +570,7 @@ fn doc_std(
     if builder.no_std(target) == Some(true) {
         panic!(
             "building std documentation for no_std target {target} is not supported\n\
-             Set `docs = false` in the config to disable documentation, or pass `--exclude doc::library`."
+             Set `docs = false` in the config to disable documentation, or pass `--skip library`."
         );
     }
 
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index a1e0a440729..e0291e407b3 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -68,7 +68,10 @@ pub struct Flags {
 
     #[arg(global(true), long, value_name = "PATH")]
     /// build paths to exclude
-    pub exclude: Vec<PathBuf>,
+    pub exclude: Vec<PathBuf>, // keeping for client backward compatibility
+    #[arg(global(true), long, value_name = "PATH")]
+    /// build paths to skip
+    pub skip: Vec<PathBuf>,
     #[arg(global(true), long)]
     /// include default paths in addition to the provided ones
     pub include_default_paths: bool,
@@ -318,7 +321,7 @@ pub enum Subcommand {
         no_fail_fast: bool,
         #[arg(long, value_name = "SUBSTRING")]
         /// skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times
-        skip: Vec<String>,
+        skip: Vec<PathBuf>,
         #[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
         /// extra arguments to be passed for the test tool being used
         /// (e.g. libtest, compiletest or rustdoc)
@@ -336,6 +339,10 @@ pub enum Subcommand {
         /// whether to automatically update stderr/stdout files
         bless: bool,
         #[arg(long)]
+        /// comma-separated list of other files types to check (accepts py, py:lint,
+        /// py:fmt, shell)
+        extra_checks: Option<String>,
+        #[arg(long)]
         /// rerun tests even if the inputs are unchanged
         force_rerun: bool,
         #[arg(long)]
@@ -473,6 +480,13 @@ impl Subcommand {
         }
     }
 
+    pub fn extra_checks(&self) -> Option<&str> {
+        match *self {
+            Subcommand::Test { ref extra_checks, .. } => extra_checks.as_ref().map(String::as_str),
+            _ => None,
+        }
+    }
+
     pub fn only_modified(&self) -> bool {
         match *self {
             Subcommand::Test { only_modified, .. } => only_modified,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 8c674d075b8..e3a9434a164 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -133,7 +133,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
     // #[cfg(bootstrap)]
     (Some(Mode::Std), "target_vendor", Some(&["unikraft"])),
     (Some(Mode::Std), "target_env", Some(&["libnx"])),
-    // (Some(Mode::Std), "target_os", Some(&[])),
+    (Some(Mode::Std), "target_os", Some(&["teeos"])),
     // #[cfg(bootstrap)] mips32r6, mips64r6
     (
         Some(Mode::Std),
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 14ee5659ed5..4943f93fa9a 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -512,27 +512,21 @@ impl Step for Llvm {
         // When building LLVM as a shared library on linux, it can contain unexpected debuginfo:
         // some can come from the C++ standard library. Unless we're explicitly requesting LLVM to
         // be built with debuginfo, strip it away after the fact, to make dist artifacts smaller.
-        // FIXME: to make things simpler for now, limit this to the host and target where we know
-        // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
-        // cross-compiling. Expand this to other appropriate targets in the future.
         if builder.llvm_link_shared()
             && builder.config.llvm_optimize
             && !builder.config.llvm_release_debuginfo
-            && target == "x86_64-unknown-linux-gnu"
-            && target == builder.config.build
         {
             // Find the name of the LLVM shared library that we just built.
             let lib_name = find_llvm_lib_name("so");
 
             // If the shared library exists in LLVM's `/build/lib/` or `/lib/` folders, strip its
-            // debuginfo. Note: `output` will propagate any errors here.
-            let strip_if_possible = |path: PathBuf| {
-                if path.exists() {
-                    output(Command::new("strip").arg("--strip-debug").arg(path));
-                }
-            };
-            strip_if_possible(out_dir.join("lib").join(&lib_name));
-            strip_if_possible(out_dir.join("build").join("lib").join(&lib_name));
+            // debuginfo.
+            crate::compile::strip_debug(builder, target, &out_dir.join("lib").join(&lib_name));
+            crate::compile::strip_debug(
+                builder,
+                target,
+                &out_dir.join("build").join("lib").join(&lib_name),
+            );
         }
 
         t!(stamp.write());
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 9476137968b..a9865e262fe 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -63,7 +63,7 @@ prepare:
 ci-msvc-py:
 	$(Q)$(CFG_SRC_DIR)/x.py test --stage 2 tidy
 ci-msvc-ps1:
-	$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --exclude tidy
+	$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --skip tidy
 ci-msvc: ci-msvc-py ci-msvc-ps1
 
 ## MingW native builders
@@ -72,7 +72,7 @@ ci-msvc: ci-msvc-py ci-msvc-ps1
 ci-mingw-x:
 	$(Q)$(CFG_SRC_DIR)/x test --stage 2 tidy
 ci-mingw-bootstrap:
-	$(Q)$(BOOTSTRAP) test --stage 2 --exclude tidy
+	$(Q)$(BOOTSTRAP) test --stage 2 --skip tidy
 ci-mingw: ci-mingw-x ci-mingw-bootstrap
 
 .PHONY: dist
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 4bfb16928f1..d0d62db0807 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -4,6 +4,7 @@
 //! our CI.
 
 use std::env;
+use std::ffi::OsStr;
 use std::ffi::OsString;
 use std::fs;
 use std::iter;
@@ -122,7 +123,7 @@ impl Step for Linkcheck {
         if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() {
             panic!(
                 "Linkcheck currently does not support builds with different hosts and targets.
-You can skip linkcheck with --exclude src/tools/linkchecker"
+You can skip linkcheck with --skip src/tools/linkchecker"
             );
         }
 
@@ -1094,6 +1095,14 @@ impl Step for Tidy {
         if builder.config.cmd.bless() {
             cmd.arg("--bless");
         }
+        if let Some(s) = builder.config.cmd.extra_checks() {
+            cmd.arg(format!("--extra-checks={s}"));
+        }
+        let mut args = std::env::args_os();
+        if let Some(_) = args.find(|arg| arg == OsStr::new("--")) {
+            cmd.arg("--");
+            cmd.args(args);
+        }
 
         if builder.config.channel == "dev" || builder.config.channel == "nightly" {
             builder.info("fmt check");
@@ -1104,7 +1113,7 @@ impl Step for Tidy {
 error: no `rustfmt` binary found in {PATH}
 info: `rust.channel` is currently set to \"{CHAN}\"
 help: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file
-help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` to `x.py test`",
+help: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to `x.py test`",
                     PATH = inferred_rustfmt_dir.display(),
                     CHAN = builder.config.channel,
                 );
@@ -1650,7 +1659,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
             cmd.arg("--run-clang-based-tests-with").arg(clang_exe);
         }
 
-        for exclude in &builder.config.exclude {
+        for exclude in &builder.config.skip {
             cmd.arg("--skip");
             cmd.arg(&exclude);
         }
diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
index b5abf6564a6..61811c41904 100644
--- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
+++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile
@@ -24,10 +24,10 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu
-# Exclude some tests that are unlikely to be platform specific, to speed up
+# Skip some tests that are unlikely to be platform specific, to speed up
 # this slow job.
 ENV SCRIPT python3 ../x.py --stage 2 test \
-  --exclude src/bootstrap \
-  --exclude tests/rustdoc-js \
-  --exclude src/tools/error_index_generator \
-  --exclude src/tools/linkchecker
+  --skip src/bootstrap \
+  --skip tests/rustdoc-js \
+  --skip src/tools/error_index_generator \
+  --skip src/tools/linkchecker
diff --git a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile b/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
index 34b93be412e..0a49eab4d50 100644
--- a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
@@ -26,11 +26,13 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 COPY host-x86_64/mingw-check/reuse-requirements.txt /tmp/
-RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt
+RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt \
+    && pip3 install virtualenv
 
 COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
 # NOTE: intentionally uses python2 for x.py so we can test it still works.
 # validate-toolstate only runs in our CI, so it's ok for it to only support python3.
-ENV SCRIPT python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest
+ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
+           --stage 0 src/tools/tidy tidyselftest --extra-checks=py:lint
diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile
index 24a1ccb7fc2..02b4664eb55 100644
--- a/src/ci/docker/host-x86_64/wasm32/Dockerfile
+++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile
@@ -59,4 +59,4 @@ RUN chown 10719 -R /emsdk-portable/
 
 # Exclude library/alloc due to OOM in benches.
 ENV SCRIPT python3 ../x.py test --stage 2 --host='' --target $TARGETS \
-    --exclude library/alloc
+    --skip library/alloc
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh
index 0120fd98298..390304b6ad5 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh
@@ -4,7 +4,7 @@ set -ex
 
 # Only run the stage 1 tests on merges, not on PR CI jobs.
 if [[ -z "${PR_CI_JOB}" ]]; then
-../x.py --stage 1 test --exclude src/tools/tidy && \
+../x.py --stage 1 test --skip src/tools/tidy && \
            # Run the `mir-opt` tests again but this time for a 32-bit target.
            # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
            # both 32-bit and 64-bit outputs updated by the PR author, before
@@ -16,7 +16,7 @@ if [[ -z "${PR_CI_JOB}" ]]; then
 fi
 
 # NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux.
-../x.py --stage 2 test --exclude src/tools/tidy && \
+../x.py --stage 2 test --skip src/tools/tidy && \
      # Run the `mir-opt` tests again but this time for a 32-bit target.
      # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have
      # both 32-bit and 64-bit outputs updated by the PR author, before
diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py
index af01f9ccbbc..f78d446c8b7 100755
--- a/src/ci/docker/scripts/fuchsia-test-runner.py
+++ b/src/ci/docker/scripts/fuchsia-test-runner.py
@@ -15,12 +15,10 @@ import hashlib
 import json
 import os
 import platform
-import re
 import shutil
-import signal
 import subprocess
 import sys
-from typing import ClassVar, List, Optional
+from typing import ClassVar, List
 
 
 @dataclass
@@ -523,7 +521,7 @@ class TestEnvironment:
                     env_vars += '\n            "RUST_BACKTRACE=0",'
 
                 # Use /tmp as the test temporary directory
-                env_vars += f'\n            "RUST_TEST_TMPDIR=/tmp",'
+                env_vars += '\n            "RUST_TEST_TMPDIR=/tmp",'
 
                 cml.write(
                     self.CML_TEMPLATE.format(env_vars=env_vars, exe_name=exe_name)
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 6efc1980e60..f900a5eb576 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -14,7 +14,6 @@
 # step CI will fail.
 
 ---
-
 ###############################
 #   YAML Anchors Definition   #
 ###############################
@@ -30,7 +29,6 @@
 # The expand-yaml-anchors tool will automatically remove this block from the
 # output YAML file.
 x--expand-yaml-anchors--remove:
-
   - &shared-ci-variables
     CI_JOB_NAME: ${{ matrix.name }}
     CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
@@ -520,7 +518,7 @@ jobs:
 
           - name: x86_64-apple-1
             env: &env-x86_64-apple-tests
-              SCRIPT: ./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps
+              SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps
               RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
               MACOSX_DEPLOYMENT_TARGET: 10.8
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 851be1c0a2c..817abbfaf26 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -28,6 +28,7 @@
     - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
     - [\*-android and \*-androideabi](platform-support/android.md)
     - [\*-linux-ohos](platform-support/openharmony.md)
+    - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md)
     - [\*-esp-espidf](platform-support/esp-idf.md)
     - [\*-unknown-fuchsia](platform-support/fuchsia.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 1b791f5eb36..393719e7115 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -221,6 +221,7 @@ target | std | host | notes
 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * |  | ARM64 Nintendo Switch, Horizon
 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ |  | ARM64 OpenHarmony |
+[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? |  | ARM64 TEEOS |
 [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ |  | ARM64 QNX Neutrino 7.1 RTOS |
 `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
 [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ |  | ARM64 Hermit
diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
new file mode 100644
index 00000000000..8fc5e6dd92b
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
@@ -0,0 +1,100 @@
+# `aarch64-unknown-teeos`
+
+**Tier: 3**
+
+Target for the TEEOS operating system.
+
+TEEOS is a mini os run in TrustZone, for trusted/security apps. The kernel of TEEOS is HongMeng/ChCore micro kernel. The libc for TEEOS is a part of musl.
+It's very small that there is no RwLock, no network, no stdin, and no file system for apps in TEEOS.
+
+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. |
+| 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. |
+
+TEEOS is open source in progress. [MORE about](https://gitee.com/opentrustee-group)
+
+## Target maintainers
+
+- Petrochenkov Vadim
+- Sword-Destiny
+
+## Setup
+We use OpenHarmony SDK for TEEOS.
+
+The OpenHarmony SDK doesn't currently support Rust compilation directly, so
+some setup is required.
+
+First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes).
+Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system".
+
+Create the following shell scripts that wrap Clang from the OpenHarmony SDK:
+
+`aarch64-unknown-teeos-clang.sh`
+
+```sh
+#!/bin/sh
+exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \
+  --target aarch64-linux-gnu \
+  "$@"
+```
+
+`aarch64-unknown-teeos-clang++.sh`
+
+```sh
+#!/bin/sh
+exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \
+  --target aarch64-linux-gnu \
+  "$@"
+```
+
+## Building the target
+
+To build a rust toolchain, create a `config.toml` with the following contents:
+
+```toml
+profile = "compiler"
+changelog-seen = 2
+
+[build]
+sanitizers = true
+profiler = true
+target = ["x86_64-unknown-linux-gnu", "aarch64-unknown-teeos"]
+submodules = false
+compiler-docs = false
+extended = true
+
+[install]
+bindir = "bin"
+libdir = "lib"
+
+[target.aarch64-unknown-teeos]
+cc = "/path/to/scripts/aarch64-unknown-teeos-clang.sh"
+cxx = "/path/to/scripts/aarch64-unknown-teeos-clang.sh"
+linker = "/path/to/scripts/aarch64-unknown-teeos-clang.sh"
+ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar"
+ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib"
+llvm-config = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-config"
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+You will need to configure the linker to use in `~/.cargo/config`:
+```toml
+[target.aarch64-unknown-teeos]
+linker = "/path/to/aarch64-unknown-teeos-clang.sh"
+```
+
+## Testing
+
+Running the Rust testsuite is not possible now.
+
+More information about how to test CA/TA. [See here](https://gitee.com/openharmony-sig/tee_tee_dev_kit/tree/master/docs)
diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md
index e351cfaf89c..4ef74295e0f 100644
--- a/src/doc/rustc/src/platform-support/android.md
+++ b/src/doc/rustc/src/platform-support/android.md
@@ -39,6 +39,8 @@ edition of the [Android NDK].  Supported Android targets are:
 * thumbv7neon-linux-androideabi
 * x86_64-linux-android
 
+The riscv64-linux-android target is supported as a Tier 3 target.
+
 [Android NDK]: https://developer.android.com/ndk/downloads
 
 A list of all supported targets can be found
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 238b5aa4d5a..151c4120ddf 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -4,6 +4,7 @@ complete -c x.py -n "__fish_use_subcommand" -l build -d 'build target of the sta
 complete -c x.py -n "__fish_use_subcommand" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_use_subcommand" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_use_subcommand" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_use_subcommand" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_use_subcommand" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_use_subcommand" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_use_subcommand" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -47,6 +48,7 @@ complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build targe
 complete -c x.py -n "__fish_seen_subcommand_from build" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from build" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from build" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from build" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from build" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from build" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from build" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -76,6 +78,7 @@ complete -c x.py -n "__fish_seen_subcommand_from check" -l build -d 'build targe
 complete -c x.py -n "__fish_seen_subcommand_from check" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from check" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from check" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from check" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from check" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from check" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from check" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -110,6 +113,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l build -d 'build targ
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clippy" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from clippy" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -140,6 +144,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fix" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fix" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from fix" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -169,6 +174,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from fmt" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from fmt" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -199,6 +205,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from doc" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -224,9 +231,10 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l dry-run -d 'dry run; do
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l json-output -d 'use message-format=json'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
+complete -c x.py -n "__fish_seen_subcommand_from test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l run -d 'whether to execute run-* tests' -r
@@ -273,6 +281,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l build -d 'build targe
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from bench" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -303,6 +312,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l build -d 'build targe
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from clean" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
@@ -332,6 +342,7 @@ complete -c x.py -n "__fish_seen_subcommand_from dist" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from dist" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from dist" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -361,6 +372,7 @@ complete -c x.py -n "__fish_seen_subcommand_from install" -l build -d 'build tar
 complete -c x.py -n "__fish_seen_subcommand_from install" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from install" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from install" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from install" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from install" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from install" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from install" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -391,6 +403,7 @@ complete -c x.py -n "__fish_seen_subcommand_from run" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from run" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from run" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from run" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from run" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from run" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from run" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from run" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -420,6 +433,7 @@ complete -c x.py -n "__fish_seen_subcommand_from setup" -l build -d 'build targe
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from setup" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from setup" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -449,6 +463,7 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build -d 'build tar
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from suggest" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from suggest" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index ff7d49d5e30..cafb8eed12d 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -27,6 +27,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -77,6 +78,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -113,6 +115,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -154,6 +157,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -191,6 +195,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -227,6 +232,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -264,6 +270,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -299,6 +306,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times')
             [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
+            [CompletionResult]::new('--extra-checks', 'extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)')
             [CompletionResult]::new('--compare-mode', 'compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to')
             [CompletionResult]::new('--pass', 'pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode')
             [CompletionResult]::new('--run', 'run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests')
@@ -352,6 +360,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -389,6 +398,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
@@ -425,6 +435,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -461,6 +472,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -498,6 +510,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -534,6 +547,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -570,6 +584,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 4e9286ae1e8..3c57e71bdb7 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -61,7 +61,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -91,6 +91,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -167,7 +171,7 @@ _x.py() {
             return 0
             ;;
         x.py__bench)
-            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -201,6 +205,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -277,7 +285,7 @@ _x.py() {
             return 0
             ;;
         x.py__build)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -307,6 +315,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -383,7 +395,7 @@ _x.py() {
             return 0
             ;;
         x.py__check)
-            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -413,6 +425,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -489,7 +505,7 @@ _x.py() {
             return 0
             ;;
         x.py__clean)
-            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -523,6 +539,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -595,7 +615,7 @@ _x.py() {
             return 0
             ;;
         x.py__clippy)
-            opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -641,6 +661,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -717,7 +741,7 @@ _x.py() {
             return 0
             ;;
         x.py__dist)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -747,6 +771,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -823,7 +851,7 @@ _x.py() {
             return 0
             ;;
         x.py__doc)
-            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -853,6 +881,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -929,7 +961,7 @@ _x.py() {
             return 0
             ;;
         x.py__fix)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -959,6 +991,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -1035,7 +1071,7 @@ _x.py() {
             return 0
             ;;
         x.py__fmt)
-            opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1065,6 +1101,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -1141,7 +1181,7 @@ _x.py() {
             return 0
             ;;
         x.py__install)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1171,6 +1211,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -1247,7 +1291,7 @@ _x.py() {
             return 0
             ;;
         x.py__run)
-            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1281,6 +1325,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -1357,7 +1405,7 @@ _x.py() {
             return 0
             ;;
         x.py__setup)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1387,6 +1435,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -1463,7 +1515,7 @@ _x.py() {
             return 0
             ;;
         x.py__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1493,6 +1545,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
@@ -1569,7 +1625,7 @@ _x.py() {
             return 0
             ;;
         x.py__test)
-            opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1587,6 +1643,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --extra-checks)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --compare-mode)
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c1987420417..3d237eb25cc 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1645,7 +1645,7 @@ impl<'test> TestCx<'test> {
         if self.props.known_bug {
             if !expected_errors.is_empty() {
                 self.fatal_proc_rec(
-                    "`known_bug` tests should not have an expected errors",
+                    "`known_bug` tests should not have an expected error",
                     proc_res,
                 );
             }
diff --git a/src/tools/opt-dist/src/bolt.rs b/src/tools/opt-dist/src/bolt.rs
index e44b8a4db92..cf9f4fabcec 100644
--- a/src/tools/opt-dist/src/bolt.rs
+++ b/src/tools/opt-dist/src/bolt.rs
@@ -65,8 +65,13 @@ pub fn bolt_optimize(path: &Utf8Path, profile: &LlvmBoltProfile) -> anyhow::Resu
         .arg("-jump-tables=move")
         // Fold functions with identical code
         .arg("-icf=1")
+        // The following flag saves about 50 MiB of libLLVM.so size.
+        // However, it succeeds very non-deterministically. To avoid frequent artifact size swings,
+        // it is kept disabled for now.
+        // FIXME(kobzol): try to re-enable this once BOLT in-place rewriting is merged or after
+        // we bump LLVM.
         // Try to reuse old text segments to reduce binary size
-        .arg("--use-old-text")
+        // .arg("--use-old-text")
         // Update DWARF debug info in the final binary
         .arg("-update-debug-sections")
         // Print optimization statistics
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index f6edd008845..8ab19674d05 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -197,7 +197,7 @@ fn main() -> anyhow::Result<()> {
             "miri",
             "rustfmt",
         ] {
-            build_args.extend(["--exclude".to_string(), target.to_string()]);
+            build_args.extend(["--skip".to_string(), target.to_string()]);
         }
     }
 
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index c85418baecd..3dd1a3223f5 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -96,7 +96,7 @@ llvm-config = "{llvm_config}"
         "tests/ui",
     ];
     for test_path in env.skipped_tests() {
-        args.extend(["--exclude", test_path]);
+        args.extend(["--skip", test_path]);
     }
     cmd(&args).env("COMPILETEST_FORCE_STAGE0", "1").run().context("Cannot execute tests")
 }
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
index c717a9cb55b..e411c1c869c 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
@@ -30,6 +30,8 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
     "efiapi",
     "avr-interrupt",
     "avr-non-blocking-interrupt",
+    "riscv-interrupt-m",
+    "riscv-interrupt-s",
     "C-cmse-nonsecure-call",
     "wasm",
     "system",
diff --git a/src/tools/tidy/config/black.toml b/src/tools/tidy/config/black.toml
new file mode 100644
index 00000000000..51a722979f5
--- /dev/null
+++ b/src/tools/tidy/config/black.toml
@@ -0,0 +1,15 @@
+[tool.black]
+# Ignore all submodules
+extend-exclude = """(\
+    src/doc/nomicon|\
+    src/tools/cargo/|\
+    src/doc/reference/|\
+    src/doc/book/|\
+    src/doc/rust-by-example/|\
+    library/stdarch/|\
+    src/doc/rustc-dev-guide/|\
+    src/doc/edition-guide/|\
+    src/llvm-project/|\
+    src/doc/embedded-book/|\
+    library/backtrace/
+    )"""
diff --git a/src/tools/tidy/config/requirements.in b/src/tools/tidy/config/requirements.in
new file mode 100644
index 00000000000..882e09dae45
--- /dev/null
+++ b/src/tools/tidy/config/requirements.in
@@ -0,0 +1,10 @@
+# requirements.in This is the source file for our pinned version requirements
+# file "requirements.txt" To regenerate that file, pip-tools is required
+# (`python -m pip install pip-tools`). Once installed, run: `pip-compile
+# --generate-hashes src/tools/tidy/config/requirements.in`
+#
+# Note: this generation step should be run with the oldest supported python
+# version (currently 3.7) to ensure backward compatibility
+
+black==23.3.0
+ruff==0.0.272
diff --git a/src/tools/tidy/config/requirements.txt b/src/tools/tidy/config/requirements.txt
new file mode 100644
index 00000000000..9fd617ad621
--- /dev/null
+++ b/src/tools/tidy/config/requirements.txt
@@ -0,0 +1,117 @@
+#
+# This file is autogenerated by pip-compile with Python 3.11
+# by the following command:
+#
+#    pip-compile --generate-hashes src/tools/tidy/config/requirements.in
+#
+black==23.3.0 \
+    --hash=sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5 \
+    --hash=sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915 \
+    --hash=sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326 \
+    --hash=sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940 \
+    --hash=sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b \
+    --hash=sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30 \
+    --hash=sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c \
+    --hash=sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c \
+    --hash=sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab \
+    --hash=sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27 \
+    --hash=sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2 \
+    --hash=sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961 \
+    --hash=sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9 \
+    --hash=sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb \
+    --hash=sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70 \
+    --hash=sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331 \
+    --hash=sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2 \
+    --hash=sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266 \
+    --hash=sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d \
+    --hash=sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6 \
+    --hash=sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b \
+    --hash=sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925 \
+    --hash=sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8 \
+    --hash=sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4 \
+    --hash=sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3
+    # via -r src/tools/tidy/config/requirements.in
+click==8.1.3 \
+    --hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \
+    --hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48
+    # via black
+importlib-metadata==6.7.0 \
+    --hash=sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4 \
+    --hash=sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5
+    # via click
+mypy-extensions==1.0.0 \
+    --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
+    --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782
+    # via black
+packaging==23.1 \
+    --hash=sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61 \
+    --hash=sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f
+    # via black
+pathspec==0.11.1 \
+    --hash=sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687 \
+    --hash=sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293
+    # via black
+platformdirs==3.6.0 \
+    --hash=sha256:57e28820ca8094678b807ff529196506d7a21e17156cb1cddb3e74cebce54640 \
+    --hash=sha256:ffa199e3fbab8365778c4a10e1fbf1b9cd50707de826eb304b50e57ec0cc8d38
+    # via black
+ruff==0.0.272 \
+    --hash=sha256:06b8ee4eb8711ab119db51028dd9f5384b44728c23586424fd6e241a5b9c4a3b \
+    --hash=sha256:1609b864a8d7ee75a8c07578bdea0a7db75a144404e75ef3162e0042bfdc100d \
+    --hash=sha256:19643d448f76b1eb8a764719072e9c885968971bfba872e14e7257e08bc2f2b7 \
+    --hash=sha256:273a01dc8c3c4fd4c2af7ea7a67c8d39bb09bce466e640dd170034da75d14cab \
+    --hash=sha256:27b2ea68d2aa69fff1b20b67636b1e3e22a6a39e476c880da1282c3e4bf6ee5a \
+    --hash=sha256:48eccf225615e106341a641f826b15224b8a4240b84269ead62f0afd6d7e2d95 \
+    --hash=sha256:677284430ac539bb23421a2b431b4ebc588097ef3ef918d0e0a8d8ed31fea216 \
+    --hash=sha256:691d72a00a99707a4e0b2846690961157aef7b17b6b884f6b4420a9f25cd39b5 \
+    --hash=sha256:86bc788245361a8148ff98667da938a01e1606b28a45e50ac977b09d3ad2c538 \
+    --hash=sha256:905ff8f3d6206ad56fcd70674453527b9011c8b0dc73ead27618426feff6908e \
+    --hash=sha256:9c4bfb75456a8e1efe14c52fcefb89cfb8f2a0d31ed8d804b82c6cf2dc29c42c \
+    --hash=sha256:a37ec80e238ead2969b746d7d1b6b0d31aa799498e9ba4281ab505b93e1f4b28 \
+    --hash=sha256:ae9b57546e118660175d45d264b87e9b4c19405c75b587b6e4d21e6a17bf4fdf \
+    --hash=sha256:bd2bbe337a3f84958f796c77820d55ac2db1e6753f39d1d1baed44e07f13f96d \
+    --hash=sha256:d5a208f8ef0e51d4746930589f54f9f92f84bb69a7d15b1de34ce80a7681bc00 \
+    --hash=sha256:dc406e5d756d932da95f3af082814d2467943631a587339ee65e5a4f4fbe83eb \
+    --hash=sha256:ee76b4f05fcfff37bd6ac209d1370520d509ea70b5a637bdf0a04d0c99e13dff
+    # via -r src/tools/tidy/config/requirements.in
+tomli==2.0.1 \
+    --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
+    --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
+    # via black
+typed-ast==1.5.4 \
+    --hash=sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2 \
+    --hash=sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1 \
+    --hash=sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6 \
+    --hash=sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62 \
+    --hash=sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac \
+    --hash=sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d \
+    --hash=sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc \
+    --hash=sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2 \
+    --hash=sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97 \
+    --hash=sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35 \
+    --hash=sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6 \
+    --hash=sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1 \
+    --hash=sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4 \
+    --hash=sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c \
+    --hash=sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e \
+    --hash=sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec \
+    --hash=sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f \
+    --hash=sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72 \
+    --hash=sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47 \
+    --hash=sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72 \
+    --hash=sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe \
+    --hash=sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6 \
+    --hash=sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3 \
+    --hash=sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66
+    # via black
+typing-extensions==4.6.3 \
+    --hash=sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26 \
+    --hash=sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5
+    # via
+    #   black
+    #   importlib-metadata
+    #   platformdirs
+zipp==3.15.0 \
+    --hash=sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b \
+    --hash=sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556
+    # via importlib-metadata
diff --git a/src/tools/tidy/config/ruff.toml b/src/tools/tidy/config/ruff.toml
new file mode 100644
index 00000000000..cf08c62648b
--- /dev/null
+++ b/src/tools/tidy/config/ruff.toml
@@ -0,0 +1,41 @@
+# Configuration for ruff python linter, run as part of tidy external tools
+
+# B (bugbear), E (pycodestyle, standard), EXE (executables) F (flakes, standard)
+# ERM for error messages would be beneficial at some point
+select = ["B", "E", "EXE", "F"]
+
+ignore = [
+    "E501", # line-too-long
+    "F403", # undefined-local-with-import-star
+    "F405", # undefined-local-with-import-star-usage
+]
+
+# lowest possible for ruff
+target-version = "py37"
+
+# Ignore all submodules
+extend-exclude = [
+    "src/doc/nomicon/",
+    "src/tools/cargo/",
+    "src/doc/reference/",
+    "src/doc/book/",
+    "src/doc/rust-by-example/",
+    "library/stdarch/",
+    "src/doc/rustc-dev-guide/",
+    "src/doc/edition-guide/",
+    "src/llvm-project/",
+    "src/doc/embedded-book/",
+    "library/backtrace/",
+    # Hack: CI runs from a subdirectory under the main checkout
+    "../src/doc/nomicon/",
+    "../src/tools/cargo/",
+    "../src/doc/reference/",
+    "../src/doc/book/",
+    "../src/doc/rust-by-example/",
+    "../library/stdarch/",
+    "../src/doc/rustc-dev-guide/",
+    "../src/doc/edition-guide/",
+    "../src/llvm-project/",
+    "../src/doc/embedded-book/",
+    "../library/backtrace/",
+]
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
new file mode 100644
index 00000000000..40e75d1d3fa
--- /dev/null
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -0,0 +1,435 @@
+//! Optional checks for file types other than Rust source
+//!
+//! Handles python tool version managment via a virtual environment in
+//! `build/venv`.
+//!
+//! # Functional outline
+//!
+//! 1. Run tidy with an extra option: `--extra-checks=py,shell`,
+//!    `--extra-checks=py:lint`, or similar. Optionally provide specific
+//!    configuration after a double dash (`--extra-checks=py -- foo.py`)
+//! 2. Build configuration based on args/environment:
+//!    - Formatters by default are in check only mode
+//!    - If in CI (TIDY_PRINT_DIFF=1 is set), check and print the diff
+//!    - If `--bless` is provided, formatters may run
+//!    - Pass any additional config after the `--`. If no files are specified,
+//!      use a default.
+//! 3. Print the output of the given command. If it fails and `TIDY_PRINT_DIFF`
+//!    is set, rerun the tool to print a suggestion diff (for e.g. CI)
+
+use std::ffi::OsStr;
+use std::fmt;
+use std::fs;
+use std::io;
+use std::path::{Path, PathBuf};
+use std::process::Command;
+
+/// Minimum python revision is 3.7 for ruff
+const MIN_PY_REV: (u32, u32) = (3, 7);
+const MIN_PY_REV_STR: &str = "≥3.7";
+
+/// Path to find the python executable within a virtual environment
+#[cfg(target_os = "windows")]
+const REL_PY_PATH: &[&str] = &["Scripts", "python3.exe"];
+#[cfg(not(target_os = "windows"))]
+const REL_PY_PATH: &[&str] = &["bin", "python3"];
+
+const RUFF_CONFIG_PATH: &[&str] = &["src", "tools", "tidy", "config", "ruff.toml"];
+const BLACK_CONFIG_PATH: &[&str] = &["src", "tools", "tidy", "config", "black.toml"];
+/// Location within build directory
+const RUFF_CACH_PATH: &[&str] = &["cache", "ruff_cache"];
+const PIP_REQ_PATH: &[&str] = &["src", "tools", "tidy", "config", "requirements.txt"];
+
+pub fn check(
+    root_path: &Path,
+    outdir: &Path,
+    bless: bool,
+    extra_checks: Option<&str>,
+    pos_args: &[String],
+    bad: &mut bool,
+) {
+    if let Err(e) = check_impl(root_path, outdir, bless, extra_checks, pos_args) {
+        tidy_error!(bad, "{e}");
+    }
+}
+
+fn check_impl(
+    root_path: &Path,
+    outdir: &Path,
+    bless: bool,
+    extra_checks: Option<&str>,
+    pos_args: &[String],
+) -> Result<(), Error> {
+    let show_diff = std::env::var("TIDY_PRINT_DIFF")
+        .map_or(false, |v| v.eq_ignore_ascii_case("true") || v == "1");
+
+    // Split comma-separated args up
+    let lint_args = match extra_checks {
+        Some(s) => s.strip_prefix("--extra-checks=").unwrap().split(',').collect(),
+        None => vec![],
+    };
+
+    let python_all = lint_args.contains(&"py");
+    let python_lint = lint_args.contains(&"py:lint") || python_all;
+    let python_fmt = lint_args.contains(&"py:fmt") || python_all;
+    let shell_all = lint_args.contains(&"shell");
+    let shell_lint = lint_args.contains(&"shell:lint") || shell_all;
+
+    let mut py_path = None;
+
+    let (cfg_args, file_args): (Vec<_>, Vec<_>) = pos_args
+        .into_iter()
+        .map(OsStr::new)
+        .partition(|arg| arg.to_str().is_some_and(|s| s.starts_with("-")));
+
+    if python_lint || python_fmt {
+        let venv_path = outdir.join("venv");
+        let mut reqs_path = root_path.to_owned();
+        reqs_path.extend(PIP_REQ_PATH);
+        py_path = Some(get_or_create_venv(&venv_path, &reqs_path)?);
+    }
+
+    if python_lint {
+        eprintln!("linting python files");
+        let mut cfg_args_ruff = cfg_args.clone();
+        let mut file_args_ruff = file_args.clone();
+
+        let mut cfg_path = root_path.to_owned();
+        cfg_path.extend(RUFF_CONFIG_PATH);
+        let mut cache_dir = outdir.to_owned();
+        cache_dir.extend(RUFF_CACH_PATH);
+
+        cfg_args_ruff.extend([
+            "--config".as_ref(),
+            cfg_path.as_os_str(),
+            "--cache-dir".as_ref(),
+            cache_dir.as_os_str(),
+        ]);
+
+        if file_args_ruff.is_empty() {
+            file_args_ruff.push(root_path.as_os_str());
+        }
+
+        let mut args = merge_args(&cfg_args_ruff, &file_args_ruff);
+        let res = py_runner(py_path.as_ref().unwrap(), "ruff", &args);
+
+        if res.is_err() && show_diff {
+            eprintln!("\npython linting failed! Printing diff suggestions:");
+
+            args.insert(0, "--diff".as_ref());
+            let _ = py_runner(py_path.as_ref().unwrap(), "ruff", &args);
+        }
+        // Rethrow error
+        let _ = res?;
+    }
+
+    if python_fmt {
+        let mut cfg_args_black = cfg_args.clone();
+        let mut file_args_black = file_args.clone();
+
+        if bless {
+            eprintln!("formatting python files");
+        } else {
+            eprintln!("checking python file formatting");
+            cfg_args_black.push("--check".as_ref());
+        }
+
+        let mut cfg_path = root_path.to_owned();
+        cfg_path.extend(BLACK_CONFIG_PATH);
+
+        cfg_args_black.extend(["--config".as_ref(), cfg_path.as_os_str()]);
+
+        if file_args_black.is_empty() {
+            file_args_black.push(root_path.as_os_str());
+        }
+
+        let mut args = merge_args(&cfg_args_black, &file_args_black);
+        let res = py_runner(py_path.as_ref().unwrap(), "black", &args);
+
+        if res.is_err() && show_diff {
+            eprintln!("\npython formatting does not match! Printing diff:");
+
+            args.insert(0, "--diff".as_ref());
+            let _ = py_runner(py_path.as_ref().unwrap(), "black", &args);
+        }
+        // Rethrow error
+        let _ = res?;
+    }
+
+    if shell_lint {
+        eprintln!("linting shell files");
+
+        let mut file_args_shc = file_args.clone();
+        let files;
+        if file_args_shc.is_empty() {
+            files = find_with_extension(root_path, "sh")?;
+            file_args_shc.extend(files.iter().map(|p| p.as_os_str()));
+        }
+
+        shellcheck_runner(&merge_args(&cfg_args, &file_args_shc))?;
+    }
+
+    Ok(())
+}
+
+/// Helper to create `cfg1 cfg2 -- file1 file2` output
+fn merge_args<'a>(cfg_args: &[&'a OsStr], file_args: &[&'a OsStr]) -> Vec<&'a OsStr> {
+    let mut args = cfg_args.to_owned();
+    args.push("--".as_ref());
+    args.extend(file_args);
+    args
+}
+
+/// Run a python command with given arguments. `py_path` should be a virtualenv.
+fn py_runner(py_path: &Path, bin: &'static str, args: &[&OsStr]) -> Result<(), Error> {
+    let status = Command::new(py_path).arg("-m").arg(bin).args(args).status()?;
+    if status.success() { Ok(()) } else { Err(Error::FailedCheck(bin)) }
+}
+
+/// Create a virtuaenv at a given path if it doesn't already exist, or validate
+/// the install if it does. Returns the path to that venv's python executable.
+fn get_or_create_venv(venv_path: &Path, src_reqs_path: &Path) -> Result<PathBuf, Error> {
+    let mut should_create = true;
+    let dst_reqs_path = venv_path.join("requirements.txt");
+    let mut py_path = venv_path.to_owned();
+    py_path.extend(REL_PY_PATH);
+
+    if let Ok(req) = fs::read_to_string(&dst_reqs_path) {
+        if req == fs::read_to_string(src_reqs_path)? {
+            // found existing environment
+            should_create = false;
+        } else {
+            eprintln!("requirements.txt file mismatch, recreating environment");
+        }
+    }
+
+    if should_create {
+        eprintln!("removing old virtual environment");
+        if venv_path.is_dir() {
+            fs::remove_dir_all(venv_path).unwrap_or_else(|_| {
+                panic!("failed to remove directory at {}", venv_path.display())
+            });
+        }
+        create_venv_at_path(venv_path)?;
+        install_requirements(&py_path, src_reqs_path, &dst_reqs_path)?;
+    }
+
+    verify_py_version(&py_path)?;
+    Ok(py_path)
+}
+
+/// Attempt to create a virtualenv at this path. Cycles through all expected
+/// valid python versions to find one that is installed.
+fn create_venv_at_path(path: &Path) -> Result<(), Error> {
+    /// Preferred python versions in order. Newest to oldest then current
+    /// development versions
+    const TRY_PY: &[&str] = &[
+        "python3.11",
+        "python3.10",
+        "python3.9",
+        "python3.8",
+        "python3.7",
+        "python3",
+        "python",
+        "python3.12",
+        "python3.13",
+    ];
+
+    let mut sys_py = None;
+    let mut found = Vec::new();
+
+    for py in TRY_PY {
+        match verify_py_version(Path::new(py)) {
+            Ok(_) => {
+                sys_py = Some(*py);
+                break;
+            }
+            // Skip not found errors
+            Err(Error::Io(e)) if e.kind() == io::ErrorKind::NotFound => (),
+            // Skip insufficient version errors
+            Err(Error::Version { installed, .. }) => found.push(installed),
+            // just log and skip unrecognized errors
+            Err(e) => eprintln!("note: error running '{py}': {e}"),
+        }
+    }
+
+    let Some(sys_py) = sys_py else {
+        let ret = if found.is_empty() {
+            Error::MissingReq("python3", "python file checks", None)
+        } else {
+            found.sort();
+            found.dedup();
+            Error::Version {
+                program: "python3",
+                required: MIN_PY_REV_STR,
+                installed: found.join(", "),
+            }
+        };
+        return Err(ret);
+    };
+
+    eprintln!("creating virtual environment at '{}' using '{sys_py}'", path.display());
+    let out = Command::new(sys_py).args(["-m", "virtualenv"]).arg(path).output().unwrap();
+
+    if out.status.success() {
+        return Ok(());
+    }
+    let err = if String::from_utf8_lossy(&out.stderr).contains("No module named virtualenv") {
+        Error::Generic(format!(
+            "virtualenv not found: you may need to install it \
+                               (`python3 -m pip install venv`)"
+        ))
+    } else {
+        Error::Generic(format!("failed to create venv at '{}' using {sys_py}", path.display()))
+    };
+    Err(err)
+}
+
+/// Parse python's version output (`Python x.y.z`) and ensure we have a
+/// suitable version.
+fn verify_py_version(py_path: &Path) -> Result<(), Error> {
+    let out = Command::new(py_path).arg("--version").output()?;
+    let outstr = String::from_utf8_lossy(&out.stdout);
+    let vers = outstr.trim().split_ascii_whitespace().nth(1).unwrap().trim();
+    let mut vers_comps = vers.split('.');
+    let major: u32 = vers_comps.next().unwrap().parse().unwrap();
+    let minor: u32 = vers_comps.next().unwrap().parse().unwrap();
+
+    if (major, minor) < MIN_PY_REV {
+        Err(Error::Version {
+            program: "python",
+            required: MIN_PY_REV_STR,
+            installed: vers.to_owned(),
+        })
+    } else {
+        Ok(())
+    }
+}
+
+fn install_requirements(
+    py_path: &Path,
+    src_reqs_path: &Path,
+    dst_reqs_path: &Path,
+) -> Result<(), Error> {
+    let stat = Command::new(py_path)
+        .args(["-m", "pip", "install", "--upgrade", "pip"])
+        .status()
+        .expect("failed to launch pip");
+    if !stat.success() {
+        return Err(Error::Generic(format!("pip install failed with status {stat}")));
+    }
+
+    let stat = Command::new(py_path)
+        .args(["-m", "pip", "install", "--require-hashes", "-r"])
+        .arg(src_reqs_path)
+        .status()?;
+    if !stat.success() {
+        return Err(Error::Generic(format!(
+            "failed to install requirements at {}",
+            src_reqs_path.display()
+        )));
+    }
+    fs::copy(src_reqs_path, dst_reqs_path)?;
+    assert_eq!(
+        fs::read_to_string(src_reqs_path).unwrap(),
+        fs::read_to_string(dst_reqs_path).unwrap()
+    );
+    Ok(())
+}
+
+/// Check that shellcheck is installed then run it at the given path
+fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> {
+    match Command::new("shellcheck").arg("--version").status() {
+        Ok(_) => (),
+        Err(e) if e.kind() == io::ErrorKind::NotFound => {
+            return Err(Error::MissingReq(
+                "shellcheck",
+                "shell file checks",
+                Some(
+                    "see <https://github.com/koalaman/shellcheck#installing> \
+                    for installation instructions"
+                        .to_owned(),
+                ),
+            ));
+        }
+        Err(e) => return Err(e.into()),
+    }
+
+    let status = Command::new("shellcheck").args(args).status()?;
+    if status.success() { Ok(()) } else { Err(Error::FailedCheck("black")) }
+}
+
+/// Check git for tracked files matching an extension
+fn find_with_extension(root_path: &Path, extension: &str) -> Result<Vec<PathBuf>, Error> {
+    // Untracked files show up for short status and are indicated with a leading `?`
+    // -C changes git to be as if run from that directory
+    let stat_output =
+        Command::new("git").arg("-C").arg(root_path).args(["status", "--short"]).output()?.stdout;
+
+    if String::from_utf8_lossy(&stat_output).lines().filter(|ln| ln.starts_with('?')).count() > 0 {
+        eprintln!("found untracked files, ignoring");
+    }
+
+    let mut output = Vec::new();
+    let binding = Command::new("git").arg("-C").arg(root_path).args(["ls-files"]).output()?;
+    let tracked = String::from_utf8_lossy(&binding.stdout);
+
+    for line in tracked.lines() {
+        let line = line.trim();
+        let path = Path::new(line);
+
+        if path.extension() == Some(OsStr::new(extension)) {
+            output.push(path.to_owned());
+        }
+    }
+
+    Ok(output)
+}
+
+#[derive(Debug)]
+enum Error {
+    Io(io::Error),
+    /// a is required to run b. c is extra info
+    MissingReq(&'static str, &'static str, Option<String>),
+    /// Tool x failed the check
+    FailedCheck(&'static str),
+    /// Any message, just print it
+    Generic(String),
+    /// Installed but wrong version
+    Version {
+        program: &'static str,
+        required: &'static str,
+        installed: String,
+    },
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::MissingReq(a, b, ex) => {
+                write!(
+                    f,
+                    "{a} is required to run {b} but it could not be located. Is it installed?"
+                )?;
+                if let Some(s) = ex {
+                    write!(f, "\n{s}")?;
+                };
+                Ok(())
+            }
+            Self::Version { program, required, installed } => write!(
+                f,
+                "insufficient version of '{program}' to run external tools: \
+                {required} required but found {installed}",
+            ),
+            Self::Generic(s) => f.write_str(s),
+            Self::Io(e) => write!(f, "IO error: {e}"),
+            Self::FailedCheck(s) => write!(f, "checks with external tool '{s}' failed"),
+        }
+    }
+}
+
+impl From<io::Error> for Error {
+    fn from(value: io::Error) -> Self {
+        Self::Io(value)
+    }
+}
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index e467514a7a3..9b19b8eecc7 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -57,6 +57,7 @@ pub mod debug_artifacts;
 pub mod deps;
 pub mod edition;
 pub mod error_codes;
+pub mod ext_tool_checks;
 pub mod extdeps;
 pub mod features;
 pub mod fluent_alphabetical;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index e21068490b6..5fa91715a07 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -37,9 +37,14 @@ fn main() {
     let librustdoc_path = src_path.join("librustdoc");
 
     let args: Vec<String> = env::args().skip(1).collect();
-
-    let verbose = args.iter().any(|s| *s == "--verbose");
-    let bless = args.iter().any(|s| *s == "--bless");
+    let (cfg_args, pos_args) = match args.iter().position(|arg| arg == "--") {
+        Some(pos) => (&args[..pos], &args[pos + 1..]),
+        None => (&args[..], [].as_slice()),
+    };
+    let verbose = cfg_args.iter().any(|s| *s == "--verbose");
+    let bless = cfg_args.iter().any(|s| *s == "--bless");
+    let extra_checks =
+        cfg_args.iter().find(|s| s.starts_with("--extra-checks=")).map(String::as_str);
 
     let bad = std::sync::Arc::new(AtomicBool::new(false));
 
@@ -150,6 +155,8 @@ fn main() {
             r
         };
         check!(unstable_book, &src_path, collected);
+
+        check!(ext_tool_checks, &root_path, &output_directory, bless, extra_checks, pos_args);
     });
 
     if bad.load(Ordering::Relaxed) {
diff --git a/tests/run-make/optimization-remarks-dir-pgo/Makefile b/tests/run-make/optimization-remarks-dir-pgo/Makefile
new file mode 100644
index 00000000000..c88ec1e6cb3
--- /dev/null
+++ b/tests/run-make/optimization-remarks-dir-pgo/Makefile
@@ -0,0 +1,20 @@
+# needs-profiler-support
+# ignore-windows-gnu
+
+# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+# properly. Since we only have GCC on the CI ignore the test for now.
+
+include ../tools.mk
+
+PROFILE_DIR=$(TMPDIR)/profiles
+
+check_hotness:
+	$(RUSTC) -Cprofile-generate="$(TMPDIR)"/profdata -O foo.rs -o$(TMPDIR)/foo
+	$(TMPDIR)/foo
+	"$(LLVM_BIN_DIR)"/llvm-profdata merge \
+		-o "$(TMPDIR)"/merged.profdata \
+		"$(TMPDIR)"/profdata/*.profraw
+	$(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata -O foo.rs -Cremark=all -Zremark-dir=$(PROFILE_DIR)
+
+	# Check that PGO hotness is included in the remark files
+	cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "Hotness"
diff --git a/tests/run-make/optimization-remarks-dir-pgo/foo.rs b/tests/run-make/optimization-remarks-dir-pgo/foo.rs
new file mode 100644
index 00000000000..f7ca1826338
--- /dev/null
+++ b/tests/run-make/optimization-remarks-dir-pgo/foo.rs
@@ -0,0 +1,6 @@
+#[inline(never)]
+pub fn bar() {}
+
+fn main() {
+    bar();
+}
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index 2ee4bce1015..0789d785f58 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -46,53 +46,53 @@ call-function: (
     "check-colors",
     {
         "theme": "ayu",
-        "mod": "rgb(57, 175, 215)",
-        "macro": "rgb(163, 122, 204)",
-        "struct": "rgb(255, 160, 165)",
-        "enum": "rgb(255, 160, 165)",
-        "trait": "rgb(57, 175, 215)",
-        "fn": "rgb(253, 214, 135)",
-        "type": "rgb(255, 160, 165)",
-        "union": "rgb(255, 160, 165)",
-        "keyword": "rgb(57, 175, 215)",
-        "sidebar": "rgb(83, 177, 219)",
-        "sidebar_current": "rgb(255, 180, 76)",
-        "sidebar_current_background": "rgba(0, 0, 0, 0)",
+        "mod": "#39afd7",
+        "macro": "#a37acc",
+        "struct": "#ffa0a5",
+        "enum": "#ffa0a5",
+        "trait": "#39afd7",
+        "fn": "#fdd687",
+        "type": "#ffa0a5",
+        "union": "#ffa0a5",
+        "keyword": "#39afd7",
+        "sidebar": "#53b1db",
+        "sidebar_current": "#ffb44c",
+        "sidebar_current_background": "transparent",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "dark",
-        "mod": "rgb(210, 153, 29)",
-        "macro": "rgb(9, 189, 0)",
-        "struct": "rgb(45, 191, 184)",
-        "enum": "rgb(45, 191, 184)",
-        "trait": "rgb(183, 140, 242)",
-        "fn": "rgb(43, 171, 99)",
-        "type": "rgb(45, 191, 184)",
-        "union": "rgb(45, 191, 184)",
-        "keyword": "rgb(210, 153, 29)",
-        "sidebar": "rgb(253, 191, 53)",
-        "sidebar_current": "rgb(253, 191, 53)",
-        "sidebar_current_background": "rgb(68, 68, 68)",
+        "mod": "#d2991d",
+        "macro": "#09bd00",
+        "struct": "#2dbfb8",
+        "enum": "#2dbfb8",
+        "trait": "#b78cf2",
+        "fn": "#2bab63",
+        "type": "#2dbfb8",
+        "union": "#2dbfb8",
+        "keyword": "#d2991d",
+        "sidebar": "#fdbf35",
+        "sidebar_current": "#fdbf35",
+        "sidebar_current_background": "#444",
     },
 )
 call-function: (
     "check-colors",
     {
         "theme": "light",
-        "mod": "rgb(56, 115, 173)",
-        "macro": "rgb(6, 128, 0)",
-        "struct": "rgb(173, 55, 138)",
-        "enum": "rgb(173, 55, 138)",
-        "trait": "rgb(110, 79, 201)",
-        "fn": "rgb(173, 124, 55)",
-        "type": "rgb(173, 55, 138)",
-        "union": "rgb(173, 55, 138)",
-        "keyword": "rgb(56, 115, 173)",
-        "sidebar": "rgb(53, 109, 164)",
-        "sidebar_current": "rgb(53, 109, 164)",
-        "sidebar_current_background": "rgb(255, 255, 255)",
+        "mod": "#3873ad",
+        "macro": "#068000",
+        "struct": "#ad378a",
+        "enum": "#ad378a",
+        "trait": "#6e4fc9",
+        "fn": "#ad7c37",
+        "type": "#ad378a",
+        "union": "#ad378a",
+        "keyword": "#3873ad",
+        "sidebar": "#356da4",
+        "sidebar_current": "#356da4",
+        "sidebar_current_background": "#fff",
     },
 )
diff --git a/tests/rustdoc-json/enums/field_order.rs b/tests/rustdoc-json/enums/field_order.rs
new file mode 100644
index 00000000000..e89add9cbbd
--- /dev/null
+++ b/tests/rustdoc-json/enums/field_order.rs
@@ -0,0 +1,40 @@
+// Check that the order of fields is preserved.
+
+pub enum Whatever {
+    Foo {
+        // Important: random prefixes are used here to ensure that
+        // sorting fields by name would cause this test to fail.
+        ews_0: i32,
+        dik_1: i32,
+        hsk_2: i32,
+        djt_3: i32,
+        jnr_4: i32,
+        dfs_5: i32,
+        bja_6: i32,
+        lyc_7: i32,
+        yqd_8: i32,
+        vll_9: i32,
+    },
+}
+
+// @set 0 = '$.index[*][?(@.name == "ews_0")].id'
+// @set 1 = '$.index[*][?(@.name == "dik_1")].id'
+// @set 2 = '$.index[*][?(@.name == "hsk_2")].id'
+// @set 3 = '$.index[*][?(@.name == "djt_3")].id'
+// @set 4 = '$.index[*][?(@.name == "jnr_4")].id'
+// @set 5 = '$.index[*][?(@.name == "dfs_5")].id'
+// @set 6 = '$.index[*][?(@.name == "bja_6")].id'
+// @set 7 = '$.index[*][?(@.name == "lyc_7")].id'
+// @set 8 = '$.index[*][?(@.name == "yqd_8")].id'
+// @set 9 = '$.index[*][?(@.name == "vll_9")].id'
+
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[0]' $0
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[1]' $1
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[2]' $2
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[3]' $3
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[4]' $4
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[5]' $5
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[6]' $6
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[7]' $7
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[8]' $8
+// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[9]' $9
diff --git a/tests/rustdoc-json/enums/variant_order.rs b/tests/rustdoc-json/enums/variant_order.rs
new file mode 100644
index 00000000000..17ca96213de
--- /dev/null
+++ b/tests/rustdoc-json/enums/variant_order.rs
@@ -0,0 +1,38 @@
+// Check that the order of variants is preserved.
+
+pub enum Foo {
+    // Important: random prefixes are used here to ensure that
+    // sorting fields by name would cause this test to fail.
+    Ews0,
+    Dik1,
+    Hsk2,
+    Djt3,
+    Jnr4,
+    Dfs5,
+    Bja6,
+    Lyc7,
+    Yqd8,
+    Vll9,
+}
+
+// @set 0 = '$.index[*][?(@.name == "Ews0")].id'
+// @set 1 = '$.index[*][?(@.name == "Dik1")].id'
+// @set 2 = '$.index[*][?(@.name == "Hsk2")].id'
+// @set 3 = '$.index[*][?(@.name == "Djt3")].id'
+// @set 4 = '$.index[*][?(@.name == "Jnr4")].id'
+// @set 5 = '$.index[*][?(@.name == "Dfs5")].id'
+// @set 6 = '$.index[*][?(@.name == "Bja6")].id'
+// @set 7 = '$.index[*][?(@.name == "Lyc7")].id'
+// @set 8 = '$.index[*][?(@.name == "Yqd8")].id'
+// @set 9 = '$.index[*][?(@.name == "Vll9")].id'
+
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[0]' $0
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[1]' $1
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[2]' $2
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[3]' $3
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[4]' $4
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[5]' $5
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[6]' $6
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[7]' $7
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[8]' $8
+// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[9]' $9
diff --git a/tests/rustdoc-json/structs/field_order.rs b/tests/rustdoc-json/structs/field_order.rs
new file mode 100644
index 00000000000..a8c18323d52
--- /dev/null
+++ b/tests/rustdoc-json/structs/field_order.rs
@@ -0,0 +1,38 @@
+// Check that the order of fields is preserved.
+
+pub struct Foo {
+    // Important: random prefixes are used here to ensure that
+    // sorting fields by name would cause this test to fail.
+    pub ews_0: i32,
+    pub dik_1: i32,
+    pub hsk_2: i32,
+    pub djt_3: i32,
+    pub jnr_4: i32,
+    pub dfs_5: i32,
+    pub bja_6: i32,
+    pub lyc_7: i32,
+    pub yqd_8: i32,
+    pub vll_9: i32,
+}
+
+// @set 0 = '$.index[*][?(@.name == "ews_0")].id'
+// @set 1 = '$.index[*][?(@.name == "dik_1")].id'
+// @set 2 = '$.index[*][?(@.name == "hsk_2")].id'
+// @set 3 = '$.index[*][?(@.name == "djt_3")].id'
+// @set 4 = '$.index[*][?(@.name == "jnr_4")].id'
+// @set 5 = '$.index[*][?(@.name == "dfs_5")].id'
+// @set 6 = '$.index[*][?(@.name == "bja_6")].id'
+// @set 7 = '$.index[*][?(@.name == "lyc_7")].id'
+// @set 8 = '$.index[*][?(@.name == "yqd_8")].id'
+// @set 9 = '$.index[*][?(@.name == "vll_9")].id'
+
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[0]' $0
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[1]' $1
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[2]' $2
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[3]' $3
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[4]' $4
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[5]' $5
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[6]' $6
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[7]' $7
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[8]' $8
+// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[9]' $9
diff --git a/tests/rustdoc-json/unions/field_order.rs b/tests/rustdoc-json/unions/field_order.rs
new file mode 100644
index 00000000000..8a40bda0399
--- /dev/null
+++ b/tests/rustdoc-json/unions/field_order.rs
@@ -0,0 +1,38 @@
+// Check that the order of fields is preserved.
+
+pub union Foo {
+    // Important: random prefixes are used here to ensure that
+    // sorting fields by name would cause this test to fail.
+    pub ews_0: i32,
+    pub dik_1: i32,
+    pub hsk_2: i32,
+    pub djt_3: i32,
+    pub jnr_4: i32,
+    pub dfs_5: i32,
+    pub bja_6: i32,
+    pub lyc_7: i32,
+    pub yqd_8: i32,
+    pub vll_9: i32,
+}
+
+// @set 0 = '$.index[*][?(@.name == "ews_0")].id'
+// @set 1 = '$.index[*][?(@.name == "dik_1")].id'
+// @set 2 = '$.index[*][?(@.name == "hsk_2")].id'
+// @set 3 = '$.index[*][?(@.name == "djt_3")].id'
+// @set 4 = '$.index[*][?(@.name == "jnr_4")].id'
+// @set 5 = '$.index[*][?(@.name == "dfs_5")].id'
+// @set 6 = '$.index[*][?(@.name == "bja_6")].id'
+// @set 7 = '$.index[*][?(@.name == "lyc_7")].id'
+// @set 8 = '$.index[*][?(@.name == "yqd_8")].id'
+// @set 9 = '$.index[*][?(@.name == "vll_9")].id'
+
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[0]' $0
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[1]' $1
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[2]' $2
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[3]' $3
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[4]' $4
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[5]' $5
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[6]' $6
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[7]' $7
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[8]' $8
+// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[9]' $9
diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr
new file mode 100644
index 00000000000..02082c13f91
--- /dev/null
+++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr
@@ -0,0 +1,27 @@
+error[E0703]: invalid ABI: found `riscv-interrupt`
+  --> $DIR/riscv-discoverability-guidance.rs:17:8
+   |
+LL | extern "riscv-interrupt" fn isr() {}
+   |        ^^^^^^^^^^^^^^^^^
+   |        |
+   |        invalid ABI
+   |        help: did you mean: `"riscv-interrupt-m"`
+   |
+   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
+   = note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively
+
+error[E0703]: invalid ABI: found `riscv-interrupt-u`
+  --> $DIR/riscv-discoverability-guidance.rs:23:8
+   |
+LL | extern "riscv-interrupt-u" fn isr_U() {}
+   |        ^^^^^^^^^^^^^^^^^^^
+   |        |
+   |        invalid ABI
+   |        help: did you mean: `"riscv-interrupt-m"`
+   |
+   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
+   = note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0703`.
diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr
new file mode 100644
index 00000000000..02082c13f91
--- /dev/null
+++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr
@@ -0,0 +1,27 @@
+error[E0703]: invalid ABI: found `riscv-interrupt`
+  --> $DIR/riscv-discoverability-guidance.rs:17:8
+   |
+LL | extern "riscv-interrupt" fn isr() {}
+   |        ^^^^^^^^^^^^^^^^^
+   |        |
+   |        invalid ABI
+   |        help: did you mean: `"riscv-interrupt-m"`
+   |
+   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
+   = note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively
+
+error[E0703]: invalid ABI: found `riscv-interrupt-u`
+  --> $DIR/riscv-discoverability-guidance.rs:23:8
+   |
+LL | extern "riscv-interrupt-u" fn isr_U() {}
+   |        ^^^^^^^^^^^^^^^^^^^
+   |        |
+   |        invalid ABI
+   |        help: did you mean: `"riscv-interrupt-m"`
+   |
+   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
+   = note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0703`.
diff --git a/tests/ui/abi/riscv-discoverability-guidance.rs b/tests/ui/abi/riscv-discoverability-guidance.rs
new file mode 100644
index 00000000000..f57fcd6044f
--- /dev/null
+++ b/tests/ui/abi/riscv-discoverability-guidance.rs
@@ -0,0 +1,27 @@
+// ignore-tidy-linelength
+// revisions: riscv32 riscv64
+//
+// [riscv32] needs-llvm-components: riscv
+// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib
+// [riscv64] needs-llvm-components: riscv
+// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib
+#![no_core]
+#![feature(
+    no_core,
+    lang_items,
+    abi_riscv_interrupt
+)]
+#[lang = "sized"]
+trait Sized {}
+
+extern "riscv-interrupt" fn isr() {}
+//~^ ERROR invalid ABI
+//~^^ NOTE invalid ABI
+//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+//~^^^^ NOTE please use one of riscv-interrupt-m or riscv-interrupt-s
+
+extern "riscv-interrupt-u" fn isr_U() {}
+//~^ ERROR invalid ABI
+//~^^ NOTE invalid ABI
+//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
+//~^^^^ NOTE user-mode interrupt handlers have been removed from LLVM pending standardization
diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr
index 980457eeab5..d7b4e6150ff 100644
--- a/tests/ui/abi/unsupported.aarch64.stderr
+++ b/tests/ui/abi/unsupported.aarch64.stderr
@@ -1,53 +1,59 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:25:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:27:1
+  --> $DIR/unsupported.rs:32:1
    |
 LL | extern "amdgpu-kernel" fn amdgpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:34:1
    |
 LL | extern "wasm" fn wasm() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:35:1
+  --> $DIR/unsupported.rs:42:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:37:1
+  --> $DIR/unsupported.rs:44:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:46:1
+   |
+LL | extern "riscv-interrupt-m" fn riscv() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:51:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:46:1
+  --> $DIR/unsupported.rs:62:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,6 +62,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 8 previous errors; 1 warning emitted
+error: aborting due to 9 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr
index 450abd94886..3a3ed2dd9c5 100644
--- a/tests/ui/abi/unsupported.arm.stderr
+++ b/tests/ui/abi/unsupported.arm.stderr
@@ -1,47 +1,53 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:25:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:27:1
+  --> $DIR/unsupported.rs:32:1
    |
 LL | extern "amdgpu-kernel" fn amdgpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:34:1
    |
 LL | extern "wasm" fn wasm() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:35:1
+  --> $DIR/unsupported.rs:42:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:37:1
+  --> $DIR/unsupported.rs:44:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:46:1
+   |
+LL | extern "riscv-interrupt-m" fn riscv() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:39:1
+  --> $DIR/unsupported.rs:51:1
    |
 LL | extern "x86-interrupt" fn x86() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:46:1
+  --> $DIR/unsupported.rs:62:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr
index 0340382a452..31b7d030bd3 100644
--- a/tests/ui/abi/unsupported.i686.stderr
+++ b/tests/ui/abi/unsupported.i686.stderr
@@ -1,39 +1,45 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:25:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:27:1
+  --> $DIR/unsupported.rs:32:1
    |
 LL | extern "amdgpu-kernel" fn amdgpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:34:1
    |
 LL | extern "wasm" fn wasm() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:35:1
+  --> $DIR/unsupported.rs:42:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:37:1
+  --> $DIR/unsupported.rs:44:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:46:1
+   |
+LL | extern "riscv-interrupt-m" fn riscv() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr
new file mode 100644
index 00000000000..1966e18f0a0
--- /dev/null
+++ b/tests/ui/abi/unsupported.riscv32.stderr
@@ -0,0 +1,61 @@
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:30:1
+   |
+LL | extern "ptx-kernel" fn ptx() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:32:1
+   |
+LL | extern "amdgpu-kernel" fn amdgpu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"wasm"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:34:1
+   |
+LL | extern "wasm" fn wasm() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"aapcs"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:36:1
+   |
+LL | extern "aapcs" fn aapcs() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:42:1
+   |
+LL | extern "msp430-interrupt" fn msp430() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:44:1
+   |
+LL | extern "avr-interrupt" fn avr() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:51:1
+   |
+LL | extern "x86-interrupt" fn x86() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"thiscall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:56:1
+   |
+LL | extern "thiscall" fn thiscall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:62:1
+   |
+LL | extern "stdcall" fn stdcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #87678 <https://github.com/rust-lang/rust/issues/87678>
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+error: aborting due to 8 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr
new file mode 100644
index 00000000000..1966e18f0a0
--- /dev/null
+++ b/tests/ui/abi/unsupported.riscv64.stderr
@@ -0,0 +1,61 @@
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:30:1
+   |
+LL | extern "ptx-kernel" fn ptx() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:32:1
+   |
+LL | extern "amdgpu-kernel" fn amdgpu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"wasm"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:34:1
+   |
+LL | extern "wasm" fn wasm() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"aapcs"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:36:1
+   |
+LL | extern "aapcs" fn aapcs() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:42:1
+   |
+LL | extern "msp430-interrupt" fn msp430() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:44:1
+   |
+LL | extern "avr-interrupt" fn avr() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:51:1
+   |
+LL | extern "x86-interrupt" fn x86() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"thiscall"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:56:1
+   |
+LL | extern "thiscall" fn thiscall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:62:1
+   |
+LL | extern "stdcall" fn stdcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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 #87678 <https://github.com/rust-lang/rust/issues/87678>
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+
+error: aborting due to 8 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs
index bcd95f1ed4c..57278e664b5 100644
--- a/tests/ui/abi/unsupported.rs
+++ b/tests/ui/abi/unsupported.rs
@@ -1,4 +1,4 @@
-// revisions: x64 i686 aarch64 arm
+// revisions: x64 i686 aarch64 arm riscv32 riscv64
 //
 // [x64] needs-llvm-components: x86
 // [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
@@ -8,6 +8,10 @@
 // [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=rlib
 // [arm] needs-llvm-components: arm
 // [arm] compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib
+// [riscv32] needs-llvm-components: riscv
+// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib
+// [riscv64] needs-llvm-components: riscv
+// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib
 #![no_core]
 #![feature(
     no_core,
@@ -17,10 +21,11 @@
     abi_avr_interrupt,
     abi_amdgpu_kernel,
     wasm_abi,
-    abi_x86_interrupt
+    abi_x86_interrupt,
+    abi_riscv_interrupt
 )]
-#[lang="sized"]
-trait Sized { }
+#[lang = "sized"]
+trait Sized {}
 
 extern "ptx-kernel" fn ptx() {}
 //~^ ERROR is not a supported ABI
@@ -32,21 +37,36 @@ extern "aapcs" fn aapcs() {}
 //[x64]~^ ERROR is not a supported ABI
 //[i686]~^^ ERROR is not a supported ABI
 //[aarch64]~^^^ ERROR is not a supported ABI
+//[riscv32]~^^^^ ERROR is not a supported ABI
+//[riscv64]~^^^^^ ERROR is not a supported ABI
 extern "msp430-interrupt" fn msp430() {}
 //~^ ERROR is not a supported ABI
 extern "avr-interrupt" fn avr() {}
 //~^ ERROR is not a supported ABI
+extern "riscv-interrupt-m" fn riscv() {}
+//[arm]~^ ERROR is not a supported ABI
+//[x64]~^^ ERROR is not a supported ABI
+//[i686]~^^^ ERROR is not a supported ABI
+//[aarch64]~^^^^ ERROR is not a supported ABI
 extern "x86-interrupt" fn x86() {}
 //[aarch64]~^ ERROR is not a supported ABI
 //[arm]~^^ ERROR is not a supported ABI
+//[riscv32]~^^^ ERROR is not a supported ABI
+//[riscv64]~^^^^ ERROR is not a supported ABI
 extern "thiscall" fn thiscall() {}
 //[x64]~^ ERROR is not a supported ABI
-//[aarch64]~^^ ERROR is not a supported ABI
-//[arm]~^^^ ERROR is not a supported ABI
+//[arm]~^^ ERROR is not a supported ABI
+//[aarch64]~^^^ ERROR is not a supported ABI
+//[riscv32]~^^^^ ERROR is not a supported ABI
+//[riscv64]~^^^^^ ERROR is not a supported ABI
 extern "stdcall" fn stdcall() {}
 //[x64]~^ WARN use of calling convention not supported
 //[x64]~^^ WARN this was previously accepted
-//[aarch64]~^^^ WARN use of calling convention not supported
-//[aarch64]~^^^^ WARN this was previously accepted
-//[arm]~^^^^^ WARN use of calling convention not supported
-//[arm]~^^^^^^ WARN this was previously accepted
+//[arm]~^^^ WARN use of calling convention not supported
+//[arm]~^^^^ WARN this was previously accepted
+//[aarch64]~^^^^^ WARN use of calling convention not supported
+//[aarch64]~^^^^^^ WARN this was previously accepted
+//[riscv32]~^^^^^^^ WARN use of calling convention not supported
+//[riscv32]~^^^^^^^^ WARN this was previously accepted
+//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported
+//[riscv64]~^^^^^^^^^^ WARN this was previously accepted
diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr
index 29eed8505b9..ea62cb15148 100644
--- a/tests/ui/abi/unsupported.x64.stderr
+++ b/tests/ui/abi/unsupported.x64.stderr
@@ -1,47 +1,53 @@
 error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:25:1
+  --> $DIR/unsupported.rs:30:1
    |
 LL | extern "ptx-kernel" fn ptx() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:27:1
+  --> $DIR/unsupported.rs:32:1
    |
 LL | extern "amdgpu-kernel" fn amdgpu() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"wasm"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:29:1
+  --> $DIR/unsupported.rs:34:1
    |
 LL | extern "wasm" fn wasm() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"aapcs"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:31:1
+  --> $DIR/unsupported.rs:36:1
    |
 LL | extern "aapcs" fn aapcs() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:35:1
+  --> $DIR/unsupported.rs:42:1
    |
 LL | extern "msp430-interrupt" fn msp430() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:37:1
+  --> $DIR/unsupported.rs:44:1
    |
 LL | extern "avr-interrupt" fn avr() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:46:1
+   |
+LL | extern "riscv-interrupt-m" fn riscv() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0570]: `"thiscall"` is not a supported ABI for the current target
-  --> $DIR/unsupported.rs:42:1
+  --> $DIR/unsupported.rs:56:1
    |
 LL | extern "thiscall" fn thiscall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of calling convention not supported on this target
-  --> $DIR/unsupported.rs:46:1
+  --> $DIR/unsupported.rs:62:1
    |
 LL | extern "stdcall" fn stdcall() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {}
    = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
    = note: `#[warn(unsupported_calling_conventions)]` on by default
 
-error: aborting due to 7 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0570`.
diff --git a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
index c23e54594ee..e7e7eac68a7 100644
--- a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
+++ b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
@@ -5,6 +5,7 @@ LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8
    |                                    ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
+   = note: consider using `std::sync::Arc<<<Self as Case1>::C as Iterator>::Item>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 help: consider further restricting the associated type
    |
 LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
@@ -29,6 +30,7 @@ LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8
    |                                                                                             ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
+   = note: consider using `std::sync::Arc<<<Self as Case1>::C as Iterator>::Item>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 help: consider further restricting the associated type
    |
 LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {
diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr
index c2da4f57696..c34a5161299 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr
@@ -14,6 +14,7 @@ LL |     is_send(foo::<T>());
    |             ^^^^^^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>>`
+   = note: consider using `std::sync::Arc<impl Future<Output = Result<(), ()>>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/basic.rs:13:5
    |
diff --git a/tests/ui/async-await/async-await-let-else.drop_tracking.stderr b/tests/ui/async-await/async-await-let-else.drop_tracking.stderr
index dee90262fd4..b74dec64de3 100644
--- a/tests/ui/async-await/async-await-let-else.drop_tracking.stderr
+++ b/tests/ui/async-await/async-await-let-else.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     is_send(foo(Some(true)));
    |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:11:15
    |
@@ -32,6 +33,7 @@ LL |     is_send(foo2(Some(true)));
    |     required by a bound introduced by this call
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it's used within this `async fn` body
   --> $DIR/async-await-let-else.rs:27:29
    |
@@ -64,6 +66,7 @@ LL |     is_send(foo3(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:33:29
    |
@@ -85,6 +88,7 @@ LL |     is_send(foo4(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:41:15
    |
diff --git a/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr b/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr
index e3fcceaa392..26881781c95 100644
--- a/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     is_send(foo(Some(true)));
    |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:11:15
    |
@@ -30,6 +31,7 @@ LL |     is_send(foo2(Some(true)));
    |     required by a bound introduced by this call
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it's used within this `async fn` body
   --> $DIR/async-await-let-else.rs:27:29
    |
@@ -62,6 +64,7 @@ LL |     is_send(foo3(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:33:29
    |
@@ -82,6 +85,7 @@ LL |     is_send(foo4(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:41:15
    |
diff --git a/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr b/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr
index ece4e51ecff..8a1215159e5 100644
--- a/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr
+++ b/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     is_send(foo(Some(true)));
    |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:11:15
    |
@@ -27,6 +28,7 @@ LL |     is_send(foo2(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo2` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:23:27
    |
@@ -49,6 +51,7 @@ LL |     is_send(foo3(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:33:29
    |
@@ -70,6 +73,7 @@ LL |     is_send(foo4(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-await-let-else.rs:41:15
    |
diff --git a/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr b/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr
index 0515edaeda3..6677b4d9bac 100644
--- a/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr
+++ b/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(non_send_temporary_in_match());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:36:26
    |
@@ -28,6 +29,7 @@ LL |     assert_send(non_sync_with_method_call());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
+   = note: consider using `std::sync::Arc<dyn std::fmt::Write>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:49:15
    |
diff --git a/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr
index 219945e0971..c03e9e56f3e 100644
--- a/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(non_send_temporary_in_match());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:36:26
    |
@@ -25,6 +26,7 @@ LL |     assert_send(non_sync_with_method_call());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
+   = note: consider using `std::sync::Arc<dyn std::fmt::Write>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:49:15
    |
diff --git a/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr
index b29d2e192f4..b182cf0c966 100644
--- a/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr
+++ b/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(local_dropped_before_await());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `local_dropped_before_await` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:27:11
    |
@@ -28,6 +29,7 @@ LL |     assert_send(non_send_temporary_in_match());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:36:26
    |
@@ -51,6 +53,7 @@ LL |     assert_send(non_sync_with_method_call());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
+   = note: consider using `std::sync::Arc<dyn std::fmt::Write>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:49:15
    |
@@ -75,6 +78,7 @@ LL |     assert_send(non_sync_with_method_call_panic());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call_panic` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
+   = note: consider using `std::sync::Arc<dyn std::fmt::Write>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:56:15
    |
@@ -99,6 +103,7 @@ LL |     assert_send(non_sync_with_method_call_infinite_loop());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call_infinite_loop` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
+   = note: consider using `std::sync::Arc<dyn std::fmt::Write>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:63:15
    |
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr
index 80402d8424d..90e97e7438e 100644
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr
+++ b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/drop-track-field-assign-nonsend.rs:23:39
    |
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr
index d9141cf4e36..42dcd65609d 100644
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/drop-track-field-assign-nonsend.rs:23:39
    |
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr
index 80402d8424d..90e97e7438e 100644
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr
+++ b/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/drop-track-field-assign-nonsend.rs:23:39
    |
diff --git a/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr b/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr
index e2e64c9ae0c..b6ff839aefa 100644
--- a/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr
+++ b/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/field-assign-nonsend.rs:23:39
    |
diff --git a/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr
index d1df8e91afa..c9888636e3c 100644
--- a/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/field-assign-nonsend.rs:23:39
    |
diff --git a/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr
index e2e64c9ae0c..b6ff839aefa 100644
--- a/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr
+++ b/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: future is not `Send` as this value is used across an await
   --> $DIR/field-assign-nonsend.rs:23:39
    |
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr
deleted file mode 100644
index b5ace9ada4f..00000000000
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28
-   |
-LL |     async fn foo(&self) -> i32 {
-   |                            ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
-   |
-note: type in trait
-  --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22
-   |
-LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
-              found signature `fn(&i32) -> impl Future<Output = i32>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr
deleted file mode 100644
index b5ace9ada4f..00000000000
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28
-   |
-LL |     async fn foo(&self) -> i32 {
-   |                            ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
-   |
-note: type in trait
-  --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22
-   |
-LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
-              found signature `fn(&i32) -> impl Future<Output = i32>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr
deleted file mode 100644
index 6c0b5859186..00000000000
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-boxed.rs:17:5
-   |
-LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
-...
-LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr
deleted file mode 100644
index 6c0b5859186..00000000000
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-boxed.rs:17:5
-   |
-LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
-...
-LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr
deleted file mode 100644
index 0d2551ab84f..00000000000
--- a/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-manual.rs:25:5
-   |
-LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
-...
-LL |     fn foo(&self) -> MyFuture {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr
deleted file mode 100644
index 0d2551ab84f..00000000000
--- a/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-manual.rs:25:5
-   |
-LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
-...
-LL |     fn foo(&self) -> MyFuture {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr
deleted file mode 100644
index 780da068962..00000000000
--- a/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error[E0311]: the parameter type `U` may not live long enough
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-   |
-note: the parameter type `U` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics-and-bounds.rs:14:18
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-
-error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-   |
-note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics-and-bounds.rs:14:18
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0311`.
diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr
deleted file mode 100644
index 780da068962..00000000000
--- a/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error[E0311]: the parameter type `U` may not live long enough
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-   |
-note: the parameter type `U` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics-and-bounds.rs:14:18
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-
-error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-   |
-note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics-and-bounds.rs:14:18
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics-and-bounds.rs:14:28
-   |
-LL |     async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
-   |                            ^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0311`.
diff --git a/tests/ui/async-await/in-trait/async-generics.current.stderr b/tests/ui/async-await/in-trait/async-generics.current.stderr
deleted file mode 100644
index 04e1ab6d769..00000000000
--- a/tests/ui/async-await/in-trait/async-generics.current.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error[E0311]: the parameter type `U` may not live long enough
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-   |
-note: the parameter type `U` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics.rs:11:18
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-
-error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-   |
-note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics.rs:11:18
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0311`.
diff --git a/tests/ui/async-await/in-trait/async-generics.next.stderr b/tests/ui/async-await/in-trait/async-generics.next.stderr
deleted file mode 100644
index 04e1ab6d769..00000000000
--- a/tests/ui/async-await/in-trait/async-generics.next.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error[E0311]: the parameter type `U` may not live long enough
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-   |
-note: the parameter type `U` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics.rs:11:18
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-
-error[E0311]: the parameter type `T` may not live long enough
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-   |
-note: the parameter type `T` must be valid for the anonymous lifetime defined here...
-  --> $DIR/async-generics.rs:11:18
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                  ^^^^^
-note: ...so that the reference type `&(T, U)` does not outlive the data it points at
-  --> $DIR/async-generics.rs:11:28
-   |
-LL |     async fn foo(&self) -> &(T, U);
-   |                            ^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0311`.
diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr
deleted file mode 100644
index 67b491f19d2..00000000000
--- a/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/async-recursive-generic.rs:13:48
-   |
-LL |     async fn foo_recursive(&self, n: usize) -> T {
-   |                                                ^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr
deleted file mode 100644
index 67b491f19d2..00000000000
--- a/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/async-recursive-generic.rs:13:48
-   |
-LL |     async fn foo_recursive(&self, n: usize) -> T {
-   |                                                ^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/in-trait/async-recursive.current.stderr b/tests/ui/async-await/in-trait/async-recursive.current.stderr
deleted file mode 100644
index 85af27e3746..00000000000
--- a/tests/ui/async-await/in-trait/async-recursive.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/async-recursive.rs:13:48
-   |
-LL |     async fn foo_recursive(&self, n: usize) -> i32 {
-   |                                                ^^^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/in-trait/async-recursive.next.stderr b/tests/ui/async-await/in-trait/async-recursive.next.stderr
deleted file mode 100644
index 85af27e3746..00000000000
--- a/tests/ui/async-await/in-trait/async-recursive.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/async-recursive.rs:13:48
-   |
-LL |     async fn foo_recursive(&self, n: usize) -> i32 {
-   |                                                ^^^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/in-trait/bad-signatures.current.stderr b/tests/ui/async-await/in-trait/bad-signatures.current.stderr
deleted file mode 100644
index ae590fb057f..00000000000
--- a/tests/ui/async-await/in-trait/bad-signatures.current.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: expected identifier, found keyword `self`
-  --> $DIR/bad-signatures.rs:8:23
-   |
-LL |     async fn bar(&abc self);
-   |                       ^^^^ expected identifier, found keyword
-
-error: expected one of `:`, `@`, or `|`, found keyword `self`
-  --> $DIR/bad-signatures.rs:8:23
-   |
-LL |     async fn bar(&abc self);
-   |                  -----^^^^
-   |                  |    |
-   |                  |    expected one of `:`, `@`, or `|`
-   |                  help: declare the type after the parameter binding: `<identifier>: <type>`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/async-await/in-trait/bad-signatures.next.stderr b/tests/ui/async-await/in-trait/bad-signatures.next.stderr
deleted file mode 100644
index ae590fb057f..00000000000
--- a/tests/ui/async-await/in-trait/bad-signatures.next.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error: expected identifier, found keyword `self`
-  --> $DIR/bad-signatures.rs:8:23
-   |
-LL |     async fn bar(&abc self);
-   |                       ^^^^ expected identifier, found keyword
-
-error: expected one of `:`, `@`, or `|`, found keyword `self`
-  --> $DIR/bad-signatures.rs:8:23
-   |
-LL |     async fn bar(&abc self);
-   |                  -----^^^^
-   |                  |    |
-   |                  |    expected one of `:`, `@`, or `|`
-   |                  help: declare the type after the parameter binding: `<identifier>: <type>`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr
deleted file mode 100644
index eec5ab06539..00000000000
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: async associated function in trait cannot be specialized
-  --> $DIR/dont-project-to-specializable-projection.rs:16:5
-   |
-LL |     default async fn foo(_: T) -> &'static str {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr
deleted file mode 100644
index 25a7f3bb56a..00000000000
--- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/dont-project-to-specializable-projection.rs:16:35
-   |
-LL |     default async fn foo(_: T) -> &'static str {
-   |                                   ^^^^^^^^^^^^ expected associated type, found future
-   |
-note: type in trait
-  --> $DIR/dont-project-to-specializable-projection.rs:12:27
-   |
-LL |     async fn foo(_: T) -> &'static str;
-   |                           ^^^^^^^^^^^^
-   = note: expected signature `fn(_) -> impl Future<Output = &'static str>`
-              found signature `fn(_) -> impl Future<Output = &'static str>`
-
-error: async associated function in trait cannot be specialized
-  --> $DIR/dont-project-to-specializable-projection.rs:16:5
-   |
-LL |     default async fn foo(_: T) -> &'static str {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr
deleted file mode 100644
index 1a749514989..00000000000
--- a/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
-  --> $DIR/fn-not-async-err2.rs:15:22
-   |
-LL |     fn foo(&self) -> impl Future<Output = i32> {
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
-   = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr
deleted file mode 100644
index 1a749514989..00000000000
--- a/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
-  --> $DIR/fn-not-async-err2.rs:15:22
-   |
-LL |     fn foo(&self) -> impl Future<Output = i32> {
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
-   = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.current.stderr b/tests/ui/async-await/in-trait/generics-mismatch.current.stderr
deleted file mode 100644
index be23384e049..00000000000
--- a/tests/ui/async-await/in-trait/generics-mismatch.current.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
-  --> $DIR/generics-mismatch.rs:13:18
-   |
-LL | trait Foo {
-   |       ---
-LL |     async fn foo<T>();
-   |                  - expected type parameter
-...
-LL | impl Foo for () {
-   | ---------------
-LL |     async fn foo<const N: usize>() {}
-   |                  ^^^^^^^^^^^^^^ found const parameter of type `usize`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/generics-mismatch.next.stderr b/tests/ui/async-await/in-trait/generics-mismatch.next.stderr
deleted file mode 100644
index be23384e049..00000000000
--- a/tests/ui/async-await/in-trait/generics-mismatch.next.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo`
-  --> $DIR/generics-mismatch.rs:13:18
-   |
-LL | trait Foo {
-   |       ---
-LL |     async fn foo<T>();
-   |                  - expected type parameter
-...
-LL | impl Foo for () {
-   | ---------------
-LL |     async fn foo<const N: usize>() {}
-   |                  ^^^^^^^^^^^^^^ found const parameter of type `usize`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr
deleted file mode 100644
index 69e7c65ee3e..00000000000
--- a/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
-  --> $DIR/lifetime-mismatch.rs:13:17
-   |
-LL |     async fn foo<'a>(&self);
-   |                 ---- lifetimes in impl do not match this method in trait
-...
-LL |     async fn foo(&self) {}
-   |                 ^ lifetimes do not match method in trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
deleted file mode 100644
index 69e7c65ee3e..00000000000
--- a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
-  --> $DIR/lifetime-mismatch.rs:13:17
-   |
-LL |     async fn foo<'a>(&self);
-   |                 ---- lifetimes in impl do not match this method in trait
-...
-LL |     async fn foo(&self) {}
-   |                 ^ lifetimes do not match method in trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr
deleted file mode 100644
index e6ac9bc2277..00000000000
--- a/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error[E0046]: not all trait items implemented, missing: `foo`
-  --> $DIR/missing-feature-flag.rs:14:1
-   |
-LL |     async fn foo(_: T) -> &'static str;
-   |     ----------------------------------- `foo` from trait
-...
-LL | impl<T> MyTrait<T> for MyStruct {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
-
-error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/missing-feature-flag.rs:18:5
-   |
-LL | impl<T> MyTrait<T> for MyStruct {}
-   | ------------------------------- parent `impl` is here
-...
-LL |     async fn foo(_: i32) -> &'static str {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
-   |
-   = note: to specialize, `foo` in the parent `impl` must be marked `default`
-
-error[E0308]: mismatched types
-  --> $DIR/missing-feature-flag.rs:18:42
-   |
-LL |     async fn foo(_: i32) -> &'static str {}
-   |                                          ^^ expected `&str`, found `()`
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0046, E0308, E0520.
-For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr
deleted file mode 100644
index e6ac9bc2277..00000000000
--- a/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error[E0046]: not all trait items implemented, missing: `foo`
-  --> $DIR/missing-feature-flag.rs:14:1
-   |
-LL |     async fn foo(_: T) -> &'static str;
-   |     ----------------------------------- `foo` from trait
-...
-LL | impl<T> MyTrait<T> for MyStruct {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
-
-error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/missing-feature-flag.rs:18:5
-   |
-LL | impl<T> MyTrait<T> for MyStruct {}
-   | ------------------------------- parent `impl` is here
-...
-LL |     async fn foo(_: i32) -> &'static str {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
-   |
-   = note: to specialize, `foo` in the parent `impl` must be marked `default`
-
-error[E0308]: mismatched types
-  --> $DIR/missing-feature-flag.rs:18:42
-   |
-LL |     async fn foo(_: i32) -> &'static str {}
-   |                                          ^^ expected `&str`, found `()`
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0046, E0308, E0520.
-For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/async-await/in-trait/missing-send-bound.current.stderr b/tests/ui/async-await/in-trait/missing-send-bound.current.stderr
deleted file mode 100644
index 9aa37f7437e..00000000000
--- a/tests/ui/async-await/in-trait/missing-send-bound.current.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/missing-send-bound.rs:16:20
-   |
-LL |     assert_is_send(test::<T>());
-   |                    ^^^^^^^^^^^ future returned by `test` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>`
-note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/missing-send-bound.rs:12:5
-   |
-LL |     T::bar().await;
-   |     ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send`
-note: required by a bound in `assert_is_send`
-  --> $DIR/missing-send-bound.rs:20:27
-   |
-LL | fn assert_is_send(_: impl Send) {}
-   |                           ^^^^ required by this bound in `assert_is_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/missing-send-bound.next.stderr b/tests/ui/async-await/in-trait/missing-send-bound.next.stderr
deleted file mode 100644
index 9aa37f7437e..00000000000
--- a/tests/ui/async-await/in-trait/missing-send-bound.next.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/missing-send-bound.rs:16:20
-   |
-LL |     assert_is_send(test::<T>());
-   |                    ^^^^^^^^^^^ future returned by `test` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>`
-note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/missing-send-bound.rs:12:5
-   |
-LL |     T::bar().await;
-   |     ^^^^^^^^ await occurs here on type `impl Future<Output = ()>`, which is not `Send`
-note: required by a bound in `assert_is_send`
-  --> $DIR/missing-send-bound.rs:20:27
-   |
-LL | fn assert_is_send(_: impl Send) {}
-   |                           ^^^^ required by this bound in `assert_is_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/in-trait/missing-send-bound.stderr b/tests/ui/async-await/in-trait/missing-send-bound.stderr
index 18185b75554..330dbef3978 100644
--- a/tests/ui/async-await/in-trait/missing-send-bound.stderr
+++ b/tests/ui/async-await/in-trait/missing-send-bound.stderr
@@ -5,6 +5,7 @@ LL |     assert_is_send(test::<T>());
    |                    ^^^^^^^^^^^ future returned by `test` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `impl Future<Output = ()>`
+   = note: consider using `std::sync::Arc<impl Future<Output = ()>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as it awaits another future which is not `Send`
   --> $DIR/missing-send-bound.rs:10:5
    |
diff --git a/tests/ui/async-await/in-trait/object-safety.current.stderr b/tests/ui/async-await/in-trait/object-safety.current.stderr
deleted file mode 100644
index 7f7ec39142c..00000000000
--- a/tests/ui/async-await/in-trait/object-safety.current.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:12:12
-   |
-LL |     let x: &dyn Foo = todo!();
-   |            ^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:8:14
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     async fn foo(&self);
-   |              ^^^ ...because method `foo` is `async`
-   = help: consider moving `foo` to another trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/async-await/in-trait/object-safety.next.stderr b/tests/ui/async-await/in-trait/object-safety.next.stderr
deleted file mode 100644
index 7f7ec39142c..00000000000
--- a/tests/ui/async-await/in-trait/object-safety.next.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:12:12
-   |
-LL |     let x: &dyn Foo = todo!();
-   |            ^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:8:14
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     async fn foo(&self);
-   |              ^^^ ...because method `foo` is `async`
-   = help: consider moving `foo` to another trait
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr
deleted file mode 100644
index 56973a1d11a..00000000000
--- a/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0726]: implicit elided lifetime not allowed here
-  --> $DIR/return-not-existing-pair.rs:12:20
-   |
-LL | impl<'a, 'b, T, U> MyTrait<T> for U {
-   |                    ^^^^^^^^^^ expected lifetime parameters
-   |
-help: indicate the anonymous lifetimes
-   |
-LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
-   |                            +++++++
-
-error[E0412]: cannot find type `ConnImpl` in this scope
-  --> $DIR/return-not-existing-pair.rs:8:48
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
-   |                                                ^^^^^^^^ not found in this scope
-
-error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
-  --> $DIR/return-not-existing-pair.rs:14:5
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
-   |     ------------------------------------------------------------ `&self` used in trait
-...
-LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl
-
-error[E0308]: mismatched types
-  --> $DIR/return-not-existing-pair.rs:14:42
-   |
-LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
-   |                                          ^^ expected `(&U, &T)`, found `()`
-   |
-   = note:  expected tuple `(&'a U, &'b T)`
-           found unit type `()`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0186, E0308, E0412, E0726.
-For more information about an error, try `rustc --explain E0186`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr
deleted file mode 100644
index 56973a1d11a..00000000000
--- a/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0726]: implicit elided lifetime not allowed here
-  --> $DIR/return-not-existing-pair.rs:12:20
-   |
-LL | impl<'a, 'b, T, U> MyTrait<T> for U {
-   |                    ^^^^^^^^^^ expected lifetime parameters
-   |
-help: indicate the anonymous lifetimes
-   |
-LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
-   |                            +++++++
-
-error[E0412]: cannot find type `ConnImpl` in this scope
-  --> $DIR/return-not-existing-pair.rs:8:48
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
-   |                                                ^^^^^^^^ not found in this scope
-
-error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
-  --> $DIR/return-not-existing-pair.rs:14:5
-   |
-LL |     async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
-   |     ------------------------------------------------------------ `&self` used in trait
-...
-LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl
-
-error[E0308]: mismatched types
-  --> $DIR/return-not-existing-pair.rs:14:42
-   |
-LL |     async fn foo(_: T) -> (&'a U, &'b T) {}
-   |                                          ^^ expected `(&U, &T)`, found `()`
-   |
-   = note:  expected tuple `(&'a U, &'b T)`
-           found unit type `()`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0186, E0308, E0412, E0726.
-For more information about an error, try `rustc --explain E0186`.
diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr
deleted file mode 100644
index 2564d68d591..00000000000
--- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0412]: cannot find type `Missing` in this scope
-  --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25
-   |
-LL |     fn bar() -> Wrapper<Missing<impl Sized>>;
-   |                         ^^^^^^^ 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/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr
deleted file mode 100644
index 2564d68d591..00000000000
--- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0412]: cannot find type `Missing` in this scope
-  --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25
-   |
-LL |     fn bar() -> Wrapper<Missing<impl Sized>>;
-   |                         ^^^^^^^ 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/in-trait/return-type-suggestion.current.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr
deleted file mode 100644
index 6a107d7beb8..00000000000
--- a/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/return-type-suggestion.rs:9:9
-   |
-LL |         Ok(())
-   |         ^^^^^^- help: consider using a semicolon here: `;`
-   |         |
-   |         expected `()`, found `Result<(), _>`
-   |
-   = note: expected unit type `()`
-                   found enum `Result<(), _>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr
deleted file mode 100644
index 6a107d7beb8..00000000000
--- a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/return-type-suggestion.rs:9:9
-   |
-LL |         Ok(())
-   |         ^^^^^^- help: consider using a semicolon here: `;`
-   |         |
-   |         expected `()`, found `Result<(), _>`
-   |
-   = note: expected unit type `()`
-                   found enum `Result<(), _>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr b/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr
index 56aa035f44b..a65ec664eab 100644
--- a/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     is_sync(bar());
    |             ^^^^^ future returned by `bar` is not `Sync`
    |
    = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Sync` as this value is used across an await
   --> $DIR/issue-64130-1-sync.rs:18:11
    |
diff --git a/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr b/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr
index ea1bfb9f9ac..159be3215e7 100644
--- a/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     is_sync(bar());
    |             ^^^^^ future returned by `bar` is not `Sync`
    |
    = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Sync` as this value is used across an await
   --> $DIR/issue-64130-1-sync.rs:18:11
    |
diff --git a/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr
index 56aa035f44b..a65ec664eab 100644
--- a/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL |     is_sync(bar());
    |             ^^^^^ future returned by `bar` is not `Sync`
    |
    = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Sync` as this value is used across an await
   --> $DIR/issue-64130-1-sync.rs:18:11
    |
diff --git a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
index 60b7551ff8a..5b60b3c3ae3 100644
--- a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL | pub fn foo() -> impl Future + Send {
    |                 ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
+   = note: consider using `std::sync::Arc<(dyn Any + Send + 'static)>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-4-async-move.rs:27:23
    |
diff --git a/tests/ui/async-await/issue-64130-non-send-future-diags.stderr b/tests/ui/async-await/issue-64130-non-send-future-diags.stderr
index e044e2ca011..d906d63fa31 100644
--- a/tests/ui/async-await/issue-64130-non-send-future-diags.stderr
+++ b/tests/ui/async-await/issue-64130-non-send-future-diags.stderr
@@ -5,6 +5,7 @@ LL |     is_send(foo());
    |             ^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
+   = note: consider using `std::sync::Arc<MutexGuard<'_, u32>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-64130-non-send-future-diags.rs:17:11
    |
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr
index fa22298658b..3c788ef8c4d 100644
--- a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr
@@ -10,6 +10,7 @@ LL | |     });
    | |_____^ future created by async block is not `Send`
    |
    = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6]`, the trait `Send` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-67252-unnamed-future.rs:23:17
    |
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr
index 8cf7bb8d917..03916f7e3f8 100644
--- a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     spawn(async {
    |     ^^^^^ future created by async block is not `Send`
    |
    = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6]`, the trait `Send` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-67252-unnamed-future.rs:23:17
    |
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr b/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr
index fa22298658b..3c788ef8c4d 100644
--- a/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr
@@ -10,6 +10,7 @@ LL | |     });
    | |_____^ future created by async block is not `Send`
    |
    = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6]`, the trait `Send` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-67252-unnamed-future.rs:23:17
    |
diff --git a/tests/ui/async-await/issue-70818.drop_tracking.stderr b/tests/ui/async-await/issue-70818.drop_tracking.stderr
index ab0698c3ec2..cf90d727efb 100644
--- a/tests/ui/async-await/issue-70818.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-70818.drop_tracking.stderr
@@ -4,6 +4,7 @@ error: future cannot be sent between threads safely
 LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
+   = note: consider using `std::sync::Arc<U>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send`
   --> $DIR/issue-70818.rs:9:18
    |
diff --git a/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr b/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr
index ab0698c3ec2..cf90d727efb 100644
--- a/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr
@@ -4,6 +4,7 @@ error: future cannot be sent between threads safely
 LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
+   = note: consider using `std::sync::Arc<U>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send`
   --> $DIR/issue-70818.rs:9:18
    |
diff --git a/tests/ui/async-await/issue-70818.no_drop_tracking.stderr b/tests/ui/async-await/issue-70818.no_drop_tracking.stderr
index ab0698c3ec2..cf90d727efb 100644
--- a/tests/ui/async-await/issue-70818.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-70818.no_drop_tracking.stderr
@@ -4,6 +4,7 @@ error: future cannot be sent between threads safely
 LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
+   = note: consider using `std::sync::Arc<U>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send`
   --> $DIR/issue-70818.rs:9:18
    |
diff --git a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
index f80bb4242aa..1e78befee83 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
@@ -5,6 +5,7 @@ LL | fn foo(x: NotSync) -> impl Future + Send {
    |                       ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
    |
    = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `PhantomData<*mut ()>`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 note: required because it appears within the type `NotSync`
diff --git a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr
index eb9d93e229f..b9163013870 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL | fn foo(x: NotSync) -> impl Future + Send {
    |                       ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
    |
    = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `PhantomData<*mut ()>`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 note: required because it appears within the type `NotSync`
diff --git a/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr b/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
index d8ef6a5eedb..1bbd8b76c1f 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
@@ -5,6 +5,7 @@ LL | fn foo(x: NotSync) -> impl Future + Send {
    |                       ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-70935-complex-spans.rs:24:12
    |
diff --git a/tests/ui/async-await/issue-71137.stderr b/tests/ui/async-await/issue-71137.stderr
index a344246d6bf..dba713dd36f 100644
--- a/tests/ui/async-await/issue-71137.stderr
+++ b/tests/ui/async-await/issue-71137.stderr
@@ -5,6 +5,7 @@ LL |   fake_spawn(wrong_mutex());
    |              ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
+   = note: consider using `std::sync::Arc<MutexGuard<'_, i32>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-71137.rs:14:26
    |
diff --git a/tests/ui/async-await/issue-86507.drop_tracking.stderr b/tests/ui/async-await/issue-86507.drop_tracking.stderr
index adb7b9bf4bf..00b71f10e1a 100644
--- a/tests/ui/async-await/issue-86507.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-86507.drop_tracking.stderr
@@ -8,6 +8,7 @@ LL | |                 }
 LL | |             )
    | |_____________^ future created by async block is not `Send`
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
   --> $DIR/issue-86507.rs:22:29
    |
diff --git a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
index adb7b9bf4bf..00b71f10e1a 100644
--- a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
@@ -8,6 +8,7 @@ LL | |                 }
 LL | |             )
    | |_____________^ future created by async block is not `Send`
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
   --> $DIR/issue-86507.rs:22:29
    |
diff --git a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
index adb7b9bf4bf..00b71f10e1a 100644
--- a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
@@ -8,6 +8,7 @@ LL | |                 }
 LL | |             )
    | |_____________^ future created by async block is not `Send`
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
   --> $DIR/issue-86507.rs:22:29
    |
diff --git a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
index 53d32620241..5840e68f3a5 100644
--- a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
+++ b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
@@ -9,6 +9,7 @@ LL | |     })
    | |_____^ future created by async block is not `Send`
    |
    = help: within `[async block@$DIR/issue-65436-raw-ptr-not-send.rs:17:17: 20:6]`, the trait `Send` is not implemented for `*const u8`
+   = note: consider using `std::sync::Arc<*const u8>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/issue-65436-raw-ptr-not-send.rs:19:36
    |
diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr
index c941b9eeb29..5b6015c3135 100644
--- a/tests/ui/async-await/issues/issue-67893.stderr
+++ b/tests/ui/async-await/issues/issue-67893.stderr
@@ -5,6 +5,7 @@ LL |     g(issue_67893::run())
    |       ^^^^^^^^^^^^^^^^^^ future is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
+   = note: consider using `std::sync::Arc<MutexGuard<'_, ()>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/auxiliary/issue_67893.rs:12:27
    |
diff --git a/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr b/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
index 17b4ef7bdc6..f8a14798696 100644
--- a/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
+++ b/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
@@ -10,10 +10,11 @@ LL | async fn foo() {
    |                - within this `impl Future<Output = ()>`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `(NotSend,)`
    = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `()`, `impl Future<Output = ()>`
 note: required because it's used within this `async fn` body
-  --> $DIR/partial-drop-partial-reinit.rs:31:16
+  --> $DIR/partial-drop-partial-reinit.rs:32:16
    |
 LL |   async fn foo() {
    |  ________________^
@@ -25,7 +26,7 @@ LL | |     bar().await;
 LL | | }
    | |_^
 note: required by a bound in `gimme_send`
-  --> $DIR/partial-drop-partial-reinit.rs:17:18
+  --> $DIR/partial-drop-partial-reinit.rs:18:18
    |
 LL | fn gimme_send<T: Send>(t: T) {
    |                  ^^^^ required by this bound in `gimme_send`
diff --git a/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr b/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr
index 34d8a159f10..5a1ff62dcdf 100644
--- a/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr
+++ b/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr
@@ -10,10 +10,11 @@ LL | async fn foo() {
    |                - within this `impl Future<Output = ()>`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `(NotSend,)`
    = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future<Output = ()>`, `()`
 note: required because it's used within this `async fn` body
-  --> $DIR/partial-drop-partial-reinit.rs:31:16
+  --> $DIR/partial-drop-partial-reinit.rs:32:16
    |
 LL |   async fn foo() {
    |  ________________^
@@ -25,7 +26,7 @@ LL | |     bar().await;
 LL | | }
    | |_^
 note: required by a bound in `gimme_send`
-  --> $DIR/partial-drop-partial-reinit.rs:17:18
+  --> $DIR/partial-drop-partial-reinit.rs:18:18
    |
 LL | fn gimme_send<T: Send>(t: T) {
    |                  ^^^^ required by this bound in `gimme_send`
diff --git a/tests/ui/async-await/partial-drop-partial-reinit.rs b/tests/ui/async-await/partial-drop-partial-reinit.rs
index 7d097e72fb4..50ba247c81b 100644
--- a/tests/ui/async-await/partial-drop-partial-reinit.rs
+++ b/tests/ui/async-await/partial-drop-partial-reinit.rs
@@ -12,6 +12,7 @@ fn main() {
     //~| NOTE bound introduced by
     //~| NOTE appears within the type
     //~| NOTE captures the following types
+    //~| NOTE consider using `std::sync::Arc<NotSend>`
 }
 
 fn gimme_send<T: Send>(t: T) {
diff --git a/tests/ui/auto-traits/issue-83857-ub.stderr b/tests/ui/auto-traits/issue-83857-ub.stderr
index 23a2f62d905..72b92b49c01 100644
--- a/tests/ui/auto-traits/issue-83857-ub.stderr
+++ b/tests/ui/auto-traits/issue-83857-ub.stderr
@@ -5,6 +5,7 @@ LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo<T, U>` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Foo<T, U>`
+   = note: consider using `std::sync::Arc<Foo<T, U>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required for `Foo<T, U>` to implement `WithAssoc`
   --> $DIR/issue-83857-ub.rs:15:15
    |
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr
index 592aa4369ce..beb336b2963 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL | impl <T: Sync+'static> Foo for (T,) { }
    |                                ^^^^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `(T,)`
 note: required by a bound in `Foo`
   --> $DIR/builtin-superkinds-double-superkind.rs:4:13
@@ -21,6 +22,7 @@ error[E0277]: `T` cannot be shared between threads safely
 LL | impl <T: Send> Foo for (T,T) { }
    |                        ^^^^^ `T` cannot be shared between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `(T, T)`
 note: required by a bound in `Foo`
   --> $DIR/builtin-superkinds-double-superkind.rs:4:18
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr
index f9d548bb8fb..9929452ab79 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
    |                                                        ^^^^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `X<T>`
   --> $DIR/builtin-superkinds-in-metadata.rs:9:8
    |
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr
index 8b19170b0f1..8d740df9708 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr
@@ -5,6 +5,7 @@ LL | impl Foo for std::rc::Rc<i8> { }
    |              ^^^^^^^^^^^^^^^ `Rc<i8>` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Rc<i8>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required by a bound in `Foo`
   --> $DIR/builtin-superkinds-simple.rs:4:13
    |
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr
index 0cfea72d5f1..481c524a9ae 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL | impl <T: Sync+'static> Foo for T { }
    |                                ^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `Foo`
   --> $DIR/builtin-superkinds-typaram-not-send.rs:3:13
    |
diff --git a/tests/ui/check-cfg/values-target-json.stderr b/tests/ui/check-cfg/values-target-json.stderr
index eb81535e3ed..e773d5d83cc 100644
--- a/tests/ui/check-cfg/values-target-json.stderr
+++ b/tests/ui/check-cfg/values-target-json.stderr
@@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")]
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: 1 warning emitted
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index 2d18cb82e03..1f775814656 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")]
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value
diff --git a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
index bf6ec5c36e4..ca2daffde27 100644
--- a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
+++ b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
@@ -4,6 +4,7 @@ error[E0277]: `F` cannot be sent between threads safely
 LL | fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
    |                      ^^^^ `F` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<F>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `X`
   --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:1:43
    |
diff --git a/tests/ui/closures/closure-bounds-subtype.stderr b/tests/ui/closures/closure-bounds-subtype.stderr
index 8ad8273fc2b..818ad6a4a0c 100644
--- a/tests/ui/closures/closure-bounds-subtype.stderr
+++ b/tests/ui/closures/closure-bounds-subtype.stderr
@@ -6,6 +6,7 @@ LL |     take_const_owned(f);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<F>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `take_const_owned`
   --> $DIR/closure-bounds-subtype.rs:4:50
    |
diff --git a/tests/ui/closures/closure-move-sync.stderr b/tests/ui/closures/closure-move-sync.stderr
index aee903ac950..f2fa7c0c7a4 100644
--- a/tests/ui/closures/closure-move-sync.stderr
+++ b/tests/ui/closures/closure-move-sync.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
+   = note: consider using `std::sync::Arc<std::sync::mpsc::Receiver<()>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send`
 note: required because it's used within this closure
   --> $DIR/closure-move-sync.rs:6:27
diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs
index 6e04cfaec31..88dff919206 100644
--- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs
+++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs
@@ -1,6 +1,6 @@
 // build-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Func<T> {
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
index 275f6995302..6b2a0153f51 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
@@ -1,4 +1,9 @@
 // check-fail
+// known-bug: #97477
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
 
 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place
 
@@ -27,6 +32,5 @@ where
 }
 
 fn main() {
-    let dst = Inline::<dyn Debug>::new(0); //~ ERROR
-    //~^ ERROR
+    let dst = Inline::<dyn Debug>::new(0);
 }
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
index dc3a400cbaa..79ed82e02e0 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr
@@ -1,71 +1,10 @@
-error[E0080]: evaluation of `Inline::<dyn Debug>::{constant#0}` failed
+error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:272:21: SizeOf MIR operator called for unsized type dyn Debug
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-   |
-   = note: size_of called on unsized type `dyn Debug`
-   |
-note: inside `std::mem::size_of::<dyn Debug>`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-note: inside `Inline::<dyn Debug>::{constant#0}`
-  --> $DIR/issue-80742.rs:22:10
-   |
-LL |     [u8; size_of::<T>() + 1]: ,
-   |          ^^^^^^^^^^^^^^
-
-error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied
-  --> $DIR/issue-80742.rs:30:36
-   |
-LL | struct Inline<T>
-   | ---------------- function or associated item `new` not found for this struct
-...
-LL |     let dst = Inline::<dyn Debug>::new(0);
-   |                                    ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds
-  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
-   |
-   = note: doesn't satisfy `dyn Debug: Sized`
-   |
-note: trait bound `dyn Debug: Sized` was not satisfied
-  --> $DIR/issue-80742.rs:20:6
-   |
-LL | impl<T> Inline<T>
-   |      ^  ---------
-   |      |
-   |      unsatisfied trait bound introduced here
-help: consider relaxing the type parameter's implicit `Sized` bound
-   |
-LL | impl<T: ?Sized> Inline<T>
-   |       ++++++++
-
-error[E0080]: evaluation of `Inline::<dyn Debug>::{constant#0}` failed
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-   |
-   = note: size_of called on unsized type `dyn Debug`
-   |
-note: inside `std::mem::size_of::<dyn Debug>`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-note: inside `Inline::<dyn Debug>::{constant#0}`
-  --> $DIR/issue-80742.rs:14:10
-   |
-LL |     [u8; size_of::<T>() + 1]: ,
-   |          ^^^^^^^^^^^^^^
-
-error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
-  --> $DIR/issue-80742.rs:30:15
-   |
-LL |     let dst = Inline::<dyn Debug>::new(0);
-   |               ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `dyn Debug`
-note: required by a bound in `Inline`
-  --> $DIR/issue-80742.rs:12:15
-   |
-LL | struct Inline<T>
-   |               ^ required by this bound in `Inline`
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | struct Inline<T: ?Sized>
-   |                ++++++++
 
-error: aborting due to 4 previous errors
+Box<dyn Any>
+query stack during panic:
+#0 [eval_to_allocation_raw] const-evaluating + checking `<impl at $DIR/issue-80742.rs:25:1: 25:18>::{constant#0}`
+#1 [eval_to_valtree] evaluating type-level constant
+end of query stack
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0277, E0599.
-For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
index 7f28771cee8..eb71ebb62eb 100644
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
@@ -1,11 +1,39 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/unify-op-with-fn-call.rs:10:12
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:18:29
    |
-LL | impl const std::ops::Add for Foo {
-   |            ^^^^^^^^^^^^^
+LL | struct Evaluatable<const N: Foo>;
+   |                             ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
+   |
+
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:20:17
+   |
+LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
+   |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
+   |
+
+error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/unify-op-with-fn-call.rs:24:17
+   |
+LL | fn bar<const N: Foo>() {}
+   |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct Foo(u8);
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/const-generics/slice-const-param.rs b/tests/ui/const-generics/slice-const-param.rs
index 05d21e08d74..90c573ab365 100644
--- a/tests/ui/const-generics/slice-const-param.rs
+++ b/tests/ui/const-generics/slice-const-param.rs
@@ -11,9 +11,30 @@ pub fn function_with_bytes<const BYTES: &'static [u8]>() -> &'static [u8] {
     BYTES
 }
 
+// Also check the codepaths for custom DST
+#[derive(PartialEq, Eq)]
+struct MyStr(str);
+impl std::marker::ConstParamTy for MyStr {}
+
+fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
+    S
+}
+
+impl MyStr {
+    const fn new(s: &'static str) -> &'static MyStr {
+        unsafe { std::mem::transmute(s) }
+    }
+
+    fn as_str(&self) -> &str {
+        &self.0
+    }
+}
+
 pub fn main() {
     assert_eq!(function_with_str::<"Rust">(), "Rust");
     assert_eq!(function_with_str::<"ℇ㇈↦">(), "ℇ㇈↦");
     assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]);
     assert_eq!(function_with_bytes::<{&[0x41, 0x41, 0x41, 0x41]}>(), b"AAAA");
+
+    assert_eq!(function_with_my_str::<{ MyStr::new("hello") }>().as_str(), "hello");
 }
diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr
index 37014f9b83f..94f4153a29e 100644
--- a/tests/ui/consts/const-try.stderr
+++ b/tests/ui/consts/const-try.stderr
@@ -1,20 +1,29 @@
-error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
-  --> $DIR/const-try.rs:15:12
+error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions
+  --> $DIR/const-try.rs:33:5
    |
-LL | impl const FromResidual<Error> for TryMe {
-   |            ^^^^^^^^^^^^^^^^^^^
+LL |     TryMe?;
+   |     ^^^^^^
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
-  --> $DIR/const-try.rs:21:12
+note: impl defined here, but it is not `const`
+  --> $DIR/const-try.rs:21:1
    |
 LL | impl const Try for TryMe {
-   |            ^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions
+  --> $DIR/const-try.rs:33:5
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL |     TryMe?;
+   |     ^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/const-try.rs:15:1
+   |
+LL | impl const FromResidual<Error> for TryMe {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs
index a1a741e80e5..2b67c2f2cff 100644
--- a/tests/ui/consts/rustc-impl-const-stability.rs
+++ b/tests/ui/consts/rustc-impl-const-stability.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 #![feature(staged_api)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![stable(feature = "foo", since = "1.0.0")]
 
 #[stable(feature = "potato", since = "1.27.0")]
diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr
index e6930da71ec..ba8e6c1555c 100644
--- a/tests/ui/consts/rustc-impl-const-stability.stderr
+++ b/tests/ui/consts/rustc-impl-const-stability.stderr
@@ -7,5 +7,15 @@ LL | impl const Default for Data {
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error: aborting due to previous error
+error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/rustc-impl-const-stability.rs:15:6
+   |
+LL | impl const Default for Data {
+   |      ^^^^^ unconstrained const parameter
+   |
+   = note: expressions using a const parameter must map each value to a distinct output value
+   = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/error-codes/E0277-2.stderr b/tests/ui/error-codes/E0277-2.stderr
index a2abf37931a..38ae0aa6aa5 100644
--- a/tests/ui/error-codes/E0277-2.stderr
+++ b/tests/ui/error-codes/E0277-2.stderr
@@ -5,6 +5,7 @@ LL |     is_send::<Foo>();
    |               ^^^ `*const u8` cannot be sent between threads safely
    |
    = help: within `Foo`, the trait `Send` is not implemented for `*const u8`
+   = note: consider using `std::sync::Arc<*const u8>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Baz`
   --> $DIR/E0277-2.rs:9:8
    |
diff --git a/tests/ui/extern/extern-type-diag-not-similar.stderr b/tests/ui/extern/extern-type-diag-not-similar.stderr
index 75836f7eca1..90e944f02b5 100644
--- a/tests/ui/extern/extern-type-diag-not-similar.stderr
+++ b/tests/ui/extern/extern-type-diag-not-similar.stderr
@@ -5,6 +5,7 @@ LL |     assert_send::<Foo>()
    |                   ^^^ `Foo` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_send`
   --> $DIR/extern-type-diag-not-similar.rs:17:19
    |
diff --git a/tests/ui/extern/extern-types-not-sync-send.stderr b/tests/ui/extern/extern-types-not-sync-send.stderr
index 7865ddeda34..5edfa5b51c4 100644
--- a/tests/ui/extern/extern-types-not-sync-send.stderr
+++ b/tests/ui/extern/extern-types-not-sync-send.stderr
@@ -5,6 +5,7 @@ LL |     assert_sync::<A>();
    |                   ^ `A` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `A`
+   = note: consider using `std::sync::Arc<A>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_sync`
   --> $DIR/extern-types-not-sync-send.rs:9:28
    |
@@ -18,6 +19,7 @@ LL |     assert_send::<A>();
    |                   ^ `A` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `A`
+   = note: consider using `std::sync::Arc<A>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_send`
   --> $DIR/extern-types-not-sync-send.rs:10:28
    |
diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs
new file mode 100644
index 00000000000..7755a46da3b
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs
@@ -0,0 +1,33 @@
+// needs-llvm-components: riscv
+// compile-flags: --target=riscv32imc-unknown-none-elf --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang = "sized"]
+trait Sized {}
+
+// Test that the riscv interrupt ABIs cannot be used when riscv_interrupt
+// feature gate is not used.
+
+extern "riscv-interrupt-m" fn f() {}
+//~^ ERROR riscv-interrupt ABIs are experimental
+extern "riscv-interrupt-s" fn f_s() {}
+//~^ ERROR riscv-interrupt ABIs are experimental
+
+trait T {
+    extern "riscv-interrupt-m" fn m();
+    //~^ ERROR riscv-interrupt ABIs are experimental
+}
+
+struct S;
+impl T for S {
+    extern "riscv-interrupt-m" fn m() {}
+    //~^ ERROR riscv-interrupt ABIs are experimental
+}
+
+impl S {
+    extern "riscv-interrupt-m" fn im() {}
+    //~^ ERROR riscv-interrupt ABIs are experimental
+}
+
+type TA = extern "riscv-interrupt-m" fn();
+//~^ ERROR riscv-interrupt ABIs are experimental
diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr
new file mode 100644
index 00000000000..60c7fa0ea67
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr
@@ -0,0 +1,57 @@
+error[E0658]: riscv-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-riscv-interrupt.rs:11:8
+   |
+LL | extern "riscv-interrupt-m" fn f() {}
+   |        ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
+   = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
+
+error[E0658]: riscv-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-riscv-interrupt.rs:13:8
+   |
+LL | extern "riscv-interrupt-s" fn f_s() {}
+   |        ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
+   = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
+
+error[E0658]: riscv-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-riscv-interrupt.rs:17:12
+   |
+LL |     extern "riscv-interrupt-m" fn m();
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
+   = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
+
+error[E0658]: riscv-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-riscv-interrupt.rs:23:12
+   |
+LL |     extern "riscv-interrupt-m" fn m() {}
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
+   = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
+
+error[E0658]: riscv-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-riscv-interrupt.rs:28:12
+   |
+LL |     extern "riscv-interrupt-m" fn im() {}
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
+   = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
+
+error[E0658]: riscv-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-riscv-interrupt.rs:32:18
+   |
+LL | type TA = extern "riscv-interrupt-m" fn();
+   |                  ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #111889 <https://github.com/rust-lang/rust/issues/111889> for more information
+   = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr
index e3ebe6cdcb8..e431501e9f8 100644
--- a/tests/ui/fmt/send-sync.stderr
+++ b/tests/ui/fmt/send-sync.stderr
@@ -7,6 +7,7 @@ LL |     send(format_args!("{:?}", c));
    |     required by a bound introduced by this call
    |
    = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`
+   = note: consider using `std::sync::Arc<core::fmt::rt::Opaque>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `&core::fmt::rt::Opaque`
 note: required because it appears within the type `Argument<'_>`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
@@ -29,6 +30,7 @@ LL |     sync(format_args!("{:?}", c));
    |     required by a bound introduced by this call
    |
    = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`
+   = note: consider using `std::sync::Arc<core::fmt::rt::Opaque>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `&core::fmt::rt::Opaque`
 note: required because it appears within the type `Argument<'_>`
   --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
diff --git a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr
index c07906ec37d..0038ed0ac1c 100644
--- a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr
+++ b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -56,6 +57,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -98,6 +100,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
diff --git a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr
index 35698a98dbd..2e684636432 100644
--- a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr
+++ b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -54,6 +55,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -94,6 +96,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
diff --git a/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr b/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr
index 1a05bfe4f0e..30f1546c6e3 100644
--- a/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr
+++ b/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `copy::Client`
+   = note: consider using `std::sync::Arc<copy::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -56,6 +57,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `copy::Client`
+   = note: consider using `std::sync::Arc<copy::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:38:22
    |
@@ -97,6 +99,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -139,6 +142,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:38:22
    |
@@ -180,6 +184,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -222,6 +227,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:38:22
    |
@@ -263,6 +269,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:25:22
    |
@@ -305,6 +312,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-tracking-parent-expression.rs:38:22
    |
diff --git a/tests/ui/generator/drop-yield-twice.stderr b/tests/ui/generator/drop-yield-twice.stderr
index 0808a2c85ee..468d9a809b4 100644
--- a/tests/ui/generator/drop-yield-twice.stderr
+++ b/tests/ui/generator/drop-yield-twice.stderr
@@ -11,6 +11,7 @@ LL | |     })
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/drop-yield-twice.rs:9:9
    |
diff --git a/tests/ui/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
index f7b8e198cc4..7dd9980635a 100644
--- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr
+++ b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: the trait `Sync` is not implemented for `copy::unsync::Client`
+   = note: consider using `std::sync::Arc<copy::unsync::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57017.rs:30:28
    |
@@ -55,6 +56,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `copy::unsend::Client`
+   = note: consider using `std::sync::Arc<copy::unsend::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57017.rs:42:28
    |
@@ -96,6 +98,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: the trait `Sync` is not implemented for `derived_drop::unsync::Client`
+   = note: consider using `std::sync::Arc<derived_drop::unsync::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57017.rs:30:28
    |
@@ -137,6 +140,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client`
+   = note: consider using `std::sync::Arc<derived_drop::unsend::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57017.rs:42:28
    |
@@ -178,6 +182,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: the trait `Sync` is not implemented for `significant_drop::unsync::Client`
+   = note: consider using `std::sync::Arc<significant_drop::unsync::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57017.rs:30:28
    |
@@ -219,6 +224,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client`
+   = note: consider using `std::sync::Arc<significant_drop::unsend::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57017.rs:42:28
    |
diff --git a/tests/ui/generator/issue-57478.no_drop_tracking.stderr b/tests/ui/generator/issue-57478.no_drop_tracking.stderr
index 612dd9c37f7..91f30ef1ef6 100644
--- a/tests/ui/generator/issue-57478.no_drop_tracking.stderr
+++ b/tests/ui/generator/issue-57478.no_drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     })
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/issue-57478.rs:13:17: 13:19]`, the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/issue-57478.rs:17:9
    |
diff --git a/tests/ui/generator/not-send-sync.drop_tracking.stderr b/tests/ui/generator/not-send-sync.drop_tracking.stderr
index 718fd42245a..3cbfcf436c5 100644
--- a/tests/ui/generator/not-send-sync.drop_tracking.stderr
+++ b/tests/ui/generator/not-send-sync.drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ generator is not `Sync`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:17:17: 17:19]`, the trait `Sync` is not implemented for `NotSync`
+   = note: consider using `std::sync::Arc<NotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:20:9
    |
@@ -40,6 +41,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:24:17: 24:19]`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/not-send-sync.rs:27:9
    |
diff --git a/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr b/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr
index 66f01ae37d8..6647adff528 100644
--- a/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr
+++ b/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ generator is not `Sync`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:17:17: 17:19]`, the trait `Sync` is not implemented for `NotSync`
+   = note: consider using `std::sync::Arc<NotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:20:9
    |
@@ -25,6 +26,7 @@ LL |     assert_send(|| {
    |     ^^^^^^^^^^^ generator is not `Send`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:24:17: 24:19]`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/not-send-sync.rs:27:9
    |
diff --git a/tests/ui/generator/not-send-sync.no_drop_tracking.stderr b/tests/ui/generator/not-send-sync.no_drop_tracking.stderr
index 718fd42245a..3cbfcf436c5 100644
--- a/tests/ui/generator/not-send-sync.no_drop_tracking.stderr
+++ b/tests/ui/generator/not-send-sync.no_drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ generator is not `Sync`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:17:17: 17:19]`, the trait `Sync` is not implemented for `NotSync`
+   = note: consider using `std::sync::Arc<NotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/not-send-sync.rs:20:9
    |
@@ -40,6 +41,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/not-send-sync.rs:24:17: 24:19]`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/not-send-sync.rs:27:9
    |
diff --git a/tests/ui/generator/parent-expression.drop_tracking.stderr b/tests/ui/generator/parent-expression.drop_tracking.stderr
index ef489088bf8..e30ace31719 100644
--- a/tests/ui/generator/parent-expression.drop_tracking.stderr
+++ b/tests/ui/generator/parent-expression.drop_tracking.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -56,6 +57,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -98,6 +100,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
diff --git a/tests/ui/generator/parent-expression.drop_tracking_mir.stderr b/tests/ui/generator/parent-expression.drop_tracking_mir.stderr
index bf814456427..82a29b29d2e 100644
--- a/tests/ui/generator/parent-expression.drop_tracking_mir.stderr
+++ b/tests/ui/generator/parent-expression.drop_tracking_mir.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -54,6 +55,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -94,6 +96,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
diff --git a/tests/ui/generator/parent-expression.no_drop_tracking.stderr b/tests/ui/generator/parent-expression.no_drop_tracking.stderr
index 2e1313a8004..23fa90edfb5 100644
--- a/tests/ui/generator/parent-expression.no_drop_tracking.stderr
+++ b/tests/ui/generator/parent-expression.no_drop_tracking.stderr
@@ -14,6 +14,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `copy::Client`
+   = note: consider using `std::sync::Arc<copy::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -56,6 +57,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `copy::Client`
+   = note: consider using `std::sync::Arc<copy::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:38:22
    |
@@ -97,6 +99,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -139,6 +142,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `derived_drop::Client`
+   = note: consider using `std::sync::Arc<derived_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:38:22
    |
@@ -180,6 +184,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -222,6 +227,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `significant_drop::Client`
+   = note: consider using `std::sync::Arc<significant_drop::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:38:22
    |
@@ -263,6 +269,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:25:22
    |
@@ -305,6 +312,7 @@ LL | |     );
    | |_____- in this macro invocation
    |
    = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = note: consider using `std::sync::Arc<insignificant_dtor::Client>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/parent-expression.rs:38:22
    |
diff --git a/tests/ui/generator/partial-drop.drop_tracking.stderr b/tests/ui/generator/partial-drop.drop_tracking.stderr
index f1b25cb8c34..018f1c05ad9 100644
--- a/tests/ui/generator/partial-drop.drop_tracking.stderr
+++ b/tests/ui/generator/partial-drop.drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/partial-drop.rs:17:17: 17:19]`, the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/partial-drop.rs:21:9
    |
@@ -41,6 +42,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/partial-drop.rs:24:17: 24:19]`, the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/partial-drop.rs:29:9
    |
diff --git a/tests/ui/generator/partial-drop.no_drop_tracking.stderr b/tests/ui/generator/partial-drop.no_drop_tracking.stderr
index 91152b5ea6f..bd74ae6ac3a 100644
--- a/tests/ui/generator/partial-drop.no_drop_tracking.stderr
+++ b/tests/ui/generator/partial-drop.no_drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/partial-drop.rs:17:17: 17:19]`, the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/partial-drop.rs:21:9
    |
@@ -41,6 +42,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[generator@$DIR/partial-drop.rs:24:17: 24:19]`, the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/partial-drop.rs:29:9
    |
diff --git a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr
index 1f2e530f6f5..ff7a6885b8e 100644
--- a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ generator is not `Sync`
    |
    = help: within `[main::{closure#0} upvar_tys=() {NotSync, ()}]`, the trait `Sync` is not implemented for `NotSync`
+   = note: consider using `std::sync::Arc<NotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:23:9
    |
@@ -40,6 +41,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[main::{closure#1} upvar_tys=() {NotSend, ()}]`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:30:9
    |
diff --git a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr
index 354369f1954..6dc8e68a708 100644
--- a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr
@@ -5,6 +5,7 @@ LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ generator is not `Sync`
    |
    = help: within `[main::{closure#0} upvar_tys=() [main::{closure#0}]]`, the trait `Sync` is not implemented for `NotSync`
+   = note: consider using `std::sync::Arc<NotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:23:9
    |
@@ -25,6 +26,7 @@ LL |     assert_send(|| {
    |     ^^^^^^^^^^^ generator is not `Send`
    |
    = help: within `[main::{closure#1} upvar_tys=() [main::{closure#1}]]`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:30:9
    |
diff --git a/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr
index 1f2e530f6f5..ff7a6885b8e 100644
--- a/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr
@@ -11,6 +11,7 @@ LL | |     });
    | |_____^ generator is not `Sync`
    |
    = help: within `[main::{closure#0} upvar_tys=() {NotSync, ()}]`, the trait `Sync` is not implemented for `NotSync`
+   = note: consider using `std::sync::Arc<NotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Sync` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:23:9
    |
@@ -40,6 +41,7 @@ LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: within `[main::{closure#1} upvar_tys=() {NotSend, ()}]`, the trait `Send` is not implemented for `NotSend`
+   = note: consider using `std::sync::Arc<NotSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: generator is not `Send` as this value is used across a yield
   --> $DIR/generator-print-verbose-2.rs:30:9
    |
diff --git a/tests/ui/generator/ref-upvar-not-send.rs b/tests/ui/generator/ref-upvar-not-send.rs
index eb9ef63ecfc..53ded21b621 100644
--- a/tests/ui/generator/ref-upvar-not-send.rs
+++ b/tests/ui/generator/ref-upvar-not-send.rs
@@ -15,6 +15,7 @@ fn main() {
     assert_send(move || {
         //~^ ERROR generator cannot be sent between threads safely
         //~| NOTE generator is not `Send`
+        //~| NOTE consider using `std::sync::Arc
         yield;
         let _x = x;
     });
@@ -23,6 +24,7 @@ fn main() {
     assert_send(move || {
         //~^ ERROR generator cannot be sent between threads safely
         //~| NOTE generator is not `Send`
+        //~| NOTE consider using `std::sync::Arc
         yield;
         let _y = y;
     });
diff --git a/tests/ui/generator/ref-upvar-not-send.stderr b/tests/ui/generator/ref-upvar-not-send.stderr
index 689ace67e34..0a5289544b8 100644
--- a/tests/ui/generator/ref-upvar-not-send.stderr
+++ b/tests/ui/generator/ref-upvar-not-send.stderr
@@ -5,14 +5,16 @@ LL |       assert_send(move || {
    |  _________________^
 LL | |
 LL | |
+LL | |
 LL | |         yield;
 LL | |         let _x = x;
 LL | |     });
    | |_____^ generator is not `Send`
    |
    = help: the trait `Sync` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> $DIR/ref-upvar-not-send.rs:19:18
+  --> $DIR/ref-upvar-not-send.rs:20:18
    |
 LL |         let _x = x;
    |                  ^ has type `&*mut ()` which is not `Send`, because `*mut ()` is not `Sync`
@@ -23,20 +25,22 @@ LL | fn assert_send<T: Send>(_: T) {}
    |                   ^^^^ required by this bound in `assert_send`
 
 error: generator cannot be sent between threads safely
-  --> $DIR/ref-upvar-not-send.rs:23:17
+  --> $DIR/ref-upvar-not-send.rs:24:17
    |
 LL |       assert_send(move || {
    |  _________________^
 LL | |
 LL | |
+LL | |
 LL | |         yield;
 LL | |         let _y = y;
 LL | |     });
    | |_____^ generator is not `Send`
    |
-   = help: within `[generator@$DIR/ref-upvar-not-send.rs:23:17: 23:24]`, the trait `Send` is not implemented for `*mut ()`
+   = help: within `[generator@$DIR/ref-upvar-not-send.rs:24:17: 24:24]`, the trait `Send` is not implemented for `*mut ()`
+   = note: consider using `std::sync::Arc<*mut ()>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send`
-  --> $DIR/ref-upvar-not-send.rs:27:18
+  --> $DIR/ref-upvar-not-send.rs:29:18
    |
 LL |         let _y = y;
    |                  ^ has type `&mut *mut ()` which is not `Send`, because `*mut ()` is not `Send`
diff --git a/tests/ui/generic-associated-types/streaming_iterator.rs b/tests/ui/generic-associated-types/streaming_iterator.rs
index 408b8dc99eb..656fb743ee4 100644
--- a/tests/ui/generic-associated-types/streaming_iterator.rs
+++ b/tests/ui/generic-associated-types/streaming_iterator.rs
@@ -15,8 +15,7 @@ struct Foo<T: StreamingIterator + 'static> {
 
 // Users can bound parameters by the type constructed by that trait's associated type constructor
 // of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid:
-//FIXME(#44265): This next line should parse and be valid
-//fn foo<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(_iter: T) { /* ... */ }
+fn _bar<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(_iter: T) { /* ... */ }
 fn _foo<T>(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ }
 
 // Full example of enumerate iterator
diff --git a/tests/ui/impl-trait/auto-trait-leak2.rs b/tests/ui/impl-trait/auto-trait-leak2.rs
index 09450089ada..bbad0df1f66 100644
--- a/tests/ui/impl-trait/auto-trait-leak2.rs
+++ b/tests/ui/impl-trait/auto-trait-leak2.rs
@@ -21,11 +21,13 @@ fn main() {
     //~^ ERROR `Rc<Cell<i32>>` cannot be sent between threads safely
     //~| NOTE `Rc<Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required by a bound
+    //~| NOTE use `std::sync::Arc` instead
 
     send(after());
     //~^ ERROR `Rc<Cell<i32>>` cannot be sent between threads safely
     //~| NOTE `Rc<Cell<i32>>` cannot be sent between threads safely
     //~| NOTE required by a bound
+    //~| NOTE use `std::sync::Arc` instead
 }
 
 // Deferred path, main has to wait until typeck finishes,
diff --git a/tests/ui/impl-trait/auto-trait-leak2.stderr b/tests/ui/impl-trait/auto-trait-leak2.stderr
index 52fa28145d6..f2f88215a39 100644
--- a/tests/ui/impl-trait/auto-trait-leak2.stderr
+++ b/tests/ui/impl-trait/auto-trait-leak2.stderr
@@ -10,6 +10,7 @@ LL |     send(before());
    |     required by a bound introduced by this call
    |
    = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it's used within this closure
   --> $DIR/auto-trait-leak2.rs:10:5
    |
@@ -27,7 +28,7 @@ LL | fn send<T: Send>(_: T) {}
    |            ^^^^ required by this bound in `send`
 
 error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
-  --> $DIR/auto-trait-leak2.rs:25:10
+  --> $DIR/auto-trait-leak2.rs:26:10
    |
 LL |     send(after());
    |     ---- ^^^^^^^ `Rc<Cell<i32>>` cannot be sent between threads safely
@@ -38,13 +39,14 @@ LL | fn after() -> impl Fn(i32) {
    |               ------------ within this `impl Fn(i32)`
    |
    = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it's used within this closure
-  --> $DIR/auto-trait-leak2.rs:38:5
+  --> $DIR/auto-trait-leak2.rs:40:5
    |
 LL |     move |x| p.set(x)
    |     ^^^^^^^^
 note: required because it appears within the type `impl Fn(i32)`
-  --> $DIR/auto-trait-leak2.rs:33:15
+  --> $DIR/auto-trait-leak2.rs:35:15
    |
 LL | fn after() -> impl Fn(i32) {
    |               ^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr
index dee87d08238..687c811a5d5 100644
--- a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr
+++ b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr
@@ -5,6 +5,7 @@ LL |     fn bar() -> Wrapper<impl Sized>;
    |                 ^^^^^^^^^^^^^^^^^^^ `impl Sized` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `impl Sized`
+   = note: consider using `std::sync::Arc<impl Sized>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `Wrapper`
   --> $DIR/check-wf-on-non-defaulted-rpitit.rs:3:19
    |
diff --git a/tests/ui/impl-trait/in-trait/deep-match.current.stderr b/tests/ui/impl-trait/in-trait/deep-match.current.stderr
deleted file mode 100644
index 400db20c79c..00000000000
--- a/tests/ui/impl-trait/in-trait/deep-match.current.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0053]: method `bar` has an incompatible return type for trait
-  --> $DIR/deep-match.rs:14:17
-   |
-LL |     fn bar() -> i32 {
-   |                 ^^^
-   |                 |
-   |                 expected `Wrapper<_>`, found `i32`
-   |                 return type in trait
-   |
-   = note: expected struct `Wrapper<_>`
-                found type `i32`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/in-trait/deep-match.next.stderr b/tests/ui/impl-trait/in-trait/deep-match.next.stderr
deleted file mode 100644
index 400db20c79c..00000000000
--- a/tests/ui/impl-trait/in-trait/deep-match.next.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0053]: method `bar` has an incompatible return type for trait
-  --> $DIR/deep-match.rs:14:17
-   |
-LL |     fn bar() -> i32 {
-   |                 ^^^
-   |                 |
-   |                 expected `Wrapper<_>`, found `i32`
-   |                 return type in trait
-   |
-   = note: expected struct `Wrapper<_>`
-                found type `i32`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr
deleted file mode 100644
index 85450e3b0a0..00000000000
--- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/default-body-type-err-2.rs:10:9
-   |
-LL |         42
-   |         ^^- help: try using a conversion method: `.to_string()`
-   |         |
-   |         expected `String`, found integer
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr
deleted file mode 100644
index 85450e3b0a0..00000000000
--- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/default-body-type-err-2.rs:10:9
-   |
-LL |         42
-   |         ^^- help: try using a conversion method: `.to_string()`
-   |         |
-   |         expected `String`, found integer
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr
deleted file mode 100644
index c949168a377..00000000000
--- a/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
-  --> $DIR/default-body-type-err.rs:10:22
-   |
-LL |     fn lol(&self) -> impl Deref<Target = String> {
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
-LL |
-LL |         &1i32
-   |         ----- return type was inferred to be `&i32` here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr
deleted file mode 100644
index c949168a377..00000000000
--- a/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
-  --> $DIR/default-body-type-err.rs:10:22
-   |
-LL |     fn lol(&self) -> impl Deref<Target = String> {
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
-LL |
-LL |         &1i32
-   |         ----- return type was inferred to be `&i32` here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr
deleted file mode 100644
index 3c24eff9ae3..00000000000
--- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/default-body-with-rpit.rs:13:9
-   |
-LL |         ""
-   |         ^^ expected `impl Debug`, got `&'static str`
-   |
-note: previous use here
-  --> $DIR/default-body-with-rpit.rs:12:39
-   |
-LL |       async fn baz(&self) -> impl Debug {
-   |  _______________________________________^
-LL | |         ""
-LL | |     }
-   | |_____^
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/default-body-with-rpit.rs:12:28
-   |
-LL |     async fn baz(&self) -> impl Debug {
-   |                            ^^^^^^^^^^ cannot resolve opaque type
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr
deleted file mode 100644
index 3c24eff9ae3..00000000000
--- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error: concrete type differs from previous defining opaque type use
-  --> $DIR/default-body-with-rpit.rs:13:9
-   |
-LL |         ""
-   |         ^^ expected `impl Debug`, got `&'static str`
-   |
-note: previous use here
-  --> $DIR/default-body-with-rpit.rs:12:39
-   |
-LL |       async fn baz(&self) -> impl Debug {
-   |  _______________________________________^
-LL | |         ""
-LL | |     }
-   | |_____^
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/default-body-with-rpit.rs:12:28
-   |
-LL |     async fn baz(&self) -> impl Debug {
-   |                            ^^^^^^^^^^ cannot resolve opaque type
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr
deleted file mode 100644
index 653016cf009..00000000000
--- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0277]: `()` doesn't implement `std::fmt::Display`
-  --> $DIR/doesnt-satisfy.rs:12:17
-   |
-LL |     fn bar() -> () {}
-   |                 ^^ `()` cannot be formatted with the default formatter
-   |
-   = help: the trait `std::fmt::Display` is not implemented for `()`
-   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-note: required by a bound in `Foo::bar::{opaque#0}`
-  --> $DIR/doesnt-satisfy.rs:8:22
-   |
-LL |     fn bar() -> impl std::fmt::Display;
-   |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{opaque#0}`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr
deleted file mode 100644
index f0cd43bcf92..00000000000
--- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0277]: `()` doesn't implement `std::fmt::Display`
-  --> $DIR/doesnt-satisfy.rs:12:17
-   |
-LL |     fn bar() -> () {}
-   |                 ^^ `()` cannot be formatted with the default formatter
-   |
-   = help: the trait `std::fmt::Display` is not implemented for `()`
-   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-note: required by a bound in `Foo::{opaque#0}`
-  --> $DIR/doesnt-satisfy.rs:8:22
-   |
-LL |     fn bar() -> impl std::fmt::Display;
-   |                      ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr
deleted file mode 100644
index d4d0124a659..00000000000
--- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0046]: not all trait items implemented, missing: `foo`
-  --> $DIR/dont-project-to-rpitit-with-no-value.rs:11:1
-   |
-LL |     fn foo(&self) -> impl Sized;
-   |     ---------------------------- `foo` from trait
-...
-LL | impl MyTrait for i32 {
-   | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr
deleted file mode 100644
index d4d0124a659..00000000000
--- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0046]: not all trait items implemented, missing: `foo`
-  --> $DIR/dont-project-to-rpitit-with-no-value.rs:11:1
-   |
-LL |     fn foo(&self) -> impl Sized;
-   |     ---------------------------- `foo` from trait
-...
-LL | impl MyTrait for i32 {
-   | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr
deleted file mode 100644
index 310edbcb6cd..00000000000
--- a/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
-  --> $DIR/generics-mismatch.rs:14:12
-   |
-LL |     fn bar(&self) -> impl Sized;
-   |           - expected 0 type parameters
-...
-LL |     fn bar<T>(&self) {}
-   |            ^ 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/impl-trait/in-trait/generics-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr
deleted file mode 100644
index 310edbcb6cd..00000000000
--- a/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
-  --> $DIR/generics-mismatch.rs:14:12
-   |
-LL |     fn bar(&self) -> impl Sized;
-   |           - expected 0 type parameters
-...
-LL |     fn bar<T>(&self) {}
-   |            ^ 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/impl-trait/in-trait/issue-102140.current.stderr b/tests/ui/impl-trait/in-trait/issue-102140.current.stderr
deleted file mode 100644
index 7aa7880e258..00000000000
--- a/tests/ui/impl-trait/in-trait/issue-102140.current.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:26:22
-   |
-LL |         MyTrait::foo(&self)
-   |         ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |         |
-   |         required by a bound introduced by this call
-   |
-help: consider removing the leading `&`-reference
-   |
-LL -         MyTrait::foo(&self)
-LL +         MyTrait::foo(self)
-   |
-
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:26:9
-   |
-LL |         MyTrait::foo(&self)
-   |         ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:26:9
-   |
-LL |         MyTrait::foo(&self)
-   |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.next.stderr b/tests/ui/impl-trait/in-trait/issue-102140.next.stderr
deleted file mode 100644
index 94893c9e7b4..00000000000
--- a/tests/ui/impl-trait/in-trait/issue-102140.next.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:26:22
-   |
-LL |         MyTrait::foo(&self)
-   |         ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |         |
-   |         required by a bound introduced by this call
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:26:9
-   |
-LL |         MyTrait::foo(&self)
-   |         ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
-error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:26:9
-   |
-LL |         MyTrait::foo(&self)
-   |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
-   |
-   = help: the trait `MyTrait` is implemented for `Outer`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/issue-102571.current.stderr b/tests/ui/impl-trait/in-trait/issue-102571.current.stderr
deleted file mode 100644
index cac9a29f644..00000000000
--- a/tests/ui/impl-trait/in-trait/issue-102571.current.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-102571.rs:23:9
-   |
-LL |     let () = t.bar();
-   |         ^^   ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
-   |         |
-   |         expected associated type, found `()`
-   |
-   = note: expected associated type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
-                    found unit type `()`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/issue-102571.next.stderr b/tests/ui/impl-trait/in-trait/issue-102571.next.stderr
deleted file mode 100644
index cac9a29f644..00000000000
--- a/tests/ui/impl-trait/in-trait/issue-102571.next.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-102571.rs:23:9
-   |
-LL |     let () = t.bar();
-   |         ^^   ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
-   |         |
-   |         expected associated type, found `()`
-   |
-   = note: expected associated type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
-                    found unit type `()`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/object-safety.current.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr
deleted file mode 100644
index 2c340a02319..00000000000
--- a/tests/ui/impl-trait/in-trait/object-safety.current.stderr
+++ /dev/null
@@ -1,49 +0,0 @@
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:20:33
-   |
-LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
-   |                                 ^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:10:22
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> impl Debug;
-   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
-   = help: consider moving `baz` to another trait
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:23:13
-   |
-LL |     let s = i.baz();
-   |             ^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:10:22
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> impl Debug;
-   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
-   = help: consider moving `baz` to another trait
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:20:13
-   |
-LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
-   |             ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:10:22
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> impl Debug;
-   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
-   = help: consider moving `baz` to another trait
-   = note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr
deleted file mode 100644
index 2c340a02319..00000000000
--- a/tests/ui/impl-trait/in-trait/object-safety.next.stderr
+++ /dev/null
@@ -1,49 +0,0 @@
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:20:33
-   |
-LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
-   |                                 ^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:10:22
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> impl Debug;
-   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
-   = help: consider moving `baz` to another trait
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:23:13
-   |
-LL |     let s = i.baz();
-   |             ^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:10:22
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> impl Debug;
-   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
-   = help: consider moving `baz` to another trait
-
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:20:13
-   |
-LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
-   |             ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:10:22
-   |
-LL | trait Foo {
-   |       --- this trait cannot be made into an object...
-LL |     fn baz(&self) -> impl Debug;
-   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
-   = help: consider moving `baz` to another trait
-   = note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr
deleted file mode 100644
index a57653b2c9e..00000000000
--- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/opaque-in-impl-is-opaque.rs:20:19
-   |
-LL |     fn bar(&self) -> impl Display {
-   |                      ------------ the found opaque type
-...
-LL |     let x: &str = ().bar();
-   |            ----   ^^^^^^^^ expected `&str`, found opaque type
-   |            |
-   |            expected due to this
-   |
-   = note: expected reference `&str`
-            found opaque type `impl std::fmt::Display`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr
deleted file mode 100644
index a57653b2c9e..00000000000
--- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/opaque-in-impl-is-opaque.rs:20:19
-   |
-LL |     fn bar(&self) -> impl Display {
-   |                      ------------ the found opaque type
-...
-LL |     let x: &str = ().bar();
-   |            ----   ^^^^^^^^ expected `&str`, found opaque type
-   |            |
-   |            expected due to this
-   |
-   = note: expected reference `&str`
-            found opaque type `impl std::fmt::Display`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs b/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs
new file mode 100644
index 00000000000..6330242ceeb
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Foo {
+    fn early<'a, T: 'a>(x: &'a T) -> impl Iterator<Item = impl Into<&'a T>>;
+
+    fn late<'a, T>(x: &'a T) -> impl Iterator<Item = impl Into<&'a T>>;
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr
deleted file mode 100644
index ff30103b771..00000000000
--- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
-  --> $DIR/return-dont-satisfy-bounds.rs:13:34
-   |
-LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
-   |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
-   |
-   = help: the trait `Foo<char>` is implemented for `Bar`
-note: required by a bound in `Foo::foo::{opaque#0}`
-  --> $DIR/return-dont-satisfy-bounds.rs:7:30
-   |
-LL |     fn foo<F2>(self) -> impl Foo<T>;
-   |                              ^^^^^^ required by this bound in `Foo::foo::{opaque#0}`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr
deleted file mode 100644
index 7c7f7feaa55..00000000000
--- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
-  --> $DIR/return-dont-satisfy-bounds.rs:13:34
-   |
-LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
-   |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
-   |
-   = help: the trait `Foo<char>` is implemented for `Bar`
-note: required by a bound in `Foo::{opaque#0}`
-  --> $DIR/return-dont-satisfy-bounds.rs:7:30
-   |
-LL |     fn foo<F2>(self) -> impl Foo<T>;
-   |                              ^^^^^^ required by this bound in `Foo::{opaque#0}`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr
deleted file mode 100644
index 8c9dd403174..00000000000
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:36:47
-   |
-LL |     fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-   |                 -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:17:40
-   |
-LL |     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:41:57
-   |
-LL |     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-   |                       -- this lifetime was captured     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:18:57
-   |
-LL |     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>>;
-   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:49:10
-   |
-LL |     fn async_fn_multiple<'a, 'b>(
-   |                              -- this lifetime was captured
-...
-LL |     ) -> impl Future<Output = Vec<u8>> + Captures2<'a, 'b> {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:20:12
-   |
-LL |         -> impl Future<Output = Vec<u8>> + Captures<'a>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + Captures2<'a, 'b>`
-
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/signature-mismatch.rs:58:10
-   |
-LL |     ) -> impl Future<Output = Vec<u8>> {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `impl Future<Output = Vec<u8>>` will meet its required lifetime bounds...
-   |
-note: ...that is required by this bound
-  --> $DIR/signature-mismatch.rs:25:42
-   |
-LL |     ) -> impl Future<Output = Vec<u8>> + 'a;
-   |                                          ^^
-help: consider adding an explicit lifetime bound...
-   |
-LL |     fn async_fn_reduce_outlive<'a, 'b, T: 'a>(
-   |                                         ++++
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr
deleted file mode 100644
index 8c9dd403174..00000000000
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:36:47
-   |
-LL |     fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-   |                 -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:17:40
-   |
-LL |     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:41:57
-   |
-LL |     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
-   |                       -- this lifetime was captured     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:18:57
-   |
-LL |     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>>;
-   |                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
-  --> $DIR/signature-mismatch.rs:49:10
-   |
-LL |     fn async_fn_multiple<'a, 'b>(
-   |                              -- this lifetime was captured
-...
-LL |     ) -> impl Future<Output = Vec<u8>> + Captures2<'a, 'b> {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: hidden type must only reference lifetimes captured by this impl trait
-  --> $DIR/signature-mismatch.rs:20:12
-   |
-LL |         -> impl Future<Output = Vec<u8>> + Captures<'a>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + Captures2<'a, 'b>`
-
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/signature-mismatch.rs:58:10
-   |
-LL |     ) -> impl Future<Output = Vec<u8>> {
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `impl Future<Output = Vec<u8>>` will meet its required lifetime bounds...
-   |
-note: ...that is required by this bound
-  --> $DIR/signature-mismatch.rs:25:42
-   |
-LL |     ) -> impl Future<Output = Vec<u8>> + 'a;
-   |                                          ^^
-help: consider adding an explicit lifetime bound...
-   |
-LL |     fn async_fn_reduce_outlive<'a, 'b, T: 'a>(
-   |                                         ++++
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr
deleted file mode 100644
index f48e7a1ed14..00000000000
--- a/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0053]: method `bar` has an incompatible type for trait
-  --> $DIR/specialization-broken.rs:19:22
-   |
-LL | default impl<U> Foo for U
-   |              - this type parameter
-...
-LL |     fn bar(&self) -> U {
-   |                      ^
-   |                      |
-   |                      expected associated type, found type parameter `U`
-   |                      help: change the output type to match the trait: `impl Sized`
-   |
-note: type in trait
-  --> $DIR/specialization-broken.rs:12:22
-   |
-LL |     fn bar(&self) -> impl Sized;
-   |                      ^^^^^^^^^^
-   = note: expected signature `fn(&U) -> impl Sized`
-              found signature `fn(&U) -> U`
-
-error: method with return-position `impl Trait` in trait cannot be specialized
-  --> $DIR/specialization-broken.rs:19:5
-   |
-LL |     fn bar(&self) -> U {
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-   = note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr
deleted file mode 100644
index f48e7a1ed14..00000000000
--- a/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0053]: method `bar` has an incompatible type for trait
-  --> $DIR/specialization-broken.rs:19:22
-   |
-LL | default impl<U> Foo for U
-   |              - this type parameter
-...
-LL |     fn bar(&self) -> U {
-   |                      ^
-   |                      |
-   |                      expected associated type, found type parameter `U`
-   |                      help: change the output type to match the trait: `impl Sized`
-   |
-note: type in trait
-  --> $DIR/specialization-broken.rs:12:22
-   |
-LL |     fn bar(&self) -> impl Sized;
-   |                      ^^^^^^^^^^
-   = note: expected signature `fn(&U) -> impl Sized`
-              found signature `fn(&U) -> U`
-
-error: method with return-position `impl Trait` in trait cannot be specialized
-  --> $DIR/specialization-broken.rs:19:5
-   |
-LL |     fn bar(&self) -> U {
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-   = note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr
deleted file mode 100644
index 64c942705cf..00000000000
--- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/trait-more-generics-than-impl.rs:14:11
-   |
-LL |     fn bar<T>() -> impl Sized;
-   |            - expected 1 type parameter
-...
-LL |     fn bar() -> impl Sized {}
-   |           ^ found 0 type parameters
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr
deleted file mode 100644
index 64c942705cf..00000000000
--- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/trait-more-generics-than-impl.rs:14:11
-   |
-LL |     fn bar<T>() -> impl Sized;
-   |            - expected 1 type parameter
-...
-LL |     fn bar() -> impl Sized {}
-   |           ^ found 0 type parameters
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr
deleted file mode 100644
index bf088ae8b25..00000000000
--- a/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/unconstrained-lt.rs:10:6
-   |
-LL | impl<'a, T> Foo for T {
-   |      ^^ unconstrained lifetime parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr
deleted file mode 100644
index bf088ae8b25..00000000000
--- a/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/unconstrained-lt.rs:10:6
-   |
-LL | impl<'a, T> Foo for T {
-   |      ^^ unconstrained lifetime parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr
deleted file mode 100644
index 74c84c012b1..00000000000
--- a/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr
+++ /dev/null
@@ -1,57 +0,0 @@
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/wf-bounds.rs:17:22
-   |
-LL |     fn nya() -> impl Wf<Vec<[u8]>>;
-   |                      ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-note: required by a bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/wf-bounds.rs:20:23
-   |
-LL |     fn nya2() -> impl Wf<[u8]>;
-   |                       ^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-note: required by a bound in `Wf`
-  --> $DIR/wf-bounds.rs:10:10
-   |
-LL | trait Wf<T> {
-   |          ^ required by this bound in `Wf`
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | trait Wf<T: ?Sized> {
-   |           ++++++++
-
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/wf-bounds.rs:23:44
-   |
-LL |     fn nya3() -> impl Wf<(), Output = impl Wf<Vec<[u8]>>>;
-   |                                            ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-note: required by a bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error[E0277]: `T` doesn't implement `std::fmt::Display`
-  --> $DIR/wf-bounds.rs:26:26
-   |
-LL |     fn nya4<T>() -> impl Wf<NeedsDisplay<T>>;
-   |                          ^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
-   |
-   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-note: required by a bound in `NeedsDisplay`
-  --> $DIR/wf-bounds.rs:14:24
-   |
-LL | struct NeedsDisplay<T: Display>(T);
-   |                        ^^^^^^^ required by this bound in `NeedsDisplay`
-help: consider restricting type parameter `T`
-   |
-LL |     fn nya4<T: std::fmt::Display>() -> impl Wf<NeedsDisplay<T>>;
-   |              +++++++++++++++++++
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr
deleted file mode 100644
index 74c84c012b1..00000000000
--- a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr
+++ /dev/null
@@ -1,57 +0,0 @@
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/wf-bounds.rs:17:22
-   |
-LL |     fn nya() -> impl Wf<Vec<[u8]>>;
-   |                      ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-note: required by a bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/wf-bounds.rs:20:23
-   |
-LL |     fn nya2() -> impl Wf<[u8]>;
-   |                       ^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-note: required by a bound in `Wf`
-  --> $DIR/wf-bounds.rs:10:10
-   |
-LL | trait Wf<T> {
-   |          ^ required by this bound in `Wf`
-help: consider relaxing the implicit `Sized` restriction
-   |
-LL | trait Wf<T: ?Sized> {
-   |           ++++++++
-
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/wf-bounds.rs:23:44
-   |
-LL |     fn nya3() -> impl Wf<(), Output = impl Wf<Vec<[u8]>>>;
-   |                                            ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-note: required by a bound in `Vec`
-  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
-
-error[E0277]: `T` doesn't implement `std::fmt::Display`
-  --> $DIR/wf-bounds.rs:26:26
-   |
-LL |     fn nya4<T>() -> impl Wf<NeedsDisplay<T>>;
-   |                          ^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
-   |
-   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-note: required by a bound in `NeedsDisplay`
-  --> $DIR/wf-bounds.rs:14:24
-   |
-LL | struct NeedsDisplay<T: Display>(T);
-   |                        ^^^^^^^ required by this bound in `NeedsDisplay`
-help: consider restricting type parameter `T`
-   |
-LL |     fn nya4<T: std::fmt::Display>() -> impl Wf<NeedsDisplay<T>>;
-   |              +++++++++++++++++++
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs b/tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs
new file mode 100644
index 00000000000..a2dd0a9308d
--- /dev/null
+++ b/tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs
@@ -0,0 +1,15 @@
+// check-pass
+// issue: 114597
+// edition: 2021
+
+struct A<'a> {
+    dat: &'a (),
+}
+
+impl<'a> A<'a> {
+    async fn a(&self) -> impl Iterator<Item = std::iter::Repeat<()>> {
+        std::iter::repeat(()).map(|()| std::iter::repeat(()))
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs
new file mode 100644
index 00000000000..bc739785c8b
--- /dev/null
+++ b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs
@@ -0,0 +1,10 @@
+// check-pass
+// issue: 114660
+
+#![feature(inline_const)]
+
+fn main() {
+    const { core::mem::transmute::<u8, u8> };
+    // Don't resolve the instance of this inline constant to be an intrinsic,
+    // even if the type of the constant is `extern "intrinsic" fn(u8) -> u8`.
+}
diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr
index df50118ac47..9bd96723d81 100644
--- a/tests/ui/issues/issue-21763.stderr
+++ b/tests/ui/issues/issue-21763.stderr
@@ -5,6 +5,7 @@ LL |     foo::<HashMap<Rc<()>, Rc<()>>>();
    |           ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
    |
    = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
    = note: required because it appears within the type `(Rc<()>, Rc<()>)`
    = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send`
 note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>`
diff --git a/tests/ui/issues/issue-24446.stderr b/tests/ui/issues/issue-24446.stderr
index 4afb87c4825..b40e73116e3 100644
--- a/tests/ui/issues/issue-24446.stderr
+++ b/tests/ui/issues/issue-24446.stderr
@@ -13,6 +13,7 @@ LL |     static foo: dyn Fn() -> u32 = || -> u32 {
    |                 ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)`
+   = note: consider using `std::sync::Arc<(dyn Fn() -> u32 + 'static)>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: shared static variables must have a type that implements `Sync`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/issues/issue-40827.stderr b/tests/ui/issues/issue-40827.stderr
index 7f5c578ae4f..67a5394bee9 100644
--- a/tests/ui/issues/issue-40827.stderr
+++ b/tests/ui/issues/issue-40827.stderr
@@ -7,6 +7,7 @@ LL |     f(Foo(Arc::new(Bar::B(None))));
    |     required by a bound introduced by this call
    |
    = help: within `Bar`, the trait `Sync` is not implemented for `Rc<Foo>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it appears within the type `Bar`
   --> $DIR/issue-40827.rs:6:6
    |
@@ -33,6 +34,7 @@ LL |     f(Foo(Arc::new(Bar::B(None))));
    |     required by a bound introduced by this call
    |
    = help: within `Bar`, the trait `Send` is not implemented for `Rc<Foo>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it appears within the type `Bar`
   --> $DIR/issue-40827.rs:6:6
    |
diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr
index 53c1940491f..37c7a293891 100644
--- a/tests/ui/kindck/kindck-impl-type-params.stderr
+++ b/tests/ui/kindck/kindck-impl-type-params.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL |     let a = &t as &dyn Gettable<T>;
    |             ^^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required for `S<T>` to implement `Gettable<T>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
@@ -42,6 +43,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL |     let a: &dyn Gettable<T> = &t;
    |                               ^^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required for `S<T>` to implement `Gettable<T>`
   --> $DIR/kindck-impl-type-params.rs:12:32
    |
diff --git a/tests/ui/kindck/kindck-nonsendable-1.stderr b/tests/ui/kindck/kindck-nonsendable-1.stderr
index cc6e1f59c77..37c8e10c82c 100644
--- a/tests/ui/kindck/kindck-nonsendable-1.stderr
+++ b/tests/ui/kindck/kindck-nonsendable-1.stderr
@@ -9,6 +9,7 @@ LL |     bar(move|| foo(x));
    |     required by a bound introduced by this call
    |
    = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc<usize>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it's used within this closure
   --> $DIR/kindck-nonsendable-1.rs:9:9
    |
diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr
index 284d5dcec31..27eebe27367 100644
--- a/tests/ui/kindck/kindck-send-object.stderr
+++ b/tests/ui/kindck/kindck-send-object.stderr
@@ -5,6 +5,7 @@ LL |     assert_send::<&'static (dyn Dummy + 'static)>();
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
+   = note: consider using `std::sync::Arc<(dyn Dummy + 'static)>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object.rs:5:18
@@ -19,6 +20,7 @@ LL |     assert_send::<Box<dyn Dummy>>();
    |                   ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `dyn Dummy`
+   = note: consider using `std::sync::Arc<dyn Dummy>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `Unique<dyn Dummy>` to implement `Send`
 note: required because it appears within the type `Box<dyn Dummy>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr
index 269193f73b4..62e0c5794d3 100644
--- a/tests/ui/kindck/kindck-send-object1.stderr
+++ b/tests/ui/kindck/kindck-send-object1.stderr
@@ -5,6 +5,7 @@ LL |     assert_send::<&'a dyn Dummy>();
    |                   ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`
+   = note: consider using `std::sync::Arc<(dyn Dummy + 'a)>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object1.rs:5:18
@@ -19,6 +20,7 @@ LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |                   ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)`
+   = note: consider using `std::sync::Arc<(dyn Dummy + 'a)>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send`
 note: required because it appears within the type `Box<dyn Dummy>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr
index 6b8df60227f..4608e88c1d1 100644
--- a/tests/ui/kindck/kindck-send-object2.stderr
+++ b/tests/ui/kindck/kindck-send-object2.stderr
@@ -5,6 +5,7 @@ LL |     assert_send::<&'static dyn Dummy>();
    |                   ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`
+   = note: consider using `std::sync::Arc<(dyn Dummy + 'static)>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-object2.rs:3:18
@@ -19,6 +20,7 @@ LL |     assert_send::<Box<dyn Dummy>>();
    |                   ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `dyn Dummy`
+   = note: consider using `std::sync::Arc<dyn Dummy>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `Unique<dyn Dummy>` to implement `Send`
 note: required because it appears within the type `Box<dyn Dummy>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr
index dc1bb6206af..3f18667f97b 100644
--- a/tests/ui/kindck/kindck-send-owned.stderr
+++ b/tests/ui/kindck/kindck-send-owned.stderr
@@ -5,6 +5,7 @@ LL |     assert_send::<Box<*mut u8>>();
    |                   ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `*mut u8`
+   = note: consider using `std::sync::Arc<*mut u8>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required for `Unique<*mut u8>` to implement `Send`
 note: required because it appears within the type `Box<*mut u8>`
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
diff --git a/tests/ui/kindck/kindck-send-unsafe.stderr b/tests/ui/kindck/kindck-send-unsafe.stderr
index f1a5054abbc..75230519c79 100644
--- a/tests/ui/kindck/kindck-send-unsafe.stderr
+++ b/tests/ui/kindck/kindck-send-unsafe.stderr
@@ -5,6 +5,7 @@ LL |     assert_send::<*mut isize>();
    |                   ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `*mut isize`
+   = note: consider using `std::sync::Arc<*mut isize>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-unsafe.rs:3:19
    |
@@ -18,6 +19,7 @@ LL |     assert_send::<*mut &'a isize>();
    |                   ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `*mut &'a isize`
+   = note: consider using `std::sync::Arc<*mut &'a isize>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_send`
   --> $DIR/kindck-send-unsafe.rs:3:19
    |
diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs
index d6b06719277..eeb51196236 100644
--- a/tests/ui/lto/issue-100772.rs
+++ b/tests/ui/lto/issue-100772.rs
@@ -1,6 +1,6 @@
-// run-pass
+// build-pass
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+// compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
 // no-prefer-dynamic
 // only-x86_64-unknown-linux-gnu
 
diff --git a/tests/ui/mut/mutable-enum-indirect.stderr b/tests/ui/mut/mutable-enum-indirect.stderr
index 9e1f4e1fe4e..0aa2f29160d 100644
--- a/tests/ui/mut/mutable-enum-indirect.stderr
+++ b/tests/ui/mut/mutable-enum-indirect.stderr
@@ -7,6 +7,7 @@ LL |     bar(&x);
    |     required by a bound introduced by this call
    |
    = help: within `&Foo`, the trait `Sync` is not implemented for `NoSync`
+   = note: consider using `std::sync::Arc<NoSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Foo`
   --> $DIR/mutable-enum-indirect.rs:11:6
    |
diff --git a/tests/ui/no-send-res-ports.stderr b/tests/ui/no-send-res-ports.stderr
index 75561f4119a..6fe1f2a1c84 100644
--- a/tests/ui/no-send-res-ports.stderr
+++ b/tests/ui/no-send-res-ports.stderr
@@ -14,6 +14,7 @@ LL | |     });
    | |_____^ `Rc<()>` cannot be sent between threads safely
    |
    = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it appears within the type `Port<()>`
   --> $DIR/no-send-res-ports.rs:5:8
    |
diff --git a/tests/ui/no_send-enum.stderr b/tests/ui/no_send-enum.stderr
index b5a14b551dc..7cd83b6b2cb 100644
--- a/tests/ui/no_send-enum.stderr
+++ b/tests/ui/no_send-enum.stderr
@@ -7,6 +7,7 @@ LL |     bar(x);
    |     required by a bound introduced by this call
    |
    = help: within `Foo`, the trait `Send` is not implemented for `NoSend`
+   = note: consider using `std::sync::Arc<NoSend>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Foo`
   --> $DIR/no_send-enum.rs:8:6
    |
diff --git a/tests/ui/no_send-rc.stderr b/tests/ui/no_send-rc.stderr
index ce25da559da..67bed5ba750 100644
--- a/tests/ui/no_send-rc.stderr
+++ b/tests/ui/no_send-rc.stderr
@@ -7,6 +7,7 @@ LL |     bar(x);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `Rc<{integer}>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required by a bound in `bar`
   --> $DIR/no_send-rc.rs:3:11
    |
diff --git a/tests/ui/no_share-enum.stderr b/tests/ui/no_share-enum.stderr
index 5b453e0da3b..03451413b2f 100644
--- a/tests/ui/no_share-enum.stderr
+++ b/tests/ui/no_share-enum.stderr
@@ -7,6 +7,7 @@ LL |     bar(x);
    |     required by a bound introduced by this call
    |
    = help: within `Foo`, the trait `Sync` is not implemented for `NoSync`
+   = note: consider using `std::sync::Arc<NoSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Foo`
   --> $DIR/no_share-enum.rs:8:6
    |
diff --git a/tests/ui/no_share-struct.stderr b/tests/ui/no_share-struct.stderr
index 9ce3a318f1d..e40d8f3e4b6 100644
--- a/tests/ui/no_share-struct.stderr
+++ b/tests/ui/no_share-struct.stderr
@@ -7,6 +7,7 @@ LL |     bar(x);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `bar`
   --> $DIR/no_share-struct.rs:8:11
    |
diff --git a/tests/ui/phantom-auto-trait.stderr b/tests/ui/phantom-auto-trait.stderr
index 5af648f6a0c..43ff20d4719 100644
--- a/tests/ui/phantom-auto-trait.stderr
+++ b/tests/ui/phantom-auto-trait.stderr
@@ -6,6 +6,7 @@ LL |     is_zen(x)
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required for `&T` to implement `Zen`
   --> $DIR/phantom-auto-trait.rs:10:24
    |
@@ -36,6 +37,7 @@ LL |     is_zen(x)
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required for `&T` to implement `Zen`
   --> $DIR/phantom-auto-trait.rs:10:24
    |
diff --git a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs
new file mode 100644
index 00000000000..a8a478ffc74
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs
@@ -0,0 +1,11 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type="lib"]
+
+// Issue 111888: this crate (1.) is imported by a proc-macro crate and (2.)
+// exports a no_mangle function; that combination of acts was broken for some
+// period of time. See further discussion in the test file that imports this
+// crate.
+
+#[no_mangle]
+pub fn some_no_mangle_function() { }
diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs
index 70b8d8da19b..72fd88e119f 100644
--- a/tests/ui/proc-macro/meta-macro-hygiene.rs
+++ b/tests/ui/proc-macro/meta-macro-hygiene.rs
@@ -3,8 +3,10 @@
 // edition:2018
 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no
 // check-pass
+// ignore-tidy-linelength
 // normalize-stdout-test "\d+#" -> "0#"
 // normalize-stdout-test "expn\d{3,}" -> "expnNNN"
+// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */"
 //
 // We don't care about symbol ids, so we set them all to 0
 // in the stdout
@@ -22,7 +24,7 @@ macro_rules! produce_it {
         // the fact that `print_def_site` is produced by a
         // `macro_rules!` macro in `make_macro`).
         meta_macro::print_def_site!($crate::dummy!());
-    }
+    };
 }
 
 fn main() {
diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout
index ac65ba07512..eeb7179e6fd 100644
--- a/tests/ui/proc-macro/meta-macro-hygiene.stdout
+++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout
@@ -1,5 +1,5 @@
 Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4)
-Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:44: 24:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#3) }]
+Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:26:37: 26:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:26:43: 26:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:44: 26:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:26:45: 26:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:50: 26:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:26:51: 26:53 (#3) }]
 Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }]
 #![feature /* 0#0 */(prelude_import)]
 // aux-build:make-macro.rs
@@ -7,8 +7,10 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro
 // edition:2018
 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no
 // check-pass
+// ignore-tidy-linelength
 // normalize-stdout-test "\d+#" -> "0#"
 // normalize-stdout-test "expn\d{3,}" -> "expnNNN"
+// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */"
 //
 // We don't care about symbol ids, so we set them all to 0
 // in the stdout
@@ -18,7 +20,7 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro
 use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*;
 #[macro_use /* 0#1 */]
 extern crate core /* 0#1 */;
-extern crate compiler_builtins /* 445 */ as _ /* 0#1 */;
+extern crate compiler_builtins /* NNN */ as _ /* 0#1 */;
 // Don't load unnecessary hygiene information from std
 extern crate std /* 0#0 */;
 
@@ -36,7 +38,7 @@ macro_rules! produce_it
         // relative to `meta_macro`, *not* `make_macro` (despite
         // the fact that `print_def_site` is produced by a
         // `macro_rules!` macro in `make_macro`).
-    }
+    } ;
 }
 
 fn main /* 0#0 */() { ; }
diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
new file mode 100644
index 00000000000..4e5208e5058
--- /dev/null
+++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs
@@ -0,0 +1,22 @@
+// build-pass
+// force-host
+// no-prefer-dynamic
+// aux-build:exports_no_mangle.rs
+#![crate_type = "proc-macro"]
+
+// Issue #111888: this proc-macro crate imports another crate that itself
+// exports a no_mangle function.
+//
+// That combination was broken for a period of time, because:
+//
+// In PR #99944 we *stopped* exporting no_mangle symbols from
+// proc-macro crates. The constructed linker version script still referred
+// to them, but resolving that discrepancy was left as a FIXME in the code.
+//
+// In PR #108017 we started telling the linker to check (via the
+// `--no-undefined-version` linker invocation flag) that every symbol referenced
+// in the "linker version script" is actually present in the linker input. So
+// the unresolved discrepancy from #99944 started surfacing as a compile-time
+// error.
+
+extern crate exports_no_mangle;
diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs
index fa52a975bca..1e9e90a6b6f 100644
--- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs
+++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs
@@ -3,12 +3,13 @@
 // check-pass
 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene
 // compile-flags: -Z trim-diagnostic-paths=no
+// ignore-tidy-linelength
 // normalize-stdout-test "\d+#" -> "0#"
 // normalize-stdout-test "expn\d{3,}" -> "expnNNN"
+// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */"
 // aux-build:test-macros.rs
 
 #![feature(decl_macro)]
-
 #![no_std] // Don't load unnecessary hygiene information from std
 extern crate std;
 
diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
index 4031eb98a38..c437853ac72 100644
--- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
+++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout
@@ -6,19 +6,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
         stream: TokenStream [
             Ident {
                 ident: "struct",
-                span: $DIR/nonterminal-token-hygiene.rs:31:5: 31:11 (#4),
+                span: $DIR/nonterminal-token-hygiene.rs:32:5: 32:11 (#4),
             },
             Ident {
                 ident: "S",
-                span: $DIR/nonterminal-token-hygiene.rs:31:12: 31:13 (#4),
+                span: $DIR/nonterminal-token-hygiene.rs:32:12: 32:13 (#4),
             },
             Punct {
                 ch: ';',
                 spacing: Alone,
-                span: $DIR/nonterminal-token-hygiene.rs:31:13: 31:14 (#4),
+                span: $DIR/nonterminal-token-hygiene.rs:32:13: 32:14 (#4),
             },
         ],
-        span: $DIR/nonterminal-token-hygiene.rs:21:27: 21:32 (#5),
+        span: $DIR/nonterminal-token-hygiene.rs:22:27: 22:32 (#5),
     },
 ]
 #![feature /* 0#0 */(prelude_import)]
@@ -28,18 +28,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
 // check-pass
 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene
 // compile-flags: -Z trim-diagnostic-paths=no
+// ignore-tidy-linelength
 // normalize-stdout-test "\d+#" -> "0#"
 // normalize-stdout-test "expn\d{3,}" -> "expnNNN"
+// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */"
 // aux-build:test-macros.rs
 
 #![feature /* 0#0 */(decl_macro)]
-
 #![no_std /* 0#0 */]
 #[prelude_import /* 0#1 */]
 use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*;
 #[macro_use /* 0#1 */]
 extern crate core /* 0#2 */;
-extern crate compiler_builtins /* 445 */ as _ /* 0#2 */;
+extern crate compiler_builtins /* NNN */ as _ /* 0#2 */;
 // Don't load unnecessary hygiene information from std
 extern crate std /* 0#0 */;
 
diff --git a/tests/ui/recursion/recursive-requirements.stderr b/tests/ui/recursion/recursive-requirements.stderr
index bb63f7cd0dc..ceb03c4cdbe 100644
--- a/tests/ui/recursion/recursive-requirements.stderr
+++ b/tests/ui/recursion/recursive-requirements.stderr
@@ -5,6 +5,7 @@ LL |     let _: AssertSync<Foo> = unimplemented!();
    |            ^^^^^^^^^^^^^^^ `*const Bar` cannot be shared between threads safely
    |
    = help: within `Foo`, the trait `Sync` is not implemented for `*const Bar`
+   = note: consider using `std::sync::Arc<*const Bar>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Foo`
   --> $DIR/recursive-requirements.rs:5:12
    |
@@ -23,6 +24,7 @@ LL |     let _: AssertSync<Foo> = unimplemented!();
    |            ^^^^^^^^^^^^^^^ `*const Foo` cannot be shared between threads safely
    |
    = help: within `Foo`, the trait `Sync` is not implemented for `*const Foo`
+   = note: consider using `std::sync::Arc<*const Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Bar`
   --> $DIR/recursive-requirements.rs:10:12
    |
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
index e73082c1127..f40dc27cb4c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait MyTrait {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
index 589e3f02420..687cb128b05 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
index 646955fd867..771c35cf6ab 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait Plus {
@@ -23,7 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
 
 pub const fn add_u32(a: u32, b: u32) -> u32 {
     a.plus(b)
-    //~^ ERROR cannot call
+    //~^ ERROR the trait bound
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
index 0ee1b1a5cb2..2d9c49af85a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
+error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
   --> $DIR/call-const-trait-method-fail.rs:25:7
    |
 LL |     a.plus(b)
-   |       ^^^^^^^
+   |       ^^^^ the trait `Plus` is not implemented for `u32`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `Plus` is implemented for `u32`
 
 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-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
index ff53eea1110..60cd000f2d8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr
@@ -1,20 +1,24 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:7:12
+error[E0015]: cannot call non-const fn `<i32 as Plus>::plus` in constant functions
+  --> $DIR/call-const-trait-method-pass.rs:36:7
    |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
+LL |     a.plus(b)
+   |       ^^^^^^^
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:15:12
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/call-const-trait-method-pass.rs:39:22
+   |
+LL | const ADD_INT: Int = Int(1i32) + Int(2i32);
+   |                      ^^^^^^^^^^^^^^^^^^^^^
    |
-LL | impl const PartialEq for Int {
-   |            ^^^^^^^^^
+note: impl defined here, but it is not `const`
+  --> $DIR/call-const-trait-method-pass.rs:7:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const std::ops::Add for Int {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
index 529a472e0bd..37faa3f6bce 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-chain.rs:9:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-chain.rs:18:32
    |
@@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
    |                                        ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
index bdc6ccc8aec..90cfe04a9a8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-dup-bound.rs:7:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-dup-bound.rs:18:44
    |
@@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits
 LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
    |                                     ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
index 7fbe89dba3c..bea1846e79b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr
@@ -1,17 +1,8 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/call-generic-method-pass.rs:9:12
-   |
-LL | impl const PartialEq for S {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/call-generic-method-pass.rs:18:32
    |
 LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
    |                                ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
index 4f858d61eeb..54bc4347722 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr
@@ -1,20 +1,25 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:7:12
+error[E0117]: only traits defined in the current crate can be implemented for primitive types
+  --> $DIR/const-and-non-const-impl.rs:7:1
    |
 LL | impl const std::ops::Add for i32 {
-   |            ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^-------------^^^^^---
+   | |          |                 |
+   | |          |                 `i32` is not defined in the current crate
+   | |          `i32` is not defined in the current crate
+   | impl doesn't use only types from inside the current crate
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   = note: define and implement a trait or new type instead
 
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:23:12
+error[E0119]: conflicting implementations of trait `Add` for type `Int`
+  --> $DIR/const-and-non-const-impl.rs:23:1
    |
+LL | impl std::ops::Add for Int {
+   | -------------------------- first implementation here
+...
 LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int`
 
 error: aborting due to 2 previous errors
 
+Some errors have detailed explanations: E0117, E0119.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
index 52984fb6be4..4854f41bf04 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 struct S;
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
index 3370f32061c..be668b4f13a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait ConstDefaultFn: Sized {
@@ -22,7 +22,7 @@ impl const ConstDefaultFn for ConstImpl {
 
 const fn test() {
     NonConstImpl.a();
-    //~^ ERROR cannot call
+    //~^ ERROR the trait bound
     ConstImpl.a();
 }
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
index 414688f71ed..7b558e3f773 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
+error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
   --> $DIR/const-default-method-bodies.rs:24:18
    |
 LL |     NonConstImpl.a();
-   |                  ^^^
+   |                  ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl`
 
 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/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
index 3de9d37d493..747ccbf0fab 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs
@@ -18,6 +18,10 @@ trait A { fn a() { } }
 
 impl A for NonTrivialDrop {}
 
+const fn check<T: ~const Destruct>(_: T) {}
+
+
+/* FIXME(effects)
 struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
 
 impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
@@ -26,11 +30,10 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> {
     }
 }
 
-const fn check<T: ~const Destruct>(_: T) {}
-
 const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
     ConstDropImplWithBounds(PhantomData)
 );
+*/
 
 struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
index 7de33003c48..100d1df87d6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr
@@ -1,28 +1,11 @@
-error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
-  --> $DIR/const-drop-fail-2.rs:25:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/const-drop-fail-2.rs:29:36
+  --> $DIR/const-drop-fail-2.rs:21:36
    |
 LL | const fn check<T: ~const Destruct>(_: T) {}
    |                                    ^      - value is dropped here
    |                                    |
    |                                    the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
-  --> $DIR/const-drop-fail-2.rs:39:9
-   |
-LL |         T::a();
-   |         ^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
index b28584e7e36..23e36887025 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
@@ -14,15 +14,6 @@ LL |     let _ = S(&mut c);
    |             |
    |             the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
-  --> $DIR/const-drop.rs:70:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
index b28584e7e36..23e36887025 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
@@ -14,15 +14,6 @@ LL |     let _ = S(&mut c);
    |             |
    |             the destructor for this type cannot be evaluated in constant functions
 
-error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
-  --> $DIR/const-drop.rs:70:13
-   |
-LL |             T::foo();
-   |             ^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
-For more information about an error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
index 2b4963991db..fc3a83876c5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs
@@ -1,9 +1,11 @@
-#![feature(const_trait_impl)]
+// known-bug: #110395
+
+#![feature(const_trait_impl, effects)]
 
 pub trait A {}
-//~^ HELP: mark `A` as const
+// FIXME ~^ HELP: mark `A` as const
 
 impl const A for () {}
-//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
+// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]`
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
index 478adcf3e9e..c45af1a9f8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr
@@ -1,5 +1,5 @@
 error: const `impl` for trait `A` which is not marked with `#[const_trait]`
-  --> $DIR/const-impl-requires-const-trait.rs:6:12
+  --> $DIR/const-impl-requires-const-trait.rs:8:12
    |
 LL | pub trait A {}
    | - help: mark `A` as const: `#[const_trait]`
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
index dba3ad7f870..348ca0ab190 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
@@ -1,5 +1,4 @@
 #[derive_const(Default)] //~ ERROR use of unstable library feature
-//~^ ERROR not marked with `#[const_trait]`
 pub struct S;
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
index 6a81f96d88d..cc9bdd2715f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
@@ -6,16 +6,6 @@ LL | #[derive_const(Default)]
    |
    = help: add `#![feature(derive_const)]` to the crate attributes to enable
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-gate.rs:1:16
-   |
-LL | #[derive_const(Default)]
-   |                ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
index b575ea8dae2..ce39045d71b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
@@ -1,5 +1,5 @@
 // known-bug: #110395
-#![feature(derive_const)]
+#![feature(derive_const, effects)]
 
 pub struct A;
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
index 88054096e63..046dbae0eae 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
@@ -10,44 +10,6 @@ error[E0635]: unknown feature `const_default_impls`
 LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
    |                                         ^^^^^^^^^^^^^^^^^^^
 
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:6:12
-   |
-LL | impl const Default for A {
-   |            ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:10:12
-   |
-LL | impl const PartialEq for A {
-   |            ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:14:16
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                ^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-use.rs:14:25
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                         ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0635`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
index fa78326587c..37d123e4ccc 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr
@@ -1,13 +1,3 @@
-error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/derive-const-with-params.rs:6:16
-   |
-LL | #[derive_const(PartialEq)]
-   |                ^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error: ~const can only be applied to `#[const_trait]` traits
   --> $DIR/derive-const-with-params.rs:6:16
    |
@@ -16,5 +6,5 @@ LL | #[derive_const(PartialEq)]
    |
    = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
index c936270de26..428286e0b12 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr
@@ -1,11 +1,11 @@
-error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
   --> $DIR/cross-crate.rs:17:14
    |
 LL |     NonConst.func();
-   |              ^^^^^^
+   |              ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
    |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`
 
 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/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
index 1f78af79418..95edbdc0efa 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs
@@ -1,6 +1,6 @@
 // revisions: stock gated stocknc gatednc
 // [gated] check-pass
-#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))]
+#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))]
 
 // aux-build: cross-crate.rs
 extern crate cross_crate;
@@ -16,7 +16,7 @@ const fn const_context() {
     #[cfg(any(stocknc, gatednc))]
     NonConst.func();
     //[stocknc]~^ ERROR: cannot call
-    //[gatednc]~^^ ERROR: cannot call
+    //[gatednc]~^^ ERROR: the trait bound
     Const.func();
     //[stock]~^ ERROR: cannot call
     //[stocknc]~^^ ERROR: cannot call
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
index c21c73f40f2..a6881b8fed5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `(): Tr` is not satisfied
+error[E0277]: the trait bound `(): ~const Tr` is not satisfied
   --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
    |
 LL |         ().a()
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
index 730e268c091..5a0db816a2b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs
@@ -1,5 +1,5 @@
 // check-pass
-#![feature(const_trait_impl, rustc_attrs)]
+#![feature(const_trait_impl, rustc_attrs, effects)]
 
 #[const_trait]
 trait Foo {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
index 49457354cc9..e7ba0505d9b 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs
@@ -7,7 +7,7 @@
 
 // ensure we are passing in the correct host effect in always const contexts.
 
-pub const fn hmm</* T, */ #[rustc_host] const host: bool = true>() -> usize {
+pub const fn hmm<T, #[rustc_host] const host: bool = true>() -> usize {
     if host {
         1
     } else {
@@ -16,14 +16,12 @@ pub const fn hmm</* T, */ #[rustc_host] const host: bool = true>() -> usize {
 }
 
 const _: () = {
-    let x = hmm();
+    let x = hmm::<()>();
     assert!(0 == x);
 };
 
-/* FIXME(effects)
 pub const fn uwu(x: [u8; hmm::<()>()]) {
     let [] = x;
 }
-*/
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
index 1b21d7c0e0e..6a177592b64 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr
@@ -1,11 +1,16 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/generic-bound.rs:16:15
+error[E0015]: cannot call non-const operator in constant functions
+  --> $DIR/generic-bound.rs:25:5
    |
-LL | impl<T> const std::ops::Add for S<T> {
-   |               ^^^^^^^^^^^^^
+LL |     arg + arg
+   |     ^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/generic-bound.rs:16:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl<T> const std::ops::Add for S<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = 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/hir-const-check.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
index 337c733403b..426534deb67 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs
@@ -1,6 +1,6 @@
 // Regression test for #69615.
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 pub trait MyTrait {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
index a3bb9b3f93e..9a93d01ed06 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -1,6 +1,6 @@
 // Tests that specializing trait impls must be at least as const as the default impl.
 
-#![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/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
index 0a28da9e65e..7206a89e5c5 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs
@@ -1,4 +1,4 @@
-#![feature(const_trait_impl, min_specialization, rustc_attrs)]
+#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)]
 
 #[rustc_specialization_trait]
 #[const_trait]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
index 1d79f5adf93..b3977e6cede 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
@@ -1,7 +1,7 @@
 // revisions: stable unstable
 
 #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file.
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![feature(staged_api)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
index 35dc1ca129b..deed05ae179 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr
@@ -1,20 +1,29 @@
-error: const `impl` for trait `Try` which is not marked with `#[const_trait]`
-  --> $DIR/trait-default-body-stability.rs:18:12
+error[E0015]: `?` cannot determine the branch of `T` in constant functions
+  --> $DIR/trait-default-body-stability.rs:44:9
    |
-LL | impl const Try for T {
-   |            ^^^
+LL |         T?
+   |         ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/trait-default-body-stability.rs:18:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const Try for T {
+   | ^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
-  --> $DIR/trait-default-body-stability.rs:33:12
+error[E0015]: `?` cannot convert from residual of `T` in constant functions
+  --> $DIR/trait-default-body-stability.rs:44:9
    |
-LL | impl const FromResidual for T {
-   |            ^^^^^^^^^^^^
+LL |         T?
+   |         ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $DIR/trait-default-body-stability.rs:33:1
    |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
+LL | impl const FromResidual for T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
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 29809a2ee56..6e1074035b7 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,7 +1,7 @@
 // known-bug: #110395
 // FIXME run-pass
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 #[const_trait]
 trait Bar {
diff --git a/tests/ui/sanitize/issue-111184-generator-witness.rs b/tests/ui/sanitize/issue-111184-generator-witness.rs
index 8f4118057ce..d36d8bce561 100644
--- a/tests/ui/sanitize/issue-111184-generator-witness.rs
+++ b/tests/ui/sanitize/issue-111184-generator-witness.rs
@@ -2,10 +2,10 @@
 // encode_ty and caused the compiler to ICE.
 //
 // needs-sanitizer-cfi
-// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
+// compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
 // no-prefer-dynamic
 // only-x86_64-unknown-linux-gnu
-// run-pass
+// build-pass
 
 use std::future::Future;
 
diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
index 29e32889fcc..e9a49dd3ff1 100644
--- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
+++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs
@@ -1,4 +1,4 @@
-// Verifies that `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`.
+// Verifies that `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`.
 //
 // needs-sanitizer-cfi
 // compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
index 5e706b513b9..8cd9c544417 100644
--- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
+++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr
@@ -1,4 +1,4 @@
-error: `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`
+error: `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs
new file mode 100644
index 00000000000..a13c12c1787
--- /dev/null
+++ b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs
@@ -0,0 +1,8 @@
+// Verifies that `-Zsanitizer=cfi` with `-Clto` or `-Clto=thin` requires `-Ccodegen-units=1`.
+//
+// needs-sanitizer-cfi
+// compile-flags: -Ccodegen-units=2 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr
new file mode 100644
index 00000000000..136f4936084
--- /dev/null
+++ b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr
@@ -0,0 +1,4 @@
+error: `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/self/arbitrary_self_type_mut_difference.rs b/tests/ui/self/arbitrary_self_type_mut_difference.rs
new file mode 100644
index 00000000000..e75c00ae956
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_type_mut_difference.rs
@@ -0,0 +1,13 @@
+// Related to #57994.
+use std::pin::Pin;
+struct S;
+
+impl S {
+    fn x(self: Pin<&mut Self>) {} //~ NOTE method is available for `Pin<&mut S>`
+    fn y(self: Pin<&Self>) {} //~ NOTE method is available for `Pin<&S>`
+}
+
+fn main() {
+    Pin::new(&S).x(); //~ ERROR no method named `x` found for struct `Pin<&S>` in the current scope
+    Pin::new(&mut S).y(); //~ ERROR no method named `y` found for struct `Pin<&mut S>` in the current scope
+}
diff --git a/tests/ui/self/arbitrary_self_type_mut_difference.stderr b/tests/ui/self/arbitrary_self_type_mut_difference.stderr
new file mode 100644
index 00000000000..a56d58694aa
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_type_mut_difference.stderr
@@ -0,0 +1,27 @@
+error[E0599]: no method named `x` found for struct `Pin<&S>` in the current scope
+  --> $DIR/arbitrary_self_type_mut_difference.rs:11:18
+   |
+LL |     Pin::new(&S).x();
+   |                  ^ help: there is a method with a similar name: `y`
+   |
+note: method is available for `Pin<&mut S>`
+  --> $DIR/arbitrary_self_type_mut_difference.rs:6:5
+   |
+LL |     fn x(self: Pin<&mut Self>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `y` found for struct `Pin<&mut S>` in the current scope
+  --> $DIR/arbitrary_self_type_mut_difference.rs:12:22
+   |
+LL |     Pin::new(&mut S).y();
+   |                      ^ help: there is a method with a similar name: `x`
+   |
+note: method is available for `Pin<&S>`
+  --> $DIR/arbitrary_self_type_mut_difference.rs:7:5
+   |
+LL |     fn y(self: Pin<&Self>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed
new file mode 100644
index 00000000000..6a94b85b9ba
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed
@@ -0,0 +1,17 @@
+// run-rustfix
+#![allow(dead_code)]
+mod first {
+    trait Foo { fn m(self: Box<Self>); }
+    fn foo<T: Foo>(a: T) {
+        Box::new(a).m(); //~ ERROR no method named `m` found
+    }
+}
+mod second {
+    use std::sync::Arc;
+    trait Bar { fn m(self: Arc<Self>); }
+    fn bar(b: impl Bar) {
+        Arc::new(b).m(); //~ ERROR no method named `m` found
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs
new file mode 100644
index 00000000000..fa480b1f72b
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs
@@ -0,0 +1,17 @@
+// run-rustfix
+#![allow(dead_code)]
+mod first {
+    trait Foo { fn m(self: Box<Self>); }
+    fn foo<T: Foo>(a: T) {
+        a.m(); //~ ERROR no method named `m` found
+    }
+}
+mod second {
+    use std::sync::Arc;
+    trait Bar { fn m(self: Arc<Self>); }
+    fn bar(b: impl Bar) {
+        b.m(); //~ ERROR no method named `m` found
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr
new file mode 100644
index 00000000000..2ab634ad3e8
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr
@@ -0,0 +1,43 @@
+error[E0599]: no method named `m` found for type parameter `T` in the current scope
+  --> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:6:11
+   |
+LL |     trait Foo { fn m(self: Box<Self>); }
+   |                    -       --------- the method might not be found because of this arbitrary self type
+   |                    |
+   |                    the method is available for `Box<T>` here
+LL |     fn foo<T: Foo>(a: T) {
+   |            - method `m` not found for this type parameter
+LL |         a.m();
+   |           ^ method not found in `T`
+...
+LL |     trait Bar { fn m(self: Arc<Self>); }
+   |                            --------- the method might not be found because of this arbitrary self type
+   |
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |         Box::new(a).m();
+   |         +++++++++ +
+
+error[E0599]: no method named `m` found for type parameter `impl Bar` in the current scope
+  --> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:13:11
+   |
+LL |     trait Foo { fn m(self: Box<Self>); }
+   |                            --------- the method might not be found because of this arbitrary self type
+...
+LL |     trait Bar { fn m(self: Arc<Self>); }
+   |                    -       --------- the method might not be found because of this arbitrary self type
+   |                    |
+   |                    the method is available for `Arc<impl Bar>` here
+LL |     fn bar(b: impl Bar) {
+   |               -------- method `m` not found for this type parameter
+LL |         b.m();
+   |           ^ method not found in `impl Bar`
+   |
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |         Arc::new(b).m();
+   |         +++++++++ +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
new file mode 100644
index 00000000000..ccd65ff4091
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+use std::pin::Pin;
+struct S;
+
+impl S {
+    fn x(self: Pin<&mut Self>) {
+    }
+}
+
+fn main() {
+    Pin::new(&mut S).x(); //~ ERROR no method named `x` found
+}
diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs b/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs
new file mode 100644
index 00000000000..d15676a623d
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs
@@ -0,0 +1,12 @@
+// run-rustfix
+use std::pin::Pin;
+struct S;
+
+impl S {
+    fn x(self: Pin<&mut Self>) {
+    }
+}
+
+fn main() {
+    S.x(); //~ ERROR no method named `x` found
+}
diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
new file mode 100644
index 00000000000..f34ce4dce49
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
@@ -0,0 +1,20 @@
+error[E0599]: no method named `x` found for struct `S` in the current scope
+  --> $DIR/arbitrary_self_types_needing_mut_pin.rs:11:7
+   |
+LL | struct S;
+   | -------- method `x` not found for this struct
+...
+LL |     fn x(self: Pin<&mut Self>) {
+   |        - the method is available for `Pin<&mut S>` here
+...
+LL |     S.x();
+   |       ^ method not found in `S`
+   |
+help: consider wrapping the receiver expression with the appropriate type
+   |
+LL |     Pin::new(&mut S).x();
+   |     +++++++++++++  +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs
new file mode 100644
index 00000000000..d877dbe6075
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs
@@ -0,0 +1,13 @@
+use std::pin::Pin;
+struct S;
+
+impl S {
+    fn x(self: Pin<&mut Self>) {
+    }
+}
+
+fn main() {
+    Pin::new(S).x();
+    //~^ ERROR the trait bound `S: Deref` is not satisfied
+    //~| ERROR no method named `x` found for struct `Pin` in the current scope
+}
diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr
new file mode 100644
index 00000000000..ec985b254b3
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the trait bound `S: Deref` is not satisfied
+  --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:14
+   |
+LL |     Pin::new(S).x();
+   |     -------- ^ the trait `Deref` is not implemented for `S`
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `Pin::<P>::new`
+  --> $SRC_DIR/core/src/pin.rs:LL:COL
+help: consider borrowing here
+   |
+LL |     Pin::new(&S).x();
+   |              +
+LL |     Pin::new(&mut S).x();
+   |              ++++
+
+error[E0599]: no method named `x` found for struct `Pin` in the current scope
+  --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:17
+   |
+LL |     Pin::new(S).x();
+   |                 ^ method not found in `Pin<S>`
+   |
+note: method is available for `Pin<&mut S>`
+  --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:5:5
+   |
+LL |     fn x(self: Pin<&mut Self>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 6eff899bfbf..621e8576249 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -1,5 +1,5 @@
 #![feature(staged_api)]
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 #![stable(feature = "stable", since = "1.0.0")]
 
 #[stable(feature = "stable", since = "1.0.0")]
diff --git a/tests/ui/statics/issue-17718-static-sync.stderr b/tests/ui/statics/issue-17718-static-sync.stderr
index bc6e45e5925..24e598280de 100644
--- a/tests/ui/statics/issue-17718-static-sync.stderr
+++ b/tests/ui/statics/issue-17718-static-sync.stderr
@@ -5,6 +5,7 @@ LL | static BAR: Foo = Foo;
    |             ^^^ `Foo` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: shared static variables must have a type that implements `Sync`
 
 error: aborting due to previous error
diff --git a/tests/ui/stdlib-unit-tests/not-sync.stderr b/tests/ui/stdlib-unit-tests/not-sync.stderr
index b9a266e4eb9..2ea08b8b4f4 100644
--- a/tests/ui/stdlib-unit-tests/not-sync.stderr
+++ b/tests/ui/stdlib-unit-tests/not-sync.stderr
@@ -33,6 +33,7 @@ LL |     test::<Rc<i32>>();
    |            ^^^^^^^ `Rc<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Rc<i32>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required by a bound in `test`
   --> $DIR/not-sync.rs:5:12
    |
@@ -46,6 +47,7 @@ LL |     test::<Weak<i32>>();
    |            ^^^^^^^^^ `std::rc::Weak<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `std::rc::Weak<i32>`
+   = note: consider using `std::sync::Arc<std::rc::Weak<i32>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `test`
   --> $DIR/not-sync.rs:5:12
    |
@@ -59,6 +61,7 @@ LL |     test::<Receiver<i32>>();
    |            ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
+   = note: consider using `std::sync::Arc<std::sync::mpsc::Receiver<i32>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `test`
   --> $DIR/not-sync.rs:5:12
    |
diff --git a/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr b/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr
index a3ab0b8efb0..86e044ac00a 100644
--- a/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr
+++ b/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr
@@ -7,6 +7,7 @@ LL |     assert_is_send(&bar);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
+   = note: consider using `std::sync::Arc<<impl Foo as Foo>::Bar>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_is_send`
   --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:30:22
    |
@@ -26,6 +27,7 @@ LL |     assert_is_send(&bar);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `<impl Foo as Foo>::Bar`
+   = note: consider using `std::sync::Arc<<impl Foo as Foo>::Bar>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `assert_is_send`
   --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:30:22
    |
diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr
index 4de9da89c9b..a3b7805c072 100644
--- a/tests/ui/suggestions/issue-84973-blacklist.stderr
+++ b/tests/ui/suggestions/issue-84973-blacklist.stderr
@@ -71,6 +71,7 @@ LL |     f_send(rc);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `Rc<{integer}>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required by a bound in `f_send`
   --> $DIR/issue-84973-blacklist.rs:10:14
    |
diff --git a/tests/ui/suggestions/restrict-type-argument.stderr b/tests/ui/suggestions/restrict-type-argument.stderr
index 01c2de79864..205634a8d68 100644
--- a/tests/ui/suggestions/restrict-type-argument.stderr
+++ b/tests/ui/suggestions/restrict-type-argument.stderr
@@ -6,6 +6,7 @@ LL |     is_send(val);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<impl Sync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
    |
@@ -24,6 +25,7 @@ LL |     is_send(val);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<S>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
    |
@@ -42,6 +44,7 @@ LL |     is_send(val);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<S>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
    |
@@ -60,6 +63,7 @@ LL |     is_send(val);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<S>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
    |
@@ -78,6 +82,7 @@ LL |     is_send(val);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<S>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
    |
@@ -96,6 +101,7 @@ LL |     is_send(val);
    |     |
    |     required by a bound introduced by this call
    |
+   = note: consider using `std::sync::Arc<S>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/restrict-type-argument.rs:1:15
    |
diff --git a/tests/ui/traits/alias/cross-crate.stderr b/tests/ui/traits/alias/cross-crate.stderr
index ae9d7d0a9b4..bccdd3da04e 100644
--- a/tests/ui/traits/alias/cross-crate.stderr
+++ b/tests/ui/traits/alias/cross-crate.stderr
@@ -5,6 +5,7 @@ LL |     use_alias::<Rc<u32>>();
    |                 ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Rc<u32>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
    = note: required for `Rc<u32>` to implement `SendSync`
 note: required by a bound in `use_alias`
   --> $DIR/cross-crate.rs:10:17
@@ -19,6 +20,7 @@ LL |     use_alias::<Rc<u32>>();
    |                 ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `Rc<u32>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
    = note: required for `Rc<u32>` to implement `SendSync`
 note: required by a bound in `use_alias`
   --> $DIR/cross-crate.rs:10:17
diff --git a/tests/ui/traits/bad-method-typaram-kind.stderr b/tests/ui/traits/bad-method-typaram-kind.stderr
index 56acfbe80d0..074284cbdd4 100644
--- a/tests/ui/traits/bad-method-typaram-kind.stderr
+++ b/tests/ui/traits/bad-method-typaram-kind.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL |     1.bar::<T>();
    |             ^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `Bar::bar`
   --> $DIR/bad-method-typaram-kind.rs:6:14
    |
diff --git a/tests/ui/traits/inductive-overflow/two-traits.stderr b/tests/ui/traits/inductive-overflow/two-traits.stderr
index 0d0bf88616c..d2f809f3577 100644
--- a/tests/ui/traits/inductive-overflow/two-traits.stderr
+++ b/tests/ui/traits/inductive-overflow/two-traits.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be shared between threads safely
 LL |     type X = Self;
    |              ^^^^ `T` cannot be shared between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `Magic::X`
   --> $DIR/two-traits.rs:8:13
    |
diff --git a/tests/ui/traits/issue-7013.stderr b/tests/ui/traits/issue-7013.stderr
index 1c0e8bcf185..335c7cd2485 100644
--- a/tests/ui/traits/issue-7013.stderr
+++ b/tests/ui/traits/issue-7013.stderr
@@ -5,6 +5,7 @@ LL |     let a = A {v: Box::new(B{v: None}) as Box<dyn Foo + Send>};
    |                   ^^^^^^^^^^^^^^^^^^^^ `Rc<RefCell<A>>` cannot be sent between threads safely
    |
    = help: within `B`, the trait `Send` is not implemented for `Rc<RefCell<A>>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it appears within the type `Option<Rc<RefCell<A>>>`
   --> $SRC_DIR/core/src/option.rs:LL:COL
 note: required because it appears within the type `B`
diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr
index a53879657f5..b61ad52a67a 100644
--- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr
+++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr
@@ -7,6 +7,7 @@ LL |     Outer(TestType);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `dummy::TestType`
+   = note: consider using `std::sync::Arc<dummy::TestType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `Outer`
   --> $DIR/negated-auto-traits-error.rs:10:17
    |
@@ -20,6 +21,7 @@ LL |     Outer(TestType);
    |     ^^^^^^^^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `dummy::TestType`
+   = note: consider using `std::sync::Arc<dummy::TestType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `Outer`
   --> $DIR/negated-auto-traits-error.rs:10:17
    |
@@ -35,6 +37,7 @@ LL |     is_send(TestType);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `dummy1b::TestType`
+   = note: consider using `std::sync::Arc<dummy1b::TestType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
    |
@@ -50,6 +53,7 @@ LL |     is_send((8, TestType));
    |     required by a bound introduced by this call
    |
    = help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType`
+   = note: consider using `std::sync::Arc<dummy1c::TestType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
    = note: required because it appears within the type `({integer}, TestType)`
 note: required by a bound in `is_send`
   --> $DIR/negated-auto-traits-error.rs:16:15
@@ -88,6 +92,7 @@ LL |     is_send(Box::new(Outer2(TestType)));
    |     required by a bound introduced by this call
    |
    = help: within `Outer2<dummy3::TestType>`, the trait `Send` is not implemented for `dummy3::TestType`
+   = note: consider using `std::sync::Arc<dummy3::TestType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `Outer2<TestType>`
   --> $DIR/negated-auto-traits-error.rs:12:8
    |
@@ -111,6 +116,7 @@ LL |     is_sync(Outer2(TestType));
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `main::TestType`
+   = note: consider using `std::sync::Arc<main::TestType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required for `Outer2<main::TestType>` to implement `Sync`
   --> $DIR/negated-auto-traits-error.rs:14:22
    |
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
index 4aefdd6bb07..ee260ca11b6 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
@@ -7,6 +7,7 @@ LL |     is_send(foo());
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `impl Future<Output = ()>`
+   = note: consider using `std::sync::Arc<impl Future<Output = ()>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/auto-with-drop_tracking_mir.rs:24:24
    |
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
new file mode 100644
index 00000000000..f06b98a79cf
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
@@ -0,0 +1,46 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs, trivial_bounds)]
+
+// We have to be careful here:
+//
+// We either have the provisional result of `A -> B -> A` on the
+// stack, which is a fully coinductive cycle. Accessing the
+// provisional result for `B` as part of the `A -> C -> B -> A` cycle
+// has to make sure we don't just use the result of `A -> B -> A` as the
+// new cycle is inductive.
+//
+// Alternatively, if we have `A -> C -> A` first, then `A -> B -> A` has
+// a purely inductive stack, so something could also go wrong here.
+
+#[rustc_coinductive]
+trait A {}
+#[rustc_coinductive]
+trait B {}
+trait C {}
+
+impl<T: B + C> A for T {}
+impl<T: A> B for T {}
+impl<T: B> C for T {}
+
+fn impls_a<T: A>() {}
+
+// The same test with reordered where clauses to make sure we're actually testing anything.
+#[rustc_coinductive]
+trait AR {}
+#[rustc_coinductive]
+trait BR {}
+trait CR {}
+
+impl<T: CR + BR> AR for T {}
+impl<T: AR> BR for T {}
+impl<T: BR> CR for T {}
+
+fn impls_ar<T: AR>() {}
+
+fn main() {
+    impls_a::<()>();
+    //~^ ERROR overflow evaluating the requirement `(): A`
+
+    impls_ar::<()>();
+    //~^ ERROR overflow evaluating the requirement `(): AR`
+}
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
new file mode 100644
index 00000000000..33fac603cbd
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
@@ -0,0 +1,29 @@
+error[E0275]: overflow evaluating the requirement `(): A`
+  --> $DIR/inductive-not-on-stack.rs:41:5
+   |
+LL |     impls_a::<()>();
+   |     ^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
+note: required by a bound in `impls_a`
+  --> $DIR/inductive-not-on-stack.rs:25:15
+   |
+LL | fn impls_a<T: A>() {}
+   |               ^ required by this bound in `impls_a`
+
+error[E0275]: overflow evaluating the requirement `(): AR`
+  --> $DIR/inductive-not-on-stack.rs:44:5
+   |
+LL |     impls_ar::<()>();
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
+note: required by a bound in `impls_ar`
+  --> $DIR/inductive-not-on-stack.rs:38:16
+   |
+LL | fn impls_ar<T: AR>() {}
+   |                ^^ required by this bound in `impls_ar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/no_send-struct.stderr b/tests/ui/traits/no_send-struct.stderr
index ee7bdf282b7..a13ef090154 100644
--- a/tests/ui/traits/no_send-struct.stderr
+++ b/tests/ui/traits/no_send-struct.stderr
@@ -7,6 +7,7 @@ LL |     bar(x);
    |     required by a bound introduced by this call
    |
    = help: the trait `Send` is not implemented for `Foo`
+   = note: consider using `std::sync::Arc<Foo>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `bar`
   --> $DIR/no_send-struct.rs:11:11
    |
diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr
index 7bd02550fb3..c0773ecec6c 100644
--- a/tests/ui/traits/non_lifetime_binders/fail.stderr
+++ b/tests/ui/traits/non_lifetime_binders/fail.stderr
@@ -29,6 +29,7 @@ LL |     auto_trait();
    |     ^^^^^^^^^^ `T` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `T`
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `auto_trait`
   --> $DIR/fail.rs:15:15
    |
diff --git a/tests/ui/traits/unsend-future.stderr b/tests/ui/traits/unsend-future.stderr
index 6ce1cf452f4..004c657c378 100644
--- a/tests/ui/traits/unsend-future.stderr
+++ b/tests/ui/traits/unsend-future.stderr
@@ -5,6 +5,7 @@ LL |     require_handler(handler)
    |                     ^^^^^^^ future returned by `handler` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const i32`
+   = note: consider using `std::sync::Arc<*const i32>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: future is not `Send` as this value is used across an await
   --> $DIR/unsend-future.rs:15:14
    |
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
index fc89b0e870e..40f6f83f235 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
@@ -22,4 +22,5 @@ fn main() {
     //~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277]
     //~| NOTE cannot be sent
     //~| NOTE required by a bound
+    //~| NOTE use `std::sync::Arc` instead
 }
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
index d7247302dd1..38c78c02bc5 100644
--- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
+++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
@@ -10,6 +10,7 @@ LL |     is_send(m::foo());
    |     required by a bound introduced by this call
    |
    = help: within `Foo`, the trait `Send` is not implemented for `Rc<u32>`
+   = note: use `std::sync::Arc` instead of `std::rc::Rc`
 note: required because it appears within the type `Foo`
   --> $DIR/auto-trait-leakage2.rs:7:16
    |
diff --git a/tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs b/tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs
new file mode 100644
index 00000000000..b92e15aad56
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs
@@ -0,0 +1,19 @@
+//check-pass
+
+pub struct Key;
+#[derive(Clone)]
+pub struct Value;
+
+use std::collections::HashMap;
+
+pub struct DiagnosticBuilder<'db> {
+    inner: HashMap<&'db Key, Vec<&'db Value>>,
+}
+
+impl<'db> DiagnosticBuilder<'db> {
+    pub fn iter<'a>(&'a self) -> impl Iterator<Item = (&'db Key, impl Iterator<Item = &'a Value>)> {
+        self.inner.iter().map(|(key, values)| (*key, values.iter().map(|v| *v)))
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr b/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
index 468a14762c0..39c8f4173ab 100644
--- a/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
+++ b/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
@@ -5,6 +5,7 @@ LL |     is_send::<T::AssocType>();
    |               ^^^^^^^^^^^^ `<T as Trait>::AssocType` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `<T as Trait>::AssocType`
+   = note: consider using `std::sync::Arc<<T as Trait>::AssocType>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/typeck-default-trait-impl-assoc-type.rs:14:14
    |
diff --git a/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr b/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr
index 2ce32990e55..3b5dc456560 100644
--- a/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr
+++ b/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr
@@ -5,6 +5,7 @@ LL |     is_send::<MyNotSendable>();
    |               ^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `MyNotSendable`
+   = note: consider using `std::sync::Arc<MyNotSendable>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/typeck-default-trait-impl-negation-send.rs:15:15
    |
diff --git a/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
index b9fca1a1b54..a6bfecbe1df 100644
--- a/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
+++ b/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
@@ -5,6 +5,7 @@ LL |     is_sync::<MyNotSync>();
    |               ^^^^^^^^^ `MyNotSync` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `MyNotSync`
+   = note: consider using `std::sync::Arc<MyNotSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_sync`
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:15
    |
@@ -18,6 +19,7 @@ LL |     is_sync::<MyTypeWUnsafe>();
    |               ^^^^^^^^^^^^^ `UnsafeCell<u8>` cannot be shared between threads safely
    |
    = help: within `MyTypeWUnsafe`, the trait `Sync` is not implemented for `UnsafeCell<u8>`
+   = note: consider using `std::sync::Arc<UnsafeCell<u8>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `MyTypeWUnsafe`
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:21:8
    |
@@ -36,6 +38,7 @@ LL |     is_sync::<MyTypeManaged>();
    |               ^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely
    |
    = help: within `MyTypeManaged`, the trait `Sync` is not implemented for `Managed`
+   = note: consider using `std::sync::Arc<Managed>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `MyTypeManaged`
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:25:8
    |
diff --git a/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr b/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr
index 887a1ddbb69..2797d995e5b 100644
--- a/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr
+++ b/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr
@@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely
 LL |     is_send::<T>()
    |               ^ `T` cannot be sent between threads safely
    |
+   = note: consider using `std::sync::Arc<T>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `is_send`
   --> $DIR/typeck-default-trait-impl-send-param.rs:8:14
    |
diff --git a/tests/ui/typeck/typeck-unsafe-always-share.stderr b/tests/ui/typeck/typeck-unsafe-always-share.stderr
index 154e504996b..e3d26790f5e 100644
--- a/tests/ui/typeck/typeck-unsafe-always-share.stderr
+++ b/tests/ui/typeck/typeck-unsafe-always-share.stderr
@@ -7,6 +7,7 @@ LL |     test(us);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `UnsafeCell<MySync<{integer}>>`
+   = note: consider using `std::sync::Arc<UnsafeCell<MySync<{integer}>>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `test`
   --> $DIR/typeck-unsafe-always-share.rs:15:12
    |
@@ -22,6 +23,7 @@ LL |     test(uns);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `UnsafeCell<NoSync>`
+   = note: consider using `std::sync::Arc<UnsafeCell<NoSync>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `test`
   --> $DIR/typeck-unsafe-always-share.rs:15:12
    |
@@ -37,6 +39,7 @@ LL |     test(ms);
    |     required by a bound introduced by this call
    |
    = help: within `MySync<NoSync>`, the trait `Sync` is not implemented for `UnsafeCell<NoSync>`
+   = note: consider using `std::sync::Arc<UnsafeCell<NoSync>>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required because it appears within the type `MySync<NoSync>`
   --> $DIR/typeck-unsafe-always-share.rs:8:8
    |
@@ -57,6 +60,7 @@ LL |     test(NoSync);
    |     required by a bound introduced by this call
    |
    = help: the trait `Sync` is not implemented for `NoSync`
+   = note: consider using `std::sync::Arc<NoSync>`; for more information visit <https://doc.rust-lang.org/book/ch16-03-shared-state.html>
 note: required by a bound in `test`
   --> $DIR/typeck-unsafe-always-share.rs:15:12
    |
diff --git a/x.py b/x.py
index ba959a3047e..6c4c106817e 100755
--- a/x.py
+++ b/x.py
@@ -40,7 +40,7 @@ if __name__ == '__main__':
 
             This message can be suppressed by setting `RUST_IGNORE_OLD_PYTHON=1`
         """.format(major, minor))
-        warnings.warn(msg)
+        warnings.warn(msg, stacklevel=1)
 
     rust_dir = os.path.dirname(os.path.abspath(__file__))
     # For the import below, have Python search in src/bootstrap first.