about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes6
-rw-r--r--compiler/rustc_ast/src/util/comments/tests.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0307.md6
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0708.md4
-rw-r--r--compiler/rustc_errors/src/lib.rs7
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs4
-rw-r--r--compiler/rustc_hir/src/tests.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl4
-rw-r--r--compiler/rustc_hir_analysis/src/autoderef.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs118
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs27
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs560
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_lint/src/async_closures.rs4
-rw-r--r--compiler/rustc_lint/src/tests.rs2
-rw-r--r--compiler/rustc_middle/src/traits/query.rs12
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs37
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs95
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs44
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs56
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs5
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs14
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs6
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs12
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs2
-rw-r--r--compiler/rustc_parse/src/parser/tokenstream/tests.rs2
-rw-r--r--compiler/rustc_span/src/edit_distance/tests.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/base/windows_gnullvm.rs2
-rw-r--r--compiler/rustc_target/src/target_features.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs59
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs58
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs79
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs26
-rw-r--r--library/alloc/src/alloc.rs3
-rw-r--r--library/alloc/src/boxed.rs9
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs3
-rw-r--r--library/alloc/src/ffi/c_str.rs3
-rw-r--r--library/alloc/src/lib.rs4
-rw-r--r--library/alloc/src/sync.rs3
-rw-r--r--library/alloc/tests/alloc.rs (renamed from library/alloc/src/alloc/tests.rs)5
-rw-r--r--library/alloc/tests/c_str2.rs (renamed from library/alloc/src/ffi/c_str/tests.rs)7
-rw-r--r--library/alloc/tests/collections/binary_heap.rs (renamed from library/alloc/src/collections/binary_heap/tests.rs)8
-rw-r--r--library/alloc/tests/collections/mod.rs1
-rw-r--r--library/alloc/tests/lib.rs24
-rw-r--r--library/alloc/tests/misc_tests.rs (renamed from library/alloc/src/tests.rs)0
-rw-r--r--library/alloc/tests/sync.rs (renamed from library/alloc/src/sync/tests.rs)10
-rw-r--r--library/alloc/tests/testing/crash_test.rs80
-rw-r--r--library/alloc/tests/testing/mod.rs1
-rw-r--r--library/core/src/ops/async_function.rs24
-rw-r--r--library/core/src/prelude/mod.rs4
-rw-r--r--library/core/src/ptr/mut_ptr.rs9
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/hurd/mod.rs1
-rw-r--r--library/std/src/prelude/common.rs3
-rw-r--r--library/std/src/prelude/mod.rs21
-rw-r--r--library/unwind/src/lib.rs5
-rw-r--r--library/unwind/src/libunwind.rs9
-rw-r--r--src/bootstrap/src/bin/main.rs20
-rw-r--r--src/bootstrap/src/bin/rustc.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs46
-rw-r--r--src/bootstrap/src/core/build_steps/suggest.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs6
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs9
-rw-r--r--src/bootstrap/src/core/builder/mod.rs14
-rw-r--r--src/bootstrap/src/core/config/config.rs60
-rw-r--r--src/bootstrap/src/core/config/flags.rs4
-rw-r--r--src/bootstrap/src/core/download.rs26
-rw-r--r--src/bootstrap/src/core/sanity.rs4
-rw-r--r--src/bootstrap/src/lib.rs28
-rw-r--r--src/bootstrap/src/utils/cc_detect.rs10
-rw-r--r--src/bootstrap/src/utils/helpers.rs6
-rw-r--r--src/bootstrap/src/utils/metrics.rs2
-rw-r--r--src/bootstrap/src/utils/render_tests.rs50
-rw-r--r--src/bootstrap/src/utils/tarball.rs2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh2
-rw-r--r--src/librustdoc/html/render/search_index.rs2
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.fixed1
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.rs1
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.stderr12
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.rs1
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.rs1
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.stderr42
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr34
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.rs2
-rw-r--r--src/tools/compiletest/src/compute_diff.rs2
-rw-r--r--src/tools/compiletest/src/debuggers.rs6
-rw-r--r--src/tools/compiletest/src/lib.rs10
-rw-r--r--src/tools/compiletest/src/runtest.rs52
-rw-r--r--src/tools/compiletest/src/runtest/codegen_units.rs22
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs10
-rw-r--r--src/tools/compiletest/src/runtest/incremental.rs2
-rw-r--r--src/tools/compiletest/src/runtest/mir_opt.rs2
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs2
-rw-r--r--src/tools/compiletest/src/runtest/ui.rs4
-rw-r--r--src/tools/compiletest/src/util.rs2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/tests/pass/async-closure-captures.rs2
-rw-r--r--src/tools/miri/tests/pass/async-closure-drop.rs2
-rw-r--r--src/tools/miri/tests/pass/async-closure.rs2
-rw-r--r--src/tools/miri/tests/pass/async-drop.rs2
-rw-r--r--tests/codegen/async-closure-debug.rs2
-rw-r--r--tests/coverage/async_closure.cov-map24
-rw-r--r--tests/coverage/async_closure.coverage1
-rw-r--r--tests/coverage/async_closure.rs1
-rw-r--r--tests/crashes/116979.rs14
-rw-r--r--tests/crashes/117808.rs27
-rw-r--r--tests/crashes/117877.rs13
-rw-r--r--tests/crashes/118778.rs24
-rw-r--r--tests/crashes/118784.rs19
-rw-r--r--tests/crashes/120175.rs11
-rw-r--r--tests/crashes/121176.rs9
-rw-r--r--tests/crashes/123861.rs5
-rw-r--r--tests/crashes/123862.rs14
-rw-r--r--tests/crashes/130395.rs10
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir2
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir6
-rw-r--r--tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir6
-rw-r--r--tests/mir-opt/async_closure_shims.rs1
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs2
-rw-r--r--tests/ui/asm/generic_const_simd_vec_len.rs21
-rw-r--r--tests/ui/asm/generic_const_simd_vec_len.stderr14
-rw-r--r--tests/ui/asm/named_const_simd_vec_len.rs22
-rw-r--r--tests/ui/async-await/async-borrowck-escaping-closure-error.rs1
-rw-r--r--tests/ui/async-await/async-borrowck-escaping-closure-error.stderr2
-rw-r--r--tests/ui/async-await/async-closure-matches-expr.rs2
-rw-r--r--tests/ui/async-await/async-closure.rs2
-rw-r--r--tests/ui/async-await/async-closures/ambiguous-arg.rs2
-rw-r--r--tests/ui/async-await/async-closures/ambiguous-arg.stderr2
-rw-r--r--tests/ui/async-await/async-closures/arg-mismatch.rs2
-rw-r--r--tests/ui/async-await/async-closures/arg-mismatch.stderr4
-rw-r--r--tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/auxiliary/block-on.rs2
-rw-r--r--tests/ui/async-await/async-closures/auxiliary/foreign.rs2
-rw-r--r--tests/ui/async-await/async-closures/await-inference-guidance.rs2
-rw-r--r--tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs2
-rw-r--r--tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs2
-rw-r--r--tests/ui/async-await/async-closures/brand.rs2
-rw-r--r--tests/ui/async-await/async-closures/call-once-deduction.rs2
-rw-r--r--tests/ui/async-await/async-closures/captures.rs2
-rw-r--r--tests/ui/async-await/async-closures/clone-closure.rs2
-rw-r--r--tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs2
-rw-r--r--tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr4
-rw-r--r--tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs2
-rw-r--r--tests/ui/async-await/async-closures/debuginfo-by-move-body.rs2
-rw-r--r--tests/ui/async-await/async-closures/def-path.rs2
-rw-r--r--tests/ui/async-await/async-closures/def-path.stderr2
-rw-r--r--tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs2
-rw-r--r--tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs2
-rw-r--r--tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr6
-rw-r--r--tests/ui/async-await/async-closures/drop.rs1
-rw-r--r--tests/ui/async-await/async-closures/fn-exception-target-features.rs2
-rw-r--r--tests/ui/async-await/async-closures/fn-exception.rs2
-rw-r--r--tests/ui/async-await/async-closures/fn-exception.stderr8
-rw-r--r--tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs2
-rw-r--r--tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs2
-rw-r--r--tests/ui/async-await/async-closures/foreign.rs2
-rw-r--r--tests/ui/async-await/async-closures/higher-ranked-return.rs2
-rw-r--r--tests/ui/async-await/async-closures/higher-ranked-return.stderr4
-rw-r--r--tests/ui/async-await/async-closures/higher-ranked.rs2
-rw-r--r--tests/ui/async-await/async-closures/implements-fnmut.rs2
-rw-r--r--tests/ui/async-await/async-closures/inline-body.rs2
-rw-r--r--tests/ui/async-await/async-closures/is-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/is-not-fn.rs4
-rw-r--r--tests/ui/async-await/async-closures/is-not-fn.stderr8
-rw-r--r--tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs1
-rw-r--r--tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr12
-rw-r--r--tests/ui/async-await/async-closures/mac-body.rs2
-rw-r--r--tests/ui/async-await/async-closures/mangle.rs2
-rw-r--r--tests/ui/async-await/async-closures/moro-example.rs2
-rw-r--r--tests/ui/async-await/async-closures/move-consuming-capture.rs2
-rw-r--r--tests/ui/async-await/async-closures/move-consuming-capture.stderr4
-rw-r--r--tests/ui/async-await/async-closures/move-is-async-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/move-out-of-ref.rs2
-rw-r--r--tests/ui/async-await/async-closures/move-out-of-ref.stderr4
-rw-r--r--tests/ui/async-await/async-closures/mut-ref-reborrow.rs2
-rw-r--r--tests/ui/async-await/async-closures/mutate.rs2
-rw-r--r--tests/ui/async-await/async-closures/no-borrow-from-env.rs2
-rw-r--r--tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs2
-rw-r--r--tests/ui/async-await/async-closures/not-clone-closure.rs2
-rw-r--r--tests/ui/async-await/async-closures/not-clone-closure.stderr8
-rw-r--r--tests/ui/async-await/async-closures/not-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/not-fn.stderr4
-rw-r--r--tests/ui/async-await/async-closures/not-lending.rs2
-rw-r--r--tests/ui/async-await/async-closures/not-lending.stderr8
-rw-r--r--tests/ui/async-await/async-closures/once.rs2
-rw-r--r--tests/ui/async-await/async-closures/overlapping-projs.rs2
-rw-r--r--tests/ui/async-await/async-closures/precise-captures.rs1
-rw-r--r--tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs4
-rw-r--r--tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr2
-rw-r--r--tests/ui/async-await/async-closures/refd.rs2
-rw-r--r--tests/ui/async-await/async-closures/return-type-mismatch.rs2
-rw-r--r--tests/ui/async-await/async-closures/return-type-mismatch.stderr2
-rw-r--r--tests/ui/async-await/async-closures/sig-from-bare-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/signature-deduction.rs2
-rw-r--r--tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs2
-rw-r--r--tests/ui/async-await/async-closures/tainted-body-2.rs2
-rw-r--r--tests/ui/async-await/async-closures/tainted-body-2.stderr2
-rw-r--r--tests/ui/async-await/async-closures/tainted-body.rs2
-rw-r--r--tests/ui/async-await/async-closures/tainted-body.stderr2
-rw-r--r--tests/ui/async-await/async-closures/truncated-fields-when-imm.rs2
-rw-r--r--tests/ui/async-await/async-closures/validate-synthetic-body.rs2
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs2
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr20
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.rs2
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.stderr6
-rw-r--r--tests/ui/async-await/async-drop.rs2
-rw-r--r--tests/ui/async-await/async-fn/auxiliary/block-on.rs2
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.rs2
-rw-r--r--tests/ui/async-await/async-fn/dyn-pos.stderr2
-rw-r--r--tests/ui/async-await/async-fn/edition-2015.rs2
-rw-r--r--tests/ui/async-await/async-fn/edition-2015.stderr22
-rw-r--r--tests/ui/async-await/async-fn/higher-ranked-async-fn.rs2
-rw-r--r--tests/ui/async-await/async-fn/impl-trait.rs2
-rw-r--r--tests/ui/async-await/async-fn/project.rs2
-rw-r--r--tests/ui/async-await/async-fn/simple.rs2
-rw-r--r--tests/ui/async-await/async-fn/sugar.rs2
-rw-r--r--tests/ui/async-await/coroutine-desc.rs1
-rw-r--r--tests/ui/async-await/coroutine-desc.stderr20
-rw-r--r--tests/ui/async-await/dyn/auxiliary/block-on.rs20
-rw-r--r--tests/ui/async-await/dyn/mut-is-pointer-like.rs40
-rw-r--r--tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout1
-rw-r--r--tests/ui/async-await/dyn/mut-is-pointer-like.stderr11
-rw-r--r--tests/ui/async-await/dyn/works.rs32
-rw-r--r--tests/ui/async-await/dyn/works.run.stdout1
-rw-r--r--tests/ui/async-await/dyn/works.stderr11
-rw-r--r--tests/ui/async-await/dyn/wrong-size.rs23
-rw-r--r--tests/ui/async-await/dyn/wrong-size.stderr21
-rw-r--r--tests/ui/async-await/feature-async-closure.rs8
-rw-r--r--tests/ui/async-await/feature-async-closure.stderr14
-rw-r--r--tests/ui/async-await/inference_var_self_argument.stderr4
-rw-r--r--tests/ui/async-await/issue-66312.stderr4
-rw-r--r--tests/ui/async-await/issue-74072-lifetime-name-annotations.rs1
-rw-r--r--tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr20
-rw-r--r--tests/ui/async-await/issues/issue-62009-2.rs2
-rw-r--r--tests/ui/async-await/issues/issue-62009-2.stderr2
-rw-r--r--tests/ui/async-await/no-params-non-move-async-closure.rs2
-rw-r--r--tests/ui/async-await/suggest-missing-await-closure.fixed2
-rw-r--r--tests/ui/async-await/suggest-missing-await-closure.rs2
-rw-r--r--tests/ui/async-await/suggest-missing-await-closure.stderr6
-rw-r--r--tests/ui/async-await/track-caller/async-closure-gate.rs2
-rw-r--r--tests/ui/async-await/track-caller/panic-track-caller.rs2
-rw-r--r--tests/ui/async-await/try-on-option-in-async.rs1
-rw-r--r--tests/ui/async-await/try-on-option-in-async.stderr6
-rw-r--r--tests/ui/closures/binder/async-closure-with-binder.rs1
-rw-r--r--tests/ui/closures/local-type-mix.rs2
-rw-r--r--tests/ui/closures/local-type-mix.stderr16
-rw-r--r--tests/ui/coroutine/break-inside-coroutine-issue-124495.rs1
-rw-r--r--tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr14
-rw-r--r--tests/ui/editions/edition-keywords-2018-2015-parsing.rs2
-rw-r--r--tests/ui/editions/edition-keywords-2018-2015-parsing.stderr14
-rw-r--r--tests/ui/editions/edition-keywords-2018-2018-parsing.rs2
-rw-r--r--tests/ui/editions/edition-keywords-2018-2018-parsing.stderr18
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.fixed28
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr52
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2024.stderr37
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.rs28
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs14
-rw-r--r--tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr48
-rw-r--r--tests/ui/feature-gates/feature-gate-async-trait-bounds.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr12
-rw-r--r--tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr4
-rw-r--r--tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs13
-rw-r--r--tests/ui/issues/auxiliary/issue-111011.rs2
-rw-r--r--tests/ui/issues/issue-56806.stderr4
-rw-r--r--tests/ui/layout/post-mono-layout-cycle-2.rs2
-rw-r--r--tests/ui/layout/post-mono-layout-cycle-2.stderr4
-rw-r--r--tests/ui/lifetimes/could-not-resolve-issue-121503.stderr2
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-variables.rs1
-rw-r--r--tests/ui/lint/unused/lint-unused-mut-variables.stderr56
-rw-r--r--tests/ui/lint/unused/lint-unused-variables.rs1
-rw-r--r--tests/ui/lint/unused/lint-unused-variables.stderr24
-rw-r--r--tests/ui/lint/unused/unused-closure.rs1
-rw-r--r--tests/ui/lint/unused/unused-closure.stderr16
-rw-r--r--tests/ui/macros/stringify.rs1
-rw-r--r--tests/ui/methods/call_method_unknown_referent.rs48
-rw-r--r--tests/ui/methods/call_method_unknown_referent.stderr29
-rw-r--r--tests/ui/methods/call_method_unknown_referent2.rs24
-rw-r--r--tests/ui/mir/issue-68841.rs2
-rw-r--r--tests/ui/never_type/fallback-closure-ret.nofallback.stderr4
-rw-r--r--tests/ui/parser/bad-name.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs1
-rw-r--r--tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr40
-rw-r--r--tests/ui/sanitizer/cfi/async-closures.rs1
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs64
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr70
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs.default.stderr4
-rw-r--r--tests/ui/self/arbitrary-self-opaque.stderr4
-rw-r--r--tests/ui/self/arbitrary_self_types_by_value_reborrow.rs69
-rw-r--r--tests/ui/self/arbitrary_self_types_generic_over_receiver.rs23
-rw-r--r--tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr59
-rw-r--r--tests/ui/self/arbitrary_self_types_generic_receiver.rs50
-rw-r--r--tests/ui/self/arbitrary_self_types_generic_receiver.stderr48
-rw-r--r--tests/ui/self/arbitrary_self_types_lifetime_elision.rs27
-rw-r--r--tests/ui/self/arbitrary_self_types_no_generics.rs32
-rw-r--r--tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs38
-rw-r--r--tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr39
-rw-r--r--tests/ui/self/arbitrary_self_types_recursive_receiver.rs32
-rw-r--r--tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs33
-rw-r--r--tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs31
-rw-r--r--tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs25
-rw-r--r--tests/ui/self/arbitrary_self_types_unshadowing.rs55
-rw-r--r--tests/ui/self/arbitrary_self_types_unshadowing.stderr105
-rw-r--r--tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs61
-rw-r--r--tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr122
-rw-r--r--tests/ui/self/conflicting_inner.rs38
-rw-r--r--tests/ui/self/conflicting_inner2.rs63
-rw-r--r--tests/ui/span/issue-27522.stderr4
-rw-r--r--tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs1
-rw-r--r--tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr14
-rw-r--r--tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr4
-rw-r--r--tests/ui/suggestions/method-missing-parentheses.rs1
-rw-r--r--tests/ui/suggestions/method-missing-parentheses.stderr8
-rw-r--r--tests/ui/suggestions/suggest-boxed-empty-block.fixed2
-rw-r--r--tests/ui/suggestions/suggest-boxed-empty-block.rs2
-rw-r--r--tests/ui/suggestions/suggest-boxed-empty-block.stderr4
-rw-r--r--tests/ui/suggestions/suggest-on-bare-closure-call.rs2
-rw-r--r--tests/ui/suggestions/suggest-on-bare-closure-call.stderr4
-rw-r--r--tests/ui/traits/const-traits/effects/auxiliary/minicore.rs10
-rw-r--r--tests/ui/traits/issue-78372.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution3.current.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution3.next.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.current.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/method_resolution4.next.stderr8
-rw-r--r--tests/ui/ufcs/ufcs-explicit-self-bad.stderr12
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.rs1
-rw-r--r--tests/ui/unpretty/expanded-exhaustive.stdout1
-rw-r--r--triagebot.toml10
351 files changed, 3527 insertions, 1196 deletions
diff --git a/.gitattributes b/.gitattributes
index a02c95fbd48..d29c15fe712 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,10 +4,8 @@
 *.cpp rust
 *.h rust
 *.rs rust diff=rust
-*.fixed linguist-language=Rust -merge
-*.mir linguist-language=Rust -merge
-*.stderr -merge
-*.stdout -merge
+*.fixed linguist-language=Rust
+*.mir linguist-language=Rust
 src/etc/installer/gfx/* binary
 src/vendor/** -text
 Cargo.lock linguist-generated=false
diff --git a/compiler/rustc_ast/src/util/comments/tests.rs b/compiler/rustc_ast/src/util/comments/tests.rs
index 61bb2468e79..f88b534a0c1 100644
--- a/compiler/rustc_ast/src/util/comments/tests.rs
+++ b/compiler/rustc_ast/src/util/comments/tests.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
+
 use rustc_span::create_default_session_globals_then;
 
 use super::*;
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index aa3b772efb1..61a710517ea 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -512,11 +512,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     );
     gate_all!(let_chains, "`let` expressions in this position are unstable");
     gate_all!(
-        async_closure,
-        "async closures are unstable",
-        "to use an async block, remove the `||`: `async {`"
-    );
-    gate_all!(
         async_trait_bounds,
         "`async` trait bounds are unstable",
         "use the desugared name of the async trait, such as `AsyncFn`"
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 8b4523bd252..d62632d1431 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -17,7 +17,9 @@ use super::debuginfo::{
     DebugEmissionKind, DebugNameTableKind,
 };
 
-pub type Bool = c_uint;
+/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
+/// which has a different ABI from Rust or C++ `bool`.
+pub type Bool = c_int;
 
 pub const True: Bool = 1 as Bool;
 pub const False: Bool = 0 as Bool;
diff --git a/compiler/rustc_error_codes/src/error_codes/E0307.md b/compiler/rustc_error_codes/src/error_codes/E0307.md
index 0d29d56ea1a..b9c0493e8d6 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0307.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0307.md
@@ -65,8 +65,10 @@ impl Trait for Foo {
 ```
 
 The nightly feature [Arbitrary self types][AST] extends the accepted
-set of receiver types to also include any type that can dereference to
-`Self`:
+set of receiver types to also include any type that implements the
+`Receiver` trait and can follow its chain of `Target` types to `Self`.
+There's a blanket implementation of `Receiver` for `T: Deref`, so any
+type which dereferences to `Self` can be used.
 
 ```
 #![feature(arbitrary_self_types)]
diff --git a/compiler/rustc_error_codes/src/error_codes/E0708.md b/compiler/rustc_error_codes/src/error_codes/E0708.md
index 61a853ac446..f793470bafd 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0708.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0708.md
@@ -5,8 +5,6 @@
 Erroneous code example:
 
 ```edition2018
-#![feature(async_closure)]
-
 fn main() {
     let add_one = async |num: u8| {
         num + 1
@@ -18,8 +16,6 @@ fn main() {
 version, you can use successfully by using move:
 
 ```edition2018
-#![feature(async_closure)]
-
 fn main() {
     let add_one = async move |num: u8| { // ok!
         num + 1
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index fc44340851c..25d41462556 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -94,8 +94,7 @@ mod styled_buffer;
 mod tests;
 pub mod translation;
 
-pub type PErr<'a> = Diag<'a>;
-pub type PResult<'a, T> = Result<T, PErr<'a>>;
+pub type PResult<'a, T> = Result<T, Diag<'a>>;
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
@@ -576,6 +575,10 @@ pub enum StashKey {
     UndeterminedMacroResolution,
     /// Used by `Parser::maybe_recover_trailing_expr`
     ExprInPat,
+    /// If in the parser we detect a field expr with turbofish generic params it's possible that
+    /// it's a method call without parens. If later on in `hir_typeck` we find out that this is
+    /// the case we suppress this message and we give a better suggestion.
+    GenericInFieldExpr,
 }
 
 fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 53362cb2529..c5913ed27cf 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -72,6 +72,8 @@ declare_features! (
     (accepted, associated_types, "1.0.0", None),
     /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
     (accepted, async_await, "1.39.0", Some(50547)),
+    /// Allows `async || body` closures.
+    (accepted, async_closure, "CURRENT_RUSTC_VERSION", Some(62290)),
     /// Allows async functions to be declared, implemented, and used in traits.
     (accepted, async_fn_in_trait, "1.75.0", Some(91611)),
     /// Allows all literals in attribute lists and values of key-value pairs.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 93a605e197c..3c9115be7f5 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -388,8 +388,8 @@ declare_features! (
     (unstable, associated_const_equality, "1.58.0", Some(92827)),
     /// Allows associated type defaults.
     (unstable, associated_type_defaults, "1.2.0", Some(29661)),
-    /// Allows `async || body` closures.
-    (unstable, async_closure, "1.37.0", Some(62290)),
+    /// Allows async functions to be called from `dyn Trait`.
+    (incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)),
     /// Allows `#[track_caller]` on async functions.
     (unstable, async_fn_track_caller, "1.73.0", Some(110011)),
     /// Allows `for await` loops.
diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs
index 5c10fa46971..953e48a6d33 100644
--- a/compiler/rustc_hir/src/tests.rs
+++ b/compiler/rustc_hir/src/tests.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
+
 use rustc_data_structures::stable_hasher::Hash64;
 use rustc_span::def_id::{DefPathHash, StableCrateId};
 use rustc_span::edition::Edition;
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 32498d9c5ab..25feb95d5df 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -241,10 +241,10 @@ hir_analysis_invalid_generic_receiver_ty_help =
     use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
 hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}`
-    .note = type of `self` must be `Self` or a type that dereferences to it
+    .note = type of `self` must be `Self` or some type implementing `Receiver`
 
 hir_analysis_invalid_receiver_ty_help =
-    consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+    consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 hir_analysis_invalid_union_field =
     field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs
index 5a66c31a0cc..d8e9227a87c 100644
--- a/compiler/rustc_hir_analysis/src/autoderef.rs
+++ b/compiler/rustc_hir_analysis/src/autoderef.rs
@@ -18,7 +18,6 @@ pub enum AutoderefKind {
     /// A type which must dispatch to a `Deref` implementation.
     Overloaded,
 }
-
 struct AutoderefSnapshot<'tcx> {
     at_start: bool,
     reached_recursion_limit: bool,
@@ -27,6 +26,10 @@ struct AutoderefSnapshot<'tcx> {
     obligations: PredicateObligations<'tcx>,
 }
 
+/// Recursively dereference a type, considering both built-in
+/// dereferences (`*`) and the `Deref` trait.
+/// Although called `Autoderef` it can be configured to use the
+/// `Receiver` trait instead of the `Deref` trait.
 pub struct Autoderef<'a, 'tcx> {
     // Meta infos:
     infcx: &'a InferCtxt<'tcx>,
@@ -39,6 +42,7 @@ pub struct Autoderef<'a, 'tcx> {
 
     // Configurations:
     include_raw_pointers: bool,
+    use_receiver_trait: bool,
     silence_errors: bool,
 }
 
@@ -69,6 +73,10 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
         }
 
         // Otherwise, deref if type is derefable:
+        // NOTE: in the case of self.use_receiver_trait = true, you might think it would
+        // be better to skip this clause and use the Overloaded case only, since &T
+        // and &mut T implement Receiver. But built-in derefs apply equally to Receiver
+        // and Deref, and this has benefits for const and the emitted MIR.
         let (kind, new_ty) =
             if let Some(ty) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) {
                 debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty));
@@ -111,7 +119,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
         body_def_id: LocalDefId,
         span: Span,
         base_ty: Ty<'tcx>,
-    ) -> Autoderef<'a, 'tcx> {
+    ) -> Self {
         Autoderef {
             infcx,
             span,
@@ -125,6 +133,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
                 reached_recursion_limit: false,
             },
             include_raw_pointers: false,
+            use_receiver_trait: false,
             silence_errors: false,
         }
     }
@@ -137,8 +146,13 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             return None;
         }
 
-        // <ty as Deref>
-        let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
+        // <ty as Deref>, or whatever the equivalent trait is that we've been asked to walk.
+        let (trait_def_id, trait_target_def_id) = if self.use_receiver_trait {
+            (tcx.lang_items().receiver_trait()?, tcx.lang_items().receiver_target()?)
+        } else {
+            (tcx.lang_items().deref_trait()?, tcx.lang_items().deref_target()?)
+        };
+        let trait_ref = ty::TraitRef::new(tcx, trait_def_id, [ty]);
         let cause = traits::ObligationCause::misc(self.span, self.body_id);
         let obligation = traits::Obligation::new(
             tcx,
@@ -151,11 +165,8 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
             return None;
         }
 
-        let (normalized_ty, obligations) = self.structurally_normalize(Ty::new_projection(
-            tcx,
-            tcx.lang_items().deref_target()?,
-            [ty],
-        ))?;
+        let (normalized_ty, obligations) =
+            self.structurally_normalize(Ty::new_projection(tcx, trait_target_def_id, [ty]))?;
         debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
         self.state.obligations.extend(obligations);
 
@@ -234,6 +245,14 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
         self
     }
 
+    /// Use `core::ops::Receiver` and `core::ops::Receiver::Target` as
+    /// the trait and associated type to iterate, instead of
+    /// `core::ops::Deref` and `core::ops::Deref::Target`
+    pub fn use_receiver_trait(mut self) -> Self {
+        self.use_receiver_trait = true;
+        self
+    }
+
     pub fn silence_errors(mut self) -> Self {
         self.silence_errors = true;
         self
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index df4da03f0f5..90e93bdbb50 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -3,6 +3,7 @@ use std::assert_matches::debug_assert_matches;
 use rustc_abi::FieldIdx;
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxIndexSet;
+use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, LangItem};
 use rustc_middle::bug;
 use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
@@ -21,6 +22,12 @@ pub struct InlineAsmCtxt<'a, 'tcx> {
     get_operand_ty: Box<dyn Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
 }
 
+enum NonAsmTypeReason<'tcx> {
+    UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>),
+    Invalid(Ty<'tcx>),
+    InvalidElement(DefId, Ty<'tcx>),
+}
+
 impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
     pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self {
         InlineAsmCtxt {
@@ -56,7 +63,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         false
     }
 
-    fn get_asm_ty(&self, ty: Ty<'tcx>) -> Option<InlineAsmType> {
+    fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result<InlineAsmType, NonAsmTypeReason<'tcx>> {
         let asm_ty_isize = match self.tcx.sess.target.pointer_width {
             16 => InlineAsmType::I16,
             32 => InlineAsmType::I32,
@@ -65,64 +72,62 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         };
 
         match *ty.kind() {
-            ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
-            ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
-            ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
-            ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64),
-            ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128),
-            ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize),
-            ty::Float(FloatTy::F16) => Some(InlineAsmType::F16),
-            ty::Float(FloatTy::F32) => Some(InlineAsmType::F32),
-            ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
-            ty::Float(FloatTy::F128) => Some(InlineAsmType::F128),
-            ty::FnPtr(..) => Some(asm_ty_isize),
-            ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
+            ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::I8),
+            ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::I16),
+            ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::I32),
+            ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::I64),
+            ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Ok(InlineAsmType::I128),
+            ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Ok(asm_ty_isize),
+            ty::Float(FloatTy::F16) => Ok(InlineAsmType::F16),
+            ty::Float(FloatTy::F32) => Ok(InlineAsmType::F32),
+            ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64),
+            ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128),
+            ty::FnPtr(..) => Ok(asm_ty_isize),
+            ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Ok(asm_ty_isize),
             ty::Adt(adt, args) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
-                let elem_ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
+                let field = &fields[FieldIdx::ZERO];
+                let elem_ty = field.ty(self.tcx, args);
 
                 let (size, ty) = match elem_ty.kind() {
                     ty::Array(ty, len) => {
+                        let len = self.tcx.normalize_erasing_regions(self.typing_env, *len);
                         if let Some(len) = len.try_to_target_usize(self.tcx) {
                             (len, *ty)
                         } else {
-                            return None;
+                            return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength(
+                                field.did, len,
+                            ));
                         }
                     }
                     _ => (fields.len() as u64, elem_ty),
                 };
 
                 match ty.kind() {
-                    ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)),
-                    ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => {
-                        Some(InlineAsmType::VecI16(size))
-                    }
-                    ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => {
-                        Some(InlineAsmType::VecI32(size))
-                    }
-                    ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => {
-                        Some(InlineAsmType::VecI64(size))
-                    }
+                    ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Ok(InlineAsmType::VecI8(size)),
+                    ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Ok(InlineAsmType::VecI16(size)),
+                    ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Ok(InlineAsmType::VecI32(size)),
+                    ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Ok(InlineAsmType::VecI64(size)),
                     ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
-                        Some(InlineAsmType::VecI128(size))
+                        Ok(InlineAsmType::VecI128(size))
                     }
                     ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
-                        Some(match self.tcx.sess.target.pointer_width {
+                        Ok(match self.tcx.sess.target.pointer_width {
                             16 => InlineAsmType::VecI16(size),
                             32 => InlineAsmType::VecI32(size),
                             64 => InlineAsmType::VecI64(size),
                             width => bug!("unsupported pointer width: {width}"),
                         })
                     }
-                    ty::Float(FloatTy::F16) => Some(InlineAsmType::VecF16(size)),
-                    ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
-                    ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(size)),
-                    ty::Float(FloatTy::F128) => Some(InlineAsmType::VecF128(size)),
-                    _ => None,
+                    ty::Float(FloatTy::F16) => Ok(InlineAsmType::VecF16(size)),
+                    ty::Float(FloatTy::F32) => Ok(InlineAsmType::VecF32(size)),
+                    ty::Float(FloatTy::F64) => Ok(InlineAsmType::VecF64(size)),
+                    ty::Float(FloatTy::F128) => Ok(InlineAsmType::VecF128(size)),
+                    _ => Err(NonAsmTypeReason::InvalidElement(field.did, ty)),
                 }
             }
             ty::Infer(_) => bug!("unexpected infer ty in asm operand"),
-            _ => None,
+            _ => Err(NonAsmTypeReason::Invalid(ty)),
         }
     }
 
@@ -163,17 +168,42 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             }
             _ => self.get_asm_ty(ty),
         };
-        let Some(asm_ty) = asm_ty else {
-            let msg = format!("cannot use value of type `{ty}` for inline assembly");
-            self.tcx
-                .dcx()
-                .struct_span_err(expr.span, msg)
-                .with_note(
-                    "only integers, floats, SIMD vectors, pointers and function pointers \
-                     can be used as arguments for inline assembly",
-                )
-                .emit();
-            return None;
+        let asm_ty = match asm_ty {
+            Ok(asm_ty) => asm_ty,
+            Err(reason) => {
+                match reason {
+                    NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => {
+                        let msg = format!("cannot evaluate SIMD vector length `{len}`");
+                        self.tcx
+                            .dcx()
+                            .struct_span_err(self.tcx.def_span(did), msg)
+                            .with_span_note(
+                                expr.span,
+                                "SIMD vector length needs to be known statically for use in `asm!`",
+                            )
+                            .emit();
+                    }
+                    NonAsmTypeReason::Invalid(ty) => {
+                        let msg = format!("cannot use value of type `{ty}` for inline assembly");
+                        self.tcx.dcx().struct_span_err(expr.span, msg).with_note(
+                            "only integers, floats, SIMD vectors, pointers and function pointers \
+                            can be used as arguments for inline assembly",
+                        ).emit();
+                    }
+                    NonAsmTypeReason::InvalidElement(did, ty) => {
+                        let msg = format!(
+                            "cannot use SIMD vector with element type `{ty}` for inline assembly"
+                        );
+                        self.tcx.dcx()
+                        .struct_span_err(self.tcx.def_span(did), msg).with_span_note(
+                            expr.span,
+                            "only integers, floats, SIMD vectors, pointers and function pointers \
+                            can be used as arguments for inline assembly",
+                        ).emit();
+                    }
+                }
+                return None;
+            }
         };
 
         // Check that the type implements Copy. The only case where this can
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index c9773972d9a..57264d0bd2a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1821,13 +1821,18 @@ fn receiver_is_valid<'tcx>(
 
     let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
 
+    // The `arbitrary_self_types` feature allows custom smart pointer
+    // types to be method receivers, as identified by following the Receiver<Target=T>
+    // chain.
+    if arbitrary_self_types_enabled.is_some() {
+        autoderef = autoderef.use_receiver_trait();
+    }
+
     // The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
     if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) {
         autoderef = autoderef.include_raw_pointers();
     }
 
-    let receiver_trait_def_id = tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));
-
     // Keep dereferencing `receiver_ty` until we get to `self_ty`.
     while let Some((potential_self_ty, _)) = autoderef.next() {
         debug!(
@@ -1849,11 +1854,13 @@ fn receiver_is_valid<'tcx>(
         }
 
         // Without `feature(arbitrary_self_types)`, we require that each step in the
-        // deref chain implement `receiver`.
+        // deref chain implement `LegacyReceiver`.
         if arbitrary_self_types_enabled.is_none() {
-            if !receiver_is_implemented(
+            let legacy_receiver_trait_def_id =
+                tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));
+            if !legacy_receiver_is_implemented(
                 wfcx,
-                receiver_trait_def_id,
+                legacy_receiver_trait_def_id,
                 cause.clone(),
                 potential_self_ty,
             ) {
@@ -1866,7 +1873,7 @@ fn receiver_is_valid<'tcx>(
                 cause.clone(),
                 wfcx.param_env,
                 potential_self_ty,
-                receiver_trait_def_id,
+                legacy_receiver_trait_def_id,
             );
         }
     }
@@ -1875,14 +1882,14 @@ fn receiver_is_valid<'tcx>(
     Err(ReceiverValidityError::DoesNotDeref)
 }
 
-fn receiver_is_implemented<'tcx>(
+fn legacy_receiver_is_implemented<'tcx>(
     wfcx: &WfCheckingCtxt<'_, 'tcx>,
-    receiver_trait_def_id: DefId,
+    legacy_receiver_trait_def_id: DefId,
     cause: ObligationCause<'tcx>,
     receiver_ty: Ty<'tcx>,
 ) -> bool {
     let tcx = wfcx.tcx();
-    let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]);
+    let trait_ref = ty::TraitRef::new(tcx, legacy_receiver_trait_def_id, [receiver_ty]);
 
     let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref);
 
@@ -1890,7 +1897,7 @@ fn receiver_is_implemented<'tcx>(
         true
     } else {
         debug!(
-            "receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
+            "receiver_is_implemented: type `{:?}` does not implement `LegacyReceiver` trait",
             receiver_ty
         );
         false
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 3399a9fe880..d0272651c08 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -917,7 +917,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             [candidate] => format!(
                 "the method of the same name on {} `{}`",
                 match candidate.kind {
-                    probe::CandidateKind::InherentImplCandidate(_) => "the inherent impl for",
+                    probe::CandidateKind::InherentImplCandidate { .. } => "the inherent impl for",
                     _ => "trait",
                 },
                 self.tcx.def_path_str(candidate.item.container_id(self.tcx))
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index b3ce1df3def..56903865277 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3076,7 +3076,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             err.help("methods are immutable and cannot be assigned to");
         }
 
-        err.emit()
+        // See `StashKey::GenericInFieldExpr` for more info
+        self.dcx().try_steal_replace_and_emit_err(field.span, StashKey::GenericInFieldExpr, err)
     }
 
     fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) {
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index ddd146fe785..b57c248ed2b 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -613,19 +613,16 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
         if arg_segment.args.is_none()
             && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
             && let generics = self.fcx.tcx.generics_of(def_id)
-            && let args = &all_args[generics.parent_count..]
+            && let args = all_args[generics.parent_count..].iter().zip(&generics.own_params)
             // We can't turbofish consts :(
-            && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_)))
+            && args.clone().all(|(_, param)| matches!(param.kind, ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Lifetime))
         {
-            let n_tys = args
-                .iter()
-                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
-                .count();
-            for (idx, arg) in args
-                .iter()
-                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
-                .enumerate()
-            {
+            // We filter out APITs, which are not turbofished.
+            let non_apit_type_args = args.filter(|(_, param)| {
+                matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: false, .. })
+            });
+            let n_tys = non_apit_type_args.clone().count();
+            for (idx, (arg, _)) in non_apit_type_args.enumerate() {
                 if let Some(ty) = arg.as_type()
                     && let Some(vid) = self.fcx.root_vid(ty)
                     && self.reachable_vids.contains(&vid)
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 039c117c099..3b377076545 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -79,12 +79,6 @@ pub(crate) struct ProbeContext<'a, 'tcx> {
     /// used for error reporting
     static_candidates: RefCell<Vec<CandidateSource>>,
 
-    /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
-    /// for error reporting
-    unsatisfied_predicates: RefCell<
-        Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
-    >,
-
     scope_expr_id: HirId,
 
     /// Is this probe being done for a diagnostic? This will skip some error reporting
@@ -109,7 +103,7 @@ pub(crate) struct Candidate<'tcx> {
 
 #[derive(Debug, Clone)]
 pub(crate) enum CandidateKind<'tcx> {
-    InherentImplCandidate(DefId),
+    InherentImplCandidate { impl_def_id: DefId, receiver_steps: usize },
     ObjectCandidate(ty::PolyTraitRef<'tcx>),
     TraitCandidate(ty::PolyTraitRef<'tcx>),
     WhereClauseCandidate(ty::PolyTraitRef<'tcx>),
@@ -162,6 +156,52 @@ impl AutorefOrPtrAdjustment {
     }
 }
 
+/// Extra information required only for error reporting.
+#[derive(Debug)]
+struct PickDiagHints<'a, 'tcx> {
+    /// Unstable candidates alongside the stable ones.
+    unstable_candidates: Option<Vec<(Candidate<'tcx>, Symbol)>>,
+
+    /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
+    /// for error reporting
+    unsatisfied_predicates: &'a mut Vec<(
+        ty::Predicate<'tcx>,
+        Option<ty::Predicate<'tcx>>,
+        Option<ObligationCause<'tcx>>,
+    )>,
+}
+
+/// Criteria to apply when searching for a given Pick. This is used during
+/// the search for potentially shadowed methods to ensure we don't search
+/// more candidates than strictly necessary.
+#[derive(Debug)]
+struct PickConstraintsForShadowed {
+    autoderefs: usize,
+    receiver_steps: Option<usize>,
+    def_id: DefId,
+}
+
+impl PickConstraintsForShadowed {
+    fn may_shadow_based_on_autoderefs(&self, autoderefs: usize) -> bool {
+        autoderefs == self.autoderefs
+    }
+
+    fn candidate_may_shadow(&self, candidate: &Candidate<'_>) -> bool {
+        // An item never shadows itself
+        candidate.item.def_id != self.def_id
+            // and we're only concerned about inherent impls doing the shadowing.
+            // Shadowing can only occur if the shadowed is further along
+            // the Receiver dereferencing chain than the shadowed.
+            && match candidate.kind {
+                CandidateKind::InherentImplCandidate { receiver_steps, .. } => match self.receiver_steps {
+                    Some(shadowed_receiver_steps) => receiver_steps > shadowed_receiver_steps,
+                    _ => false
+                },
+                _ => false
+            }
+    }
+}
+
 #[derive(Debug, Clone)]
 pub(crate) struct Pick<'tcx> {
     pub item: ty::AssocItem,
@@ -181,6 +221,11 @@ pub(crate) struct Pick<'tcx> {
 
     /// Unstable candidates alongside the stable ones.
     unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
+
+    /// Number of jumps along the `Receiver::Target` chain we followed
+    /// to identify this method. Used only for deshadowing errors.
+    /// Only applies for inherent impls.
+    pub receiver_steps: Option<usize>,
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -366,6 +411,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         autoderefs: 0,
                         from_unsafe_deref: false,
                         unsize: false,
+                        reachable_via_deref: true,
                     }]),
                     opt_bad_ty: None,
                     reached_recursion_limit: false,
@@ -516,47 +562,93 @@ fn method_autoderef_steps<'tcx>(
     let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal);
     let ParamEnvAnd { param_env, value: self_ty } = goal;
 
-    let mut autoderef =
+    // If arbitrary self types is not enabled, we follow the chain of
+    // `Deref<Target=T>`. If arbitrary self types is enabled, we instead
+    // follow the chain of `Receiver<Target=T>`, but we also record whether
+    // such types are reachable by following the (potentially shorter)
+    // chain of `Deref<Target=T>`. We will use the first list when finding
+    // potentially relevant function implementations (e.g. relevant impl blocks)
+    // but the second list when determining types that the receiver may be
+    // converted to, in order to find out which of those methods might actually
+    // be callable.
+    let mut autoderef_via_deref =
         Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, self_ty)
             .include_raw_pointers()
             .silence_errors();
-    let mut reached_raw_pointer = false;
-    let mut steps: Vec<_> = autoderef
-        .by_ref()
-        .map(|(ty, d)| {
-            let step = CandidateStep {
-                self_ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, ty),
-                autoderefs: d,
-                from_unsafe_deref: reached_raw_pointer,
-                unsize: false,
-            };
-            if let ty::RawPtr(_, _) = ty.kind() {
-                // all the subsequent steps will be from_unsafe_deref
-                reached_raw_pointer = true;
-            }
-            step
-        })
-        .collect();
 
-    let final_ty = autoderef.final_ty(true);
+    let mut reached_raw_pointer = false;
+    let arbitrary_self_types_enabled =
+        tcx.features().arbitrary_self_types() || tcx.features().arbitrary_self_types_pointers();
+    let (mut steps, reached_recursion_limit): (Vec<_>, bool) = if arbitrary_self_types_enabled {
+        let reachable_via_deref =
+            autoderef_via_deref.by_ref().map(|_| true).chain(std::iter::repeat(false));
+
+        let mut autoderef_via_receiver =
+            Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, self_ty)
+                .include_raw_pointers()
+                .use_receiver_trait()
+                .silence_errors();
+        let steps = autoderef_via_receiver
+            .by_ref()
+            .zip(reachable_via_deref)
+            .map(|((ty, d), reachable_via_deref)| {
+                let step = CandidateStep {
+                    self_ty: infcx
+                        .make_query_response_ignoring_pending_obligations(inference_vars, ty),
+                    autoderefs: d,
+                    from_unsafe_deref: reached_raw_pointer,
+                    unsize: false,
+                    reachable_via_deref,
+                };
+                if ty.is_unsafe_ptr() {
+                    // all the subsequent steps will be from_unsafe_deref
+                    reached_raw_pointer = true;
+                }
+                step
+            })
+            .collect();
+        (steps, autoderef_via_receiver.reached_recursion_limit())
+    } else {
+        let steps = autoderef_via_deref
+            .by_ref()
+            .map(|(ty, d)| {
+                let step = CandidateStep {
+                    self_ty: infcx
+                        .make_query_response_ignoring_pending_obligations(inference_vars, ty),
+                    autoderefs: d,
+                    from_unsafe_deref: reached_raw_pointer,
+                    unsize: false,
+                    reachable_via_deref: true,
+                };
+                if ty.is_unsafe_ptr() {
+                    // all the subsequent steps will be from_unsafe_deref
+                    reached_raw_pointer = true;
+                }
+                step
+            })
+            .collect();
+        (steps, autoderef_via_deref.reached_recursion_limit())
+    };
+    let final_ty = autoderef_via_deref.final_ty(true);
     let opt_bad_ty = match final_ty.kind() {
         ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
             reached_raw_pointer,
             ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
         }),
         ty::Array(elem_ty, _) => {
-            let dereferences = steps.len() - 1;
-
+            let autoderefs = steps.iter().filter(|s| s.reachable_via_deref).count() - 1;
             steps.push(CandidateStep {
                 self_ty: infcx.make_query_response_ignoring_pending_obligations(
                     inference_vars,
                     Ty::new_slice(infcx.tcx, *elem_ty),
                 ),
-                autoderefs: dereferences,
+                autoderefs,
                 // this could be from an unsafe deref if we had
                 // a *mut/const [T; N]
                 from_unsafe_deref: reached_raw_pointer,
                 unsize: true,
+                reachable_via_deref: true, // this is always the final type from
+                                           // autoderef_via_deref
             });
 
             None
@@ -569,7 +661,7 @@ fn method_autoderef_steps<'tcx>(
     MethodAutoderefStepsResult {
         steps: tcx.arena.alloc_from_iter(steps),
         opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),
-        reached_recursion_limit: autoderef.reached_recursion_limit(),
+        reached_recursion_limit,
     }
 }
 
@@ -600,7 +692,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             private_candidates: Vec::new(),
             private_candidate: Cell::new(None),
             static_candidates: RefCell::new(Vec::new()),
-            unsatisfied_predicates: RefCell::new(Vec::new()),
             scope_expr_id,
             is_suggestion,
         }
@@ -613,7 +704,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.private_candidates.clear();
         self.private_candidate.set(None);
         self.static_candidates.borrow_mut().clear();
-        self.unsatisfied_predicates.borrow_mut().clear();
     }
 
     /// When we're looking up a method by path (UFCS), we relate the receiver
@@ -652,12 +742,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
     fn assemble_inherent_candidates(&mut self) {
         for step in self.steps.iter() {
-            self.assemble_probe(&step.self_ty);
+            self.assemble_probe(&step.self_ty, step.autoderefs);
         }
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>) {
+    fn assemble_probe(
+        &mut self,
+        self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
+        receiver_steps: usize,
+    ) {
         let raw_self_ty = self_ty.value.value;
         match *raw_self_ty.kind() {
             ty::Dynamic(data, ..) if let Some(p) = data.principal() => {
@@ -682,22 +776,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     self.fcx.instantiate_canonical(self.span, self_ty);
 
                 self.assemble_inherent_candidates_from_object(generalized_self_ty);
-                self.assemble_inherent_impl_candidates_for_type(p.def_id());
+                self.assemble_inherent_impl_candidates_for_type(p.def_id(), receiver_steps);
                 if self.tcx.has_attr(p.def_id(), sym::rustc_has_incoherent_inherent_impls) {
-                    self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
+                    self.assemble_inherent_candidates_for_incoherent_ty(
+                        raw_self_ty,
+                        receiver_steps,
+                    );
                 }
             }
             ty::Adt(def, _) => {
                 let def_id = def.did();
-                self.assemble_inherent_impl_candidates_for_type(def_id);
+                self.assemble_inherent_impl_candidates_for_type(def_id, receiver_steps);
                 if self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) {
-                    self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
+                    self.assemble_inherent_candidates_for_incoherent_ty(
+                        raw_self_ty,
+                        receiver_steps,
+                    );
                 }
             }
             ty::Foreign(did) => {
-                self.assemble_inherent_impl_candidates_for_type(did);
+                self.assemble_inherent_impl_candidates_for_type(did, receiver_steps);
                 if self.tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
-                    self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
+                    self.assemble_inherent_candidates_for_incoherent_ty(
+                        raw_self_ty,
+                        receiver_steps,
+                    );
                 }
             }
             ty::Param(p) => {
@@ -714,29 +817,35 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             | ty::RawPtr(_, _)
             | ty::Ref(..)
             | ty::Never
-            | ty::Tuple(..) => self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty),
+            | ty::Tuple(..) => {
+                self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps)
+            }
             _ => {}
         }
     }
 
-    fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
+    fn assemble_inherent_candidates_for_incoherent_ty(
+        &mut self,
+        self_ty: Ty<'tcx>,
+        receiver_steps: usize,
+    ) {
         let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
             bug!("unexpected incoherent type: {:?}", self_ty)
         };
         for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter() {
-            self.assemble_inherent_impl_probe(impl_def_id);
+            self.assemble_inherent_impl_probe(impl_def_id, receiver_steps);
         }
     }
 
-    fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
+    fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId, receiver_steps: usize) {
         let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id).into_iter();
         for &impl_def_id in impl_def_ids {
-            self.assemble_inherent_impl_probe(impl_def_id);
+            self.assemble_inherent_impl_probe(impl_def_id, receiver_steps);
         }
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
+    fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId, receiver_steps: usize) {
         if !self.impl_dups.insert(impl_def_id) {
             return; // already visited
         }
@@ -750,7 +859,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             self.push_candidate(
                 Candidate {
                     item,
-                    kind: InherentImplCandidate(impl_def_id),
+                    kind: InherentImplCandidate { impl_def_id, receiver_steps },
                     import_ids: smallvec![],
                 },
                 true,
@@ -989,7 +1098,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     fn pick(mut self) -> PickResult<'tcx> {
         assert!(self.method_name.is_some());
 
-        if let Some(r) = self.pick_core() {
+        let mut unsatisfied_predicates = Vec::new();
+
+        if let Some(r) = self.pick_core(&mut unsatisfied_predicates) {
             return r;
         }
 
@@ -1009,7 +1120,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
         let static_candidates = std::mem::take(self.static_candidates.get_mut());
         let private_candidate = self.private_candidate.take();
-        let unsatisfied_predicates = std::mem::take(self.unsatisfied_predicates.get_mut());
 
         // things failed, so lets look at all traits, for diagnostic purposes now:
         self.reset();
@@ -1019,7 +1129,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
         self.assemble_extension_candidates_for_all_traits();
 
-        let out_of_scope_traits = match self.pick_core() {
+        let out_of_scope_traits = match self.pick_core(&mut Vec::new()) {
             Some(Ok(p)) => vec![p.item.container_id(self.tcx)],
             Some(Err(MethodError::Ambiguity(v))) => v
                 .into_iter()
@@ -1054,17 +1164,48 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         }))
     }
 
-    fn pick_core(&self) -> Option<PickResult<'tcx>> {
+    fn pick_core(
+        &self,
+        unsatisfied_predicates: &mut Vec<(
+            ty::Predicate<'tcx>,
+            Option<ty::Predicate<'tcx>>,
+            Option<ObligationCause<'tcx>>,
+        )>,
+    ) -> Option<PickResult<'tcx>> {
         // Pick stable methods only first, and consider unstable candidates if not found.
-        self.pick_all_method(Some(&mut vec![])).or_else(|| self.pick_all_method(None))
+        self.pick_all_method(&mut PickDiagHints {
+            // This first cycle, maintain a list of unstable candidates which
+            // we encounter. This will end up in the Pick for diagnostics.
+            unstable_candidates: Some(Vec::new()),
+            // Contribute to the list of unsatisfied predicates which may
+            // also be used for diagnostics.
+            unsatisfied_predicates,
+        })
+        .or_else(|| {
+            self.pick_all_method(&mut PickDiagHints {
+                // On the second search, don't provide a special list of unstable
+                // candidates. This indicates to the picking code that it should
+                // in fact include such unstable candidates in the actual
+                // search.
+                unstable_candidates: None,
+                // And there's no need to duplicate ourselves in the
+                // unsatisifed predicates list. Provide a throwaway list.
+                unsatisfied_predicates: &mut Vec::new(),
+            })
+        })
     }
 
-    fn pick_all_method(
+    fn pick_all_method<'b>(
         &self,
-        mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'b, 'tcx>,
     ) -> Option<PickResult<'tcx>> {
+        let track_unstable_candidates = pick_diag_hints.unstable_candidates.is_some();
         self.steps
             .iter()
+            // At this point we're considering the types to which the receiver can be converted,
+            // so we want to follow the `Deref` chain not the `Receiver` chain. Filter out
+            // steps which can only be reached by following the (longer) `Receiver` chain.
+            .filter(|step| step.reachable_via_deref)
             .filter(|step| {
                 debug!("pick_all_method: step={:?}", step);
                 // skip types that are from a type error or that would require dereferencing
@@ -1082,40 +1223,188 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     .unwrap_or_else(|_| {
                         span_bug!(self.span, "{:?} was applicable but now isn't?", step.self_ty)
                     });
-                self.pick_by_value_method(step, self_ty, unstable_candidates.as_deref_mut())
-                    .or_else(|| {
-                        self.pick_autorefd_method(
-                            step,
-                            self_ty,
-                            hir::Mutability::Not,
-                            unstable_candidates.as_deref_mut(),
-                        )
-                        .or_else(|| {
-                            self.pick_autorefd_method(
+
+                let by_value_pick = self.pick_by_value_method(step, self_ty, pick_diag_hints);
+
+                // Check for shadowing of a by-reference method by a by-value method (see comments on check_for_shadowing)
+                if let Some(by_value_pick) = by_value_pick {
+                    if let Ok(by_value_pick) = by_value_pick.as_ref() {
+                        if by_value_pick.kind == PickKind::InherentImplPick {
+                            if let Err(e) = self.check_for_shadowed_autorefd_method(
+                                by_value_pick,
                                 step,
                                 self_ty,
-                                hir::Mutability::Mut,
-                                unstable_candidates.as_deref_mut(),
-                            )
-                        })
-                        .or_else(|| {
-                            self.pick_const_ptr_method(
+                                hir::Mutability::Not,
+                                track_unstable_candidates,
+                            ) {
+                                return Some(Err(e));
+                            }
+                            if let Err(e) = self.check_for_shadowed_autorefd_method(
+                                by_value_pick,
                                 step,
                                 self_ty,
-                                unstable_candidates.as_deref_mut(),
-                            )
-                        })
-                        .or_else(|| {
-                            self.pick_reborrow_pin_method(
+                                hir::Mutability::Mut,
+                                track_unstable_candidates,
+                            ) {
+                                return Some(Err(e));
+                            }
+                        }
+                    }
+                    return Some(by_value_pick);
+                }
+
+                let autoref_pick = self.pick_autorefd_method(
+                    step,
+                    self_ty,
+                    hir::Mutability::Not,
+                    pick_diag_hints,
+                    None,
+                );
+                // Check for shadowing of a by-mut-ref method by a by-reference method (see comments on check_for_shadowing)
+                if let Some(autoref_pick) = autoref_pick {
+                    if let Ok(autoref_pick) = autoref_pick.as_ref() {
+                        // Check we're not shadowing others
+                        if autoref_pick.kind == PickKind::InherentImplPick {
+                            if let Err(e) = self.check_for_shadowed_autorefd_method(
+                                autoref_pick,
                                 step,
                                 self_ty,
-                                unstable_candidates.as_deref_mut(),
-                            )
-                        })
-                    })
+                                hir::Mutability::Mut,
+                                track_unstable_candidates,
+                            ) {
+                                return Some(Err(e));
+                            }
+                        }
+                    }
+                    return Some(autoref_pick);
+                }
+
+                // Note that no shadowing errors are produced from here on,
+                // as we consider const ptr methods.
+                // We allow new methods that take *mut T to shadow
+                // methods which took *const T, so there is no entry in
+                // this list for the results of `pick_const_ptr_method`.
+                // The reason is that the standard pointer cast method
+                // (on a mutable pointer) always already shadows the
+                // cast method (on a const pointer). So, if we added
+                // `pick_const_ptr_method` to this method, the anti-
+                // shadowing algorithm would always complain about
+                // the conflict between *const::cast and *mut::cast.
+                // In practice therefore this does constrain us:
+                // we cannot add new
+                //   self: *mut Self
+                // methods to types such as NonNull or anything else
+                // which implements Receiver, because this might in future
+                // shadow existing methods taking
+                //   self: *const NonNull<Self>
+                // in the pointee. In practice, methods taking raw pointers
+                // are rare, and it seems that it should be easily possible
+                // to avoid such compatibility breaks.
+                // We also don't check for reborrowed pin methods which
+                // may be shadowed; these also seem unlikely to occur.
+                self.pick_autorefd_method(
+                    step,
+                    self_ty,
+                    hir::Mutability::Mut,
+                    pick_diag_hints,
+                    None,
+                )
+                .or_else(|| self.pick_const_ptr_method(step, self_ty, pick_diag_hints))
+                .or_else(|| self.pick_reborrow_pin_method(step, self_ty, pick_diag_hints))
             })
     }
 
+    /// Check for cases where arbitrary self types allows shadowing
+    /// of methods that might be a compatibility break. Specifically,
+    /// we have something like:
+    /// ```ignore (illustrative)
+    /// struct A;
+    /// impl A {
+    ///   fn foo(self: &NonNull<A>) {}
+    ///      // note this is by reference
+    /// }
+    /// ```
+    /// then we've come along and added this method to `NonNull`:
+    /// ```ignore (illustrative)
+    ///   fn foo(self)  // note this is by value
+    /// ```
+    /// Report an error in this case.
+    fn check_for_shadowed_autorefd_method(
+        &self,
+        possible_shadower: &Pick<'tcx>,
+        step: &CandidateStep<'tcx>,
+        self_ty: Ty<'tcx>,
+        mutbl: hir::Mutability,
+        track_unstable_candidates: bool,
+    ) -> Result<(), MethodError<'tcx>> {
+        // We don't want to remember any of the diagnostic hints from this
+        // shadow search, but we do need to provide Some/None for the
+        // unstable_candidates in order to reflect the behavior of the
+        // main search.
+        let mut pick_diag_hints = PickDiagHints {
+            unstable_candidates: if track_unstable_candidates { Some(Vec::new()) } else { None },
+            unsatisfied_predicates: &mut Vec::new(),
+        };
+        // Set criteria for how we find methods possibly shadowed by 'possible_shadower'
+        let pick_constraints = PickConstraintsForShadowed {
+            // It's the same `self` type...
+            autoderefs: possible_shadower.autoderefs,
+            // ... but the method was found in an impl block determined
+            // by searching further along the Receiver chain than the other,
+            // showing that it's a smart pointer type causing the problem...
+            receiver_steps: possible_shadower.receiver_steps,
+            // ... and they don't end up pointing to the same item in the
+            // first place (could happen with things like blanket impls for T)
+            def_id: possible_shadower.item.def_id,
+        };
+        // A note on the autoderefs above. Within pick_by_value_method, an extra
+        // autoderef may be applied in order to reborrow a reference with
+        // a different lifetime. That seems as though it would break the
+        // logic of these constraints, since the number of autoderefs could
+        // no longer be used to identify the fundamental type of the receiver.
+        // However, this extra autoderef is applied only to by-value calls
+        // where the receiver is already a reference. So this situation would
+        // only occur in cases where the shadowing looks like this:
+        // ```
+        // struct A;
+        // impl A {
+        //   fn foo(self: &&NonNull<A>) {}
+        //      // note this is by DOUBLE reference
+        // }
+        // ```
+        // then we've come along and added this method to `NonNull`:
+        // ```
+        //   fn foo(&self)  // note this is by single reference
+        // ```
+        // and the call is:
+        // ```
+        // let bar = NonNull<Foo>;
+        // let bar = &foo;
+        // bar.foo();
+        // ```
+        // In these circumstances, the logic is wrong, and we wouldn't spot
+        // the shadowing, because the autoderef-based maths wouldn't line up.
+        // This is a niche case and we can live without generating an error
+        // in the case of such shadowing.
+        let potentially_shadowed_pick = self.pick_autorefd_method(
+            step,
+            self_ty,
+            mutbl,
+            &mut pick_diag_hints,
+            Some(&pick_constraints),
+        );
+        // Look for actual pairs of shadower/shadowed which are
+        // the sort of shadowing case we want to avoid. Specifically...
+        if let Some(Ok(possible_shadowed)) = potentially_shadowed_pick.as_ref() {
+            let sources = [possible_shadower, possible_shadowed]
+                .into_iter()
+                .map(|p| self.candidate_source_from_pick(p))
+                .collect();
+            return Err(MethodError::Ambiguity(sources));
+        }
+        Ok(())
+    }
+
     /// For each type `T` in the step list, this attempts to find a method where
     /// the (transformed) self type is exactly `T`. We do however do one
     /// transformation on the adjustment: if we are passing a region pointer in,
@@ -1126,13 +1415,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         &self,
         step: &CandidateStep<'tcx>,
         self_ty: Ty<'tcx>,
-        unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'_, 'tcx>,
     ) -> Option<PickResult<'tcx>> {
         if step.unsize {
             return None;
         }
 
-        self.pick_method(self_ty, unstable_candidates).map(|r| {
+        self.pick_method(self_ty, pick_diag_hints, None).map(|r| {
             r.map(|mut pick| {
                 pick.autoderefs = step.autoderefs;
 
@@ -1170,15 +1459,22 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         step: &CandidateStep<'tcx>,
         self_ty: Ty<'tcx>,
         mutbl: hir::Mutability,
-        unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'_, 'tcx>,
+        pick_constraints: Option<&PickConstraintsForShadowed>,
     ) -> Option<PickResult<'tcx>> {
         let tcx = self.tcx;
 
+        if let Some(pick_constraints) = pick_constraints {
+            if !pick_constraints.may_shadow_based_on_autoderefs(step.autoderefs) {
+                return None;
+            }
+        }
+
         // In general, during probing we erase regions.
         let region = tcx.lifetimes.re_erased;
 
         let autoref_ty = Ty::new_ref(tcx, region, self_ty, mutbl);
-        self.pick_method(autoref_ty, unstable_candidates).map(|r| {
+        self.pick_method(autoref_ty, pick_diag_hints, pick_constraints).map(|r| {
             r.map(|mut pick| {
                 pick.autoderefs = step.autoderefs;
                 pick.autoref_or_ptr_adjustment =
@@ -1189,12 +1485,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     }
 
     /// Looks for applicable methods if we reborrow a `Pin<&mut T>` as a `Pin<&T>`.
-    #[instrument(level = "debug", skip(self, step, unstable_candidates))]
+    #[instrument(level = "debug", skip(self, step, pick_diag_hints))]
     fn pick_reborrow_pin_method(
         &self,
         step: &CandidateStep<'tcx>,
         self_ty: Ty<'tcx>,
-        unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'_, 'tcx>,
     ) -> Option<PickResult<'tcx>> {
         if !self.tcx.features().pin_ergonomics() {
             return None;
@@ -1215,7 +1511,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
         let region = self.tcx.lifetimes.re_erased;
         let autopin_ty = Ty::new_pinned_ref(self.tcx, region, inner_ty, hir::Mutability::Not);
-        self.pick_method(autopin_ty, unstable_candidates).map(|r| {
+        self.pick_method(autopin_ty, pick_diag_hints, None).map(|r| {
             r.map(|mut pick| {
                 pick.autoderefs = step.autoderefs;
                 pick.autoref_or_ptr_adjustment =
@@ -1232,7 +1528,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         &self,
         step: &CandidateStep<'tcx>,
         self_ty: Ty<'tcx>,
-        unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'_, 'tcx>,
     ) -> Option<PickResult<'tcx>> {
         // Don't convert an unsized reference to ptr
         if step.unsize {
@@ -1244,7 +1540,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         };
 
         let const_ptr_ty = Ty::new_imm_ptr(self.tcx, ty);
-        self.pick_method(const_ptr_ty, unstable_candidates).map(|r| {
+        self.pick_method(const_ptr_ty, pick_diag_hints, None).map(|r| {
             r.map(|mut pick| {
                 pick.autoderefs = step.autoderefs;
                 pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::ToConstPtr);
@@ -1256,40 +1552,35 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     fn pick_method(
         &self,
         self_ty: Ty<'tcx>,
-        mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'_, 'tcx>,
+        pick_constraints: Option<&PickConstraintsForShadowed>,
     ) -> Option<PickResult<'tcx>> {
         debug!("pick_method(self_ty={})", self.ty_to_string(self_ty));
 
-        let mut possibly_unsatisfied_predicates = Vec::new();
-
         for (kind, candidates) in
             [("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
         {
             debug!("searching {} candidates", kind);
-            let res = self.consider_candidates(
-                self_ty,
-                candidates,
-                &mut possibly_unsatisfied_predicates,
-                unstable_candidates.as_deref_mut(),
-            );
+            let res =
+                self.consider_candidates(self_ty, candidates, pick_diag_hints, pick_constraints);
             if let Some(pick) = res {
                 return Some(pick);
             }
         }
 
         if self.private_candidate.get().is_none() {
-            if let Some(Ok(pick)) =
-                self.consider_candidates(self_ty, &self.private_candidates, &mut vec![], None)
-            {
+            if let Some(Ok(pick)) = self.consider_candidates(
+                self_ty,
+                &self.private_candidates,
+                &mut PickDiagHints {
+                    unstable_candidates: None,
+                    unsatisfied_predicates: &mut vec![],
+                },
+                None,
+            ) {
                 self.private_candidate.set(Some((pick.item.kind.as_def_kind(), pick.item.def_id)));
             }
         }
-
-        // `pick_method` may be called twice for the same self_ty if no stable methods
-        // match. Only extend once.
-        if unstable_candidates.is_some() {
-            self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates);
-        }
         None
     }
 
@@ -1297,17 +1588,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         &self,
         self_ty: Ty<'tcx>,
         candidates: &[Candidate<'tcx>],
-        possibly_unsatisfied_predicates: &mut Vec<(
-            ty::Predicate<'tcx>,
-            Option<ty::Predicate<'tcx>>,
-            Option<ObligationCause<'tcx>>,
-        )>,
-        mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
+        pick_diag_hints: &mut PickDiagHints<'_, 'tcx>,
+        pick_constraints: Option<&PickConstraintsForShadowed>,
     ) -> Option<PickResult<'tcx>> {
         let mut applicable_candidates: Vec<_> = candidates
             .iter()
+            .filter(|candidate| {
+                pick_constraints
+                    .map(|pick_constraints| pick_constraints.candidate_may_shadow(&candidate))
+                    .unwrap_or(true)
+            })
             .map(|probe| {
-                (probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates))
+                (
+                    probe,
+                    self.consider_probe(
+                        self_ty,
+                        probe,
+                        &mut pick_diag_hints.unsatisfied_predicates,
+                    ),
+                )
             })
             .filter(|&(_, status)| status != ProbeResult::NoMatch)
             .collect();
@@ -1322,7 +1621,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             }
         }
 
-        if let Some(uc) = &mut unstable_candidates {
+        if let Some(uc) = &mut pick_diag_hints.unstable_candidates {
             applicable_candidates.retain(|&(candidate, _)| {
                 if let stability::EvalResult::Deny { feature, .. } =
                     self.tcx.eval_stability(candidate.item.def_id, None, self.span, None)
@@ -1340,10 +1639,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         }
 
         applicable_candidates.pop().map(|(probe, status)| match status {
-            ProbeResult::Match => {
-                Ok(probe
-                    .to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default()))
-            }
+            ProbeResult::Match => Ok(probe.to_unadjusted_pick(
+                self_ty,
+                pick_diag_hints.unstable_candidates.clone().unwrap_or_default(),
+            )),
             ProbeResult::NoMatch | ProbeResult::BadReturnType => Err(MethodError::BadReturnType),
         })
     }
@@ -1372,6 +1671,7 @@ impl<'tcx> Pick<'tcx> {
             autoref_or_ptr_adjustment: _,
             self_ty,
             unstable_candidates: _,
+            receiver_steps: _,
         } = *self;
         self_ty != other.self_ty || def_id != other.item.def_id
     }
@@ -1447,7 +1747,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     /// so do not use to make a decision that may lead to a successful compilation.
     fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource {
         match candidate.kind {
-            InherentImplCandidate(_) => {
+            InherentImplCandidate { .. } => {
                 CandidateSource::Impl(candidate.item.container_id(self.tcx))
             }
             ObjectCandidate(_) | WhereClauseCandidate(_) => {
@@ -1477,6 +1777,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         }
     }
 
+    fn candidate_source_from_pick(&self, pick: &Pick<'tcx>) -> CandidateSource {
+        match pick.kind {
+            InherentImplPick => CandidateSource::Impl(pick.item.container_id(self.tcx)),
+            ObjectPick | WhereClausePick(_) | TraitPick => {
+                CandidateSource::Trait(pick.item.container_id(self.tcx))
+            }
+        }
+    }
+
     #[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)]
     fn consider_probe(
         &self,
@@ -1501,7 +1810,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             let (mut xform_self_ty, mut xform_ret_ty);
 
             match probe.kind {
-                InherentImplCandidate(impl_def_id) => {
+                InherentImplCandidate { impl_def_id, .. } => {
                     let impl_args = self.fresh_args_for_item(self.span, impl_def_id);
                     let impl_ty = self.tcx.type_of(impl_def_id).instantiate(self.tcx, impl_args);
                     (xform_self_ty, xform_ret_ty) =
@@ -1693,7 +2002,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 // We don't normalize the other candidates for perf/backwards-compat reasons...
                 // but `self.return_type` is only set on the diagnostic-path, so we
                 // should be okay doing it here.
-                if !matches!(probe.kind, InherentImplCandidate(_)) {
+                if !matches!(probe.kind, InherentImplCandidate { .. }) {
                     xform_ret_ty = ocx.normalize(&cause, self.param_env, xform_ret_ty);
                 }
 
@@ -1771,6 +2080,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             autoref_or_ptr_adjustment: None,
             self_ty,
             unstable_candidates: vec![],
+            receiver_steps: None,
         })
     }
 
@@ -1808,7 +2118,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     pcx.method_name = Some(method_name);
                     pcx.assemble_inherent_candidates();
                     pcx.assemble_extension_candidates_for_all_traits();
-                    pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item)
+                    pcx.pick_core(&mut Vec::new()).and_then(|pick| pick.ok()).map(|pick| pick.item)
                 })
                 .collect();
 
@@ -2042,7 +2352,7 @@ impl<'tcx> Candidate<'tcx> {
         Pick {
             item: self.item,
             kind: match self.kind {
-                InherentImplCandidate(_) => InherentImplPick,
+                InherentImplCandidate { .. } => InherentImplPick,
                 ObjectCandidate(_) => ObjectPick,
                 TraitCandidate(_) => TraitPick,
                 WhereClauseCandidate(trait_ref) => {
@@ -2064,6 +2374,10 @@ impl<'tcx> Candidate<'tcx> {
             autoref_or_ptr_adjustment: None,
             self_ty,
             unstable_candidates,
+            receiver_steps: match self.kind {
+                InherentImplCandidate { receiver_steps, .. } => Some(receiver_steps),
+                _ => None,
+            },
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index b0c020dd7cb..4f283644cbe 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -1840,7 +1840,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 /// captured by move.
 ///
 /// ```rust
-/// #![feature(async_closure)]
 /// let x = &1i32; // Let's call this lifetime `'1`.
 /// let c = async move || {
 ///     println!("{:?}", *x);
@@ -1855,7 +1854,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 /// child capture with the lifetime of the parent coroutine-closure's env.
 ///
 /// ```rust
-/// #![feature(async_closure)]
 /// let mut x = 1i32;
 /// let c = async || {
 ///     x = 1;
diff --git a/compiler/rustc_lint/src/async_closures.rs b/compiler/rustc_lint/src/async_closures.rs
index 2a821b71103..5d40b8ab2ee 100644
--- a/compiler/rustc_lint/src/async_closures.rs
+++ b/compiler/rustc_lint/src/async_closures.rs
@@ -12,7 +12,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
-    /// #![feature(async_closure)]
     /// #![warn(closure_returning_async_block)]
     /// let c = |x: &str| async {};
     /// ```
@@ -40,8 +39,6 @@ declare_lint! {
     /// But it does work with async closures:
     ///
     /// ```rust
-    /// #![feature(async_closure)]
-    ///
     /// async fn callback(x: &str) {}
     ///
     /// let captured_str = String::new();
@@ -52,7 +49,6 @@ declare_lint! {
     pub CLOSURE_RETURNING_ASYNC_BLOCK,
     Allow,
     "closure that returns `async {}` could be rewritten as an async closure",
-    @feature_gate = async_closure;
 }
 
 declare_lint_pass!(
diff --git a/compiler/rustc_lint/src/tests.rs b/compiler/rustc_lint/src/tests.rs
index 7fbf381a8d3..186dec5904b 100644
--- a/compiler/rustc_lint/src/tests.rs
+++ b/compiler/rustc_lint/src/tests.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
+
 use rustc_span::{Symbol, create_default_session_globals_then};
 
 use crate::levels::parse_lint_and_tool_name;
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index eeed5118592..f049da95f29 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -149,11 +149,21 @@ pub struct CandidateStep<'tcx> {
     /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
     pub from_unsafe_deref: bool,
     pub unsize: bool,
+    /// We will generate CandidateSteps which are reachable via a chain
+    /// of following `Receiver`. The first 'n' of those will be reachable
+    /// by following a chain of 'Deref' instead (since there's a blanket
+    /// implementation of Receiver for Deref).
+    /// We use the entire set of steps when identifying method candidates
+    /// (e.g. identifying relevant `impl` blocks) but only those that are
+    /// reachable via Deref when examining what the receiver type can
+    /// be converted into by autodereffing.
+    pub reachable_via_deref: bool,
 }
 
 #[derive(Copy, Clone, Debug, HashStable)]
 pub struct MethodAutoderefStepsResult<'tcx> {
-    /// The valid autoderef steps that could be found.
+    /// The valid autoderef steps that could be found by following a chain
+    /// of `Receiver<Target=T>` or `Deref<Target=T>` trait implementations.
     pub steps: &'tcx [CandidateStep<'tcx>],
     /// If Some(T), a type autoderef reported an error on.
     pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>,
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 65c909e70f6..1dd564d9798 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -677,23 +677,26 @@ impl<'tcx> Instance<'tcx> {
                 //
                 // 1) The underlying method expects a caller location parameter
                 // in the ABI
-                if resolved.def.requires_caller_location(tcx)
-                        // 2) The caller location parameter comes from having `#[track_caller]`
-                        // on the implementation, and *not* on the trait method.
-                        && !tcx.should_inherit_track_caller(def)
-                        // If the method implementation comes from the trait definition itself
-                        // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
-                        // then we don't need to generate a shim. This check is needed because
-                        // `should_inherit_track_caller` returns `false` if our method
-                        // implementation comes from the trait block, and not an impl block
-                        && !matches!(
-                            tcx.opt_associated_item(def),
-                            Some(ty::AssocItem {
-                                container: ty::AssocItemContainer::Trait,
-                                ..
-                            })
-                        )
-                {
+                let needs_track_caller_shim = resolved.def.requires_caller_location(tcx)
+                    // 2) The caller location parameter comes from having `#[track_caller]`
+                    // on the implementation, and *not* on the trait method.
+                    && !tcx.should_inherit_track_caller(def)
+                    // If the method implementation comes from the trait definition itself
+                    // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`),
+                    // then we don't need to generate a shim. This check is needed because
+                    // `should_inherit_track_caller` returns `false` if our method
+                    // implementation comes from the trait block, and not an impl block
+                    && !matches!(
+                        tcx.opt_associated_item(def),
+                        Some(ty::AssocItem {
+                            container: ty::AssocItemContainer::Trait,
+                            ..
+                        })
+                    );
+                // We also need to generate a shim if this is an AFIT.
+                let needs_rpitit_shim =
+                    tcx.return_position_impl_trait_in_trait_shim_data(def).is_some();
+                if needs_track_caller_shim || needs_rpitit_shim {
                     if tcx.is_closure_like(def) {
                         debug!(
                             " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 70e0568b202..80b11892a42 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -146,6 +146,7 @@ mod opaque_types;
 mod parameterized;
 mod predicate;
 mod region;
+mod return_position_impl_trait_in_trait;
 mod rvalue_scopes;
 mod structural_impls;
 #[allow(hidden_glob_reexports)]
diff --git a/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs
new file mode 100644
index 00000000000..21c605f8296
--- /dev/null
+++ b/compiler/rustc_middle/src/ty/return_position_impl_trait_in_trait.rs
@@ -0,0 +1,95 @@
+use rustc_hir::def_id::DefId;
+
+use crate::ty::{self, ExistentialPredicateStableCmpExt, TyCtxt};
+
+impl<'tcx> TyCtxt<'tcx> {
+    /// Given a `def_id` of a trait or impl method, compute whether that method needs to
+    /// have an RPITIT shim applied to it for it to be object safe. If so, return the
+    /// `def_id` of the RPITIT, and also the args of trait method that returns the RPITIT.
+    ///
+    /// NOTE that these args are not, in general, the same as than the RPITIT's args. They
+    /// are a subset of those args,  since they do not include the late-bound lifetimes of
+    /// the RPITIT. Depending on the context, these will need to be dealt with in different
+    /// ways -- in codegen, it's okay to fill them with ReErased.
+    pub fn return_position_impl_trait_in_trait_shim_data(
+        self,
+        def_id: DefId,
+    ) -> Option<(DefId, ty::EarlyBinder<'tcx, ty::GenericArgsRef<'tcx>>)> {
+        let assoc_item = self.opt_associated_item(def_id)?;
+
+        let (trait_item_def_id, opt_impl_def_id) = match assoc_item.container {
+            ty::AssocItemContainer::Impl => {
+                (assoc_item.trait_item_def_id?, Some(self.parent(def_id)))
+            }
+            ty::AssocItemContainer::Trait => (def_id, None),
+        };
+
+        let sig = self.fn_sig(trait_item_def_id);
+
+        // Check if the trait returns an RPITIT.
+        let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) =
+            *sig.skip_binder().skip_binder().output().kind()
+        else {
+            return None;
+        };
+        if !self.is_impl_trait_in_trait(def_id) {
+            return None;
+        }
+
+        let args = if let Some(impl_def_id) = opt_impl_def_id {
+            // Rebase the args from the RPITIT onto the impl trait ref, so we can later
+            // substitute them with the method args of the *impl* method, since that's
+            // the instance we're building a vtable shim for.
+            ty::GenericArgs::identity_for_item(self, trait_item_def_id).rebase_onto(
+                self,
+                self.parent(trait_item_def_id),
+                self.impl_trait_ref(impl_def_id)
+                    .expect("expected impl trait ref from parent of impl item")
+                    .instantiate_identity()
+                    .args,
+            )
+        } else {
+            // This is when we have a default trait implementation.
+            ty::GenericArgs::identity_for_item(self, trait_item_def_id)
+        };
+
+        Some((def_id, ty::EarlyBinder::bind(args)))
+    }
+
+    /// Given a `DefId` of an RPITIT and its args, return the existential predicates
+    /// that corresponds to the RPITIT's bounds with the self type erased.
+    pub fn item_bounds_to_existential_predicates(
+        self,
+        def_id: DefId,
+        args: ty::GenericArgsRef<'tcx>,
+    ) -> &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
+        let mut bounds: Vec<_> = self
+            .item_super_predicates(def_id)
+            .iter_instantiated(self, args)
+            .filter_map(|clause| {
+                clause
+                    .kind()
+                    .map_bound(|clause| match clause {
+                        ty::ClauseKind::Trait(trait_pred) => Some(ty::ExistentialPredicate::Trait(
+                            ty::ExistentialTraitRef::erase_self_ty(self, trait_pred.trait_ref),
+                        )),
+                        ty::ClauseKind::Projection(projection_pred) => {
+                            Some(ty::ExistentialPredicate::Projection(
+                                ty::ExistentialProjection::erase_self_ty(self, projection_pred),
+                            ))
+                        }
+                        ty::ClauseKind::TypeOutlives(_) => {
+                            // Type outlives bounds don't really turn into anything,
+                            // since we must use an intersection region for the `dyn*`'s
+                            // region anyways.
+                            None
+                        }
+                        _ => unreachable!("unexpected clause in item bounds: {clause:?}"),
+                    })
+                    .transpose()
+            })
+            .collect();
+        bounds.sort_by(|a, b| a.skip_binder().stable_cmp(self, &b.skip_binder()));
+        self.mk_poly_existential_predicates(&bounds)
+    }
+}
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
index df4c0593246..d79d2c316ee 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
@@ -4,52 +4,26 @@
 //! field-deref on a local variable, `x.field`, has the same meaning
 //! in both domains). Indexed projections are the exception: `a[x]`
 //! needs to be treated as mapping to the same move path as `a[y]` as
-//! well as `a[13]`, etc.
+//! well as `a[13]`, etc. So we map these `x`/`y` values to `()`.
 //!
 //! (In theory, the analysis could be extended to work with sets of
 //! paths, so that `a[0]` and `a[13]` could be kept distinct, while
 //! `a[x]` would still overlap them both. But that is not this
 //! representation does today.)
 
-use rustc_middle::mir::{Local, Operand, PlaceElem, ProjectionElem};
-use rustc_middle::ty::Ty;
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub(crate) struct AbstractOperand;
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub(crate) struct AbstractType;
-pub(crate) type AbstractElem = ProjectionElem<AbstractOperand, AbstractType>;
+use rustc_middle::mir::{PlaceElem, ProjectionElem, ProjectionKind};
 
 pub(crate) trait Lift {
-    type Abstract;
-    fn lift(&self) -> Self::Abstract;
-}
-impl<'tcx> Lift for Operand<'tcx> {
-    type Abstract = AbstractOperand;
-    fn lift(&self) -> Self::Abstract {
-        AbstractOperand
-    }
-}
-impl Lift for Local {
-    type Abstract = AbstractOperand;
-    fn lift(&self) -> Self::Abstract {
-        AbstractOperand
-    }
-}
-impl<'tcx> Lift for Ty<'tcx> {
-    type Abstract = AbstractType;
-    fn lift(&self) -> Self::Abstract {
-        AbstractType
-    }
+    fn lift(&self) -> ProjectionKind;
 }
+
 impl<'tcx> Lift for PlaceElem<'tcx> {
-    type Abstract = AbstractElem;
-    fn lift(&self) -> Self::Abstract {
+    fn lift(&self) -> ProjectionKind {
         match *self {
             ProjectionElem::Deref => ProjectionElem::Deref,
-            ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty.lift()),
-            ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty.lift()),
-            ProjectionElem::Index(ref i) => ProjectionElem::Index(i.lift()),
+            ProjectionElem::Field(f, _ty) => ProjectionElem::Field(f, ()),
+            ProjectionElem::OpaqueCast(_ty) => ProjectionElem::OpaqueCast(()),
+            ProjectionElem::Index(_i) => ProjectionElem::Index(()),
             ProjectionElem::Subslice { from, to, from_end } => {
                 ProjectionElem::Subslice { from, to, from_end }
             }
@@ -57,7 +31,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> {
                 ProjectionElem::ConstantIndex { offset, min_length, from_end }
             }
             ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
-            ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty.lift()),
+            ProjectionElem::Subtype(_ty) => ProjectionElem::Subtype(()),
         }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index 926bd187431..8aea8d2ae3c 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_span::Span;
 use smallvec::SmallVec;
 
-use self::abs_domain::{AbstractElem, Lift};
+use self::abs_domain::Lift;
 use crate::un_derefer::UnDerefer;
 
 mod abs_domain;
@@ -300,7 +300,7 @@ pub struct MovePathLookup<'tcx> {
     /// subsequent search so that it is solely relative to that
     /// base-place). For the remaining lookup, we map the projection
     /// elem to the associated MovePathIndex.
-    projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>,
+    projections: FxHashMap<(MovePathIndex, ProjectionKind), MovePathIndex>,
 
     un_derefer: UnDerefer<'tcx>,
 }
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 36eb435c63a..ef61866e902 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -3,8 +3,6 @@
 //!
 //! Consider an async closure like:
 //! ```rust
-//! #![feature(async_closure)]
-//!
 //! let x = vec![1, 2, 3];
 //!
 //! let closure = async move || {
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index b8383e734e2..722da3c420d 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -9,6 +9,7 @@ use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::*;
 use rustc_middle::query::Providers;
+use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{
     self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt,
 };
@@ -710,6 +711,13 @@ fn build_call_shim<'tcx>(
     };
 
     let def_id = instance.def_id();
+
+    let rpitit_shim = if let ty::InstanceKind::ReifyShim(..) = instance {
+        tcx.return_position_impl_trait_in_trait_shim_data(def_id)
+    } else {
+        None
+    };
+
     let sig = tcx.fn_sig(def_id);
     let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig));
 
@@ -765,9 +773,34 @@ fn build_call_shim<'tcx>(
     let mut local_decls = local_decls_for_sig(&sig, span);
     let source_info = SourceInfo::outermost(span);
 
+    let mut destination = Place::return_place();
+    if let Some((rpitit_def_id, fn_args)) = rpitit_shim {
+        let rpitit_args =
+            fn_args.instantiate_identity().extend_to(tcx, rpitit_def_id, |param, _| {
+                match param.kind {
+                    ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
+                    ty::GenericParamDefKind::Type { .. }
+                    | ty::GenericParamDefKind::Const { .. } => {
+                        unreachable!("rpitit should have no addition ty/ct")
+                    }
+                }
+            });
+        let dyn_star_ty = Ty::new_dynamic(
+            tcx,
+            tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args),
+            tcx.lifetimes.re_erased,
+            ty::DynStar,
+        );
+        destination = local_decls.push(local_decls[RETURN_PLACE].clone()).into();
+        local_decls[RETURN_PLACE].ty = dyn_star_ty;
+        let mut inputs_and_output = sig.inputs_and_output.to_vec();
+        *inputs_and_output.last_mut().unwrap() = dyn_star_ty;
+        sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
+    }
+
     let rcvr_place = || {
         assert!(rcvr_adjustment.is_some());
-        Place::from(Local::new(1 + 0))
+        Place::from(Local::new(1))
     };
     let mut statements = vec![];
 
@@ -854,7 +887,7 @@ fn build_call_shim<'tcx>(
         TerminatorKind::Call {
             func: callee,
             args,
-            destination: Place::return_place(),
+            destination,
             target: Some(BasicBlock::new(1)),
             unwind: if let Some(Adjustment::RefMut) = rcvr_adjustment {
                 UnwindAction::Cleanup(BasicBlock::new(3))
@@ -882,7 +915,24 @@ fn build_call_shim<'tcx>(
         );
     }
     // BB #1/#2 - return
-    block(&mut blocks, vec![], TerminatorKind::Return, false);
+    // NOTE: If this is an RPITIT in dyn, we also want to coerce
+    // the return type of the function into a `dyn*`.
+    let stmts = if rpitit_shim.is_some() {
+        vec![Statement {
+            source_info,
+            kind: StatementKind::Assign(Box::new((
+                Place::return_place(),
+                Rvalue::Cast(
+                    CastKind::PointerCoercion(PointerCoercion::DynStar, CoercionSource::Implicit),
+                    Operand::Move(destination),
+                    sig.output(),
+                ),
+            ))),
+        }]
+    } else {
+        vec![]
+    };
+    block(&mut blocks, stmts, TerminatorKind::Return, false);
     if let Some(Adjustment::RefMut) = rcvr_adjustment {
         // BB #3 - drop if closure panics
         block(
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index caae54cd559..714b64b3a23 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -42,7 +42,10 @@ fn custom_coerce_unsize_info<'tcx>(
             ..
         })) => Ok(tcx.coerce_unsized_info(impl_def_id)?.custom_kind.unwrap()),
         impl_source => {
-            bug!("invalid `CoerceUnsized` impl_source: {:?}", impl_source);
+            bug!(
+                "invalid `CoerceUnsized` from {source_ty} to {target_ty}: impl_source: {:?}",
+                impl_source
+            );
         }
     }
 }
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index c6c9eb3b0b2..ee38f16d4ec 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -1,7 +1,7 @@
 use rustc_ast::token::{self, Delimiter, Token};
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
 use rustc_ast_pretty::pprust::token_to_string;
-use rustc_errors::{Applicability, PErr};
+use rustc_errors::{Applicability, Diag};
 use rustc_span::symbol::kw;
 
 use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
@@ -14,7 +14,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
     pub(super) fn lex_token_trees(
         &mut self,
         is_delimited: bool,
-    ) -> (Spacing, TokenStream, Result<(), Vec<PErr<'psess>>>) {
+    ) -> (Spacing, TokenStream, Result<(), Vec<Diag<'psess>>>) {
         // Move past the opening delimiter.
         let open_spacing = self.bump_minimal();
 
@@ -56,7 +56,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         }
     }
 
-    fn eof_err(&mut self) -> PErr<'psess> {
+    fn eof_err(&mut self) -> Diag<'psess> {
         let msg = "this file contains an unclosed delimiter";
         let mut err = self.dcx().struct_span_err(self.token.span, msg);
 
@@ -98,7 +98,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
     fn lex_token_tree_open_delim(
         &mut self,
         open_delim: Delimiter,
-    ) -> Result<TokenTree, Vec<PErr<'psess>>> {
+    ) -> Result<TokenTree, Vec<Diag<'psess>>> {
         // The span for beginning of the delimited section.
         let pre_span = self.token.span;
 
@@ -250,8 +250,8 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
     fn unclosed_delim_err(
         &mut self,
         tts: TokenStream,
-        mut errs: Vec<PErr<'psess>>,
-    ) -> Vec<PErr<'psess>> {
+        mut errs: Vec<Diag<'psess>>,
+    ) -> Vec<Diag<'psess>> {
         // If there are unclosed delims, see if there are diff markers and if so, point them
         // out instead of complaining about the unclosed delims.
         let mut parser = Parser::new(self.psess, tts, None);
@@ -308,7 +308,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         errs
     }
 
-    fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'psess> {
+    fn close_delim_err(&mut self, delim: Delimiter) -> Diag<'psess> {
         // An unexpected closing delimiter (i.e., there is no matching opening delimiter).
         let token_str = token_to_string(&self.token);
         let msg = format!("unexpected closing delimiter: `{token_str}`");
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 34131e3af6e..e5edf605d82 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -16,7 +16,7 @@ use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{
-    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult, Subdiagnostic,
+    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PResult, Subdiagnostic,
     Suggestions, pluralize,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
@@ -2132,7 +2132,7 @@ impl<'a> Parser<'a> {
         &mut self,
         delim: Delimiter,
         lo: Span,
-        err: PErr<'a>,
+        err: Diag<'a>,
     ) -> P<Expr> {
         let guar = err.emit();
         // Recover from parse error, callers expect the closing delim to be consumed.
@@ -3014,7 +3014,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Check for exclusive ranges written as `..<`
-    pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> {
+    pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: Diag<'a>) -> Diag<'a> {
         if maybe_lt == token::Lt
             && (self.expected_tokens.contains(&TokenType::Token(token::Gt))
                 || matches!(self.token.kind, token::Literal(..)))
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index eeb83a85e59..44f42e5fbf2 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1369,11 +1369,14 @@ impl<'a> Parser<'a> {
             ))
         } else {
             // Field access `expr.f`
+            let span = lo.to(self.prev_token.span);
             if let Some(args) = seg.args {
-                self.dcx().emit_err(errors::FieldExpressionWithGeneric(args.span()));
+                // See `StashKey::GenericInFieldExpr` for more info on why we stash this.
+                self.dcx()
+                    .create_err(errors::FieldExpressionWithGeneric(args.span()))
+                    .stash(seg.ident.span, StashKey::GenericInFieldExpr);
             }
 
-            let span = lo.to(self.prev_token.span);
             Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident)))
         }
     }
@@ -2363,10 +2366,7 @@ impl<'a> Parser<'a> {
         };
 
         match coroutine_kind {
-            Some(CoroutineKind::Async { span, .. }) => {
-                // Feature-gate `async ||` closures.
-                self.psess.gated_spans.gate(sym::async_closure, span);
-            }
+            Some(CoroutineKind::Async { .. }) => {}
             Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
                 // Feature-gate `gen ||` and `async gen ||` closures.
                 // FIXME(gen_blocks): This perhaps should be a different gate.
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index decaecd2682..1813960dad0 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
+
 use std::assert_matches::assert_matches;
 use std::io::prelude::*;
 use std::iter::Peekable;
diff --git a/compiler/rustc_parse/src/parser/tokenstream/tests.rs b/compiler/rustc_parse/src/parser/tokenstream/tests.rs
index efe266f5290..b13b68c266a 100644
--- a/compiler/rustc_parse/src/parser/tokenstream/tests.rs
+++ b/compiler/rustc_parse/src/parser/tokenstream/tests.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
+
 use rustc_ast::token::{self, IdentIsRaw};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_span::{BytePos, Span, Symbol, create_default_session_globals_then};
diff --git a/compiler/rustc_span/src/edit_distance/tests.rs b/compiler/rustc_span/src/edit_distance/tests.rs
index c9c7a1f1bf2..9540f934d7e 100644
--- a/compiler/rustc_span/src/edit_distance/tests.rs
+++ b/compiler/rustc_span/src/edit_distance/tests.rs
@@ -1,3 +1,5 @@
+#![cfg_attr(not(bootstrap), allow(rustc::symbol_intern_string_literal))]
+
 use super::*;
 
 #[test]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d30b17c9cd8..9b499c71603 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -461,6 +461,7 @@ symbols! {
         async_drop_slice,
         async_drop_surface_drop_in_place,
         async_fn,
+        async_fn_in_dyn_trait,
         async_fn_in_trait,
         async_fn_kind_helper,
         async_fn_kind_upvars,
diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
index d5acd37092a..4f370ec8bd0 100644
--- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
+++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs
@@ -42,6 +42,8 @@ pub(crate) fn opts() -> TargetOptions {
         eh_frame_header: false,
         no_default_libraries: false,
         has_thread_local: true,
+        crt_static_allows_dylibs: true,
+        crt_static_respected: true,
         // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
         // output DWO, despite using DWARF, doesn't use ELF..
         debuginfo_kind: DebuginfoKind::Pdb,
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 3a130607265..c89045c93e3 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -611,6 +611,8 @@ const HEXAGON_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
     &[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")];
 const MIPS_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")];
 const CSKY_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vdspv1")];
+const LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
+    &[(128, "lsx"), (256, "lasx")];
 
 impl super::spec::Target {
     pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
@@ -638,7 +640,7 @@ impl super::spec::Target {
             "aarch64" | "arm64ec" => AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "arm" => ARM_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "powerpc" | "powerpc64" => POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI,
-            "loongarch64" => &[], // on-stack ABI, so we complain about all by-val vectors
+            "loongarch64" => LOONGARCH_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "riscv32" | "riscv64" => RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "wasm32" | "wasm64" => WASM_FEATURES_FOR_CORRECT_VECTOR_ABI,
             "s390x" => S390X_FEATURES_FOR_CORRECT_VECTOR_ABI,
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index c9297027519..d2abd881c45 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -11,6 +11,7 @@ use rustc_abi::BackendRepr;
 use rustc_errors::FatalError;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
     self, EarlyBinder, ExistentialPredicateStableCmpExt as _, GenericArgs, Ty, TyCtxt,
@@ -901,23 +902,59 @@ fn contains_illegal_impl_trait_in_trait<'tcx>(
     fn_def_id: DefId,
     ty: ty::Binder<'tcx, Ty<'tcx>>,
 ) -> Option<MethodViolationCode> {
-    // This would be caught below, but rendering the error as a separate
-    // `async-specific` message is better.
+    let ty = tcx.liberate_late_bound_regions(fn_def_id, ty);
+
     if tcx.asyncness(fn_def_id).is_async() {
-        return Some(MethodViolationCode::AsyncFn);
+        // FIXME(async_fn_in_dyn_trait): Think of a better way to unify these code paths
+        // to issue an appropriate feature suggestion when users try to use AFIDT.
+        // Obviously we must only do this once AFIDT is finished enough to actually be usable.
+        if tcx.features().async_fn_in_dyn_trait() {
+            let ty::Alias(ty::Projection, proj) = *ty.kind() else {
+                bug!("expected async fn in trait to return an RPITIT");
+            };
+            assert!(tcx.is_impl_trait_in_trait(proj.def_id));
+
+            // FIXME(async_fn_in_dyn_trait): We should check that this bound is legal too,
+            // and stop relying on `async fn` in the definition.
+            for bound in tcx.item_bounds(proj.def_id).instantiate(tcx, proj.args) {
+                if let Some(violation) = bound
+                    .visit_with(&mut IllegalRpititVisitor { tcx, allowed: Some(proj) })
+                    .break_value()
+                {
+                    return Some(violation);
+                }
+            }
+
+            None
+        } else {
+            // Rendering the error as a separate `async-specific` message is better.
+            Some(MethodViolationCode::AsyncFn)
+        }
+    } else {
+        ty.visit_with(&mut IllegalRpititVisitor { tcx, allowed: None }).break_value()
     }
+}
+
+struct IllegalRpititVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    allowed: Option<ty::AliasTy<'tcx>>,
+}
+
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalRpititVisitor<'tcx> {
+    type Result = ControlFlow<MethodViolationCode>;
 
-    // FIXME(RPITIT): Perhaps we should use a visitor here?
-    ty.skip_binder().walk().find_map(|arg| {
-        if let ty::GenericArgKind::Type(ty) = arg.unpack()
-            && let ty::Alias(ty::Projection, proj) = ty.kind()
-            && tcx.is_impl_trait_in_trait(proj.def_id)
+    fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
+        if let ty::Alias(ty::Projection, proj) = *ty.kind()
+            && Some(proj) != self.allowed
+            && self.tcx.is_impl_trait_in_trait(proj.def_id)
         {
-            Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id)))
+            ControlFlow::Break(MethodViolationCode::ReferencesImplTraitInTrait(
+                self.tcx.def_span(proj.def_id),
+            ))
         } else {
-            None
+            ty.super_visit_with(self)
         }
-    })
+    }
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 541c0c915ff..5f1dbfeedfb 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -7,8 +7,8 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::lang_items::LangItem;
-use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
+use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin};
 use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
@@ -18,6 +18,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast};
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::sym;
+use thin_vec::thin_vec;
 use tracing::{debug, instrument};
 
 use super::{
@@ -61,6 +62,9 @@ enum ProjectionCandidate<'tcx> {
     /// Bounds specified on an object type
     Object(ty::PolyProjectionPredicate<'tcx>),
 
+    /// Built-in bound for a dyn async fn in trait
+    ObjectRpitit,
+
     /// From an "impl" (or a "pseudo-impl" returned by select)
     Select(Selection<'tcx>),
 }
@@ -827,6 +831,17 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
         env_predicates,
         false,
     );
+
+    // `dyn Trait` automagically project their AFITs to `dyn* Future`.
+    if tcx.is_impl_trait_in_trait(obligation.predicate.def_id)
+        && let Some(out_trait_def_id) = data.principal_def_id()
+        && let rpitit_trait_def_id = tcx.parent(obligation.predicate.def_id)
+        && tcx
+            .supertrait_def_ids(out_trait_def_id)
+            .any(|trait_def_id| trait_def_id == rpitit_trait_def_id)
+    {
+        candidate_set.push_candidate(ProjectionCandidate::ObjectRpitit);
+    }
 }
 
 #[instrument(
@@ -1247,6 +1262,8 @@ fn confirm_candidate<'cx, 'tcx>(
         ProjectionCandidate::Select(impl_source) => {
             confirm_select_candidate(selcx, obligation, impl_source)
         }
+
+        ProjectionCandidate::ObjectRpitit => confirm_object_rpitit_candidate(selcx, obligation),
     };
 
     // When checking for cycle during evaluation, we compare predicates with
@@ -2034,6 +2051,45 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     }
 }
 
+fn confirm_object_rpitit_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
+    obligation: &ProjectionTermObligation<'tcx>,
+) -> Progress<'tcx> {
+    let tcx = selcx.tcx();
+    let mut obligations = thin_vec![];
+
+    // Compute an intersection lifetime for all the input components of this GAT.
+    let intersection =
+        selcx.infcx.next_region_var(RegionVariableOrigin::MiscVariable(obligation.cause.span));
+    for component in obligation.predicate.args {
+        match component.unpack() {
+            ty::GenericArgKind::Lifetime(lt) => {
+                obligations.push(obligation.with(tcx, ty::OutlivesPredicate(lt, intersection)));
+            }
+            ty::GenericArgKind::Type(ty) => {
+                obligations.push(obligation.with(tcx, ty::OutlivesPredicate(ty, intersection)));
+            }
+            ty::GenericArgKind::Const(_ct) => {
+                // Consts have no outlives...
+            }
+        }
+    }
+
+    Progress {
+        term: Ty::new_dynamic(
+            tcx,
+            tcx.item_bounds_to_existential_predicates(
+                obligation.predicate.def_id,
+                obligation.predicate.args,
+            ),
+            intersection,
+            ty::DynStar,
+        )
+        .into(),
+        obligations,
+    }
+}
+
 // Get obligations corresponding to the predicates from the where-clause of the
 // associated type itself.
 fn assoc_ty_own_obligations<'cx, 'tcx>(
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 2fbe2e1e323..962b6b94fa6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -19,6 +19,7 @@ use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
 use rustc_middle::ty::{self, GenericArgsRef, ToPolyTraitRef, Ty, TyCtxt, Upcast};
 use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::DefId;
+use rustc_type_ir::elaborate;
 use tracing::{debug, instrument};
 
 use super::SelectionCandidate::{self, *};
@@ -624,6 +625,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         for assoc_type in assoc_types {
             let defs: &ty::Generics = tcx.generics_of(assoc_type);
 
+            // When `async_fn_in_dyn_trait` is enabled, we don't need to check the
+            // RPITIT for compatibility, since it's not provided by the user.
+            if tcx.features().async_fn_in_dyn_trait() && tcx.is_impl_trait_in_trait(assoc_type) {
+                continue;
+            }
+
             if !defs.own_params.is_empty() {
                 tcx.dcx().span_delayed_bug(
                     obligation.cause.span,
@@ -1175,6 +1182,38 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
                 ));
 
+                // Require that all AFIT will return something that can be coerced into `dyn*`
+                // -- a shim will be responsible for doing the actual coercion to `dyn*`.
+                if let Some(principal) = data.principal() {
+                    for supertrait in
+                        elaborate::supertraits(tcx, principal.with_self_ty(tcx, source))
+                    {
+                        if tcx.is_trait_alias(supertrait.def_id()) {
+                            continue;
+                        }
+
+                        for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) {
+                            if !tcx.is_impl_trait_in_trait(assoc_item) {
+                                continue;
+                            }
+
+                            // RPITITs with `Self: Sized` don't need to be checked.
+                            if tcx.generics_require_sized_self(assoc_item) {
+                                continue;
+                            }
+
+                            let pointer_like_goal = pointer_like_goal_for_rpitit(
+                                tcx,
+                                supertrait,
+                                assoc_item,
+                                &obligation.cause,
+                            );
+
+                            nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx)));
+                        }
+                    }
+                }
+
                 ImplSource::Builtin(BuiltinImplSource::Misc, nested)
             }
 
@@ -1280,3 +1319,43 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         })
     }
 }
+
+/// Compute a goal that some RPITIT (right now, only RPITITs corresponding to Futures)
+/// implements the `PointerLike` trait, which is a requirement for the RPITIT to be
+/// coercible to `dyn* Future`, which is itself a requirement for the RPITIT's parent
+/// trait to be coercible to `dyn Trait`.
+///
+/// We do this given a supertrait's substitutions, and then augment the substitutions
+/// with bound variables to compute the goal universally. Given that `PointerLike` has
+/// no region requirements (at least for the built-in pointer types), this shouldn't
+/// *really* matter, but it is the best choice for soundness.
+fn pointer_like_goal_for_rpitit<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    supertrait: ty::PolyTraitRef<'tcx>,
+    rpitit_item: DefId,
+    cause: &ObligationCause<'tcx>,
+) -> ty::PolyTraitRef<'tcx> {
+    let mut bound_vars = supertrait.bound_vars().to_vec();
+
+    let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind {
+        ty::GenericParamDefKind::Lifetime => {
+            let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
+            bound_vars.push(ty::BoundVariableKind::Region(kind));
+            ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
+                var: ty::BoundVar::from_usize(bound_vars.len() - 1),
+                kind,
+            })
+            .into()
+        }
+        ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
+            unreachable!()
+        }
+    });
+
+    ty::Binder::bind_with_vars(
+        ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)), [
+            Ty::new_projection_from_args(tcx, rpitit_item, args),
+        ]),
+        tcx.mk_bound_variable_kinds(&bound_vars),
+    )
+}
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index ae6d697794f..b63534880d1 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -48,12 +48,38 @@ fn fn_sig_for_fn_abi<'tcx>(
             let mut sig = tcx
                 .instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args));
 
+            // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
             if let ty::InstanceKind::VTableShim(..) = instance.def {
                 let mut inputs_and_output = sig.inputs_and_output.to_vec();
                 inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]);
                 sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
             }
 
+            // Modify `fn() -> impl Future` to `fn() -> dyn* Future`.
+            if let ty::InstanceKind::ReifyShim(def_id, _) = instance.def
+                && let Some((rpitit_def_id, fn_args)) =
+                    tcx.return_position_impl_trait_in_trait_shim_data(def_id)
+            {
+                let fn_args = fn_args.instantiate(tcx, args);
+                let rpitit_args =
+                    fn_args.extend_to(tcx, rpitit_def_id, |param, _| match param.kind {
+                        ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
+                        ty::GenericParamDefKind::Type { .. }
+                        | ty::GenericParamDefKind::Const { .. } => {
+                            unreachable!("rpitit should have no addition ty/ct")
+                        }
+                    });
+                let dyn_star_ty = Ty::new_dynamic(
+                    tcx,
+                    tcx.item_bounds_to_existential_predicates(rpitit_def_id, rpitit_args),
+                    tcx.lifetimes.re_erased,
+                    ty::DynStar,
+                );
+                let mut inputs_and_output = sig.inputs_and_output.to_vec();
+                *inputs_and_output.last_mut().unwrap() = dyn_star_ty;
+                sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
+            }
+
             sig
         }
         ty::Closure(def_id, args) => {
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 04b7315e650..ae34fc65326 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -10,9 +10,6 @@ use core::hint;
 #[cfg(not(test))]
 use core::ptr::{self, NonNull};
 
-#[cfg(test)]
-mod tests;
-
 extern "Rust" {
     // These are the magic symbols to call the global allocator. rustc generates
     // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index e0f94428cfa..23b85fbd4eb 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1985,7 +1985,8 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
     }
 }
 
-#[unstable(feature = "async_fn_traits", issue = "none")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args> for Box<F, A> {
     type Output = F::Output;
     type CallOnceFuture = F::CallOnceFuture;
@@ -1995,7 +1996,8 @@ impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args>
     }
 }
 
-#[unstable(feature = "async_fn_traits", issue = "none")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> for Box<F, A> {
     type CallRefFuture<'a>
         = F::CallRefFuture<'a>
@@ -2007,7 +2009,8 @@ impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> f
     }
 }
 
-#[unstable(feature = "async_fn_traits", issue = "none")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box<F, A> {
     extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> {
         F::async_call(self, args)
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index 5d3997e14e3..116e0e73e96 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -155,9 +155,6 @@ use crate::collections::TryReserveError;
 use crate::slice;
 use crate::vec::{self, AsVecIntoIter, Vec};
 
-#[cfg(test)]
-mod tests;
-
 /// A priority queue implemented with a binary heap.
 ///
 /// This will be a max-heap.
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index 9c074383a5e..c7d6d8a55c2 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -1,8 +1,5 @@
 //! [`CString`] and its related types.
 
-#[cfg(test)]
-mod tests;
-
 use core::borrow::Borrow;
 use core::ffi::{CStr, c_char};
 use core::num::NonZero;
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 927c3aa23b9..40759cb0ba8 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -91,6 +91,7 @@
 //
 // Library features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(async_closure))]
 #![cfg_attr(test, feature(str_as_str))]
 #![feature(alloc_layout_extra)]
 #![feature(allocator_api)]
@@ -99,7 +100,6 @@
 #![feature(array_windows)]
 #![feature(ascii_char)]
 #![feature(assert_matches)]
-#![feature(async_closure)]
 #![feature(async_fn_traits)]
 #![feature(async_iterator)]
 #![feature(box_uninit_write)]
@@ -239,8 +239,6 @@ pub mod string;
 pub mod sync;
 #[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))]
 pub mod task;
-#[cfg(test)]
-mod tests;
 pub mod vec;
 
 #[doc(hidden)]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index b8bdd298c27..6cf41a3fa4e 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -39,9 +39,6 @@ use crate::string::String;
 #[cfg(not(no_global_oom_handling))]
 use crate::vec::Vec;
 
-#[cfg(test)]
-mod tests;
-
 /// A soft limit on the amount of references that may be made to an `Arc`.
 ///
 /// Going above this limit will abort your program (although not
diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/tests/alloc.rs
index 5d6077f057a..1e722d66795 100644
--- a/library/alloc/src/alloc/tests.rs
+++ b/library/alloc/tests/alloc.rs
@@ -1,10 +1,9 @@
-use super::*;
+use alloc::alloc::*;
+use alloc::boxed::Box;
 
 extern crate test;
 use test::Bencher;
 
-use crate::boxed::Box;
-
 #[test]
 fn allocate_zeroed() {
     unsafe {
diff --git a/library/alloc/src/ffi/c_str/tests.rs b/library/alloc/tests/c_str2.rs
index d6b797347c2..0f4c27fa123 100644
--- a/library/alloc/src/ffi/c_str/tests.rs
+++ b/library/alloc/tests/c_str2.rs
@@ -1,11 +1,12 @@
+use alloc::ffi::CString;
+use alloc::rc::Rc;
+use alloc::sync::Arc;
 use core::assert_matches::assert_matches;
-use core::ffi::FromBytesUntilNulError;
+use core::ffi::{CStr, FromBytesUntilNulError, c_char};
 #[allow(deprecated)]
 use core::hash::SipHasher13 as DefaultHasher;
 use core::hash::{Hash, Hasher};
 
-use super::*;
-
 #[test]
 fn c_to_rust() {
     let data = b"123\0";
diff --git a/library/alloc/src/collections/binary_heap/tests.rs b/library/alloc/tests/collections/binary_heap.rs
index ad0a020a1a9..55405ffe8c4 100644
--- a/library/alloc/src/collections/binary_heap/tests.rs
+++ b/library/alloc/tests/collections/binary_heap.rs
@@ -1,7 +1,9 @@
+use alloc::boxed::Box;
+use alloc::collections::binary_heap::*;
+use std::iter::TrustedLen;
+use std::mem;
 use std::panic::{AssertUnwindSafe, catch_unwind};
 
-use super::*;
-use crate::boxed::Box;
 use crate::testing::crash_test::{CrashTestDummy, Panic};
 
 #[test]
@@ -531,7 +533,7 @@ fn panic_safe() {
             self.0.partial_cmp(&other.0)
         }
     }
-    let mut rng = crate::test_helpers::test_rng();
+    let mut rng = crate::test_rng();
     const DATASZ: usize = 32;
     // Miri is too slow
     let ntest = if cfg!(miri) { 1 } else { 10 };
diff --git a/library/alloc/tests/collections/mod.rs b/library/alloc/tests/collections/mod.rs
new file mode 100644
index 00000000000..e73f3aaef8c
--- /dev/null
+++ b/library/alloc/tests/collections/mod.rs
@@ -0,0 +1 @@
+mod binary_heap;
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index bcab17e7b2d..393bdfe48b7 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -5,8 +5,10 @@
 #![feature(btree_extract_if)]
 #![feature(cow_is_borrowed)]
 #![feature(core_intrinsics)]
+#![feature(downcast_unchecked)]
 #![feature(extract_if)]
 #![feature(exact_size_is_empty)]
+#![feature(hashmap_internals)]
 #![feature(linked_list_cursors)]
 #![feature(map_try_insert)]
 #![feature(pattern)]
@@ -29,9 +31,11 @@
 #![feature(const_str_from_utf8)]
 #![feature(panic_update_hook)]
 #![feature(pointer_is_aligned_to)]
+#![feature(test)]
 #![feature(thin_box)]
 #![feature(drain_keep_rest)]
 #![feature(local_waker)]
+#![feature(str_as_str)]
 #![feature(strict_provenance_lints)]
 #![feature(vec_pop_if)]
 #![feature(unique_rc_arc)]
@@ -40,25 +44,33 @@
 #![deny(fuzzy_provenance_casts)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
+extern crate test;
+
 use std::hash::{DefaultHasher, Hash, Hasher};
 
+mod alloc;
 mod arc;
 mod autotraits;
 mod borrow;
 mod boxed;
 mod btree_set_hash;
 mod c_str;
+mod c_str2;
+mod collections;
 mod const_fns;
 mod cow_str;
 mod fmt;
 mod heap;
 mod linked_list;
+mod misc_tests;
 mod rc;
 mod slice;
 mod sort;
 mod str;
 mod string;
+mod sync;
 mod task;
+mod testing;
 mod thin_box;
 mod vec;
 mod vec_deque;
@@ -69,6 +81,18 @@ fn hash<T: Hash>(t: &T) -> u64 {
     s.finish()
 }
 
+/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
+/// seed not being the same for every RNG invocation too.
+fn test_rng() -> rand_xorshift::XorShiftRng {
+    use std::hash::{BuildHasher, Hash, Hasher};
+    let mut hasher = std::hash::RandomState::new().build_hasher();
+    std::panic::Location::caller().hash(&mut hasher);
+    let hc64 = hasher.finish();
+    let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
+    let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
+    rand::SeedableRng::from_seed(seed)
+}
+
 // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten.
 // See https://github.com/kripken/emscripten-fastcomp/issues/169
 #[cfg(not(target_os = "emscripten"))]
diff --git a/library/alloc/src/tests.rs b/library/alloc/tests/misc_tests.rs
index b95d11cb07e..b95d11cb07e 100644
--- a/library/alloc/src/tests.rs
+++ b/library/alloc/tests/misc_tests.rs
diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/tests/sync.rs
index de5816fda97..7a9a4abfdc6 100644
--- a/library/alloc/src/sync/tests.rs
+++ b/library/alloc/tests/sync.rs
@@ -1,14 +1,16 @@
+use alloc::sync::*;
+use std::alloc::{AllocError, Allocator, Layout};
+use std::any::Any;
 use std::clone::Clone;
 use std::mem::MaybeUninit;
 use std::option::Option::None;
+use std::ptr::NonNull;
 use std::sync::Mutex;
-use std::sync::atomic::AtomicUsize;
-use std::sync::atomic::Ordering::SeqCst;
+use std::sync::atomic::Ordering::*;
+use std::sync::atomic::{self, AtomicUsize};
 use std::sync::mpsc::channel;
 use std::thread;
 
-use super::*;
-
 struct Canary(*mut AtomicUsize);
 
 impl Drop for Canary {
diff --git a/library/alloc/tests/testing/crash_test.rs b/library/alloc/tests/testing/crash_test.rs
new file mode 100644
index 00000000000..502fe6c10c6
--- /dev/null
+++ b/library/alloc/tests/testing/crash_test.rs
@@ -0,0 +1,80 @@
+use std::cmp::Ordering;
+use std::fmt::Debug;
+use std::sync::atomic::AtomicUsize;
+use std::sync::atomic::Ordering::SeqCst;
+
+/// A blueprint for crash test dummy instances that monitor drops.
+/// Some instances may be configured to panic at some point.
+///
+/// Crash test dummies are identified and ordered by an id, so they can be used
+/// as keys in a BTreeMap.
+#[derive(Debug)]
+pub struct CrashTestDummy {
+    pub id: usize,
+    dropped: AtomicUsize,
+}
+
+impl CrashTestDummy {
+    /// Creates a crash test dummy design. The `id` determines order and equality of instances.
+    pub fn new(id: usize) -> CrashTestDummy {
+        CrashTestDummy { id, dropped: AtomicUsize::new(0) }
+    }
+
+    /// Creates an instance of a crash test dummy that records what events it experiences
+    /// and optionally panics.
+    pub fn spawn(&self, panic: Panic) -> Instance<'_> {
+        Instance { origin: self, panic }
+    }
+
+    /// Returns how many times instances of the dummy have been dropped.
+    pub fn dropped(&self) -> usize {
+        self.dropped.load(SeqCst)
+    }
+}
+
+#[derive(Debug)]
+pub struct Instance<'a> {
+    origin: &'a CrashTestDummy,
+    panic: Panic,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum Panic {
+    Never,
+    InDrop,
+}
+
+impl Instance<'_> {
+    pub fn id(&self) -> usize {
+        self.origin.id
+    }
+}
+
+impl Drop for Instance<'_> {
+    fn drop(&mut self) {
+        self.origin.dropped.fetch_add(1, SeqCst);
+        if self.panic == Panic::InDrop {
+            panic!("panic in `drop`");
+        }
+    }
+}
+
+impl PartialOrd for Instance<'_> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.id().partial_cmp(&other.id())
+    }
+}
+
+impl Ord for Instance<'_> {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.id().cmp(&other.id())
+    }
+}
+
+impl PartialEq for Instance<'_> {
+    fn eq(&self, other: &Self) -> bool {
+        self.id().eq(&other.id())
+    }
+}
+
+impl Eq for Instance<'_> {}
diff --git a/library/alloc/tests/testing/mod.rs b/library/alloc/tests/testing/mod.rs
new file mode 100644
index 00000000000..0a3dd191dc8
--- /dev/null
+++ b/library/alloc/tests/testing/mod.rs
@@ -0,0 +1 @@
+pub mod crash_test;
diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs
index 4b230b15a1e..0073afd4960 100644
--- a/library/core/src/ops/async_function.rs
+++ b/library/core/src/ops/async_function.rs
@@ -4,7 +4,8 @@ use crate::marker::Tuple;
 /// An async-aware version of the [`Fn`](crate::ops::Fn) trait.
 ///
 /// All `async fn` and functions returning futures implement this trait.
-#[unstable(feature = "async_closure", issue = "62290")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 #[rustc_paren_sugar]
 #[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
@@ -18,7 +19,8 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
 /// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait.
 ///
 /// All `async fn` and functions returning futures implement this trait.
-#[unstable(feature = "async_closure", issue = "62290")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 #[rustc_paren_sugar]
 #[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
@@ -39,7 +41,8 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
 /// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait.
 ///
 /// All `async fn` and functions returning futures implement this trait.
-#[unstable(feature = "async_closure", issue = "62290")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 #[rustc_paren_sugar]
 #[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
@@ -64,7 +67,8 @@ mod impls {
     use super::{AsyncFn, AsyncFnMut, AsyncFnOnce};
     use crate::marker::Tuple;
 
-    #[unstable(feature = "async_fn_traits", issue = "none")]
+    #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
     impl<A: Tuple, F: ?Sized> AsyncFn<A> for &F
     where
         F: AsyncFn<A>,
@@ -74,7 +78,8 @@ mod impls {
         }
     }
 
-    #[unstable(feature = "async_fn_traits", issue = "none")]
+    #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
     impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &F
     where
         F: AsyncFn<A>,
@@ -89,7 +94,8 @@ mod impls {
         }
     }
 
-    #[unstable(feature = "async_fn_traits", issue = "none")]
+    #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
     impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a F
     where
         F: AsyncFn<A>,
@@ -102,7 +108,8 @@ mod impls {
         }
     }
 
-    #[unstable(feature = "async_fn_traits", issue = "none")]
+    #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
     impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &mut F
     where
         F: AsyncFnMut<A>,
@@ -117,7 +124,8 @@ mod impls {
         }
     }
 
-    #[unstable(feature = "async_fn_traits", issue = "none")]
+    #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
     impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a mut F
     where
         F: AsyncFnMut<A>,
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index 496b78439ea..9b23874bcf7 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -71,7 +71,7 @@ pub mod rust_2021 {
 /// The 2024 version of the core prelude.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2024", issue = "121042")]
+#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
 pub mod rust_2024 {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::common::*;
@@ -84,7 +84,7 @@ pub mod rust_2024 {
     #[doc(no_inline)]
     pub use crate::convert::{TryFrom, TryInto};
 
-    #[unstable(feature = "prelude_2024", issue = "121042")]
+    #[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
     #[doc(no_inline)]
     pub use crate::future::{Future, IntoFuture};
 }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 6d0361b8c63..3639feaacf3 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1587,15 +1587,6 @@ impl<T: ?Sized> *mut T {
     /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
     /// the returned offset is correct in all terms other than alignment.
     ///
-    /// When this is called during compile-time evaluation (which is unstable), the implementation
-    /// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
-    /// actual alignment of pointers is not known yet during compile-time, so an offset with
-    /// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
-    /// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
-    /// known, so the execution has to be correct for either choice. It is therefore impossible to
-    /// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
-    /// for unstable APIs.)
-    ///
     /// # Panics
     ///
     /// The function panics if `align` is not a power-of-two.
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 49a03220039..047f5b0c4c5 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -348,7 +348,6 @@
 #![feature(pin_coerce_unsized_trait)]
 #![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
-#![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
 #![feature(ptr_mask)]
 #![feature(random)]
diff --git a/library/std/src/os/hurd/mod.rs b/library/std/src/os/hurd/mod.rs
index aee86c7f616..6cd50aeada1 100644
--- a/library/std/src/os/hurd/mod.rs
+++ b/library/std/src/os/hurd/mod.rs
@@ -1,6 +1,7 @@
 //! Hurd-specific definitions
 
 #![stable(feature = "raw_ext", since = "1.1.0")]
+#![forbid(unsafe_op_in_unsafe_fn)]
 
 pub mod fs;
 pub mod raw;
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index e4731280ffe..22a364074c5 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -12,7 +12,8 @@ pub use crate::marker::{Send, Sized, Sync, Unpin};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
 pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
-#[unstable(feature = "async_closure", issue = "62290")]
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
 #[doc(no_inline)]
 pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
 
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 0c610ba67e6..64349987fcf 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -25,6 +25,7 @@
 //!
 //! # Prelude contents
 //!
+//! The items included in the prelude depend on the edition of the crate.
 //! The first version of the prelude is used in Rust 2015 and Rust 2018,
 //! and lives in [`std::prelude::v1`].
 //! [`std::prelude::rust_2015`] and [`std::prelude::rust_2018`] re-export this prelude.
@@ -32,8 +33,9 @@
 //!
 //! * <code>[std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}</code>,
 //!   marker traits that indicate fundamental properties of types.
-//! * <code>[std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}</code>, various
-//!   operations for both destructors and overloading `()`.
+//! * <code>[std::ops]::{[Fn], [FnMut], [FnOnce]}</code>, and their analogous
+//!   async traits, <code>[std::ops]::{[AsyncFn], [AsyncFnMut], [AsyncFnOnce]}</code>.
+//! * <code>[std::ops]::[Drop]</code>, for implementing destructors.
 //! * <code>[std::mem]::[drop]</code>, a convenience function for explicitly
 //!   dropping a value.
 //! * <code>[std::mem]::{[size_of], [size_of_val]}</code>, to get the size of
@@ -67,15 +69,21 @@
 //! The prelude used in Rust 2021, [`std::prelude::rust_2021`], includes all of the above,
 //! and in addition re-exports:
 //!
-//! * <code>[std::convert]::{[TryFrom], [TryInto]}</code>,
+//! * <code>[std::convert]::{[TryFrom], [TryInto]}</code>.
 //! * <code>[std::iter]::[FromIterator]</code>.
 //!
+//! The prelude used in Rust 2024, [`std::prelude::rust_2024`], includes all of the above,
+//! and in addition re-exports:
+//!
+//! * <code>[std::future]::{[Future], [IntoFuture]}</code>.
+//!
 //! [std::borrow]: crate::borrow
 //! [std::boxed]: crate::boxed
 //! [std::clone]: crate::clone
 //! [std::cmp]: crate::cmp
 //! [std::convert]: crate::convert
 //! [std::default]: crate::default
+//! [std::future]: crate::future
 //! [std::iter]: crate::iter
 //! [std::marker]: crate::marker
 //! [std::mem]: crate::mem
@@ -85,6 +93,7 @@
 //! [`std::prelude::rust_2015`]: rust_2015
 //! [`std::prelude::rust_2018`]: rust_2018
 //! [`std::prelude::rust_2021`]: rust_2021
+//! [`std::prelude::rust_2024`]: rust_2024
 //! [std::result]: crate::result
 //! [std::slice]: crate::slice
 //! [std::string]: crate::string
@@ -94,6 +103,8 @@
 //! [book-dtor]: ../../book/ch15-03-drop.html
 //! [book-enums]: ../../book/ch06-01-defining-an-enum.html
 //! [book-iter]: ../../book/ch13-02-iterators.html
+//! [Future]: crate::future::Future
+//! [IntoFuture]: crate::future::IntoFuture
 
 // No formatting: this file is nothing but re-exports, and their order is worth preserving.
 #![cfg_attr(rustfmt, rustfmt::skip)]
@@ -158,12 +169,12 @@ pub mod rust_2021 {
 /// The 2024 version of the prelude of The Rust Standard Library.
 ///
 /// See the [module-level documentation](self) for more.
-#[unstable(feature = "prelude_2024", issue = "121042")]
+#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
 pub mod rust_2024 {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::common::*;
 
-    #[unstable(feature = "prelude_2024", issue = "121042")]
+    #[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
     #[doc(no_inline)]
     pub use core::prelude::rust_2024::*;
 }
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 79baa5b0b83..40d409310ff 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -178,3 +178,8 @@ cfg_if::cfg_if! {
 #[cfg(target_os = "hurd")]
 #[link(name = "gcc_s")]
 extern "C" {}
+
+#[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))]
+#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
+#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
+extern "C" {}
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index 715f8b57876..1fa9e480166 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -102,12 +102,9 @@ pub type _Unwind_Exception_Cleanup_Fn =
 // rustc_codegen_ssa::src::back::symbol_export, rustc_middle::middle::exported_symbols
 // and RFC 2841
 #[cfg_attr(
-    any(
-        all(
-            feature = "llvm-libunwind",
-            any(target_os = "fuchsia", target_os = "linux", target_os = "xous")
-        ),
-        all(target_os = "windows", target_env = "gnu", target_abi = "llvm")
+    all(
+        feature = "llvm-libunwind",
+        any(target_os = "fuchsia", target_os = "linux", target_os = "xous")
     ),
     link(name = "unwind", kind = "static", modifiers = "-bundle")
 )]
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 74dfe2e7ec8..ee813de1c9e 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -48,9 +48,9 @@ fn main() {
             err => {
                 drop(err);
                 if let Ok(pid) = pid {
-                    eprintln!("WARNING: build directory locked by process {pid}, waiting for lock");
+                    println!("WARNING: build directory locked by process {pid}, waiting for lock");
                 } else {
-                    eprintln!("WARNING: build directory locked, waiting for lock");
+                    println!("WARNING: build directory locked, waiting for lock");
                 }
                 let mut lock = t!(build_lock.write());
                 t!(lock.write(process::id().to_string().as_ref()));
@@ -70,13 +70,13 @@ fn main() {
     // changelog warning, not the `x.py setup` message.
     let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
     if suggest_setup {
-        eprintln!("WARNING: you have not made a `config.toml`");
-        eprintln!(
+        println!("WARNING: you have not made a `config.toml`");
+        println!(
             "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
             `cp config.example.toml config.toml`"
         );
     } else if let Some(suggestion) = &changelog_suggestion {
-        eprintln!("{suggestion}");
+        println!("{suggestion}");
     }
 
     let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
@@ -86,13 +86,13 @@ fn main() {
     Build::new(config).build();
 
     if suggest_setup {
-        eprintln!("WARNING: you have not made a `config.toml`");
-        eprintln!(
+        println!("WARNING: you have not made a `config.toml`");
+        println!(
             "HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
             `cp config.example.toml config.toml`"
         );
     } else if let Some(suggestion) = &changelog_suggestion {
-        eprintln!("{suggestion}");
+        println!("{suggestion}");
     }
 
     // Give a warning if the pre-commit script is in pre-commit and not pre-push.
@@ -102,14 +102,14 @@ fn main() {
     if fs::read_to_string(pre_commit).is_ok_and(|contents| {
         contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
     }) {
-        eprintln!(
+        println!(
             "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \
                   Consider moving it to .git/hooks/pre-push instead, which runs less often."
         );
     }
 
     if suggest_setup || changelog_suggestion.is_some() {
-        eprintln!("NOTE: this message was printed twice to make it more likely to be seen");
+        println!("NOTE: this message was printed twice to make it more likely to be seen");
     }
 
     if dump_bootstrap_shims {
diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs
index e57ed488f97..88595ff7e51 100644
--- a/src/bootstrap/src/bin/rustc.rs
+++ b/src/bootstrap/src/bin/rustc.rs
@@ -306,7 +306,7 @@ fn main() {
         // should run on success, after this block.
     }
     if verbose > 0 {
-        eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
+        println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
     }
 
     if let Some(mut on_fail) = on_fail {
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index 2af2e83db8f..d46c0ab7fef 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -287,7 +287,7 @@ impl Step for CodegenBackend {
     fn run(self, builder: &Builder<'_>) {
         // FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
         if builder.build.config.vendor && self.backend == "gcc" {
-            eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
+            println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
             return;
         }
 
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 93f8091299f..0cacd6e4f37 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1611,7 +1611,7 @@ impl Step for Sysroot {
         let sysroot = sysroot_dir(compiler.stage);
 
         builder
-            .verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
+            .verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
         let _ = fs::remove_dir_all(&sysroot);
         t!(fs::create_dir_all(&sysroot));
 
@@ -1681,7 +1681,7 @@ impl Step for Sysroot {
                     return true;
                 }
                 if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
-                    builder.verbose_than(1, || eprintln!("ignoring {}", path.display()));
+                    builder.verbose_than(1, || println!("ignoring {}", path.display()));
                     false
                 } else {
                     true
@@ -2240,7 +2240,7 @@ pub fn stream_cargo(
         cargo.arg(arg);
     }
 
-    builder.verbose(|| eprintln!("running: {cargo:?}"));
+    builder.verbose(|| println!("running: {cargo:?}"));
 
     if builder.config.dry_run() {
         return true;
@@ -2266,7 +2266,7 @@ pub fn stream_cargo(
                 cb(msg)
             }
             // If this was informational, just print it out and continue
-            Err(_) => eprintln!("{line}"),
+            Err(_) => println!("{line}"),
         }
     }
 
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 57fce206f95..0c739115165 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -2080,7 +2080,7 @@ fn maybe_install_llvm(
     {
         let mut cmd = command(llvm_config);
         cmd.arg("--libfiles");
-        builder.verbose(|| eprintln!("running {cmd:?}"));
+        builder.verbose(|| println!("running {cmd:?}"));
         let files = cmd.run_capture_stdout(builder).stdout();
         let build_llvm_out = &builder.llvm_out(builder.config.build);
         let target_llvm_out = &builder.llvm_out(target);
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index d32e06d8748..29a96f77672 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -107,10 +107,10 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
         if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() };
     if len <= 10 {
         for path in paths {
-            eprintln!("fmt: {verb} {adjective}file {path}");
+            println!("fmt: {verb} {adjective}file {path}");
         }
     } else {
-        eprintln!("fmt: {verb} {len} {adjective}files");
+        println!("fmt: {verb} {len} {adjective}files");
     }
 }
 
@@ -199,7 +199,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
                 match get_modified_rs_files(build) {
                     Ok(Some(files)) => {
                         if files.is_empty() {
-                            eprintln!("fmt info: No modified files detected for formatting.");
+                            println!("fmt info: No modified files detected for formatting.");
                             return;
                         }
 
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index 175e9982cc1..7ed01f25c94 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -134,7 +134,7 @@ impl Step for Profile {
                     t!(fs::remove_file(path));
                 }
                 _ => {
-                    eprintln!("Exiting.");
+                    println!("Exiting.");
                     crate::exit!(1);
                 }
             }
@@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) {
         Profile::Dist => &["dist", "build"],
     };
 
-    eprintln!();
+    println!();
 
-    eprintln!("To get started, try one of the following commands:");
+    println!("To get started, try one of the following commands:");
     for cmd in suggestions {
-        eprintln!("- `x.py {cmd}`");
+        println!("- `x.py {cmd}`");
     }
 
     if profile != Profile::Dist {
-        eprintln!(
+        println!(
             "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
         );
     }
@@ -224,7 +224,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
     t!(fs::write(path, settings));
 
     let include_path = profile.include_path(&config.src);
-    eprintln!("`x.py` will now use the configuration at {}", include_path.display());
+    println!("`x.py` will now use the configuration at {}", include_path.display());
 }
 
 /// Creates a toolchain link for stage1 using `rustup`
@@ -256,7 +256,7 @@ impl Step for Link {
         }
 
         if !rustup_installed(builder) {
-            eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking.");
+            println!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking.");
             return;
         }
 
@@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) {
     }
 
     if try_link_toolchain(builder, stage_path) {
-        eprintln!(
+        println!(
             "Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
         );
     } else {
@@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool {
                 return false;
             }
             // The toolchain has already been linked.
-            eprintln!(
+            println!(
                 "`stage1` toolchain already linked; not attempting to link `stage1` toolchain"
             );
         }
         None => {
             // In this case, we don't know if the `stage1` toolchain has been linked;
             // but `rustup` failed, so let's not go any further.
-            eprintln!(
+            println!(
                 "`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain"
             );
         }
@@ -389,12 +389,12 @@ pub fn interactive_path() -> io::Result<Profile> {
         input.parse()
     }
 
-    eprintln!("Welcome to the Rust project! What do you want to do with x.py?");
+    println!("Welcome to the Rust project! What do you want to do with x.py?");
     for ((letter, _), profile) in abbrev_all() {
-        eprintln!("{}) {}: {}", letter, profile, profile.purpose());
+        println!("{}) {}: {}", letter, profile, profile.purpose());
     }
     let template = loop {
-        eprint!(
+        print!(
             "Please choose one ({}): ",
             abbrev_all().map(|((l, _), _)| l).collect::<Vec<_>>().join("/")
         );
@@ -428,7 +428,7 @@ enum PromptResult {
 fn prompt_user(prompt: &str) -> io::Result<Option<PromptResult>> {
     let mut input = String::new();
     loop {
-        eprint!("{prompt} ");
+        print!("{prompt} ");
         io::stdout().flush()?;
         input.clear();
         io::stdin().read_line(&mut input)?;
@@ -490,7 +490,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
         return Ok(());
     }
 
-    eprintln!(
+    println!(
         "\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
 If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before
 pushing your code to ensure your code is up to par. If you decide later that this behavior is
@@ -498,7 +498,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
     );
 
     if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) {
-        eprintln!("Ok, skipping installation!");
+        println!("Ok, skipping installation!");
         return Ok(());
     }
     if !hooks_dir.exists() {
@@ -515,7 +515,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
             );
             return Err(e);
         }
-        Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
+        Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
     };
     Ok(())
 }
@@ -541,7 +541,7 @@ Select which editor you would like to set up [default: None]: ";
 
         let mut input = String::new();
         loop {
-            eprint!("{}", prompt_str);
+            print!("{}", prompt_str);
             io::stdout().flush()?;
             input.clear();
             io::stdin().read_line(&mut input)?;
@@ -656,7 +656,7 @@ impl Step for Editor {
                 if let Some(editor_kind) = editor_kind {
                     while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
                 } else {
-                    eprintln!("Ok, skipping editor setup!");
+                    println!("Ok, skipping editor setup!");
                 }
             }
             Err(e) => eprintln!("Could not determine the editor: {e}"),
@@ -689,7 +689,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
             mismatched_settings = Some(false);
         }
     }
-    eprintln!(
+    println!(
         "\nx.py can automatically install the recommended `{settings_filename}` file for rustc development"
     );
 
@@ -708,7 +708,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
         Some(PromptResult::Yes) => true,
         Some(PromptResult::Print) => false,
         _ => {
-            eprintln!("Ok, skipping settings!");
+            println!("Ok, skipping settings!");
             return Ok(true);
         }
     };
@@ -735,9 +735,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
             _ => "Created",
         };
         fs::write(&settings_path, editor.settings_template())?;
-        eprintln!("{verb} `{}`", settings_filename);
+        println!("{verb} `{}`", settings_filename);
     } else {
-        eprintln!("\n{}", editor.settings_template());
+        println!("\n{}", editor.settings_template());
     }
     Ok(should_create)
 }
diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs
index 7b2d9fff8f5..ba9b1b2fc33 100644
--- a/src/bootstrap/src/core/build_steps/suggest.rs
+++ b/src/bootstrap/src/core/build_steps/suggest.rs
@@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) {
             build.build();
         }
     } else {
-        eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests");
+        println!("HELP: consider using the `--run` flag to automatically run suggested tests");
     }
 }
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 380626952b2..30fdea7e19e 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -471,11 +471,11 @@ impl Miri {
         // We re-use the `cargo` from above.
         cargo.arg("--print-sysroot");
 
-        builder.verbose(|| eprintln!("running: {cargo:?}"));
+        builder.verbose(|| println!("running: {cargo:?}"));
         let stdout = cargo.run_capture_stdout(builder).stdout();
         // Output is "<sysroot>\n".
         let sysroot = stdout.trim_end();
-        builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
+        builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
         PathBuf::from(sysroot)
     }
 }
@@ -2488,7 +2488,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
         }
     }
 
-    builder.verbose(|| eprintln!("doc tests for: {}", markdown.display()));
+    builder.verbose(|| println!("doc tests for: {}", markdown.display()));
     let mut cmd = builder.rustdoc_cmd(compiler);
     builder.add_rust_test_threads(&mut cmd);
     // allow for unstable options such as new editions
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 38abca8b8da..6e848628e5c 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -523,7 +523,7 @@ impl Builder<'_> {
 
         let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
         if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
-            eprintln!("using sysroot {sysroot_str}");
+            println!("using sysroot {sysroot_str}");
         }
 
         let mut rustflags = Rustflags::new(target);
@@ -1035,12 +1035,7 @@ impl Builder<'_> {
             rustflags.arg("-Wrustc::internal");
             // cfg(bootstrap) - remove this check when lint is in bootstrap compiler
             if stage != 0 {
-                // Lint is allow by default so downstream tools don't get a lit
-                // they can do nothing about
-                // We shouldn't be preinterning symbols used by tests
-                if cmd_kind != Kind::Test {
-                    rustflags.arg("-Drustc::symbol_intern_string_literal");
-                }
+                rustflags.arg("-Drustc::symbol_intern_string_literal");
             }
             // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
             // of the individual lints are satisfied.
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index ffe3e053e72..026c26479d3 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -392,14 +392,14 @@ impl StepDescription {
     fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
         if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) {
             if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
-                eprintln!("Skipping {pathset:?} because it is excluded");
+                println!("Skipping {pathset:?} because it is excluded");
             }
             return true;
         }
 
         if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
             builder.verbose(|| {
-                eprintln!(
+                println!(
                     "{:?} not skipped for {:?} -- not in {:?}",
                     pathset, self.name, builder.config.skip
                 )
@@ -1437,11 +1437,11 @@ impl<'a> Builder<'a> {
                 panic!("{}", out);
             }
             if let Some(out) = self.cache.get(&step) {
-                self.verbose_than(1, || eprintln!("{}c {:?}", "  ".repeat(stack.len()), step));
+                self.verbose_than(1, || println!("{}c {:?}", "  ".repeat(stack.len()), step));
 
                 return out;
             }
-            self.verbose_than(1, || eprintln!("{}> {:?}", "  ".repeat(stack.len()), step));
+            self.verbose_than(1, || println!("{}> {:?}", "  ".repeat(stack.len()), step));
             stack.push(Box::new(step.clone()));
         }
 
@@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> {
             let step_string = format!("{step:?}");
             let brace_index = step_string.find('{').unwrap_or(0);
             let type_string = type_name::<S>();
-            eprintln!(
+            println!(
                 "[TIMING] {} {} -- {}.{:03}",
                 &type_string.strip_prefix("bootstrap::").unwrap_or(type_string),
                 &step_string[brace_index..],
@@ -1479,9 +1479,7 @@ impl<'a> Builder<'a> {
             let cur_step = stack.pop().expect("step stack empty");
             assert_eq!(cur_step.downcast_ref(), Some(&step));
         }
-        self.verbose_than(1, || {
-            eprintln!("{}< {:?}", "  ".repeat(self.stack.borrow().len()), step)
-        });
+        self.verbose_than(1, || println!("{}< {:?}", "  ".repeat(self.stack.borrow().len()), step));
         self.cache.put(step, out.clone());
         out
     }
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 002b990bb52..c6800aedca9 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -1299,7 +1299,7 @@ impl Config {
                     .map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
                 {
                     if !changes.is_empty() {
-                        eprintln!(
+                        println!(
                             "WARNING: There have been changes to x.py since you last updated:\n{}",
                             crate::human_readable_changes(&changes)
                         );
@@ -1565,7 +1565,7 @@ impl Config {
         }
 
         if cargo_clippy.is_some() && rustc.is_none() {
-            eprintln!(
+            println!(
                 "WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict."
             );
         }
@@ -1852,7 +1852,7 @@ impl Config {
 
             // FIXME: Remove this option at the end of 2024.
             if parallel_compiler.is_some() {
-                eprintln!(
+                println!(
                     "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default"
                 );
             }
@@ -1884,7 +1884,7 @@ impl Config {
                         if available_backends.contains(&backend) {
                             panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
                         } else {
-                            eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
+                            println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
                                 Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
                                 In this case, it would be referred to as '{backend}'.");
                         }
@@ -1913,7 +1913,7 @@ impl Config {
         // tests may fail due to using a different channel than the one used by the compiler during tests.
         if let Some(commit) = &config.download_rustc_commit {
             if is_user_configured_rust_channel {
-                eprintln!(
+                println!(
                     "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel."
                 );
 
@@ -2003,10 +2003,10 @@ impl Config {
 
             if config.llvm_from_ci {
                 let warn = |option: &str| {
-                    eprintln!(
+                    println!(
                         "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
                     );
-                    eprintln!(
+                    println!(
                         "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
                     );
                 };
@@ -2025,12 +2025,12 @@ impl Config {
                 // if they've chosen a different value.
 
                 if libzstd.is_some() {
-                    eprintln!(
+                    println!(
                         "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
                         like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
                         artifacts builder config."
                     );
-                    eprintln!(
+                    println!(
                         "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
                     );
                 }
@@ -2099,7 +2099,7 @@ impl Config {
                             if available_backends.contains(&backend) {
                                 panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
                             } else {
-                                eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
+                                println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
                                     Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
                                     In this case, it would be referred to as '{backend}'.");
                             }
@@ -2315,7 +2315,7 @@ impl Config {
         if self.dry_run() {
             return Ok(());
         }
-        self.verbose(|| eprintln!("running: {cmd:?}"));
+        self.verbose(|| println!("running: {cmd:?}"));
         build_helper::util::try_run(cmd, self.is_verbose())
     }
 
@@ -2490,7 +2490,7 @@ impl Config {
                         // This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error
                         // to not break CI. For non-CI environments, we should return an error.
                         if CiEnv::is_ci() {
-                            eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
+                            println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
                             return None;
                         } else {
                             panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used.");
@@ -2501,8 +2501,8 @@ impl Config {
                         let ci_config_toml = match self.get_builder_toml("ci-rustc") {
                             Ok(ci_config_toml) => ci_config_toml,
                             Err(e) if e.to_string().contains("unknown field") => {
-                                eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled.");
-                                eprintln!("HELP: Consider rebasing to a newer commit if available.");
+                                println!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled.");
+                                println!("HELP: Consider rebasing to a newer commit if available.");
                                 return None;
                             },
                             Err(e) => {
@@ -2527,7 +2527,7 @@ impl Config {
                             .is_some_and(|s| s == "1" || s == "true");
 
                         if disable_ci_rustc_if_incompatible && res.is_err() {
-                            eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
+                            println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
                             return None;
                         }
 
@@ -2712,7 +2712,7 @@ impl Config {
             return;
         }
 
-        eprintln!("Updating submodule {relative_path}");
+        println!("Updating submodule {relative_path}");
         self.check_run(
             helpers::git(Some(&self.src))
                 .run_always()
@@ -2835,7 +2835,7 @@ impl Config {
             Some(StringOrBool::Bool(true)) => false,
             Some(StringOrBool::String(s)) if s == "if-unchanged" => {
                 if !self.rust_info.is_managed_git_subrepository() {
-                    eprintln!(
+                    println!(
                         "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
                     );
                     crate::exit!(1);
@@ -2868,10 +2868,10 @@ impl Config {
                 if if_unchanged {
                     return None;
                 }
-                eprintln!("ERROR: could not find commit hash for downloading rustc");
-                eprintln!("HELP: maybe your repository history is too shallow?");
-                eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml");
-                eprintln!("HELP: or fetch enough history to include one upstream commit");
+                println!("ERROR: could not find commit hash for downloading rustc");
+                println!("HELP: maybe your repository history is too shallow?");
+                println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
+                println!("HELP: or fetch enough history to include one upstream commit");
                 crate::exit!(1);
             }
         };
@@ -2910,7 +2910,7 @@ impl Config {
         let if_unchanged = || {
             if self.rust_info.is_from_tarball() {
                 // Git is needed for running "if-unchanged" logic.
-                eprintln!(
+                println!(
                     "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
                 );
                 return false;
@@ -2959,10 +2959,10 @@ impl Config {
         // Only commits merged by bors will have CI artifacts.
         let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
         if commit.is_empty() {
-            eprintln!("error: could not find commit hash for downloading components from CI");
-            eprintln!("help: maybe your repository history is too shallow?");
-            eprintln!("help: consider disabling `{option_name}`");
-            eprintln!("help: or fetch enough history to include one upstream commit");
+            println!("error: could not find commit hash for downloading components from CI");
+            println!("help: maybe your repository history is too shallow?");
+            println!("help: consider disabling `{option_name}`");
+            println!("help: or fetch enough history to include one upstream commit");
             crate::exit!(1);
         }
 
@@ -2974,14 +2974,14 @@ impl Config {
         if has_changes {
             if if_unchanged {
                 if self.is_verbose() {
-                    eprintln!(
+                    println!(
                         "warning: saw changes to one of {modified_paths:?} since {commit}; \
                             ignoring `{option_name}`"
                     );
                 }
                 return None;
             }
-            eprintln!(
+            println!(
                 "warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}"
             );
         }
@@ -3018,7 +3018,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm(
         ($current:expr, $expected:expr) => {
             if let Some(current) = &$current {
                 if Some(current) != $expected.as_ref() {
-                    eprintln!(
+                    println!(
                         "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
                         Current value: {:?}, Expected value(s): {}{:?}",
                         stringify!($expected).replace("_", "-"),
@@ -3123,7 +3123,7 @@ fn check_incompatible_options_for_ci_rustc(
         ($current:expr, $expected:expr, $config_section:expr) => {
             if let Some(current) = &$current {
                 if Some(current) != $expected.as_ref() {
-                    eprintln!(
+                    println!(
                         "WARNING: `{}` has no effect with `rust.download-rustc`. \
                         Current value: {:?}, Expected value(s): {}{:?}",
                         format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 66b9f5ed84e..bfeb811508c 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -196,12 +196,12 @@ impl Flags {
         if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
             HelpVerboseOnly::try_parse_from(normalize_args(args))
         {
-            eprintln!("NOTE: updating submodules before printing available paths");
+            println!("NOTE: updating submodules before printing available paths");
             let config = Config::parse(Self::parse(&[String::from("build")]));
             let build = Build::new(config);
             let paths = Builder::get_help(&build, subcommand);
             if let Some(s) = paths {
-                eprintln!("{s}");
+                println!("{s}");
             } else {
                 panic!("No paths available for subcommand `{}`", subcommand.as_str());
             }
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 05b91c518cf..db35e6907e6 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -77,7 +77,7 @@ impl Config {
         if self.dry_run() && !cmd.run_always {
             return true;
         }
-        self.verbose(|| eprintln!("running: {cmd:?}"));
+        self.verbose(|| println!("running: {cmd:?}"));
         check_run(cmd, self.is_verbose())
     }
 
@@ -144,7 +144,7 @@ impl Config {
     /// Please see <https://nixos.org/patchelf.html> for more information
     fn fix_bin_or_dylib(&self, fname: &Path) {
         assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true));
-        eprintln!("attempting to patch {}", fname.display());
+        println!("attempting to patch {}", fname.display());
 
         // Only build `.nix-deps` once.
         static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new();
@@ -206,7 +206,7 @@ impl Config {
     }
 
     fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
-        self.verbose(|| eprintln!("download {url}"));
+        self.verbose(|| println!("download {url}"));
         // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
         let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
         // While bootstrap itself only supports http and https downloads, downstream forks might
@@ -226,7 +226,7 @@ impl Config {
     }
 
     fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
-        eprintln!("downloading {url}");
+        println!("downloading {url}");
         // Try curl. If that fails and we are on windows, fallback to PowerShell.
         // options should be kept in sync with
         // src/bootstrap/src/core/download.rs
@@ -341,7 +341,7 @@ impl Config {
             short_path = short_path.strip_prefix(pattern).unwrap_or(short_path);
             let dst_path = dst.join(short_path);
             self.verbose(|| {
-                eprintln!("extracting {} to {}", original_path.display(), dst.display())
+                println!("extracting {} to {}", original_path.display(), dst.display())
             });
             if !t!(member.unpack_in(dst)) {
                 panic!("path traversal attack ??");
@@ -365,7 +365,7 @@ impl Config {
     pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
         use sha2::Digest;
 
-        self.verbose(|| eprintln!("verifying {}", path.display()));
+        self.verbose(|| println!("verifying {}", path.display()));
 
         if self.dry_run() {
             return false;
@@ -391,7 +391,7 @@ impl Config {
         let verified = checksum == expected;
 
         if !verified {
-            eprintln!(
+            println!(
                 "invalid checksum: \n\
                 found:    {checksum}\n\
                 expected: {expected}",
@@ -421,7 +421,7 @@ enum DownloadSource {
 /// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions.
 impl Config {
     pub(crate) fn download_clippy(&self) -> PathBuf {
-        self.verbose(|| eprintln!("downloading stage0 clippy artifacts"));
+        self.verbose(|| println!("downloading stage0 clippy artifacts"));
 
         let date = &self.stage0_metadata.compiler.date;
         let version = &self.stage0_metadata.compiler.version;
@@ -518,7 +518,7 @@ impl Config {
     }
 
     pub(crate) fn download_ci_rustc(&self, commit: &str) {
-        self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})"));
+        self.verbose(|| println!("using downloaded stage2 artifacts from CI (commit {commit})"));
 
         let version = self.artifact_version_part(commit);
         // download-rustc doesn't need its own cargo, it can just use beta's. But it does need the
@@ -539,7 +539,7 @@ impl Config {
 
     #[cfg(not(feature = "bootstrap-self-test"))]
     pub(crate) fn download_beta_toolchain(&self) {
-        self.verbose(|| eprintln!("downloading stage0 beta artifacts"));
+        self.verbose(|| println!("downloading stage0 beta artifacts"));
 
         let date = &self.stage0_metadata.compiler.date;
         let version = &self.stage0_metadata.compiler.version;
@@ -677,7 +677,7 @@ impl Config {
                     return;
                 } else {
                     self.verbose(|| {
-                        eprintln!(
+                        println!(
                             "ignoring cached file {} due to failed verification",
                             tarball.display()
                         )
@@ -776,10 +776,10 @@ download-rustc = false
                     t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml));
                 }
                 Err(e) if e.to_string().contains("unknown field") => {
-                    eprintln!(
+                    println!(
                         "WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled."
                     );
-                    eprintln!("HELP: Consider rebasing to a newer commit if available.");
+                    println!("HELP: Consider rebasing to a newer commit if available.");
                 }
                 Err(e) => {
                     eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}");
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 71e7f40f032..dcf68cbeeda 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -237,11 +237,11 @@ than building it.
                 stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
 
             if !duplicated_targets.is_empty() {
-                eprintln!(
+                println!(
                     "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
                 );
                 for duplicated_target in duplicated_targets {
-                    eprintln!("  {duplicated_target}");
+                    println!("  {duplicated_target}");
                 }
                 std::process::exit(1);
             }
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 5f778223d7d..0ecf61ffcd9 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -406,11 +406,11 @@ impl Build {
             .unwrap()
             .trim();
         if local_release.split('.').take(2).eq(version.split('.').take(2)) {
-            build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}"));
+            build.verbose(|| println!("auto-detected local-rebuild {local_release}"));
             build.local_rebuild = true;
         }
 
-        build.verbose(|| eprintln!("finding compilers"));
+        build.verbose(|| println!("finding compilers"));
         utils::cc_detect::find(&build);
         // When running `setup`, the profile is about to change, so any requirements we have now may
         // be different on the next invocation. Don't check for them until the next time x.py is
@@ -418,7 +418,7 @@ impl Build {
         //
         // Similarly, for `setup` we don't actually need submodules or cargo metadata.
         if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
-            build.verbose(|| eprintln!("running sanity check"));
+            build.verbose(|| println!("running sanity check"));
             crate::core::sanity::check(&mut build);
 
             // Make sure we update these before gathering metadata so we don't get an error about missing
@@ -436,7 +436,7 @@ impl Build {
             // Now, update all existing submodules.
             build.update_existing_submodules();
 
-            build.verbose(|| eprintln!("learning about cargo"));
+            build.verbose(|| println!("learning about cargo"));
             crate::core::metadata::build(&mut build);
         }
 
@@ -605,7 +605,7 @@ impl Build {
         let stamp = dir.join(".stamp");
         let mut cleared = false;
         if mtime(&stamp) < mtime(input) {
-            self.verbose(|| eprintln!("Dirty - {}", dir.display()));
+            self.verbose(|| println!("Dirty - {}", dir.display()));
             let _ = fs::remove_dir_all(dir);
             cleared = true;
         } else if stamp.exists() {
@@ -890,7 +890,7 @@ impl Build {
         let executed_at = std::panic::Location::caller();
 
         self.verbose(|| {
-            eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})")
+            println!("running: {command:?} (created at {created_at}, executed at {executed_at})")
         });
 
         let cmd = command.as_command_mut();
@@ -947,7 +947,7 @@ Executed at: {executed_at}"#,
 
         let fail = |message: &str, output: CommandOutput| -> ! {
             if self.is_verbose() {
-                eprintln!("{message}");
+                println!("{message}");
             } else {
                 let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
                 // If the command captures output, the user would not see any indication that
@@ -957,16 +957,16 @@ Executed at: {executed_at}"#,
                     if let Some(stdout) =
                         output.stdout_if_present().take_if(|s| !s.trim().is_empty())
                     {
-                        eprintln!("STDOUT:\n{stdout}\n");
+                        println!("STDOUT:\n{stdout}\n");
                     }
                     if let Some(stderr) =
                         output.stderr_if_present().take_if(|s| !s.trim().is_empty())
                     {
-                        eprintln!("STDERR:\n{stderr}\n");
+                        println!("STDERR:\n{stderr}\n");
                     }
-                    eprintln!("Command {command:?} has failed. Rerun with -v to see more details.");
+                    println!("Command {command:?} has failed. Rerun with -v to see more details.");
                 } else {
-                    eprintln!("Command has failed. Rerun with -v to see more details.");
+                    println!("Command has failed. Rerun with -v to see more details.");
                 }
             }
             exit!(1);
@@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#,
         match self.config.dry_run {
             DryRun::SelfCheck => (),
             DryRun::Disabled | DryRun::UserSelected => {
-                eprintln!("{msg}");
+                println!("{msg}");
             }
         }
     }
@@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#,
         if self.config.dry_run() {
             return;
         }
-        self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}"));
+        self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}"));
         if src == dst {
             return;
         }
@@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#,
             return;
         }
         let dst = dstdir.join(src.file_name().unwrap());
-        self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}"));
+        self.verbose_than(1, || println!("Install {src:?} to {dst:?}"));
         t!(fs::create_dir_all(dstdir));
         if !src.exists() {
             panic!("ERROR: File \"{}\" not found!", src.display());
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index e8d5b60948a..0df00469452 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) {
         build.cxx.borrow_mut().insert(target, compiler);
     }
 
-    build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target)));
-    build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple));
+    build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
+    build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
     if let Ok(cxx) = build.cxx(target) {
         let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
-        build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple));
-        build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
+        build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
+        build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
     }
     if let Some(ar) = ar {
-        build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple));
+        build.verbose(|| println!("AR_{} = {ar:?}", target.triple));
         build.ar.borrow_mut().insert(target, ar);
     }
 
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index c0d52fd3430..923cc2dfc28 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -135,7 +135,7 @@ impl Drop for TimeIt {
     fn drop(&mut self) {
         let time = self.1.elapsed();
         if !self.0 {
-            eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis());
+            println!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis());
         }
     }
 }
@@ -267,12 +267,12 @@ pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool {
     let status = match cmd.as_command_mut().status() {
         Ok(status) => status,
         Err(e) => {
-            eprintln!("failed to execute command: {cmd:?}\nERROR: {e}");
+            println!("failed to execute command: {cmd:?}\nERROR: {e}");
             return false;
         }
     };
     if !status.success() && print_cmd_on_fail {
-        eprintln!(
+        println!(
             "\n\ncommand did not execute successfully: {cmd:?}\n\
              expected success, got: {status}\n\n"
         );
diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs
index 06d3add6281..b51fd490535 100644
--- a/src/bootstrap/src/utils/metrics.rs
+++ b/src/bootstrap/src/utils/metrics.rs
@@ -185,7 +185,7 @@ impl BuildMetrics {
                 if version.format_version == CURRENT_FORMAT_VERSION {
                     t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations
                 } else {
-                    eprintln!(
+                    println!(
                         "WARNING: overriding existing build/metrics.json, as it's not \
                          compatible with build metrics format version {CURRENT_FORMAT_VERSION}."
                     );
diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs
index 7a3ec61c6da..eb2c8254dc0 100644
--- a/src/bootstrap/src/utils/render_tests.rs
+++ b/src/bootstrap/src/utils/render_tests.rs
@@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
     let cmd = cmd.as_command_mut();
     cmd.stdout(Stdio::piped());
 
-    builder.verbose(|| eprintln!("running: {cmd:?}"));
+    builder.verbose(|| println!("running: {cmd:?}"));
 
     let mut process = cmd.spawn().unwrap();
 
@@ -71,7 +71,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
 
     let result = process.wait_with_output().unwrap();
     if !result.status.success() && builder.is_verbose() {
-        eprintln!(
+        println!(
             "\n\ncommand did not execute successfully: {cmd:?}\n\
              expected success, got: {}",
             result.status
@@ -135,9 +135,7 @@ impl<'a> Renderer<'a> {
         if self.up_to_date_tests > 0 {
             let n = self.up_to_date_tests;
             let s = if n > 1 { "s" } else { "" };
-            eprintln!(
-                "help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"
-            );
+            println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n");
         }
     }
 
@@ -187,12 +185,12 @@ impl<'a> Renderer<'a> {
     }
 
     fn render_test_outcome_verbose(&self, outcome: Outcome<'_>, test: &TestOutcome) {
-        eprint!("test {} ... ", test.name);
-        self.builder.colored_stderr(|stdout| outcome.write_long(stdout)).unwrap();
+        print!("test {} ... ", test.name);
+        self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
         if let Some(exec_time) = test.exec_time {
-            eprint!(" ({exec_time:.2?})");
+            print!(" ({exec_time:.2?})");
         }
-        eprintln!();
+        println!();
     }
 
     fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
@@ -200,45 +198,45 @@ impl<'a> Renderer<'a> {
             if let Some(total) = self.tests_count {
                 let total = total.to_string();
                 let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len());
-                eprint!(" {executed}/{total}");
+                print!(" {executed}/{total}");
             }
-            eprintln!();
+            println!();
             self.terse_tests_in_line = 0;
         }
 
         self.terse_tests_in_line += 1;
-        self.builder.colored_stderr(|stdout| outcome.write_short(stdout, &test.name)).unwrap();
+        self.builder.colored_stdout(|stdout| outcome.write_short(stdout, &test.name)).unwrap();
         let _ = std::io::stdout().flush();
     }
 
     fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) {
         // The terse output doesn't end with a newline, so we need to add it ourselves.
         if !self.builder.config.verbose_tests {
-            eprintln!();
+            println!();
         }
 
         if !self.failures.is_empty() {
-            eprintln!("\nfailures:\n");
+            println!("\nfailures:\n");
             for failure in &self.failures {
                 if failure.stdout.is_some() || failure.message.is_some() {
-                    eprintln!("---- {} stdout ----", failure.name);
+                    println!("---- {} stdout ----", failure.name);
                     if let Some(stdout) = &failure.stdout {
-                        eprintln!("{stdout}");
+                        println!("{stdout}");
                     }
                     if let Some(message) = &failure.message {
-                        eprintln!("NOTE: {message}");
+                        println!("NOTE: {message}");
                     }
                 }
             }
 
-            eprintln!("\nfailures:");
+            println!("\nfailures:");
             for failure in &self.failures {
-                eprintln!("    {}", failure.name);
+                println!("    {}", failure.name);
             }
         }
 
         if !self.benches.is_empty() {
-            eprintln!("\nbenchmarks:");
+            println!("\nbenchmarks:");
 
             let mut rows = Vec::new();
             for bench in &self.benches {
@@ -253,13 +251,13 @@ impl<'a> Renderer<'a> {
             let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0);
             let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0);
             for row in &rows {
-                eprintln!("    {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
+                println!("    {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
             }
         }
 
-        eprint!("\ntest result: ");
-        self.builder.colored_stderr(|stdout| outcome.write_long(stdout)).unwrap();
-        eprintln!(
+        print!("\ntest result: ");
+        self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
+        println!(
             ". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
             suite.passed,
             suite.failed,
@@ -276,7 +274,7 @@ impl<'a> Renderer<'a> {
     fn render_message(&mut self, message: Message) {
         match message {
             Message::Suite(SuiteMessage::Started { test_count }) => {
-                eprintln!("\nrunning {test_count} tests");
+                println!("\nrunning {test_count} tests");
                 self.executed_tests = 0;
                 self.terse_tests_in_line = 0;
                 self.tests_count = Some(test_count);
@@ -316,7 +314,7 @@ impl<'a> Renderer<'a> {
                 self.failures.push(outcome);
             }
             Message::Test(TestMessage::Timeout { name }) => {
-                eprintln!("test {name} has been running for a long time");
+                println!("test {name} has been running for a long time");
             }
             Message::Test(TestMessage::Started) => {} // Not useful
         }
diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs
index f60498a4872..3c6c7a7fa18 100644
--- a/src/bootstrap/src/utils/tarball.rs
+++ b/src/bootstrap/src/utils/tarball.rs
@@ -344,7 +344,7 @@ impl<'a> Tarball<'a> {
         // For `x install` tarball files aren't needed, so we can speed up the process by not producing them.
         let compression_profile = if self.builder.kind == Kind::Install {
             self.builder.verbose(|| {
-                eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.")
+                println!("Forcing dist.compression-profile = 'no-op' for `x install`.")
             });
             // "no-op" indicates that the rust-installer won't produce compressed tarball sources.
             "no-op"
diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh
index 969389f92f7..7027c93857c 100755
--- a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh
+++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh
@@ -35,7 +35,7 @@ PICK_REFS=()
 # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in
 # addition to versions of prebuilts. It should be bumped regularly by the
 # Fuchsia team – we aim for every 1-2 months.
-INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511
+INTEGRATION_SHA=bb38af4e3d45e490531b71fc52a460003141d032
 
 checkout=fuchsia
 jiri=.jiri_root/bin/jiri
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index cfb62c3ca16..91b31f31ab1 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -201,7 +201,7 @@ pub(crate) fn build_index(
                             // exported from this same module). It's also likely to Do
                             // What I Mean, since if a re-export changes the name, it might
                             // also be a change in semantic meaning.
-                            .filter(|fqp| fqp.last() == fqp.last());
+                            .filter(|this_fqp| this_fqp.last() == fqp.last());
                         Some(insert_into_map(
                             itemid_to_pathid,
                             ItemId::DefId(defid),
diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed
index 208651bab1f..48402164a82 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.fixed
+++ b/src/tools/clippy/tests/ui/async_yields_async.fixed
@@ -1,4 +1,3 @@
-#![feature(async_closure)]
 #![warn(clippy::async_yields_async)]
 #![allow(clippy::redundant_async_block)]
 
diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs
index b124c994442..8ad016b6bb4 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.rs
+++ b/src/tools/clippy/tests/ui/async_yields_async.rs
@@ -1,4 +1,3 @@
-#![feature(async_closure)]
 #![warn(clippy::async_yields_async)]
 #![allow(clippy::redundant_async_block)]
 
diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr
index 861c3f2ce4a..c900a9d7421 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.stderr
+++ b/src/tools/clippy/tests/ui/async_yields_async.stderr
@@ -1,5 +1,5 @@
 error: an async construct yields a type which is itself awaitable
-  --> tests/ui/async_yields_async.rs:38:9
+  --> tests/ui/async_yields_async.rs:37:9
    |
 LL |        let _h = async {
    |  _____________________-
@@ -20,7 +20,7 @@ LL +         }.await
    |
 
 error: an async construct yields a type which is itself awaitable
-  --> tests/ui/async_yields_async.rs:43:9
+  --> tests/ui/async_yields_async.rs:42:9
    |
 LL |       let _i = async {
    |  ____________________-
@@ -33,7 +33,7 @@ LL | |     };
    | |_____- outer async construct
 
 error: an async construct yields a type which is itself awaitable
-  --> tests/ui/async_yields_async.rs:49:9
+  --> tests/ui/async_yields_async.rs:48:9
    |
 LL |        let _j = async || {
    |  ________________________-
@@ -52,7 +52,7 @@ LL +         }.await
    |
 
 error: an async construct yields a type which is itself awaitable
-  --> tests/ui/async_yields_async.rs:54:9
+  --> tests/ui/async_yields_async.rs:53:9
    |
 LL |       let _k = async || {
    |  _______________________-
@@ -65,7 +65,7 @@ LL | |     };
    | |_____- outer async construct
 
 error: an async construct yields a type which is itself awaitable
-  --> tests/ui/async_yields_async.rs:56:23
+  --> tests/ui/async_yields_async.rs:55:23
    |
 LL |     let _l = async || CustomFutureType;
    |                       ^^^^^^^^^^^^^^^^
@@ -75,7 +75,7 @@ LL |     let _l = async || CustomFutureType;
    |                       help: consider awaiting this value: `CustomFutureType.await`
 
 error: an async construct yields a type which is itself awaitable
-  --> tests/ui/async_yields_async.rs:62:9
+  --> tests/ui/async_yields_async.rs:61:9
    |
 LL |       let _m = async || {
    |  _______________________-
diff --git a/src/tools/clippy/tests/ui/author/blocks.rs b/src/tools/clippy/tests/ui/author/blocks.rs
index 164f7d0d9d6..e9db611a2aa 100644
--- a/src/tools/clippy/tests/ui/author/blocks.rs
+++ b/src/tools/clippy/tests/ui/author/blocks.rs
@@ -2,7 +2,6 @@
 
 #![allow(redundant_semicolons, clippy::no_effect)]
 #![feature(stmt_expr_attributes)]
-#![feature(async_closure)]
 
 #[rustfmt::skip]
 fn main() {
diff --git a/src/tools/clippy/tests/ui/infinite_loops.rs b/src/tools/clippy/tests/ui/infinite_loops.rs
index 0613eddce26..d7be6f9ce7e 100644
--- a/src/tools/clippy/tests/ui/infinite_loops.rs
+++ b/src/tools/clippy/tests/ui/infinite_loops.rs
@@ -3,7 +3,6 @@
 
 #![allow(clippy::never_loop)]
 #![warn(clippy::infinite_loop)]
-#![feature(async_closure)]
 
 extern crate proc_macros;
 use proc_macros::{external, with_span};
diff --git a/src/tools/clippy/tests/ui/infinite_loops.stderr b/src/tools/clippy/tests/ui/infinite_loops.stderr
index 3a3ed7d0fe8..7635a7442f4 100644
--- a/src/tools/clippy/tests/ui/infinite_loops.stderr
+++ b/src/tools/clippy/tests/ui/infinite_loops.stderr
@@ -1,5 +1,5 @@
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:14:5
+  --> tests/ui/infinite_loops.rs:13:5
    |
 LL | /     loop {
 LL | |
@@ -15,7 +15,7 @@ LL | fn no_break() -> ! {
    |               ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:21:5
+  --> tests/ui/infinite_loops.rs:20:5
    |
 LL | /     loop {
 LL | |
@@ -32,7 +32,7 @@ LL | fn all_inf() -> ! {
    |              ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:23:9
+  --> tests/ui/infinite_loops.rs:22:9
    |
 LL | /         loop {
 LL | |
@@ -49,7 +49,7 @@ LL | fn all_inf() -> ! {
    |              ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:25:13
+  --> tests/ui/infinite_loops.rs:24:13
    |
 LL | /             loop {
 LL | |
@@ -63,7 +63,7 @@ LL | fn all_inf() -> ! {
    |              ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:39:5
+  --> tests/ui/infinite_loops.rs:38:5
    |
 LL | /     loop {
 LL | |
@@ -74,7 +74,7 @@ LL | |     }
    = help: if this is not intended, try adding a `break` or `return` condition in the loop
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:52:5
+  --> tests/ui/infinite_loops.rs:51:5
    |
 LL | /     loop {
 LL | |         fn inner_fn() -> ! {
@@ -90,7 +90,7 @@ LL | fn no_break_never_ret_noise() -> ! {
    |                               ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:95:5
+  --> tests/ui/infinite_loops.rs:94:5
    |
 LL | /     loop {
 LL | |
@@ -107,7 +107,7 @@ LL | fn break_inner_but_not_outer_1(cond: bool) -> ! {
    |                                            ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:106:5
+  --> tests/ui/infinite_loops.rs:105:5
    |
 LL | /     loop {
 LL | |
@@ -124,7 +124,7 @@ LL | fn break_inner_but_not_outer_2(cond: bool) -> ! {
    |                                            ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:120:9
+  --> tests/ui/infinite_loops.rs:119:9
    |
 LL | /         loop {
 LL | |
@@ -138,7 +138,7 @@ LL | fn break_outer_but_not_inner() -> ! {
    |                                ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:143:9
+  --> tests/ui/infinite_loops.rs:142:9
    |
 LL | /         loop {
 LL | |
@@ -155,7 +155,7 @@ LL | fn break_wrong_loop(cond: bool) -> ! {
    |                                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:183:5
+  --> tests/ui/infinite_loops.rs:182:5
    |
 LL | /     loop {
 LL | |
@@ -172,7 +172,7 @@ LL | fn match_like() -> ! {
    |                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:224:5
+  --> tests/ui/infinite_loops.rs:223:5
    |
 LL | /     loop {
 LL | |
@@ -186,7 +186,7 @@ LL | fn match_like() -> ! {
    |                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:229:5
+  --> tests/ui/infinite_loops.rs:228:5
    |
 LL | /     loop {
 LL | |
@@ -203,7 +203,7 @@ LL | fn match_like() -> ! {
    |                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:334:9
+  --> tests/ui/infinite_loops.rs:333:9
    |
 LL | /         loop {
 LL | |
@@ -217,7 +217,7 @@ LL |     fn problematic_trait_method() -> ! {
    |                                   ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:344:9
+  --> tests/ui/infinite_loops.rs:343:9
    |
 LL | /         loop {
 LL | |
@@ -231,7 +231,7 @@ LL |     fn could_be_problematic() -> ! {
    |                               ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:353:9
+  --> tests/ui/infinite_loops.rs:352:9
    |
 LL | /         loop {
 LL | |
@@ -245,7 +245,7 @@ LL |     let _loop_forever = || -> ! {
    |                            ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:367:8
+  --> tests/ui/infinite_loops.rs:366:8
    |
 LL |       Ok(loop {
    |  ________^
@@ -256,7 +256,7 @@ LL | |     })
    = help: if this is not intended, try adding a `break` or `return` condition in the loop
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:409:5
+  --> tests/ui/infinite_loops.rs:408:5
    |
 LL | /     'infinite: loop {
 LL | |
@@ -272,7 +272,7 @@ LL | fn continue_outer() -> ! {
    |                     ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:416:5
+  --> tests/ui/infinite_loops.rs:415:5
    |
 LL | /     loop {
 LL | |
@@ -289,7 +289,7 @@ LL | fn continue_outer() -> ! {
    |                     ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:418:9
+  --> tests/ui/infinite_loops.rs:417:9
    |
 LL | /         'inner: loop {
 LL | |             loop {
@@ -304,7 +304,7 @@ LL | fn continue_outer() -> ! {
    |                     ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:426:5
+  --> tests/ui/infinite_loops.rs:425:5
    |
 LL | /     loop {
 LL | |
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index 191f7719904..9138a8bacfe 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -1,4 +1,3 @@
-#![feature(async_closure)]
 #![warn(clippy::redundant_closure_call)]
 #![allow(clippy::redundant_async_block)]
 #![allow(clippy::type_complexity)]
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index 33a3b90f9cf..ede6fa27778 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -1,4 +1,3 @@
-#![feature(async_closure)]
 #![warn(clippy::redundant_closure_call)]
 #![allow(clippy::redundant_async_block)]
 #![allow(clippy::type_complexity)]
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
index 000d81f811f..8e0d37df96b 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
@@ -1,5 +1,5 @@
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:16:13
+  --> tests/ui/redundant_closure_call_fixable.rs:15:13
    |
 LL |     let a = (|| 42)();
    |             ^^^^^^^^^ help: try doing something like: `42`
@@ -8,7 +8,7 @@ LL |     let a = (|| 42)();
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:17:13
+  --> tests/ui/redundant_closure_call_fixable.rs:16:13
    |
 LL |       let b = (async || {
    |  _____________^
@@ -28,7 +28,7 @@ LL ~     };
    |
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:22:13
+  --> tests/ui/redundant_closure_call_fixable.rs:21:13
    |
 LL |       let c = (|| {
    |  _____________^
@@ -48,13 +48,13 @@ LL ~     };
    |
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:27:13
+  --> tests/ui/redundant_closure_call_fixable.rs:26:13
    |
 LL |     let d = (async || something().await)();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:36:13
+  --> tests/ui/redundant_closure_call_fixable.rs:35:13
    |
 LL |             (|| m!())()
    |             ^^^^^^^^^^^ help: try doing something like: `m!()`
@@ -65,7 +65,7 @@ LL |     m2!();
    = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:31:13
+  --> tests/ui/redundant_closure_call_fixable.rs:30:13
    |
 LL |             (|| 0)()
    |             ^^^^^^^^ help: try doing something like: `0`
@@ -76,67 +76,67 @@ LL |     m2!();
    = note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:44:16
+  --> tests/ui/redundant_closure_call_fixable.rs:43:16
    |
 LL |     assert_eq!((|| || 43)()(), 42);
    |                ^^^^^^^^^^^^^^ help: try doing something like: `43`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:53:10
+  --> tests/ui/redundant_closure_call_fixable.rs:52:10
    |
 LL |     dbg!((|| 42)());
    |          ^^^^^^^^^ help: try doing something like: `42`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:56:13
+  --> tests/ui/redundant_closure_call_fixable.rs:55:13
    |
 LL |     let a = (|| || || 123)();
    |             ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:60:13
+  --> tests/ui/redundant_closure_call_fixable.rs:59:13
    |
 LL |     let a = (|| || || || async || 1)()()()()();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:69:13
+  --> tests/ui/redundant_closure_call_fixable.rs:68:13
    |
 LL |     let a = (|| echo!(|| echo!(|| 1)))()()();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:71:13
+  --> tests/ui/redundant_closure_call_fixable.rs:70:13
    |
 LL |     let a = (|| echo!((|| 123)))()();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:84:11
+  --> tests/ui/redundant_closure_call_fixable.rs:83:11
    |
 LL |     bar()((|| || 42)()(), 5);
    |           ^^^^^^^^^^^^^^ help: try doing something like: `42`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:85:9
+  --> tests/ui/redundant_closure_call_fixable.rs:84:9
    |
 LL |     foo((|| || 42)()(), 5);
    |         ^^^^^^^^^^^^^^ help: try doing something like: `42`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:89:5
+  --> tests/ui/redundant_closure_call_fixable.rs:88:5
    |
 LL |     (|| async {})().await;
    |     ^^^^^^^^^^^^^^^ help: try doing something like: `async {}`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:98:18
+  --> tests/ui/redundant_closure_call_fixable.rs:97:18
    |
 LL |         spawn_on((|| async move {})());
    |                  ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}`
 
 error: try not to call a closure in the expression where it is declared
-  --> tests/ui/redundant_closure_call_fixable.rs:103:28
+  --> tests/ui/redundant_closure_call_fixable.rs:102:28
    |
 LL |     std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`
diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs
index d21aa240b2d..3e7695106a7 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.rs
+++ b/src/tools/clippy/tests/ui/redundant_locals.rs
@@ -1,7 +1,7 @@
 //@aux-build:proc_macros.rs
 #![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]
 #![warn(clippy::redundant_locals)]
-#![feature(async_closure, coroutines, stmt_expr_attributes)]
+#![feature(coroutines, stmt_expr_attributes)]
 
 extern crate proc_macros;
 use proc_macros::{external, with_span};
diff --git a/src/tools/compiletest/src/compute_diff.rs b/src/tools/compiletest/src/compute_diff.rs
index 3ace6c5b6d7..92c80c27de0 100644
--- a/src/tools/compiletest/src/compute_diff.rs
+++ b/src/tools/compiletest/src/compute_diff.rs
@@ -144,7 +144,7 @@ where
     }
 
     if !wrote_data {
-        eprintln!("note: diff is identical to nightly rustdoc");
+        println!("note: diff is identical to nightly rustdoc");
         assert!(diff_output.metadata().unwrap().len() == 0);
         return false;
     } else if verbose {
diff --git a/src/tools/compiletest/src/debuggers.rs b/src/tools/compiletest/src/debuggers.rs
index e75c8a5993e..b605bc813f1 100644
--- a/src/tools/compiletest/src/debuggers.rs
+++ b/src/tools/compiletest/src/debuggers.rs
@@ -20,7 +20,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
     }
 
     if config.remote_test_client.is_some() && !config.target.contains("android") {
-        eprintln!(
+        println!(
             "WARNING: debuginfo tests are not available when \
              testing with remote"
         );
@@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
     }
 
     if config.target.contains("android") {
-        eprintln!(
+        println!(
             "{} debug-info test uses tcp 5039 port.\
              please reserve it",
             config.target
@@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> {
     config.lldb_python_dir.as_ref()?;
 
     if let Some(350) = config.lldb_version {
-        eprintln!(
+        println!(
             "WARNING: The used version of LLDB (350) has a \
              known issue that breaks debuginfo tests. See \
              issue #32520 for more information. Skipping all \
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 9acb7d393b4..a5a166af33b 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -188,8 +188,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
     let (argv0, args_) = args.split_first().unwrap();
     if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
         let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
-        eprintln!("{}", opts.usage(&message));
-        eprintln!();
+        println!("{}", opts.usage(&message));
+        println!();
         panic!()
     }
 
@@ -200,8 +200,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
 
     if matches.opt_present("h") || matches.opt_present("help") {
         let message = format!("Usage: {} [OPTIONS]  [TESTNAME...]", argv0);
-        eprintln!("{}", opts.usage(&message));
-        eprintln!();
+        println!("{}", opts.usage(&message));
+        println!();
         panic!()
     }
 
@@ -508,7 +508,7 @@ pub fn run_tests(config: Arc<Config>) {
             // easy to miss which tests failed, and as such fail to reproduce
             // the failure locally.
 
-            eprintln!(
+            println!(
                 "Some tests failed in compiletest suite={}{} mode={} host={} target={}",
                 config.suite,
                 config
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index ca746ed8c55..7b11bf3b121 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -131,7 +131,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
 
     if config.verbose {
         // We're going to be dumping a lot of info. Start on a new line.
-        eprintln!("\n");
+        print!("\n\n");
     }
     debug!("running {:?}", testpaths.file.display());
     let mut props = TestProps::from_file(&testpaths.file, revision, &config);
@@ -353,7 +353,7 @@ impl<'test> TestCx<'test> {
                 {
                     self.error(&format!("{} test did not emit an error", self.config.mode));
                     if self.config.mode == crate::common::Mode::Ui {
-                        eprintln!("note: by default, ui tests are expected not to compile");
+                        println!("note: by default, ui tests are expected not to compile");
                     }
                     proc_res.fatal(None, || ());
                 };
@@ -774,20 +774,20 @@ impl<'test> TestCx<'test> {
                 unexpected.len(),
                 not_found.len()
             ));
-            eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
+            println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
             if !unexpected.is_empty() {
-                eprintln!("{}", "--- unexpected errors (from JSON output) ---".green());
+                println!("{}", "--- unexpected errors (from JSON output) ---".green());
                 for error in &unexpected {
-                    eprintln!("{}", error.render_for_expected());
+                    println!("{}", error.render_for_expected());
                 }
-                eprintln!("{}", "---".green());
+                println!("{}", "---".green());
             }
             if !not_found.is_empty() {
-                eprintln!("{}", "--- not found errors (from test file) ---".red());
+                println!("{}", "--- not found errors (from test file) ---".red());
                 for error in &not_found {
-                    eprintln!("{}", error.render_for_expected());
+                    println!("{}", error.render_for_expected());
                 }
-                eprintln!("{}", "---\n".red());
+                println!("{}", "---\n".red());
             }
             panic!("errors differ from expected");
         }
@@ -1876,18 +1876,18 @@ impl<'test> TestCx<'test> {
 
     fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
         if self.config.verbose {
-            eprintln!("------stdout------------------------------");
-            eprintln!("{}", out);
-            eprintln!("------stderr------------------------------");
-            eprintln!("{}", err);
-            eprintln!("------------------------------------------");
+            println!("------stdout------------------------------");
+            println!("{}", out);
+            println!("------stderr------------------------------");
+            println!("{}", err);
+            println!("------------------------------------------");
         }
     }
 
     fn error(&self, err: &str) {
         match self.revision {
-            Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err),
-            None => eprintln!("\nerror: {}", err),
+            Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
+            None => println!("\nerror: {}", err),
         }
     }
 
@@ -1972,7 +1972,7 @@ impl<'test> TestCx<'test> {
         if !self.config.has_html_tidy {
             return;
         }
-        eprintln!("info: generating a diff against nightly rustdoc");
+        println!("info: generating a diff against nightly rustdoc");
 
         let suffix =
             self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
@@ -2082,7 +2082,7 @@ impl<'test> TestCx<'test> {
                 .output()
                 .unwrap();
             assert!(output.status.success());
-            eprintln!("{}", String::from_utf8_lossy(&output.stdout));
+            println!("{}", String::from_utf8_lossy(&output.stdout));
             eprintln!("{}", String::from_utf8_lossy(&output.stderr));
         } else {
             use colored::Colorize;
@@ -2496,7 +2496,7 @@ impl<'test> TestCx<'test> {
                 )"#
             )
             .replace_all(&output, |caps: &Captures<'_>| {
-                eprintln!("{}", &caps[0]);
+                println!("{}", &caps[0]);
                 caps[0].replace(r"\", "/")
             })
             .replace("\r\n", "\n")
@@ -2601,14 +2601,14 @@ impl<'test> TestCx<'test> {
         if let Err(err) = fs::write(&actual_path, &actual) {
             self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
         }
-        eprintln!("Saved the actual {stream} to {actual_path:?}");
+        println!("Saved the actual {stream} to {actual_path:?}");
 
         let expected_path =
             expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);
 
         if !self.config.bless {
             if expected.is_empty() {
-                eprintln!("normalized {}:\n{}\n", stream, actual);
+                println!("normalized {}:\n{}\n", stream, actual);
             } else {
                 self.show_diff(
                     stream,
@@ -2631,10 +2631,10 @@ impl<'test> TestCx<'test> {
             if let Err(err) = fs::write(&expected_path, &actual) {
                 self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
             }
-            eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}");
+            println!("Blessing the {stream} of {test_name} in {expected_path:?}");
         }
 
-        eprintln!("\nThe actual {0} differed from the expected {0}.", stream);
+        println!("\nThe actual {0} differed from the expected {0}.", stream);
 
         if self.config.bless { 0 } else { 1 }
     }
@@ -2783,7 +2783,7 @@ impl<'test> TestCx<'test> {
         fs::create_dir_all(&incremental_dir).unwrap();
 
         if self.config.verbose {
-            eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display());
+            println!("init_incremental_test: incremental_dir={}", incremental_dir.display());
         }
     }
 
@@ -2841,7 +2841,7 @@ impl ProcRes {
             }
         }
 
-        eprintln!(
+        println!(
             "status: {}\ncommand: {}\n{}\n{}\n",
             self.status,
             self.cmdline,
@@ -2852,7 +2852,7 @@ impl ProcRes {
 
     pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
         if let Some(e) = err {
-            eprintln!("\nerror: {}", e);
+            println!("\nerror: {}", e);
         }
         self.print_info();
         on_failure();
diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs
index 6acd140183d..6c866cbef21 100644
--- a/src/tools/compiletest/src/runtest/codegen_units.rs
+++ b/src/tools/compiletest/src/runtest/codegen_units.rs
@@ -64,13 +64,13 @@ impl TestCx<'_> {
         if !missing.is_empty() {
             missing.sort();
 
-            eprintln!("\nThese items should have been contained but were not:\n");
+            println!("\nThese items should have been contained but were not:\n");
 
             for item in &missing {
-                eprintln!("{}", item);
+                println!("{}", item);
             }
 
-            eprintln!("\n");
+            println!("\n");
         }
 
         if !unexpected.is_empty() {
@@ -80,24 +80,24 @@ impl TestCx<'_> {
                 sorted
             };
 
-            eprintln!("\nThese items were contained but should not have been:\n");
+            println!("\nThese items were contained but should not have been:\n");
 
             for item in sorted {
-                eprintln!("{}", item);
+                println!("{}", item);
             }
 
-            eprintln!("\n");
+            println!("\n");
         }
 
         if !wrong_cgus.is_empty() {
             wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
-            eprintln!("\nThe following items were assigned to wrong codegen units:\n");
+            println!("\nThe following items were assigned to wrong codegen units:\n");
 
             for &(ref expected_item, ref actual_item) in &wrong_cgus {
-                eprintln!("{}", expected_item.name);
-                eprintln!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
-                eprintln!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
-                eprintln!();
+                println!("{}", expected_item.name);
+                println!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
+                println!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
+                println!();
             }
         }
 
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 7322e730e53..c621c22ac99 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -260,7 +260,7 @@ impl TestCx<'_> {
                 cmdline,
             };
             if adb.kill().is_err() {
-                eprintln!("Adb process is already finished.");
+                println!("Adb process is already finished.");
             }
         } else {
             let rust_src_root =
@@ -275,7 +275,7 @@ impl TestCx<'_> {
 
             match self.config.gdb_version {
                 Some(version) => {
-                    eprintln!("NOTE: compiletest thinks it is using GDB version {}", version);
+                    println!("NOTE: compiletest thinks it is using GDB version {}", version);
 
                     if version > extract_gdb_version("7.4").unwrap() {
                         // Add the directory containing the pretty printers to
@@ -297,7 +297,7 @@ impl TestCx<'_> {
                     }
                 }
                 _ => {
-                    eprintln!(
+                    println!(
                         "NOTE: compiletest does not know which version of \
                          GDB it is using"
                     );
@@ -392,10 +392,10 @@ impl TestCx<'_> {
 
         match self.config.lldb_version {
             Some(ref version) => {
-                eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version);
+                println!("NOTE: compiletest thinks it is using LLDB version {}", version);
             }
             _ => {
-                eprintln!(
+                println!(
                     "NOTE: compiletest does not know which version of \
                      LLDB it is using"
                 );
diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs
index 4f26786129b..591aff0defe 100644
--- a/src/tools/compiletest/src/runtest/incremental.rs
+++ b/src/tools/compiletest/src/runtest/incremental.rs
@@ -30,7 +30,7 @@ impl TestCx<'_> {
         assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
 
         if self.config.verbose {
-            eprint!("revision={:?} props={:#?}", revision, self.props);
+            print!("revision={:?} props={:#?}", revision, self.props);
         }
 
         if revision.starts_with("cpass") {
diff --git a/src/tools/compiletest/src/runtest/mir_opt.rs b/src/tools/compiletest/src/runtest/mir_opt.rs
index 64a2addaa28..d1ec0035744 100644
--- a/src/tools/compiletest/src/runtest/mir_opt.rs
+++ b/src/tools/compiletest/src/runtest/mir_opt.rs
@@ -89,7 +89,7 @@ impl TestCx<'_> {
                 }
                 let expected_string = fs::read_to_string(&expected_file).unwrap();
                 if dumped_string != expected_string {
-                    eprint!("{}", write_diff(&expected_string, &dumped_string, 3));
+                    print!("{}", write_diff(&expected_string, &dumped_string, 3));
                     panic!(
                         "Actual MIR output differs from expected MIR output {}",
                         expected_file.display()
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
index 84376d346af..31fdb0a5d13 100644
--- a/src/tools/compiletest/src/runtest/rustdoc_json.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -29,7 +29,7 @@ impl TestCx<'_> {
 
         if !res.status.success() {
             self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
-                eprintln!("Rustdoc Output:");
+                println!("Rustdoc Output:");
                 proc_res.print_info();
             })
         }
diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs
index bc860bf18c7..172b1e32aad 100644
--- a/src/tools/compiletest/src/runtest/ui.rs
+++ b/src/tools/compiletest/src/runtest/ui.rs
@@ -109,10 +109,10 @@ impl TestCx<'_> {
         }
 
         if errors > 0 {
-            eprintln!("To update references, rerun the tests and pass the `--bless` flag");
+            println!("To update references, rerun the tests and pass the `--bless` flag");
             let relative_path_to_file =
                 self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
-            eprintln!(
+            println!(
                 "To only update this specific test, also pass `--test-args {}`",
                 relative_path_to_file.display(),
             );
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 7b50e62c29b..bff02f1db9f 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -30,7 +30,7 @@ fn path_div() -> &'static str {
 pub fn logv(config: &Config, s: String) {
     debug!("{}", s);
     if config.verbose {
-        eprintln!("{}", s);
+        println!("{}", s);
     }
 }
 
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 03ad4a74a2c..ff62667f9b8 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-903d2976fdb6ceeb65526b7555d8d1e6f8c02134
+f4f0fafd0c7849e162eddbc69fa5fe82dbec28c7
diff --git a/src/tools/miri/tests/pass/async-closure-captures.rs b/src/tools/miri/tests/pass/async-closure-captures.rs
index 979a6d1cbe0..ed6b7b205b5 100644
--- a/src/tools/miri/tests/pass/async-closure-captures.rs
+++ b/src/tools/miri/tests/pass/async-closure-captures.rs
@@ -1,6 +1,6 @@
 // Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync
 
-#![feature(async_closure, async_trait_bounds)]
+#![feature(async_trait_bounds)]
 
 use std::future::Future;
 use std::pin::pin;
diff --git a/src/tools/miri/tests/pass/async-closure-drop.rs b/src/tools/miri/tests/pass/async-closure-drop.rs
index ad9822fa46d..105aa434b0a 100644
--- a/src/tools/miri/tests/pass/async-closure-drop.rs
+++ b/src/tools/miri/tests/pass/async-closure-drop.rs
@@ -1,4 +1,4 @@
-#![feature(async_closure, async_trait_bounds)]
+#![feature(async_fn_traits, async_trait_bounds)]
 
 use std::future::Future;
 use std::pin::pin;
diff --git a/src/tools/miri/tests/pass/async-closure.rs b/src/tools/miri/tests/pass/async-closure.rs
index 979b83687e4..4c0fb356f9d 100644
--- a/src/tools/miri/tests/pass/async-closure.rs
+++ b/src/tools/miri/tests/pass/async-closure.rs
@@ -1,4 +1,4 @@
-#![feature(async_closure, async_fn_traits)]
+#![feature(async_fn_traits)]
 #![allow(unused)]
 
 use std::future::Future;
diff --git a/src/tools/miri/tests/pass/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs
index a455f377e85..6d556b77795 100644
--- a/src/tools/miri/tests/pass/async-drop.rs
+++ b/src/tools/miri/tests/pass/async-drop.rs
@@ -6,7 +6,7 @@
 // please consider modifying rustc's async drop test at
 // `tests/ui/async-await/async-drop.rs`.
 
-#![feature(async_drop, impl_trait_in_assoc_type, async_closure)]
+#![feature(async_drop, impl_trait_in_assoc_type)]
 #![allow(incomplete_features, dead_code)]
 
 // FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests
diff --git a/tests/codegen/async-closure-debug.rs b/tests/codegen/async-closure-debug.rs
index 644df169a36..2d67e02eb9c 100644
--- a/tests/codegen/async-closure-debug.rs
+++ b/tests/codegen/async-closure-debug.rs
@@ -7,8 +7,6 @@
 // CHECK-DAG:  [[CLOSURE:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[GEN_FN]]
 // CHECK-DAG:  [[UPVAR:!.*]] = !DIDerivedType(tag: DW_TAG_member, name: "upvar", scope: [[CLOSURE]]
 
-#![feature(async_closure)]
-
 fn async_closure_test(upvar: &str) -> impl AsyncFn() + '_ {
     async move || {
         let hello = String::from("hello");
diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map
index 9ff29af8e8e..04c05ba098b 100644
--- a/tests/coverage/async_closure.cov-map
+++ b/tests/coverage/async_closure.cov-map
@@ -1,56 +1,56 @@
 Function name: async_closure::call_once::<async_closure::main::{closure#0}>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2b]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 43)
+- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43)
 Highest counter ID seen: c0
 
 Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2b, 01, 0e, 05, 02, 01, 00, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 06, 2b, 01, 0e, 05, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 7, 43) to (start + 1, 14)
+- Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14)
 - Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: async_closure::main
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 01, 01, 16, 01, 02, 05, 02, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 22)
+- Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22)
 - Code(Counter(0)) at (prev + 2, 5) to (start + 2, 2)
 Highest counter ID seen: c0
 
 Function name: async_closure::main::{closure#0}
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 23, 00, 24]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 35) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36)
 Highest counter ID seen: c0
 
 Function name: async_closure::main::{closure#0}::{closure#0}::<i16>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 22, 00, 24]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 34) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36)
 Highest counter ID seen: c0
 
 Function name: async_closure::main::{closure#0}::{closure#1}::<i32>
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 23, 00, 24]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 12, 35) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36)
 Highest counter ID seen: c0
 
diff --git a/tests/coverage/async_closure.coverage b/tests/coverage/async_closure.coverage
index 75da1a01fc1..7fbea265812 100644
--- a/tests/coverage/async_closure.coverage
+++ b/tests/coverage/async_closure.coverage
@@ -1,4 +1,3 @@
-   LL|       |#![feature(async_closure)]
    LL|       |//@ edition: 2021
    LL|       |
    LL|       |//@ aux-build: executor.rs
diff --git a/tests/coverage/async_closure.rs b/tests/coverage/async_closure.rs
index cbac592d957..85c5df1f1ab 100644
--- a/tests/coverage/async_closure.rs
+++ b/tests/coverage/async_closure.rs
@@ -1,4 +1,3 @@
-#![feature(async_closure)]
 //@ edition: 2021
 
 //@ aux-build: executor.rs
diff --git a/tests/crashes/116979.rs b/tests/crashes/116979.rs
new file mode 100644
index 00000000000..28bbc972ea3
--- /dev/null
+++ b/tests/crashes/116979.rs
@@ -0,0 +1,14 @@
+//@ known-bug: #116979
+//@ compile-flags: -Csymbol-mangling-version=v0
+//@ needs-rustc-debug-assertions
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::fmt::Display;
+
+pub fn require_dyn_star_display(_: dyn* Display) {}
+
+fn main() {
+    require_dyn_star_display(1usize);
+}
diff --git a/tests/crashes/117808.rs b/tests/crashes/117808.rs
new file mode 100644
index 00000000000..2c727986dd0
--- /dev/null
+++ b/tests/crashes/117808.rs
@@ -0,0 +1,27 @@
+//@ known-bug: #117808
+//@ edition:2021
+//@ needs-rustc-debug-assertions
+
+use std::future::Future;
+
+fn hrc<R, F: for<'a> AsyncClosure<'a, (), R>>(f: F) -> F {
+    f
+}
+
+fn main() {
+    hrc(|x| async {});
+}
+
+trait AsyncClosure<'a, I, R>
+where
+    I: 'a,
+{
+}
+
+impl<'a, I, R, Fut, F> AsyncClosure<'a, I, R> for F
+where
+    I: 'a,
+    F: Fn(&'a I) -> Fut,
+    Fut: Future<Output = R> + Send + 'a,
+{
+}
diff --git a/tests/crashes/117877.rs b/tests/crashes/117877.rs
new file mode 100644
index 00000000000..b1effc0cbcb
--- /dev/null
+++ b/tests/crashes/117877.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #117877
+//@ edition:2021
+//@ needs-rustc-debug-assertions
+//@ only-x86_64
+#![feature(asm_const)]
+
+use std::arch::asm;
+
+async unsafe fn foo<'a>() {
+    asm!("/* {0} */", const N);
+}
+
+fn main() {}
diff --git a/tests/crashes/118778.rs b/tests/crashes/118778.rs
new file mode 100644
index 00000000000..9914e76022d
--- /dev/null
+++ b/tests/crashes/118778.rs
@@ -0,0 +1,24 @@
+//@ known-bug: #118778
+//@ edition:2021
+//@ needs-rustc-debug-assertions
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+trait Owner {
+    type T<const N: u16>;
+}
+
+impl Owner for () {
+    type T<const N: u32> = U32<{ N + 1 }>
+    where
+        U32<{ N + 1 }>:;
+}
+
+struct U32<const N: u32>;
+
+fn take1(_: impl Owner<T<1> = U32<1>>) {}
+
+fn main() {
+    take1(());
+}
diff --git a/tests/crashes/118784.rs b/tests/crashes/118784.rs
new file mode 100644
index 00000000000..7bf943c8177
--- /dev/null
+++ b/tests/crashes/118784.rs
@@ -0,0 +1,19 @@
+//@ known-bug: #118784
+//@ needs-rustc-debug-assertions
+
+use std::collections::HashMap;
+
+macro_rules! all_sync_send {
+    ($ctor:expr, $($iter:expr),+) => ({
+        $(
+            let mut x = $ctor;
+            is_sync(x.$iter());
+            let mut y = $ctor;
+            is_send(y.$iter());
+        )+
+    })
+}
+
+fn main() {
+    all_sync_send!(HashMap, HashMap);
+}
diff --git a/tests/crashes/120175.rs b/tests/crashes/120175.rs
new file mode 100644
index 00000000000..c6e7203ff98
--- /dev/null
+++ b/tests/crashes/120175.rs
@@ -0,0 +1,11 @@
+//@ known-bug: #120175
+//@ needs-rustc-debug-assertions
+
+#![feature(extern_types)]
+
+#[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")]
+extern "C" {
+    pub type CrossCrate;
+}
+
+fn main() {}
diff --git a/tests/crashes/121176.rs b/tests/crashes/121176.rs
new file mode 100644
index 00000000000..4d82e51de8f
--- /dev/null
+++ b/tests/crashes/121176.rs
@@ -0,0 +1,9 @@
+//@ known-bug: #121176
+//@ needs-rustc-debug-assertions
+use std::fmt::Debug;
+
+static STATIC_1: dyn Debug + Sync = *();
+
+fn main() {
+    println!("{:?}", &STATIC_1);
+}
diff --git a/tests/crashes/123861.rs b/tests/crashes/123861.rs
new file mode 100644
index 00000000000..60245960af0
--- /dev/null
+++ b/tests/crashes/123861.rs
@@ -0,0 +1,5 @@
+//@ known-bug: #123861
+//@ needs-rustc-debug-assertions
+
+struct _;
+fn mainIterator<_ = _> {}
diff --git a/tests/crashes/123862.rs b/tests/crashes/123862.rs
new file mode 100644
index 00000000000..075e0e6fc8f
--- /dev/null
+++ b/tests/crashes/123862.rs
@@ -0,0 +1,14 @@
+//@ known-bug: #123862
+//@ needs-rustc-debug-assertions
+
+macro_rules! pos {
+    () => {
+        (file![$($pos,)* pos!()], line!())
+    };
+}
+
+fn outer() {
+    inner_inlined(main_pos, pos!());
+}
+
+fn inner_inlined() {}
diff --git a/tests/crashes/130395.rs b/tests/crashes/130395.rs
new file mode 100644
index 00000000000..c1d189c79ba
--- /dev/null
+++ b/tests/crashes/130395.rs
@@ -0,0 +1,10 @@
+//@ known-bug: #130395
+//@ needs-rustc-debug-assertions
+
+enum U {
+    B(isize, usize),
+}
+
+fn main() {
+    let x = T::A(U::C);
+}
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
index 7da33b8a094..8a584853e00 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.built.after.mir
@@ -1,6 +1,6 @@
 // MIR for `main::{closure#0}::{closure#0}::{closure#0}` after built
 
-fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
index a21e82ef5b6..a9e08d2e8f6 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#1}.built.after.mir
@@ -1,6 +1,6 @@
 // MIR for `main::{closure#0}::{closure#0}::{closure#1}` after built
 
-fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
index c1566360995..a984845fd2c 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move
 
-fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:54:33: 54:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10};
+fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:54:53: 57:10 (#0)} { a: move _2, b: move (_1.0: i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
index a4a6a535a23..c6721085eb2 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.built.after.mir
@@ -1,6 +1,6 @@
 // MIR for `main::{closure#0}::{closure#1}::{closure#0}` after built
 
-fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
index 69bba6f5194..4452ae7812e 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#1}.built.after.mir
@@ -1,6 +1,6 @@
 // MIR for `main::{closure#0}::{closure#1}::{closure#1}` after built
 
-fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> ()
+fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
 yields ()
  {
     debug _task_context => _2;
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
index 134fe145bae..aab9f7b03b9 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move
 
-fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10};
+fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
index f267d93bd60..3fdc81791de 100644
--- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
+++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir
@@ -1,10 +1,10 @@
 // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref
 
-fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} {
-    let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10};
+fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
+    let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
 
     bb0: {
-        _0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
+        _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
         return;
     }
 }
diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs
index f28400e298f..cd2e83e939a 100644
--- a/tests/mir-opt/async_closure_shims.rs
+++ b/tests/mir-opt/async_closure_shims.rs
@@ -1,7 +1,6 @@
 //@ edition:2021
 // skip-filecheck
 
-#![feature(async_closure, async_fn_traits)]
 #![allow(unused)]
 
 use std::future::Future;
diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
index 56708ec9310..6ab3cc6f6fe 100644
--- a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
@@ -1,5 +1,3 @@
-#![feature(async_closure)]
-
 use std::ops::AsyncFnMut;
 
 pub trait Main {
diff --git a/tests/ui/asm/generic_const_simd_vec_len.rs b/tests/ui/asm/generic_const_simd_vec_len.rs
new file mode 100644
index 00000000000..fb8c5274ddb
--- /dev/null
+++ b/tests/ui/asm/generic_const_simd_vec_len.rs
@@ -0,0 +1,21 @@
+//! This is a regression test to ensure that we emit a diagnostic pointing to the
+//! reason the type was rejected in inline assembly.
+
+//@ only-x86_64
+
+#![feature(repr_simd)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct Foo<const C: usize>([u8; C]);
+//~^ ERROR: cannot evaluate SIMD vector length
+
+pub unsafe fn foo<const C: usize>(a: Foo<C>) {
+    std::arch::asm!(
+        "movaps {src}, {src}",
+        src = in(xmm_reg) a,
+        //~^ NOTE: SIMD vector length needs to be known statically
+    );
+}
+
+fn main() {}
diff --git a/tests/ui/asm/generic_const_simd_vec_len.stderr b/tests/ui/asm/generic_const_simd_vec_len.stderr
new file mode 100644
index 00000000000..486281b6062
--- /dev/null
+++ b/tests/ui/asm/generic_const_simd_vec_len.stderr
@@ -0,0 +1,14 @@
+error: cannot evaluate SIMD vector length `C`
+  --> $DIR/generic_const_simd_vec_len.rs:10:32
+   |
+LL | pub struct Foo<const C: usize>([u8; C]);
+   |                                ^^^^^^^
+   |
+note: SIMD vector length needs to be known statically for use in `asm!`
+  --> $DIR/generic_const_simd_vec_len.rs:16:27
+   |
+LL |         src = in(xmm_reg) a,
+   |                           ^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/asm/named_const_simd_vec_len.rs b/tests/ui/asm/named_const_simd_vec_len.rs
new file mode 100644
index 00000000000..7df4d922d5c
--- /dev/null
+++ b/tests/ui/asm/named_const_simd_vec_len.rs
@@ -0,0 +1,22 @@
+//! This is a regression test to ensure that we evaluate
+//! SIMD vector length constants instead of assuming they are literals.
+
+//@ only-x86_64
+//@ check-pass
+
+#![feature(repr_simd)]
+
+const C: usize = 16;
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct Foo([u8; C]);
+
+pub unsafe fn foo(a: Foo) {
+    std::arch::asm!(
+        "movaps {src}, {src}",
+        src = in(xmm_reg) a,
+    );
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/async-borrowck-escaping-closure-error.rs b/tests/ui/async-await/async-borrowck-escaping-closure-error.rs
index ffb97ca04ac..4489f344e6f 100644
--- a/tests/ui/async-await/async-borrowck-escaping-closure-error.rs
+++ b/tests/ui/async-await/async-borrowck-escaping-closure-error.rs
@@ -1,6 +1,5 @@
 //@ edition:2018
 
-#![feature(async_closure)]
 fn foo() -> Box<dyn std::future::Future<Output = u32>> {
     let x = 0u32;
     Box::new((async || x)())
diff --git a/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr b/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr
index 4b1ce300b56..967b3bf5a77 100644
--- a/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr
+++ b/tests/ui/async-await/async-borrowck-escaping-closure-error.stderr
@@ -1,5 +1,5 @@
 error[E0515]: cannot return value referencing local variable `x`
-  --> $DIR/async-borrowck-escaping-closure-error.rs:6:5
+  --> $DIR/async-borrowck-escaping-closure-error.rs:5:5
    |
 LL |     Box::new((async || x)())
    |     ^^^^^^^^^------------^^^
diff --git a/tests/ui/async-await/async-closure-matches-expr.rs b/tests/ui/async-await/async-closure-matches-expr.rs
index 75ce14a4947..3f1c70e691c 100644
--- a/tests/ui/async-await/async-closure-matches-expr.rs
+++ b/tests/ui/async-await/async-closure-matches-expr.rs
@@ -1,8 +1,6 @@
 //@ build-pass
 //@ edition:2018
 
-#![feature(async_closure)]
-
 macro_rules! match_expr {
     ($x:expr) => {}
 }
diff --git a/tests/ui/async-await/async-closure.rs b/tests/ui/async-await/async-closure.rs
index 77c00bbdc9f..3dd88fbf739 100644
--- a/tests/ui/async-await/async-closure.rs
+++ b/tests/ui/async-await/async-closure.rs
@@ -6,8 +6,6 @@
 //@ edition:2018
 //@ aux-build:arc_wake.rs
 
-#![feature(async_closure)]
-
 extern crate arc_wake;
 
 use std::pin::Pin;
diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.rs b/tests/ui/async-await/async-closures/ambiguous-arg.rs
index d76a1cf953e..e8e6ff6d97c 100644
--- a/tests/ui/async-await/async-closures/ambiguous-arg.rs
+++ b/tests/ui/async-await/async-closures/ambiguous-arg.rs
@@ -3,8 +3,6 @@
 // Regression test for #123901. We previously ICE'd as we silently
 // swallowed an in the `ExprUseVisitor`.
 
-#![feature(async_closure)]
-
 pub fn test(test: &u64, temp: &u64) {
     async |check, a, b| {
         //~^ ERROR type annotations needed
diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.stderr b/tests/ui/async-await/async-closures/ambiguous-arg.stderr
index 01f72e94ecc..adb71d676dc 100644
--- a/tests/ui/async-await/async-closures/ambiguous-arg.stderr
+++ b/tests/ui/async-await/async-closures/ambiguous-arg.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/ambiguous-arg.rs:9:25
+  --> $DIR/ambiguous-arg.rs:7:25
    |
 LL |       async |check, a, b| {
    |  _________________________^
diff --git a/tests/ui/async-await/async-closures/arg-mismatch.rs b/tests/ui/async-await/async-closures/arg-mismatch.rs
index c8dddee6275..f69c8122d1d 100644
--- a/tests/ui/async-await/async-closures/arg-mismatch.rs
+++ b/tests/ui/async-await/async-closures/arg-mismatch.rs
@@ -1,8 +1,6 @@
 //@ aux-build:block-on.rs
 //@ edition:2021
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/arg-mismatch.stderr b/tests/ui/async-await/async-closures/arg-mismatch.stderr
index 70853ae2815..5c8e6650293 100644
--- a/tests/ui/async-await/async-closures/arg-mismatch.stderr
+++ b/tests/ui/async-await/async-closures/arg-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/arg-mismatch.rs:12:11
+  --> $DIR/arg-mismatch.rs:10:11
    |
 LL |         c(2usize).await;
    |         - ^^^^^^ expected `i32`, found `usize`
@@ -7,7 +7,7 @@ LL |         c(2usize).await;
    |         arguments to this function are incorrect
    |
 note: closure parameter defined here
-  --> $DIR/arg-mismatch.rs:10:24
+  --> $DIR/arg-mismatch.rs:8:24
    |
 LL |         let c = async |x| {};
    |                        ^
diff --git a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs
index 8309cfbd58f..e739230fd46 100644
--- a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs
+++ b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ run-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs
index e7644e3dfe0..078348eb4e6 100644
--- a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs
+++ b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ run-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/auxiliary/block-on.rs b/tests/ui/async-await/async-closures/auxiliary/block-on.rs
index 8b50c5571c1..4ec45ddf333 100644
--- a/tests/ui/async-await/async-closures/auxiliary/block-on.rs
+++ b/tests/ui/async-await/async-closures/auxiliary/block-on.rs
@@ -1,7 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 use std::future::Future;
 use std::pin::pin;
 use std::task::*;
diff --git a/tests/ui/async-await/async-closures/auxiliary/foreign.rs b/tests/ui/async-await/async-closures/auxiliary/foreign.rs
index 33548a1b30d..935b029a7c5 100644
--- a/tests/ui/async-await/async-closures/auxiliary/foreign.rs
+++ b/tests/ui/async-await/async-closures/auxiliary/foreign.rs
@@ -1,7 +1,5 @@
 //@ edition:2021
 
-#![feature(async_closure)]
-
 pub fn closure() -> impl AsyncFn() {
     async || { /* Don't really need to do anything here. */ }
 }
diff --git a/tests/ui/async-await/async-closures/await-inference-guidance.rs b/tests/ui/async-await/async-closures/await-inference-guidance.rs
index 1ddc1f8d1c5..f4f91e2e073 100644
--- a/tests/ui/async-await/async-closures/await-inference-guidance.rs
+++ b/tests/ui/async-await/async-closures/await-inference-guidance.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ run-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs
index a72ff8e5dce..0560d3b0867 100644
--- a/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs
+++ b/tests/ui/async-await/async-closures/body-check-on-non-fnmut.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 // Make sure that we don't call `coroutine_by_move_body_def_id` query
diff --git a/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs b/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs
index 5ec1c5ee50e..10f7636720c 100644
--- a/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs
+++ b/tests/ui/async-await/async-closures/box-deref-in-debuginfo.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ run-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 pub trait Trait {
diff --git a/tests/ui/async-await/async-closures/brand.rs b/tests/ui/async-await/async-closures/brand.rs
index db1f5d271c6..3b13506cf00 100644
--- a/tests/ui/async-await/async-closures/brand.rs
+++ b/tests/ui/async-await/async-closures/brand.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 use std::future::Future;
diff --git a/tests/ui/async-await/async-closures/call-once-deduction.rs b/tests/ui/async-await/async-closures/call-once-deduction.rs
index 41d92bc3d78..ed2830a5e82 100644
--- a/tests/ui/async-await/async-closures/call-once-deduction.rs
+++ b/tests/ui/async-await/async-closures/call-once-deduction.rs
@@ -1,7 +1,7 @@
 //@ edition: 2021
 //@ check-pass
 
-#![feature(async_closure, async_fn_traits, unboxed_closures)]
+#![feature(async_fn_traits, unboxed_closures)]
 
 fn bar<F, O>(_: F)
 where
diff --git a/tests/ui/async-await/async-closures/captures.rs b/tests/ui/async-await/async-closures/captures.rs
index 2bd4b685997..296fca6cb86 100644
--- a/tests/ui/async-await/async-closures/captures.rs
+++ b/tests/ui/async-await/async-closures/captures.rs
@@ -5,8 +5,6 @@
 
 // Same as miri's `tests/pass/async-closure-captures.rs`, keep in sync
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/clone-closure.rs b/tests/ui/async-await/async-closures/clone-closure.rs
index a9e1d6bccc7..b637ab45b9a 100644
--- a/tests/ui/async-await/async-closures/clone-closure.rs
+++ b/tests/ui/async-await/async-closures/clone-closure.rs
@@ -3,8 +3,6 @@
 //@ run-pass
 //@ check-run-results
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 async fn for_each(f: impl AsyncFnOnce(&str) + Clone) {
diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
index 4cbbefb0f52..069744a3282 100644
--- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.rs
@@ -1,7 +1,5 @@
 //@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
 
-#![feature(async_closure)]
-
 fn main() {}
 
 fn needs_fn_mut<T>(mut x: impl FnMut() -> T) {
diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
index bab26c19482..52697bac509 100644
--- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of `x` which is behind a mutable reference
-  --> $DIR/closure-shim-borrowck-error.rs:12:18
+  --> $DIR/closure-shim-borrowck-error.rs:10:18
    |
 LL |     needs_fn_mut(async || {
    |                  ^^^^^^^^ `x` is moved here
@@ -11,7 +11,7 @@ LL |         x.hello();
    |         move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
    |
 note: if `Ty` implemented `Clone`, you could clone the value
-  --> $DIR/closure-shim-borrowck-error.rs:18:1
+  --> $DIR/closure-shim-borrowck-error.rs:16:1
    |
 LL |         x.hello();
    |         - you could clone this value
diff --git a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs
index 1acbf0311b3..993f8378439 100644
--- a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs
+++ b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs
@@ -4,8 +4,6 @@
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
-#![feature(async_closure)]
-
 fn constrain<T: AsyncFnOnce()>(t: T) -> T {
     t
 }
diff --git a/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs b/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs
index f71cc1ef537..a1d6ce259e2 100644
--- a/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs
+++ b/tests/ui/async-await/async-closures/debuginfo-by-move-body.rs
@@ -3,8 +3,6 @@
 //@ build-pass
 //@ compile-flags: -Cdebuginfo=2
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 async fn call_once(f: impl AsyncFnOnce()) {
diff --git a/tests/ui/async-await/async-closures/def-path.rs b/tests/ui/async-await/async-closures/def-path.rs
index 70450697816..838556966e8 100644
--- a/tests/ui/async-await/async-closures/def-path.rs
+++ b/tests/ui/async-await/async-closures/def-path.rs
@@ -1,8 +1,6 @@
 //@ compile-flags: -Zverbose-internals
 //@ edition:2021
 
-#![feature(async_closure)]
-
 fn main() {
     let x = async || {};
     //~^ NOTE the expected `async` closure body
diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr
index 0a1e30c1253..cf25b2d2d23 100644
--- a/tests/ui/async-await/async-closures/def-path.stderr
+++ b/tests/ui/async-await/async-closures/def-path.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/def-path.rs:9:9
+  --> $DIR/def-path.rs:7:9
    |
 LL |     let x = async || {};
    |                      -- the expected `async` closure body
diff --git a/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs b/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs
index 2313db506be..d40c9548a3a 100644
--- a/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs
+++ b/tests/ui/async-await/async-closures/different-projection-lengths-for-different-upvars.rs
@@ -2,8 +2,6 @@
 //@ edition: 2021
 // issue: rust-lang/rust#123697
 
-#![feature(async_closure)]
-
 struct S { t: i32 }
 
 fn test(s: &S, t: &i32) {
diff --git a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs
index 8fc9924a12f..f90d10ebe85 100644
--- a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs
+++ b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.rs
@@ -1,7 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 struct DropMe;
 
 trait Impossible {}
diff --git a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr
index b4dc3e268bd..c93c1732a22 100644
--- a/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr
+++ b/tests/ui/async-await/async-closures/dont-ice-when-body-tainted-by-errors.stderr
@@ -1,16 +1,16 @@
 error[E0277]: the trait bound `(): Impossible` is not satisfied
-  --> $DIR/dont-ice-when-body-tainted-by-errors.rs:19:23
+  --> $DIR/dont-ice-when-body-tainted-by-errors.rs:17:23
    |
 LL |         trait_error::<()>();
    |                       ^^ the trait `Impossible` is not implemented for `()`
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/dont-ice-when-body-tainted-by-errors.rs:7:1
+  --> $DIR/dont-ice-when-body-tainted-by-errors.rs:5:1
    |
 LL | trait Impossible {}
    | ^^^^^^^^^^^^^^^^
 note: required by a bound in `trait_error`
-  --> $DIR/dont-ice-when-body-tainted-by-errors.rs:8:19
+  --> $DIR/dont-ice-when-body-tainted-by-errors.rs:6:19
    |
 LL | fn trait_error<T: Impossible>() {}
    |                   ^^^^^^^^^^ required by this bound in `trait_error`
diff --git a/tests/ui/async-await/async-closures/drop.rs b/tests/ui/async-await/async-closures/drop.rs
index 9c99550e3b7..24c182d2c2d 100644
--- a/tests/ui/async-await/async-closures/drop.rs
+++ b/tests/ui/async-await/async-closures/drop.rs
@@ -3,7 +3,6 @@
 //@ run-pass
 //@ check-run-results
 
-#![feature(async_closure)]
 #![allow(unused)]
 
 extern crate block_on;
diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.rs b/tests/ui/async-await/async-closures/fn-exception-target-features.rs
index eb554650b7c..82fc776fd2c 100644
--- a/tests/ui/async-await/async-closures/fn-exception-target-features.rs
+++ b/tests/ui/async-await/async-closures/fn-exception-target-features.rs
@@ -1,7 +1,7 @@
 //@ edition: 2021
 //@ only-x86_64
 
-#![feature(async_closure, target_feature_11)]
+#![feature(target_feature_11)]
 // `target_feature_11` just to test safe functions w/ target features.
 
 use std::pin::Pin;
diff --git a/tests/ui/async-await/async-closures/fn-exception.rs b/tests/ui/async-await/async-closures/fn-exception.rs
index 36cb955cd5c..8ff63983e79 100644
--- a/tests/ui/async-await/async-closures/fn-exception.rs
+++ b/tests/ui/async-await/async-closures/fn-exception.rs
@@ -1,7 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 use std::pin::Pin;
 use std::future::Future;
 
diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr
index b3118664c15..aa74ed234df 100644
--- a/tests/ui/async-await/async-closures/fn-exception.stderr
+++ b/tests/ui/async-await/async-closures/fn-exception.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn()` is not satisfied
-  --> $DIR/fn-exception.rs:19:10
+  --> $DIR/fn-exception.rs:17:10
    |
 LL |     test(unsafety);
    |     ---- ^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
@@ -7,13 +7,13 @@ LL |     test(unsafety);
    |     required by a bound introduced by this call
    |
 note: required by a bound in `test`
-  --> $DIR/fn-exception.rs:16:17
+  --> $DIR/fn-exception.rs:14:17
    |
 LL | fn test(f: impl AsyncFn()) {}
    |                 ^^^^^^^^^ required by this bound in `test`
 
 error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied
-  --> $DIR/fn-exception.rs:20:10
+  --> $DIR/fn-exception.rs:18:10
    |
 LL |     test(abi);
    |     ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
@@ -21,7 +21,7 @@ LL |     test(abi);
    |     required by a bound introduced by this call
    |
 note: required by a bound in `test`
-  --> $DIR/fn-exception.rs:16:17
+  --> $DIR/fn-exception.rs:14:17
    |
 LL | fn test(f: impl AsyncFn()) {}
    |                 ^^^^^^^^^ required by this bound in `test`
diff --git a/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs b/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs
index 7244a29673b..1347a4b259b 100644
--- a/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs
+++ b/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn consume(_: String) {}
diff --git a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs
index c20e3664d8b..c963d282c4e 100644
--- a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs
+++ b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn force_fnonce<T: AsyncFnOnce()>(t: T) -> T { t }
diff --git a/tests/ui/async-await/async-closures/foreign.rs b/tests/ui/async-await/async-closures/foreign.rs
index a244eef4102..b0580a8f09d 100644
--- a/tests/ui/async-await/async-closures/foreign.rs
+++ b/tests/ui/async-await/async-closures/foreign.rs
@@ -3,8 +3,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 use std::future::Future;
 
 extern crate block_on;
diff --git a/tests/ui/async-await/async-closures/higher-ranked-return.rs b/tests/ui/async-await/async-closures/higher-ranked-return.rs
index d6bea5dd103..328c733d42d 100644
--- a/tests/ui/async-await/async-closures/higher-ranked-return.rs
+++ b/tests/ui/async-await/async-closures/higher-ranked-return.rs
@@ -4,8 +4,6 @@
 //@ known-bug: unknown
 // Borrow checking doesn't like that higher-ranked output...
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/higher-ranked-return.stderr b/tests/ui/async-await/async-closures/higher-ranked-return.stderr
index 268631f67cd..23ce3df6616 100644
--- a/tests/ui/async-await/async-closures/higher-ranked-return.stderr
+++ b/tests/ui/async-await/async-closures/higher-ranked-return.stderr
@@ -1,10 +1,10 @@
 error: lifetime may not live long enough
-  --> $DIR/higher-ranked-return.rs:13:46
+  --> $DIR/higher-ranked-return.rs:11:46
    |
 LL |           let x = async move |x: &str| -> &str {
    |  ________________________________-________----_^
    | |                                |        |
-   | |                                |        return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:13:46: 15:10}` contains a lifetime `'2`
+   | |                                |        return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:11:46: 13:10}` contains a lifetime `'2`
    | |                                let's call the lifetime of this reference `'1`
 LL | |             x
 LL | |         };
diff --git a/tests/ui/async-await/async-closures/higher-ranked.rs b/tests/ui/async-await/async-closures/higher-ranked.rs
index 5b34bfce961..28f9df60130 100644
--- a/tests/ui/async-await/async-closures/higher-ranked.rs
+++ b/tests/ui/async-await/async-closures/higher-ranked.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/implements-fnmut.rs b/tests/ui/async-await/async-closures/implements-fnmut.rs
index f49d1423c40..a2e31bb9870 100644
--- a/tests/ui/async-await/async-closures/implements-fnmut.rs
+++ b/tests/ui/async-await/async-closures/implements-fnmut.rs
@@ -7,8 +7,6 @@
 // `should_reborrow_from_env_of_parent_coroutine_closure` for more detail for when we
 // must borrow from the closure env.
 
-#![feature(async_closure)]
-
 fn main() {
     hello(&Ty);
 }
diff --git a/tests/ui/async-await/async-closures/inline-body.rs b/tests/ui/async-await/async-closures/inline-body.rs
index b7d7102c287..3f1b9c26601 100644
--- a/tests/ui/async-await/async-closures/inline-body.rs
+++ b/tests/ui/async-await/async-closures/inline-body.rs
@@ -6,8 +6,6 @@
 // `mir_inliner_callees` for the synthetic by-move coroutine body since
 // its def-id wasn't previously being considered.
 
-#![feature(async_closure)]
-
 use std::future::Future;
 use std::pin::pin;
 use std::task::*;
diff --git a/tests/ui/async-await/async-closures/is-fn.rs b/tests/ui/async-await/async-closures/is-fn.rs
index 89c3a96bbbe..45c2b6ae342 100644
--- a/tests/ui/async-await/async-closures/is-fn.rs
+++ b/tests/ui/async-await/async-closures/is-fn.rs
@@ -5,8 +5,6 @@
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
-#![feature(async_closure)]
-
 use std::future::Future;
 
 extern crate block_on;
diff --git a/tests/ui/async-await/async-closures/is-not-fn.rs b/tests/ui/async-await/async-closures/is-not-fn.rs
index f877513043d..4acaa5d9809 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.rs
+++ b/tests/ui/async-await/async-closures/is-not-fn.rs
@@ -1,9 +1,7 @@
 //@ edition:2021
 
-#![feature(async_closure)]
-
 fn main() {
     fn needs_fn(x: impl FnOnce()) {}
     needs_fn(async || {});
-    //~^ ERROR expected `{async closure@is-not-fn.rs:7:14}` to be a closure that returns `()`
+    //~^ ERROR expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`
 }
diff --git a/tests/ui/async-await/async-closures/is-not-fn.stderr b/tests/ui/async-await/async-closures/is-not-fn.stderr
index 130746ece67..bc1d5e6e9d1 100644
--- a/tests/ui/async-await/async-closures/is-not-fn.stderr
+++ b/tests/ui/async-await/async-closures/is-not-fn.stderr
@@ -1,5 +1,5 @@
-error[E0271]: expected `{async closure@is-not-fn.rs:7:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:7:23: 7:25}`
-  --> $DIR/is-not-fn.rs:7:14
+error[E0271]: expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}`
+  --> $DIR/is-not-fn.rs:5:14
    |
 LL |     needs_fn(async || {});
    |     -------- ^^^^^^^^^^^ expected `()`, found `async` closure body
@@ -7,9 +7,9 @@ LL |     needs_fn(async || {});
    |     required by a bound introduced by this call
    |
    = note:         expected unit type `()`
-           found `async` closure body `{async closure body@$DIR/is-not-fn.rs:7:23: 7:25}`
+           found `async` closure body `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}`
 note: required by a bound in `needs_fn`
-  --> $DIR/is-not-fn.rs:6:25
+  --> $DIR/is-not-fn.rs:4:25
    |
 LL |     fn needs_fn(x: impl FnOnce()) {}
    |                         ^^^^^^^^ required by this bound in `needs_fn`
diff --git a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs
index 3e2ab8321a8..f05d918aef2 100644
--- a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs
+++ b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs
@@ -1,6 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
 #![deny(closure_returning_async_block)]
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr
index 4c0c4d797d8..287dc52c593 100644
--- a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr
+++ b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr
@@ -1,11 +1,11 @@
 error: closure returning async block can be made into an async closure
-  --> $DIR/lint-closure-returning-async-block.rs:7:13
+  --> $DIR/lint-closure-returning-async-block.rs:6:13
    |
 LL |     let x = || async {};
    |             ^^ ----- this async block can be removed, and the closure can be turned into an async closure
    |
 note: the lint level is defined here
-  --> $DIR/lint-closure-returning-async-block.rs:4:9
+  --> $DIR/lint-closure-returning-async-block.rs:3:9
    |
 LL | #![deny(closure_returning_async_block)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL +     let x = async || {};
    |
 
 error: closure returning async block can be made into an async closure
-  --> $DIR/lint-closure-returning-async-block.rs:10:13
+  --> $DIR/lint-closure-returning-async-block.rs:9:13
    |
 LL |     let x = || async move {};
    |             ^^ ---------- this async block can be removed, and the closure can be turned into an async closure
@@ -28,7 +28,7 @@ LL +     let x = async || {};
    |
 
 error: closure returning async block can be made into an async closure
-  --> $DIR/lint-closure-returning-async-block.rs:13:13
+  --> $DIR/lint-closure-returning-async-block.rs:12:13
    |
 LL |     let x = move || async move {};
    |             ^^^^^^^ ---------- this async block can be removed, and the closure can be turned into an async closure
@@ -40,7 +40,7 @@ LL +     let x = async move || {};
    |
 
 error: closure returning async block can be made into an async closure
-  --> $DIR/lint-closure-returning-async-block.rs:16:13
+  --> $DIR/lint-closure-returning-async-block.rs:15:13
    |
 LL |     let x = move || async {};
    |             ^^^^^^^ ----- this async block can be removed, and the closure can be turned into an async closure
@@ -52,7 +52,7 @@ LL +     let x = async move || {};
    |
 
 error: closure returning async block can be made into an async closure
-  --> $DIR/lint-closure-returning-async-block.rs:19:13
+  --> $DIR/lint-closure-returning-async-block.rs:18:13
    |
 LL |     let x = || {{ async {} }};
    |             ^^    ----- this async block can be removed, and the closure can be turned into an async closure
diff --git a/tests/ui/async-await/async-closures/mac-body.rs b/tests/ui/async-await/async-closures/mac-body.rs
index a416227c390..51c077ba03f 100644
--- a/tests/ui/async-await/async-closures/mac-body.rs
+++ b/tests/ui/async-await/async-closures/mac-body.rs
@@ -1,8 +1,6 @@
 //@ edition: 2021
 //@ check-pass
 
-#![feature(async_closure)]
-
 // Make sure we don't ICE if an async closure has a macro body.
 // This happened because we were calling walk instead of visit
 // in the def collector, oops!
diff --git a/tests/ui/async-await/async-closures/mangle.rs b/tests/ui/async-await/async-closures/mangle.rs
index 1790f369c57..c8e5e52e1b2 100644
--- a/tests/ui/async-await/async-closures/mangle.rs
+++ b/tests/ui/async-await/async-closures/mangle.rs
@@ -5,8 +5,6 @@
 //@[v0] compile-flags: -Csymbol-mangling-version=v0
 //@[legacy] compile-flags: -Csymbol-mangling-version=legacy -Zunstable-options
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 use std::future::Future;
diff --git a/tests/ui/async-await/async-closures/moro-example.rs b/tests/ui/async-await/async-closures/moro-example.rs
index c331b8e5b5e..502b3e1bbf8 100644
--- a/tests/ui/async-await/async-closures/moro-example.rs
+++ b/tests/ui/async-await/async-closures/moro-example.rs
@@ -1,8 +1,6 @@
 //@ check-pass
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 use std::future::Future;
 use std::pin::Pin;
 use std::{marker::PhantomData, sync::Mutex};
diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.rs b/tests/ui/async-await/async-closures/move-consuming-capture.rs
index 17925fc89ba..c833bc7e895 100644
--- a/tests/ui/async-await/async-closures/move-consuming-capture.rs
+++ b/tests/ui/async-await/async-closures/move-consuming-capture.rs
@@ -1,8 +1,6 @@
 //@ aux-build:block-on.rs
 //@ edition:2021
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 struct NoCopy;
diff --git a/tests/ui/async-await/async-closures/move-consuming-capture.stderr b/tests/ui/async-await/async-closures/move-consuming-capture.stderr
index 4ce71ec49d6..e28716ca213 100644
--- a/tests/ui/async-await/async-closures/move-consuming-capture.stderr
+++ b/tests/ui/async-await/async-closures/move-consuming-capture.stderr
@@ -1,8 +1,8 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-consuming-capture.rs:17:9
+  --> $DIR/move-consuming-capture.rs:15:9
    |
 LL |         let x = async move || {
-   |             - move occurs because `x` has type `{async closure@$DIR/move-consuming-capture.rs:13:17: 13:30}`, which does not implement the `Copy` trait
+   |             - move occurs because `x` has type `{async closure@$DIR/move-consuming-capture.rs:11:17: 11:30}`, which does not implement the `Copy` trait
 ...
 LL |         x().await;
    |         --- `x` moved due to this method call
diff --git a/tests/ui/async-await/async-closures/move-is-async-fn.rs b/tests/ui/async-await/async-closures/move-is-async-fn.rs
index d0e2bc24b52..2cbad0faffc 100644
--- a/tests/ui/async-await/async-closures/move-is-async-fn.rs
+++ b/tests/ui/async-await/async-closures/move-is-async-fn.rs
@@ -2,7 +2,7 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure, async_fn_traits)]
+#![feature(async_fn_traits)]
 
 extern crate block_on;
 
diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.rs b/tests/ui/async-await/async-closures/move-out-of-ref.rs
index a05447232f6..34389d2d00a 100644
--- a/tests/ui/async-await/async-closures/move-out-of-ref.rs
+++ b/tests/ui/async-await/async-closures/move-out-of-ref.rs
@@ -1,8 +1,6 @@
 //@ compile-flags: -Zvalidate-mir
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 // NOT copy.
 struct Ty;
 
diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.stderr b/tests/ui/async-await/async-closures/move-out-of-ref.stderr
index 294905a481d..8a63515a8a9 100644
--- a/tests/ui/async-await/async-closures/move-out-of-ref.stderr
+++ b/tests/ui/async-await/async-closures/move-out-of-ref.stderr
@@ -1,11 +1,11 @@
 error[E0507]: cannot move out of `*x` which is behind a shared reference
-  --> $DIR/move-out-of-ref.rs:11:9
+  --> $DIR/move-out-of-ref.rs:9:9
    |
 LL |         *x;
    |         ^^ move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait
    |
 note: if `Ty` implemented `Clone`, you could clone the value
-  --> $DIR/move-out-of-ref.rs:7:1
+  --> $DIR/move-out-of-ref.rs:5:1
    |
 LL | struct Ty;
    | ^^^^^^^^^ consider implementing `Clone` for this type
diff --git a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
index c37048398e9..a1a90a1c9ad 100644
--- a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
+++ b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
@@ -5,8 +5,6 @@
 //@[e2018] edition:2018
 //@[e2021] edition:2021
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 async fn call_once(f: impl AsyncFnOnce()) { f().await; }
diff --git a/tests/ui/async-await/async-closures/mutate.rs b/tests/ui/async-await/async-closures/mutate.rs
index 562a7271c66..7c1d8389eac 100644
--- a/tests/ui/async-await/async-closures/mutate.rs
+++ b/tests/ui/async-await/async-closures/mutate.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ run-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/no-borrow-from-env.rs b/tests/ui/async-await/async-closures/no-borrow-from-env.rs
index 36b10c06dca..ce180631389 100644
--- a/tests/ui/async-await/async-closures/no-borrow-from-env.rs
+++ b/tests/ui/async-await/async-closures/no-borrow-from-env.rs
@@ -1,8 +1,6 @@
 //@ edition: 2021
 //@ check-pass
 
-#![feature(async_closure)]
-
 fn outlives<'a>(_: impl Sized + 'a) {}
 
 async fn call_once(f: impl AsyncFnOnce()) {
diff --git a/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs b/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs
index cfb50dd5574..0c22ac97265 100644
--- a/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs
+++ b/tests/ui/async-await/async-closures/non-copy-arg-does-not-force-inner-move.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn wrapper(f: impl Fn(String)) -> impl AsyncFn(String) {
diff --git a/tests/ui/async-await/async-closures/not-clone-closure.rs b/tests/ui/async-await/async-closures/not-clone-closure.rs
index 2776ce4690f..c96c50e85d8 100644
--- a/tests/ui/async-await/async-closures/not-clone-closure.rs
+++ b/tests/ui/async-await/async-closures/not-clone-closure.rs
@@ -1,7 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 struct NotClonableArg;
 #[derive(Default)]
 struct NotClonableReturnType;
diff --git a/tests/ui/async-await/async-closures/not-clone-closure.stderr b/tests/ui/async-await/async-closures/not-clone-closure.stderr
index c2f963f9b92..a08ee45f970 100644
--- a/tests/ui/async-await/async-closures/not-clone-closure.stderr
+++ b/tests/ui/async-await/async-closures/not-clone-closure.stderr
@@ -1,12 +1,12 @@
-error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`
-  --> $DIR/not-clone-closure.rs:32:15
+error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:27:21: 27:34}`
+  --> $DIR/not-clone-closure.rs:30:15
    |
 LL |     not_clone.clone();
    |               ^^^^^ unsatisfied trait bound
    |
-   = help: within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`
+   = help: within `{async closure@$DIR/not-clone-closure.rs:27:21: 27:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`
 note: required because it's used within this closure
-  --> $DIR/not-clone-closure.rs:29:21
+  --> $DIR/not-clone-closure.rs:27:21
    |
 LL |     let not_clone = async move || {
    |                     ^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/async-closures/not-fn.rs b/tests/ui/async-await/async-closures/not-fn.rs
index 5f2d047c3e9..34dd2a22bbb 100644
--- a/tests/ui/async-await/async-closures/not-fn.rs
+++ b/tests/ui/async-await/async-closures/not-fn.rs
@@ -2,8 +2,6 @@
 
 // FIXME(async_closures): This needs a better error message!
 
-#![feature(async_closure)]
-
 fn main() {
     fn needs_fn<T>(_: impl FnMut() -> T) {}
 
diff --git a/tests/ui/async-await/async-closures/not-fn.stderr b/tests/ui/async-await/async-closures/not-fn.stderr
index 9c40613599a..4b9d2db9a25 100644
--- a/tests/ui/async-await/async-closures/not-fn.stderr
+++ b/tests/ui/async-await/async-closures/not-fn.stderr
@@ -1,5 +1,5 @@
 error: async closure does not implement `FnMut` because it captures state from its environment
-  --> $DIR/not-fn.rs:11:14
+  --> $DIR/not-fn.rs:9:14
    |
 LL |     needs_fn(async || {
    |     -------- ^^^^^^^^
@@ -7,7 +7,7 @@ LL |     needs_fn(async || {
    |     required by a bound introduced by this call
    |
 note: required by a bound in `needs_fn`
-  --> $DIR/not-fn.rs:8:28
+  --> $DIR/not-fn.rs:6:28
    |
 LL |     fn needs_fn<T>(_: impl FnMut() -> T) {}
    |                            ^^^^^^^^^^^^ required by this bound in `needs_fn`
diff --git a/tests/ui/async-await/async-closures/not-lending.rs b/tests/ui/async-await/async-closures/not-lending.rs
index 2e5542207cf..7bf2d3ead52 100644
--- a/tests/ui/async-await/async-closures/not-lending.rs
+++ b/tests/ui/async-await/async-closures/not-lending.rs
@@ -1,8 +1,6 @@
 //@ aux-build:block-on.rs
 //@ edition:2021
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 // Make sure that we can't make an async closure that evaluates to a self-borrow.
diff --git a/tests/ui/async-await/async-closures/not-lending.stderr b/tests/ui/async-await/async-closures/not-lending.stderr
index 1713e49b551..f0028129caa 100644
--- a/tests/ui/async-await/async-closures/not-lending.stderr
+++ b/tests/ui/async-await/async-closures/not-lending.stderr
@@ -1,21 +1,21 @@
 error: lifetime may not live long enough
-  --> $DIR/not-lending.rs:14:42
+  --> $DIR/not-lending.rs:12:42
    |
 LL |         let x = async move || -> &String { &s };
    |                 ------------------------ ^^^^^^ returning this value requires that `'1` must outlive `'2`
    |                 |                |
-   |                 |                return type of async closure `{async closure body@$DIR/not-lending.rs:14:42: 14:48}` contains a lifetime `'2`
+   |                 |                return type of async closure `{async closure body@$DIR/not-lending.rs:12:42: 12:48}` contains a lifetime `'2`
    |                 lifetime `'1` represents this closure's body
    |
    = note: closure implements `Fn`, so references to captured variables can't escape the closure
 
 error: lifetime may not live long enough
-  --> $DIR/not-lending.rs:18:31
+  --> $DIR/not-lending.rs:16:31
    |
 LL |         let x = async move || { &s };
    |                 ------------- ^^^^^^ returning this value requires that `'1` must outlive `'2`
    |                 |           |
-   |                 |           return type of async closure `{async closure body@$DIR/not-lending.rs:18:31: 18:37}` contains a lifetime `'2`
+   |                 |           return type of async closure `{async closure body@$DIR/not-lending.rs:16:31: 16:37}` contains a lifetime `'2`
    |                 lifetime `'1` represents this closure's body
    |
    = note: closure implements `Fn`, so references to captured variables can't escape the closure
diff --git a/tests/ui/async-await/async-closures/once.rs b/tests/ui/async-await/async-closures/once.rs
index 7009e0d132f..3cf70e16a12 100644
--- a/tests/ui/async-await/async-closures/once.rs
+++ b/tests/ui/async-await/async-closures/once.rs
@@ -5,8 +5,6 @@
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
-#![feature(async_closure)]
-
 use std::future::Future;
 
 extern crate block_on;
diff --git a/tests/ui/async-await/async-closures/overlapping-projs.rs b/tests/ui/async-await/async-closures/overlapping-projs.rs
index f778534cfe2..c37f24b4ff2 100644
--- a/tests/ui/async-await/async-closures/overlapping-projs.rs
+++ b/tests/ui/async-await/async-closures/overlapping-projs.rs
@@ -3,8 +3,6 @@
 //@ run-pass
 //@ check-run-results
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 async fn call_once(f: impl AsyncFnOnce()) {
diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs
index 7dcbf2595f0..638fb67c3a4 100644
--- a/tests/ui/async-await/async-closures/precise-captures.rs
+++ b/tests/ui/async-await/async-closures/precise-captures.rs
@@ -9,7 +9,6 @@
 // force_once - Force the closure mode to `FnOnce`, so exercising what was fixed
 //   in <https://github.com/rust-lang/rust/pull/123350>.
 
-#![feature(async_closure)]
 #![allow(unused_mut)]
 
 extern crate block_on;
diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
index 2e7cf1b09fd..deae1c9376a 100644
--- a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
+++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
@@ -1,9 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
-use std::ops::AsyncFnMut;
-
 fn produce() -> impl AsyncFnMut() -> &'static str {
     async || ""
 }
diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
index 863e61eb35a..8bbd9fbec3e 100644
--- a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
+++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/pretty-async-fn-opaque.rs:12:18
+  --> $DIR/pretty-async-fn-opaque.rs:8:18
    |
 LL | fn produce() -> impl AsyncFnMut() -> &'static str {
    |                 --------------------------------- the found opaque type
diff --git a/tests/ui/async-await/async-closures/refd.rs b/tests/ui/async-await/async-closures/refd.rs
index 8c16ecb1531..ae8a10a530a 100644
--- a/tests/ui/async-await/async-closures/refd.rs
+++ b/tests/ui/async-await/async-closures/refd.rs
@@ -2,8 +2,6 @@
 //@ edition:2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 struct NoCopy;
diff --git a/tests/ui/async-await/async-closures/return-type-mismatch.rs b/tests/ui/async-await/async-closures/return-type-mismatch.rs
index 992f033180e..d3b4cb61cdf 100644
--- a/tests/ui/async-await/async-closures/return-type-mismatch.rs
+++ b/tests/ui/async-await/async-closures/return-type-mismatch.rs
@@ -1,8 +1,6 @@
 //@ aux-build:block-on.rs
 //@ edition:2021
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/return-type-mismatch.stderr b/tests/ui/async-await/async-closures/return-type-mismatch.stderr
index 53841f62777..d7675aab953 100644
--- a/tests/ui/async-await/async-closures/return-type-mismatch.stderr
+++ b/tests/ui/async-await/async-closures/return-type-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/return-type-mismatch.rs:11:24
+  --> $DIR/return-type-mismatch.rs:9:24
    |
 LL |         let y: usize = x().await;
    |                        ^^^^^^^^^ expected `usize`, found `i32`
diff --git a/tests/ui/async-await/async-closures/sig-from-bare-fn.rs b/tests/ui/async-await/async-closures/sig-from-bare-fn.rs
index a679471a3b3..72aac140256 100644
--- a/tests/ui/async-await/async-closures/sig-from-bare-fn.rs
+++ b/tests/ui/async-await/async-closures/sig-from-bare-fn.rs
@@ -5,8 +5,6 @@
 // a function that requires the async closure implement `Fn*` but does *not* have
 // a `Future` bound on the return type.
 
-#![feature(async_closure)]
-
 use std::future::Future;
 
 trait TryStream {
diff --git a/tests/ui/async-await/async-closures/signature-deduction.rs b/tests/ui/async-await/async-closures/signature-deduction.rs
index 4e9a6747f1f..27ec54ba4f9 100644
--- a/tests/ui/async-await/async-closures/signature-deduction.rs
+++ b/tests/ui/async-await/async-closures/signature-deduction.rs
@@ -1,8 +1,6 @@
 //@ build-pass
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 async fn foo(x: impl AsyncFn(&str) -> &str) {}
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs
index 0e2d1ef1208..f66787bd6fc 100644
--- a/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs
+++ b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs
@@ -4,8 +4,6 @@
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
-#![feature(async_closure)]
-
 use std::future::Future;
 use std::any::Any;
 
diff --git a/tests/ui/async-await/async-closures/tainted-body-2.rs b/tests/ui/async-await/async-closures/tainted-body-2.rs
index 73c6bdc30a0..8314f7e7f96 100644
--- a/tests/ui/async-await/async-closures/tainted-body-2.rs
+++ b/tests/ui/async-await/async-closures/tainted-body-2.rs
@@ -1,7 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 // Ensure that building a by-ref async closure body doesn't ICE when the parent
 // body is tainted.
 
diff --git a/tests/ui/async-await/async-closures/tainted-body-2.stderr b/tests/ui/async-await/async-closures/tainted-body-2.stderr
index 798d47064d9..cffd67b6361 100644
--- a/tests/ui/async-await/async-closures/tainted-body-2.stderr
+++ b/tests/ui/async-await/async-closures/tainted-body-2.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `missing` in this scope
-  --> $DIR/tainted-body-2.rs:9:5
+  --> $DIR/tainted-body-2.rs:7:5
    |
 LL |     missing;
    |     ^^^^^^^ not found in this scope
diff --git a/tests/ui/async-await/async-closures/tainted-body.rs b/tests/ui/async-await/async-closures/tainted-body.rs
index e42d9d6e36a..118c0887469 100644
--- a/tests/ui/async-await/async-closures/tainted-body.rs
+++ b/tests/ui/async-await/async-closures/tainted-body.rs
@@ -1,7 +1,5 @@
 //@ edition:2021
 
-#![feature(async_closure)]
-
 // Don't ICE in ByMove shim builder when MIR body is tainted by writeback errors
 
 fn main() {
diff --git a/tests/ui/async-await/async-closures/tainted-body.stderr b/tests/ui/async-await/async-closures/tainted-body.stderr
index b06a896b81f..617d87e9df2 100644
--- a/tests/ui/async-await/async-closures/tainted-body.stderr
+++ b/tests/ui/async-await/async-closures/tainted-body.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find function `used_fn` in this scope
-  --> $DIR/tainted-body.rs:9:9
+  --> $DIR/tainted-body.rs:7:9
    |
 LL |         used_fn();
    |         ^^^^^^^ not found in this scope
diff --git a/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs b/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs
index 5c718638d80..7d08cdb91e5 100644
--- a/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs
+++ b/tests/ui/async-await/async-closures/truncated-fields-when-imm.rs
@@ -1,8 +1,6 @@
 //@ edition: 2021
 //@ check-pass
 
-#![feature(async_closure)]
-
 pub struct Struct {
     pub path: String,
 }
diff --git a/tests/ui/async-await/async-closures/validate-synthetic-body.rs b/tests/ui/async-await/async-closures/validate-synthetic-body.rs
index 67e683ac08a..3fd7382f7f9 100644
--- a/tests/ui/async-await/async-closures/validate-synthetic-body.rs
+++ b/tests/ui/async-await/async-closures/validate-synthetic-body.rs
@@ -1,8 +1,6 @@
 //@ check-pass
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 // Make sure that we don't hit a query cycle when validating
 // the by-move coroutine body for an async closure.
 
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
index 19f366cc903..19a31d1889b 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
@@ -4,8 +4,6 @@
 // sure that we don't ICE or anything, even if precise closure captures means
 // that we can't actually borrowck successfully.
 
-#![feature(async_closure)]
-
 fn outlives<'a>(_: impl Sized + 'a) {}
 
 async fn call_once(f: impl AsyncFnOnce()) {
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
index a70aece2dea..be39dbf313b 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `x` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:16:13
+  --> $DIR/without-precise-captures-we-are-powerless.rs:14:13
    |
 LL | fn simple<'a>(x: &'a i32) {
    |           -- lifetime `'a` defined here
@@ -13,7 +13,7 @@ LL | }
    |  - `x` dropped here while still borrowed
 
 error[E0597]: `c` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:21:20
+  --> $DIR/without-precise-captures-we-are-powerless.rs:19:20
    |
 LL | fn simple<'a>(x: &'a i32) {
    |           -- lifetime `'a` defined here
@@ -30,7 +30,7 @@ LL | }
    | - `c` dropped here while still borrowed
 
 error[E0597]: `x` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:28:13
+  --> $DIR/without-precise-captures-we-are-powerless.rs:26:13
    |
 LL | fn through_field<'a>(x: S<'a>) {
    |                  -- lifetime `'a` defined here
@@ -44,7 +44,7 @@ LL | }
    |  - `x` dropped here while still borrowed
 
 error[E0505]: cannot move out of `x` because it is borrowed
-  --> $DIR/without-precise-captures-we-are-powerless.rs:32:13
+  --> $DIR/without-precise-captures-we-are-powerless.rs:30:13
    |
 LL | fn through_field<'a>(x: S<'a>) {
    |                  -- lifetime `'a` defined here
@@ -58,7 +58,7 @@ LL |     let c = async move || { println!("{}", *x.0); };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `x` occurs here
 
 error[E0597]: `c` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:33:20
+  --> $DIR/without-precise-captures-we-are-powerless.rs:31:20
    |
 LL | fn through_field<'a>(x: S<'a>) {
    |                  -- lifetime `'a` defined here
@@ -75,7 +75,7 @@ LL | }
    | - `c` dropped here while still borrowed
 
 error[E0505]: cannot move out of `c` because it is borrowed
-  --> $DIR/without-precise-captures-we-are-powerless.rs:34:30
+  --> $DIR/without-precise-captures-we-are-powerless.rs:32:30
    |
 LL | fn through_field<'a>(x: S<'a>) {
    |                  -- lifetime `'a` defined here
@@ -91,7 +91,7 @@ LL |     outlives::<'a>(call_once(c));
    |                              ^ move out of `c` occurs here
 
 error[E0597]: `x` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:38:13
+  --> $DIR/without-precise-captures-we-are-powerless.rs:36:13
    |
 LL | fn through_field_and_ref<'a>(x: &S<'a>) {
    |                          -- lifetime `'a` defined here
@@ -104,7 +104,7 @@ LL | }
    |  - `x` dropped here while still borrowed
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/without-precise-captures-we-are-powerless.rs:40:20
+  --> $DIR/without-precise-captures-we-are-powerless.rs:38:20
    |
 LL | fn through_field_and_ref<'a>(x: &S<'a>) {
    |                                 ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
@@ -113,7 +113,7 @@ LL |     outlives::<'a>(call_once(c));
    |                    ^^^^^^^^^^^^ lifetime `'a` required
 
 error[E0597]: `c` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:45:20
+  --> $DIR/without-precise-captures-we-are-powerless.rs:43:20
    |
 LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
    |                               -- lifetime `'a` defined here
@@ -129,7 +129,7 @@ LL | }
    | - `c` dropped here while still borrowed
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/without-precise-captures-we-are-powerless.rs:46:20
+  --> $DIR/without-precise-captures-we-are-powerless.rs:44:20
    |
 LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
    |                                      ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
index a566b8aa663..2aed6dc6d80 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
@@ -1,7 +1,5 @@
 //@ edition:2021
 
-#![feature(async_closure)]
-
 fn needs_async_fn(_: impl AsyncFn()) {}
 
 fn a() {
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
index d03b10ca2cc..95f314214cc 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
@@ -1,5 +1,5 @@
 error[E0525]: expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce`
-  --> $DIR/wrong-fn-kind.rs:17:20
+  --> $DIR/wrong-fn-kind.rs:15:20
    |
 LL |       needs_async_fn(move || async move {
    |       -------------- -^^^^^^
@@ -14,13 +14,13 @@ LL | |     });
    | |_____- the requirement to implement `AsyncFn` derives from here
    |
 note: required by a bound in `needs_async_fn`
-  --> $DIR/wrong-fn-kind.rs:5:27
+  --> $DIR/wrong-fn-kind.rs:3:27
    |
 LL | fn needs_async_fn(_: impl AsyncFn()) {}
    |                           ^^^^^^^^^ required by this bound in `needs_async_fn`
 
 error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
-  --> $DIR/wrong-fn-kind.rs:9:20
+  --> $DIR/wrong-fn-kind.rs:7:20
    |
 LL | fn needs_async_fn(_: impl AsyncFn()) {}
    |                      -------------- change this to accept `FnMut` instead of `Fn`
diff --git a/tests/ui/async-await/async-drop.rs b/tests/ui/async-await/async-drop.rs
index d3884680e51..b1af81423ce 100644
--- a/tests/ui/async-await/async-drop.rs
+++ b/tests/ui/async-await/async-drop.rs
@@ -5,7 +5,7 @@
 // please consider modifying miri's async drop test at
 // `src/tools/miri/tests/pass/async-drop.rs`.
 
-#![feature(async_drop, impl_trait_in_assoc_type, async_closure)]
+#![feature(async_drop, impl_trait_in_assoc_type)]
 #![allow(incomplete_features, dead_code)]
 
 //@ edition: 2021
diff --git a/tests/ui/async-await/async-fn/auxiliary/block-on.rs b/tests/ui/async-await/async-fn/auxiliary/block-on.rs
index 8b50c5571c1..4ec45ddf333 100644
--- a/tests/ui/async-await/async-fn/auxiliary/block-on.rs
+++ b/tests/ui/async-await/async-fn/auxiliary/block-on.rs
@@ -1,7 +1,5 @@
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 use std::future::Future;
 use std::pin::pin;
 use std::task::*;
diff --git a/tests/ui/async-await/async-fn/dyn-pos.rs b/tests/ui/async-await/async-fn/dyn-pos.rs
index 129ea282936..d71af1bd53e 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.rs
+++ b/tests/ui/async-await/async-fn/dyn-pos.rs
@@ -1,7 +1,5 @@
 //@ edition:2018
 
-#![feature(async_closure)]
-
 fn foo(x: &dyn AsyncFn()) {}
 //~^ ERROR the trait `AsyncFnMut` cannot be made into an object
 
diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr
index aaa8eb2634d..0c901846671 100644
--- a/tests/ui/async-await/async-fn/dyn-pos.stderr
+++ b/tests/ui/async-await/async-fn/dyn-pos.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `AsyncFnMut` cannot be made into an object
-  --> $DIR/dyn-pos.rs:5:16
+  --> $DIR/dyn-pos.rs:3:16
    |
 LL | fn foo(x: &dyn AsyncFn()) {}
    |                ^^^^^^^^^ `AsyncFnMut` cannot be made into an object
diff --git a/tests/ui/async-await/async-fn/edition-2015.rs b/tests/ui/async-await/async-fn/edition-2015.rs
index 7fc62a8dd93..341b9b10e67 100644
--- a/tests/ui/async-await/async-fn/edition-2015.rs
+++ b/tests/ui/async-await/async-fn/edition-2015.rs
@@ -3,7 +3,5 @@ fn foo(x: impl async Fn()) -> impl async Fn() { x }
 //~| ERROR `async` trait bounds are only allowed in Rust 2018 or later
 //~| ERROR `async` trait bounds are unstable
 //~| ERROR `async` trait bounds are unstable
-//~| ERROR use of unstable library feature `async_closure`
-//~| ERROR use of unstable library feature `async_closure`
 
 fn main() {}
diff --git a/tests/ui/async-await/async-fn/edition-2015.stderr b/tests/ui/async-await/async-fn/edition-2015.stderr
index 96fb4c9e979..ca9e64cd1bb 100644
--- a/tests/ui/async-await/async-fn/edition-2015.stderr
+++ b/tests/ui/async-await/async-fn/edition-2015.stderr
@@ -38,26 +38,6 @@ LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: use the desugared name of the async trait, such as `AsyncFn`
 
-error[E0658]: use of unstable library feature `async_closure`
-  --> $DIR/edition-2015.rs:1:42
-   |
-LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
-   |                                          ^^^^
-   |
-   = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
-   = help: add `#![feature(async_closure)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: use of unstable library feature `async_closure`
-  --> $DIR/edition-2015.rs:1:22
-   |
-LL | fn foo(x: impl async Fn()) -> impl async Fn() { x }
-   |                      ^^^^
-   |
-   = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
-   = help: add `#![feature(async_closure)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs
index 5d675921028..ac8e0d7c63e 100644
--- a/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs
+++ b/tests/ui/async-await/async-fn/higher-ranked-async-fn.rs
@@ -5,8 +5,6 @@
 //@[next] compile-flags: -Znext-solver
 //@ build-pass (since it ICEs during mono)
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 use std::future::Future;
diff --git a/tests/ui/async-await/async-fn/impl-trait.rs b/tests/ui/async-await/async-fn/impl-trait.rs
index 11faf9ac983..f284de8981a 100644
--- a/tests/ui/async-await/async-fn/impl-trait.rs
+++ b/tests/ui/async-await/async-fn/impl-trait.rs
@@ -1,7 +1,7 @@
 //@ edition:2018
 //@ check-pass
 
-#![feature(async_closure, type_alias_impl_trait)]
+#![feature(type_alias_impl_trait)]
 
 type Tait = impl AsyncFn();
 fn tait() -> Tait {
diff --git a/tests/ui/async-await/async-fn/project.rs b/tests/ui/async-await/async-fn/project.rs
index b6068a916ae..8ee50724e4c 100644
--- a/tests/ui/async-await/async-fn/project.rs
+++ b/tests/ui/async-await/async-fn/project.rs
@@ -4,7 +4,7 @@
 //@[next] compile-flags: -Znext-solver
 //@ check-pass
 
-#![feature(async_closure, unboxed_closures, async_fn_traits)]
+#![feature(unboxed_closures, async_fn_traits)]
 
 use std::ops::AsyncFn;
 
diff --git a/tests/ui/async-await/async-fn/simple.rs b/tests/ui/async-await/async-fn/simple.rs
index 3f15b08560a..89b68e12435 100644
--- a/tests/ui/async-await/async-fn/simple.rs
+++ b/tests/ui/async-await/async-fn/simple.rs
@@ -2,8 +2,6 @@
 //@ edition: 2021
 //@ build-pass
 
-#![feature(async_closure)]
-
 extern crate block_on;
 
 use std::ops::AsyncFn;
diff --git a/tests/ui/async-await/async-fn/sugar.rs b/tests/ui/async-await/async-fn/sugar.rs
index 0225b666ac5..d00965ee647 100644
--- a/tests/ui/async-await/async-fn/sugar.rs
+++ b/tests/ui/async-await/async-fn/sugar.rs
@@ -1,7 +1,7 @@
 //@ edition: 2021
 //@ check-pass
 
-#![feature(async_closure, async_trait_bounds)]
+#![feature(async_trait_bounds)]
 
 async fn foo() {}
 
diff --git a/tests/ui/async-await/coroutine-desc.rs b/tests/ui/async-await/coroutine-desc.rs
index 9a61c9719db..9a581049107 100644
--- a/tests/ui/async-await/coroutine-desc.rs
+++ b/tests/ui/async-await/coroutine-desc.rs
@@ -1,5 +1,4 @@
 //@ edition:2018
-#![feature(async_closure)]
 use std::future::Future;
 
 async fn one() {}
diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr
index 5434ff3d958..01482a9cb1f 100644
--- a/tests/ui/async-await/coroutine-desc.stderr
+++ b/tests/ui/async-await/coroutine-desc.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/coroutine-desc.rs:10:19
+  --> $DIR/coroutine-desc.rs:9:19
    |
 LL |     fun(async {}, async {});
    |     --- --------  ^^^^^^^^ expected `async` block, found a different `async` block
@@ -8,12 +8,12 @@ LL |     fun(async {}, async {});
    |     |   expected all arguments to be this `async` block type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
-   = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:14}`
-              found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:24}`
+   = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:9:9: 9:14}`
+              found `async` block `{async block@$DIR/coroutine-desc.rs:9:19: 9:24}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
 note: function defined here
-  --> $DIR/coroutine-desc.rs:8:4
+  --> $DIR/coroutine-desc.rs:7:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |    ^^^ -                       -----  ----- this parameter needs to match the `async` block type of `f1`
@@ -22,7 +22,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |        `f1` and `f2` both reference this parameter `F`
 
 error[E0308]: mismatched types
-  --> $DIR/coroutine-desc.rs:12:16
+  --> $DIR/coroutine-desc.rs:11:16
    |
 LL |     fun(one(), two());
    |     --- -----  ^^^^^ expected future, found a different future
@@ -33,7 +33,7 @@ LL |     fun(one(), two());
    = help: consider `await`ing on both `Future`s
    = note: distinct uses of `impl Trait` result in different opaque types
 note: function defined here
-  --> $DIR/coroutine-desc.rs:8:4
+  --> $DIR/coroutine-desc.rs:7:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |    ^^^ -                       -----  ----- this parameter needs to match the future type of `f1`
@@ -42,7 +42,7 @@ LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |        `f1` and `f2` both reference this parameter `F`
 
 error[E0308]: mismatched types
-  --> $DIR/coroutine-desc.rs:14:26
+  --> $DIR/coroutine-desc.rs:13:26
    |
 LL |     fun((async || {})(), (async || {})());
    |     --- ---------------  ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
@@ -51,12 +51,12 @@ LL |     fun((async || {})(), (async || {})());
    |     |   expected all arguments to be this `async` closure body type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
-   = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}`
-              found `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:36: 14:38}`
+   = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:13:19: 13:21}`
+              found `async` closure body `{async closure body@$DIR/coroutine-desc.rs:13:36: 13:38}`
    = note: no two async blocks, even if identical, have the same type
    = help: consider pinning your async block and casting it to a trait object
 note: function defined here
-  --> $DIR/coroutine-desc.rs:8:4
+  --> $DIR/coroutine-desc.rs:7:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
    |    ^^^ -                       -----  ----- this parameter needs to match the `async` closure body type of `f1`
diff --git a/tests/ui/async-await/dyn/auxiliary/block-on.rs b/tests/ui/async-await/dyn/auxiliary/block-on.rs
new file mode 100644
index 00000000000..dcb710fc97c
--- /dev/null
+++ b/tests/ui/async-await/dyn/auxiliary/block-on.rs
@@ -0,0 +1,20 @@
+//@ edition: 2021
+
+#![feature(async_closure, noop_waker)]
+
+use std::future::Future;
+use std::pin::pin;
+use std::task::*;
+
+pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
+    let mut fut = pin!(fut);
+    // Poll loop, just to test the future...
+    let ctx = &mut Context::from_waker(Waker::noop());
+
+    loop {
+        match unsafe { fut.as_mut().poll(ctx) } {
+            Poll::Pending => {}
+            Poll::Ready(t) => break t,
+        }
+    }
+}
diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.rs b/tests/ui/async-await/dyn/mut-is-pointer-like.rs
new file mode 100644
index 00000000000..93e8281164c
--- /dev/null
+++ b/tests/ui/async-await/dyn/mut-is-pointer-like.rs
@@ -0,0 +1,40 @@
+//@ aux-build:block-on.rs
+//@ edition: 2021
+//@ run-pass
+//@ check-run-results
+
+#![allow(refining_impl_trait)]
+#![feature(async_fn_in_dyn_trait)]
+//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete
+
+extern crate block_on;
+
+use std::future::Future;
+use std::pin::Pin;
+
+trait AsyncTrait {
+    type Output;
+
+    async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
+}
+
+impl<F> AsyncTrait for F
+where
+    F: Future,
+{
+    type Output = F::Output;
+
+    fn async_dispatch(self: Pin<&mut Self>) -> Pin<&mut Self> {
+        self
+    }
+}
+
+fn main() {
+    block_on::block_on(async {
+        let f = std::pin::pin!(async {
+            println!("hello, world");
+        });
+        let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f;
+        x.async_dispatch().await;
+    });
+}
diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout b/tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout
new file mode 100644
index 00000000000..4b5fa63702d
--- /dev/null
+++ b/tests/ui/async-await/dyn/mut-is-pointer-like.run.stdout
@@ -0,0 +1 @@
+hello, world
diff --git a/tests/ui/async-await/dyn/mut-is-pointer-like.stderr b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr
new file mode 100644
index 00000000000..7c72ce43cf0
--- /dev/null
+++ b/tests/ui/async-await/dyn/mut-is-pointer-like.stderr
@@ -0,0 +1,11 @@
+warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/mut-is-pointer-like.rs:7:12
+   |
+LL | #![feature(async_fn_in_dyn_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/async-await/dyn/works.rs b/tests/ui/async-await/dyn/works.rs
new file mode 100644
index 00000000000..0732a3ee2f2
--- /dev/null
+++ b/tests/ui/async-await/dyn/works.rs
@@ -0,0 +1,32 @@
+//@ aux-build:block-on.rs
+//@ edition: 2021
+//@ run-pass
+//@ check-run-results
+
+#![allow(refining_impl_trait)]
+#![feature(async_fn_in_dyn_trait)]
+//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete
+
+extern crate block_on;
+
+use std::pin::Pin;
+use std::future::Future;
+
+trait AsyncTrait {
+    async fn async_dispatch(&self);
+}
+
+impl AsyncTrait for &'static str {
+    fn async_dispatch(&self) -> Pin<Box<impl Future<Output = ()>>> {
+        Box::pin(async move {
+            println!("message from the aether: {self}");
+        })
+    }
+}
+
+fn main() {
+    block_on::block_on(async {
+        let x: &dyn AsyncTrait = &"hello, world!";
+        x.async_dispatch().await;
+    });
+}
diff --git a/tests/ui/async-await/dyn/works.run.stdout b/tests/ui/async-await/dyn/works.run.stdout
new file mode 100644
index 00000000000..7b45a504e60
--- /dev/null
+++ b/tests/ui/async-await/dyn/works.run.stdout
@@ -0,0 +1 @@
+message from the aether: hello, world!
diff --git a/tests/ui/async-await/dyn/works.stderr b/tests/ui/async-await/dyn/works.stderr
new file mode 100644
index 00000000000..2c7db7c32f5
--- /dev/null
+++ b/tests/ui/async-await/dyn/works.stderr
@@ -0,0 +1,11 @@
+warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/works.rs:7:12
+   |
+LL | #![feature(async_fn_in_dyn_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/async-await/dyn/wrong-size.rs b/tests/ui/async-await/dyn/wrong-size.rs
new file mode 100644
index 00000000000..ac15dd26067
--- /dev/null
+++ b/tests/ui/async-await/dyn/wrong-size.rs
@@ -0,0 +1,23 @@
+//@ edition: 2021
+
+#![feature(async_fn_in_dyn_trait)]
+//~^ WARN the feature `async_fn_in_dyn_trait` is incomplete
+
+use std::future::Future;
+
+trait AsyncTrait {
+    async fn async_dispatch(&self);
+}
+
+impl AsyncTrait for &'static str {
+    fn async_dispatch(&self) -> impl Future<Output = ()> {
+        async move {
+            // The implementor must box the future...
+        }
+    }
+}
+
+fn main() {
+    let x: &dyn AsyncTrait = &"hello, world!";
+    //~^ ERROR `impl Future<Output = ()>` needs to have the same ABI as a pointer
+}
diff --git a/tests/ui/async-await/dyn/wrong-size.stderr b/tests/ui/async-await/dyn/wrong-size.stderr
new file mode 100644
index 00000000000..0202b5f2409
--- /dev/null
+++ b/tests/ui/async-await/dyn/wrong-size.stderr
@@ -0,0 +1,21 @@
+warning: the feature `async_fn_in_dyn_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/wrong-size.rs:3:12
+   |
+LL | #![feature(async_fn_in_dyn_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: `impl Future<Output = ()>` needs to have the same ABI as a pointer
+  --> $DIR/wrong-size.rs:21:30
+   |
+LL |     let x: &dyn AsyncTrait = &"hello, world!";
+   |                              ^^^^^^^^^^^^^^^^ `impl Future<Output = ()>` needs to be a pointer-like type
+   |
+   = help: the trait `for<'a> PointerLike` is not implemented for `impl Future<Output = ()>`
+   = note: required for the cast from `&&'static str` to `&dyn AsyncTrait`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/feature-async-closure.rs b/tests/ui/async-await/feature-async-closure.rs
deleted file mode 100644
index 15108aa5a33..00000000000
--- a/tests/ui/async-await/feature-async-closure.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ edition:2018
-// gate-test-async_closure
-
-fn f() {
-    let _ = async || {}; //~ ERROR async closures are unstable
-}
-
-fn main() {}
diff --git a/tests/ui/async-await/feature-async-closure.stderr b/tests/ui/async-await/feature-async-closure.stderr
deleted file mode 100644
index 650500b4890..00000000000
--- a/tests/ui/async-await/feature-async-closure.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0658]: async closures are unstable
-  --> $DIR/feature-async-closure.rs:5:13
-   |
-LL |     let _ = async || {};
-   |             ^^^^^
-   |
-   = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
-   = help: add `#![feature(async_closure)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: to use an async block, remove the `||`: `async {`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr
index 7b7b3dbc757..a33c5f7b07d 100644
--- a/tests/ui/async-await/inference_var_self_argument.stderr
+++ b/tests/ui/async-await/inference_var_self_argument.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `&dyn Foo`
 LL |     async fn foo(self: &dyn Foo) {
    |                        ^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/inference_var_self_argument.rs:5:5
diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr
index c95ae1147df..f4db949a5f4 100644
--- a/tests/ui/async-await/issue-66312.stderr
+++ b/tests/ui/async-await/issue-66312.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `T`
 LL |     fn is_some(self: T);
    |                      ^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0308]: mismatched types
   --> $DIR/issue-66312.rs:9:8
diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs b/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs
index 58509642b10..f6c9fdd6d68 100644
--- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs
+++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.rs
@@ -1,5 +1,4 @@
 //@ edition:2018
-#![feature(async_closure)]
 use std::future::Future;
 
 // test the quality of annotations giving lifetimes names (`'1`) when async constructs are involved
diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr
index 9d963686dea..e1f268116fc 100644
--- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr
+++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr
@@ -1,5 +1,5 @@
 error[E0506]: cannot assign to `*x` because it is borrowed
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:8:5
    |
 LL | pub async fn async_fn(x: &mut i32) -> &i32 {
    |                          - let's call the lifetime of this reference `'1`
@@ -11,7 +11,7 @@ LL |     y
    |     - returning this value requires that `*x` is borrowed for `'1`
 
 error[E0506]: cannot assign to `*x` because it is borrowed
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:18:9
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:17:9
    |
 LL |     (async move || {
    |                  - return type of async closure is &'1 i32
@@ -24,12 +24,12 @@ LL |         y
    |         - returning this value requires that `*x` is borrowed for `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:14:20
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:13:20
    |
 LL |       (async move || {
    |  ______-------------_^
    | |      |           |
-   | |      |           return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:14:20: 20:6}` contains a lifetime `'2`
+   | |      |           return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:13:20: 19:6}` contains a lifetime `'2`
    | |      lifetime `'1` represents this closure's body
 LL | |
 LL | |
@@ -42,7 +42,7 @@ LL | |     })()
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:14:5
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:13:5
    |
 LL |    pub fn async_closure(x: &mut i32) -> impl Future<Output=&i32> {
    |                            - let's call the lifetime of this reference `'1`
@@ -60,7 +60,7 @@ LL |    }
    |    - temporary value is freed at the end of this statement
 
 error[E0506]: cannot assign to `*x` because it is borrowed
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:28:9
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:27:9
    |
 LL |     (async move || -> &i32 {
    |                          - return type of async closure is &'1 i32
@@ -73,12 +73,12 @@ LL |         y
    |         - returning this value requires that `*x` is borrowed for `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:24:28
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:23:28
    |
 LL |       (async move || -> &i32 {
    |  ______---------------------_^
    | |      |                |
-   | |      |                return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:24:28: 30:6}` contains a lifetime `'2`
+   | |      |                return type of async closure `{async closure body@$DIR/issue-74072-lifetime-name-annotations.rs:23:28: 29:6}` contains a lifetime `'2`
    | |      lifetime `'1` represents this closure's body
 LL | |
 LL | |
@@ -91,7 +91,7 @@ LL | |     })()
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:24:5
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:23:5
    |
 LL |    pub fn async_closure_explicit_return_type(x: &mut i32) -> impl Future<Output=&i32> {
    |                                                 - let's call the lifetime of this reference `'1`
@@ -109,7 +109,7 @@ LL |    }
    |    - temporary value is freed at the end of this statement
 
 error[E0506]: cannot assign to `*x` because it is borrowed
-  --> $DIR/issue-74072-lifetime-name-annotations.rs:36:9
+  --> $DIR/issue-74072-lifetime-name-annotations.rs:35:9
    |
 LL |     async move {
    |              - return type of async block is &'1 i32
diff --git a/tests/ui/async-await/issues/issue-62009-2.rs b/tests/ui/async-await/issues/issue-62009-2.rs
index f7cba29a747..b660d8a206c 100644
--- a/tests/ui/async-await/issues/issue-62009-2.rs
+++ b/tests/ui/async-await/issues/issue-62009-2.rs
@@ -1,7 +1,5 @@
 //@ edition:2018
 
-#![feature(async_closure)]
-
 async fn print_dur() {}
 
 fn main() {
diff --git a/tests/ui/async-await/issues/issue-62009-2.stderr b/tests/ui/async-await/issues/issue-62009-2.stderr
index 0004f99f901..9377a02612b 100644
--- a/tests/ui/async-await/issues/issue-62009-2.stderr
+++ b/tests/ui/async-await/issues/issue-62009-2.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-2.rs:8:23
+  --> $DIR/issue-62009-2.rs:6:23
    |
 LL | fn main() {
    | --------- this is not `async`
diff --git a/tests/ui/async-await/no-params-non-move-async-closure.rs b/tests/ui/async-await/no-params-non-move-async-closure.rs
index e9e43b3484a..48651396d25 100644
--- a/tests/ui/async-await/no-params-non-move-async-closure.rs
+++ b/tests/ui/async-await/no-params-non-move-async-closure.rs
@@ -1,8 +1,6 @@
 //@ edition:2018
 //@ check-pass
 
-#![feature(async_closure)]
-
 fn main() {
     let _ = async |x: u8| {};
 }
diff --git a/tests/ui/async-await/suggest-missing-await-closure.fixed b/tests/ui/async-await/suggest-missing-await-closure.fixed
index 1ec3456a265..9ab16d34175 100644
--- a/tests/ui/async-await/suggest-missing-await-closure.fixed
+++ b/tests/ui/async-await/suggest-missing-await-closure.fixed
@@ -1,8 +1,6 @@
 //@ edition:2018
 //@ run-rustfix
 
-#![feature(async_closure)]
-
 fn take_u32(_x: u32) {}
 
 async fn make_u32() -> u32 {
diff --git a/tests/ui/async-await/suggest-missing-await-closure.rs b/tests/ui/async-await/suggest-missing-await-closure.rs
index 3a448ad411b..172132fda33 100644
--- a/tests/ui/async-await/suggest-missing-await-closure.rs
+++ b/tests/ui/async-await/suggest-missing-await-closure.rs
@@ -1,8 +1,6 @@
 //@ edition:2018
 //@ run-rustfix
 
-#![feature(async_closure)]
-
 fn take_u32(_x: u32) {}
 
 async fn make_u32() -> u32 {
diff --git a/tests/ui/async-await/suggest-missing-await-closure.stderr b/tests/ui/async-await/suggest-missing-await-closure.stderr
index 47af270a03a..002c2024f21 100644
--- a/tests/ui/async-await/suggest-missing-await-closure.stderr
+++ b/tests/ui/async-await/suggest-missing-await-closure.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await-closure.rs:16:18
+  --> $DIR/suggest-missing-await-closure.rs:14:18
    |
 LL |         take_u32(x)
    |         -------- ^ expected `u32`, found future
@@ -7,12 +7,12 @@ LL |         take_u32(x)
    |         arguments to this function are incorrect
    |
 note: calling an async function returns a future
-  --> $DIR/suggest-missing-await-closure.rs:16:18
+  --> $DIR/suggest-missing-await-closure.rs:14:18
    |
 LL |         take_u32(x)
    |                  ^
 note: function defined here
-  --> $DIR/suggest-missing-await-closure.rs:6:4
+  --> $DIR/suggest-missing-await-closure.rs:4:4
    |
 LL | fn take_u32(_x: u32) {}
    |    ^^^^^^^^ -------
diff --git a/tests/ui/async-await/track-caller/async-closure-gate.rs b/tests/ui/async-await/track-caller/async-closure-gate.rs
index 4b88255bc36..e72ce2afa45 100644
--- a/tests/ui/async-await/track-caller/async-closure-gate.rs
+++ b/tests/ui/async-await/track-caller/async-closure-gate.rs
@@ -1,7 +1,7 @@
 //@ edition:2021
 //@ revisions: afn nofeat
 
-#![feature(async_closure, stmt_expr_attributes)]
+#![feature(stmt_expr_attributes)]
 #![cfg_attr(afn, feature(async_fn_track_caller))]
 
 fn main() {
diff --git a/tests/ui/async-await/track-caller/panic-track-caller.rs b/tests/ui/async-await/track-caller/panic-track-caller.rs
index c693a446eed..bd12bf11d6c 100644
--- a/tests/ui/async-await/track-caller/panic-track-caller.rs
+++ b/tests/ui/async-await/track-caller/panic-track-caller.rs
@@ -3,7 +3,7 @@
 //@ revisions: afn cls nofeat
 //@ needs-unwind
 // gate-test-async_fn_track_caller
-#![feature(async_closure, stmt_expr_attributes)]
+#![feature(stmt_expr_attributes)]
 #![cfg_attr(afn, feature(async_fn_track_caller))]
 #![cfg_attr(cls, feature(closure_track_caller))]
 #![allow(unused)]
diff --git a/tests/ui/async-await/try-on-option-in-async.rs b/tests/ui/async-await/try-on-option-in-async.rs
index fda848141d3..4822197bf39 100644
--- a/tests/ui/async-await/try-on-option-in-async.rs
+++ b/tests/ui/async-await/try-on-option-in-async.rs
@@ -1,4 +1,3 @@
-#![feature(async_closure)]
 //@ edition:2018
 fn main() {}
 
diff --git a/tests/ui/async-await/try-on-option-in-async.stderr b/tests/ui/async-await/try-on-option-in-async.stderr
index 65f63093728..9e0bb42a697 100644
--- a/tests/ui/async-await/try-on-option-in-async.stderr
+++ b/tests/ui/async-await/try-on-option-in-async.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`)
-  --> $DIR/try-on-option-in-async.rs:8:10
+  --> $DIR/try-on-option-in-async.rs:7:10
    |
 LL |     async {
    |     ----- this function should return `Result` or `Option` to accept `?`
@@ -10,7 +10,7 @@ LL |         x?;
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
 
 error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
-  --> $DIR/try-on-option-in-async.rs:17:10
+  --> $DIR/try-on-option-in-async.rs:16:10
    |
 LL |       let async_closure = async || {
    |  __________________________________-
@@ -24,7 +24,7 @@ LL | |     };
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
 
 error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
-  --> $DIR/try-on-option-in-async.rs:26:6
+  --> $DIR/try-on-option-in-async.rs:25:6
    |
 LL |   async fn an_async_function() -> u32 {
    |  _____________________________________-
diff --git a/tests/ui/closures/binder/async-closure-with-binder.rs b/tests/ui/closures/binder/async-closure-with-binder.rs
index 24f4e8e4175..8f84f3074cd 100644
--- a/tests/ui/closures/binder/async-closure-with-binder.rs
+++ b/tests/ui/closures/binder/async-closure-with-binder.rs
@@ -2,7 +2,6 @@
 //@ check-pass
 
 #![feature(closure_lifetime_binder)]
-#![feature(async_closure)]
 
 fn main() {
     for<'a> async || -> () {};
diff --git a/tests/ui/closures/local-type-mix.rs b/tests/ui/closures/local-type-mix.rs
index 823ceb211a3..edcdac2a611 100644
--- a/tests/ui/closures/local-type-mix.rs
+++ b/tests/ui/closures/local-type-mix.rs
@@ -1,8 +1,6 @@
 // Check that using the parameter name in its type does not ICE.
 //@ edition:2018
 
-#![feature(async_closure)]
-
 fn main() {
     let _ = |x: x| x; //~ ERROR expected type
     let _ = |x: bool| -> x { x }; //~ ERROR expected type
diff --git a/tests/ui/closures/local-type-mix.stderr b/tests/ui/closures/local-type-mix.stderr
index 68c320a065d..f3b6a73afd5 100644
--- a/tests/ui/closures/local-type-mix.stderr
+++ b/tests/ui/closures/local-type-mix.stderr
@@ -1,47 +1,47 @@
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:7:17
+  --> $DIR/local-type-mix.rs:5:17
    |
 LL |     let _ = |x: x| x;
    |                 ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:8:26
+  --> $DIR/local-type-mix.rs:6:26
    |
 LL |     let _ = |x: bool| -> x { x };
    |                          ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:9:28
+  --> $DIR/local-type-mix.rs:7:28
    |
 LL |     let _ = async move |x: x| x;
    |                            ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:10:37
+  --> $DIR/local-type-mix.rs:8:37
    |
 LL |     let _ = async move |x: bool| -> x { x };
    |                                     ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:13:11
+  --> $DIR/local-type-mix.rs:11:11
    |
 LL | fn foo(x: x) {}
    |           ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:14:24
+  --> $DIR/local-type-mix.rs:12:24
    |
 LL | fn foo_ret(x: bool) -> x {}
    |                        ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:16:23
+  --> $DIR/local-type-mix.rs:14:23
    |
 LL | async fn async_foo(x: x) {}
    |                       ^ not a type
 
 error[E0573]: expected type, found local variable `x`
-  --> $DIR/local-type-mix.rs:17:36
+  --> $DIR/local-type-mix.rs:15:36
    |
 LL | async fn async_foo_ret(x: bool) -> x {}
    |                                    ^ not a type
diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
index d0597fdd8e1..7d8b1a1156c 100644
--- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
+++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.rs
@@ -1,7 +1,6 @@
 //@ edition: 2024
 
 #![feature(gen_blocks)]
-#![feature(async_closure)]
 
 async fn async_fn() {
     break; //~ ERROR `break` inside `async` function
diff --git a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr
index bdd26d39d82..ee838fbe694 100644
--- a/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr
+++ b/tests/ui/coroutine/break-inside-coroutine-issue-124495.stderr
@@ -1,5 +1,5 @@
 error[E0267]: `break` inside `async` function
-  --> $DIR/break-inside-coroutine-issue-124495.rs:7:5
+  --> $DIR/break-inside-coroutine-issue-124495.rs:6:5
    |
 LL | async fn async_fn() {
    | ------------------- enclosing `async` function
@@ -7,7 +7,7 @@ LL |     break;
    |     ^^^^^ cannot `break` inside `async` function
 
 error[E0267]: `break` inside `gen` function
-  --> $DIR/break-inside-coroutine-issue-124495.rs:11:5
+  --> $DIR/break-inside-coroutine-issue-124495.rs:10:5
    |
 LL | gen fn gen_fn() {
    | --------------- enclosing `gen` function
@@ -15,7 +15,7 @@ LL |     break;
    |     ^^^^^ cannot `break` inside `gen` function
 
 error[E0267]: `break` inside `async gen` function
-  --> $DIR/break-inside-coroutine-issue-124495.rs:15:5
+  --> $DIR/break-inside-coroutine-issue-124495.rs:14:5
    |
 LL | async gen fn async_gen_fn() {
    | --------------------------- enclosing `async gen` function
@@ -23,7 +23,7 @@ LL |     break;
    |     ^^^^^ cannot `break` inside `async gen` function
 
 error[E0267]: `break` inside `async` block
-  --> $DIR/break-inside-coroutine-issue-124495.rs:19:21
+  --> $DIR/break-inside-coroutine-issue-124495.rs:18:21
    |
 LL |     let _ = async { break; };
    |             -----   ^^^^^ cannot `break` inside `async` block
@@ -31,7 +31,7 @@ LL |     let _ = async { break; };
    |             enclosing `async` block
 
 error[E0267]: `break` inside `async` closure
-  --> $DIR/break-inside-coroutine-issue-124495.rs:21:24
+  --> $DIR/break-inside-coroutine-issue-124495.rs:20:24
    |
 LL |     let _ = async || { break; };
    |             --------   ^^^^^ cannot `break` inside `async` closure
@@ -39,7 +39,7 @@ LL |     let _ = async || { break; };
    |             enclosing `async` closure
 
 error[E0267]: `break` inside `gen` block
-  --> $DIR/break-inside-coroutine-issue-124495.rs:23:19
+  --> $DIR/break-inside-coroutine-issue-124495.rs:22:19
    |
 LL |     let _ = gen { break; };
    |             ---   ^^^^^ cannot `break` inside `gen` block
@@ -47,7 +47,7 @@ LL |     let _ = gen { break; };
    |             enclosing `gen` block
 
 error[E0267]: `break` inside `async gen` block
-  --> $DIR/break-inside-coroutine-issue-124495.rs:25:25
+  --> $DIR/break-inside-coroutine-issue-124495.rs:24:25
    |
 LL |     let _ = async gen { break; };
    |             ---------   ^^^^^ cannot `break` inside `async gen` block
diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs
index c346be50856..c3dfcfb19cb 100644
--- a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs
+++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs
@@ -1,8 +1,6 @@
 //@ edition:2018
 //@ aux-build:edition-kw-macro-2015.rs
 
-#![feature(async_closure)]
-
 fn main() {}
 
 #[macro_use]
diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr
index aed5837abea..905e1249d97 100644
--- a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr
+++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:16:13
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:14:13
    |
 LL |     let mut async = 1;
    |             ^^^^^ expected identifier, found keyword
@@ -10,7 +10,7 @@ LL |     let mut r#async = 1;
    |             ++
 
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:28:13
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:26:13
    |
 LL |     module::async();
    |             ^^^^^ expected identifier, found keyword
@@ -21,7 +21,7 @@ LL |     module::r#async();
    |             ++
 
 error: no rules expected `r#async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:20:31
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:18:31
    |
 LL |     r#async = consumes_async!(r#async);
    |                               ^^^^^^^ no rules expected this token in macro call
@@ -33,7 +33,7 @@ LL |     (async) => (1)
    |      ^^^^^
 
 error: no rules expected keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:19:35
    |
 LL |     r#async = consumes_async_raw!(async);
    |                                   ^^^^^ no rules expected this token in macro call
@@ -50,19 +50,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
    |
-  ::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8
+  ::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8
    |
 LL |     if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved
    |        -------------------- in this macro invocation
 
 error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:26:24
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:24:24
    |
 LL |     if passes_tt!(async) == 1 {}
    |                        ^ expected one of `move`, `|`, or `||`
 
 error[E0308]: mismatched types
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:31:33
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
    |
 LL |     let _recovery_witness: () = 0;
    |                            --   ^ expected `()`, found integer
diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs
index b75b68b3feb..1447c49ef71 100644
--- a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs
+++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs
@@ -1,8 +1,6 @@
 //@ edition:2018
 //@ aux-build:edition-kw-macro-2018.rs
 
-#![feature(async_closure)]
-
 fn main() {}
 
 #[macro_use]
diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr
index 6503e9cc73c..af5cc515bb2 100644
--- a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr
+++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:23:13
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:21:13
    |
 LL |     let mut async = 1;
    |             ^^^^^ expected identifier, found keyword
@@ -10,7 +10,7 @@ LL |     let mut r#async = 1;
    |             ++
 
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:39:13
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:37:13
    |
 LL |     module::async();
    |             ^^^^^ expected identifier, found keyword
@@ -21,7 +21,7 @@ LL |     module::r#async();
    |             ++
 
 error: no rules expected `r#async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:27:31
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:25:31
    |
 LL |     r#async = consumes_async!(r#async);
    |                               ^^^^^^^ no rules expected this token in macro call
@@ -33,7 +33,7 @@ LL |     (async) => (1)
    |      ^^^^^
 
 error: no rules expected keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:28:35
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:26:35
    |
 LL |     r#async = consumes_async_raw!(async);
    |                                   ^^^^^ no rules expected this token in macro call
@@ -50,31 +50,31 @@ error: macro expansion ends with an incomplete expression: expected one of `move
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
    |
-  ::: $DIR/edition-keywords-2018-2018-parsing.rs:31:8
+  ::: $DIR/edition-keywords-2018-2018-parsing.rs:29:8
    |
 LL |     if passes_ident!(async) == 1 {} // FIXME: Edition hygiene bug, async here is 2018 and reserved
    |        -------------------- in this macro invocation
 
 error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:33:24
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:31:24
    |
 LL |     if passes_tt!(async) == 1 {}
    |                        ^ expected one of `move`, `|`, or `||`
 
 error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:16:23
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:14:23
    |
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
 
 error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:37:30
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:35:30
    |
 LL |     if local_passes_tt!(async) == 1 {}
    |                              ^ expected one of `move`, `|`, or `||`
 
 error[E0308]: mismatched types
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:42:33
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:40:33
    |
 LL |     let _recovery_witness: () = 0;
    |                            --   ^ expected `()`, found integer
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
index 91d30de74c7..11ec273fc4b 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
@@ -11,6 +11,8 @@ fn main() {
     m();
     q();
     let _ = meow();
+    let _ = fallback_return();
+    let _ = fully_apit();
 }
 
 fn m() {
@@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
     //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
     Ok(())
 }
+
+pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
+    Err(())
+}
+
+pub fn fallback_return() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit::<()>(|| Default::default())?;
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
+
+fn mk<T>() -> Result<T, ()> {
+    Err(())
+}
+
+fn takes_apit2(_x: impl Default) {}
+
+fn fully_apit() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit2(mk::<()>()?);
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index 6fdb548c431..9009d617936 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -1,5 +1,5 @@
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:16:1
+  --> $DIR/never-type-fallback-breaking.rs:18:1
    |
 LL | fn m() {
    | ^^^^^^
@@ -8,7 +8,7 @@ LL | fn m() {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
-  --> $DIR/never-type-fallback-breaking.rs:20:17
+  --> $DIR/never-type-fallback-breaking.rs:22:17
    |
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |     let x: () = match true {
    |          ++++
 
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:28:1
+  --> $DIR/never-type-fallback-breaking.rs:30:1
    |
 LL | fn q() -> Option<()> {
    | ^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
-  --> $DIR/never-type-fallback-breaking.rs:35:5
+  --> $DIR/never-type-fallback-breaking.rs:37:5
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
@@ -38,7 +38,7 @@ LL |     deserialize::<()>()?;
    |                ++++++
 
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:45:1
+  --> $DIR/never-type-fallback-breaking.rs:47:1
    |
 LL | fn meow() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL | fn meow() -> Result<(), ()> {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `(): From<!>` will fail
-  --> $DIR/never-type-fallback-breaking.rs:48:5
+  --> $DIR/never-type-fallback-breaking.rs:50:5
    |
 LL |     help(1)?;
    |     ^^^^^^^
@@ -56,5 +56,43 @@ help: use `()` annotations to avoid fallback changes
 LL |     help::<(), _>(1)?;
    |         +++++++++
 
-warning: 3 warnings emitted
+warning: this function depends on never type fallback being `()`
+  --> $DIR/never-type-fallback-breaking.rs:59:1
+   |
+LL | pub fn fallback_return() -> Result<(), ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: Default` will fail
+  --> $DIR/never-type-fallback-breaking.rs:62:19
+   |
+LL |     takes_apit(|| Default::default())?;
+   |                   ^^^^^^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     takes_apit::<()>(|| Default::default())?;
+   |               ++++++
+
+warning: this function depends on never type fallback being `()`
+  --> $DIR/never-type-fallback-breaking.rs:73:1
+   |
+LL | fn fully_apit() -> Result<(), ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: Default` will fail
+  --> $DIR/never-type-fallback-breaking.rs:76:17
+   |
+LL |     takes_apit2(mk()?);
+   |                 ^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     takes_apit2(mk::<()>()?);
+   |                   ++++++
+
+warning: 5 warnings emitted
 
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
index 9d79dfb4099..2daf00f7804 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `!: Default` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:20:17
+  --> $DIR/never-type-fallback-breaking.rs:22:17
    |
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -8,7 +8,7 @@ LL |         true => Default::default(),
    = help: did you intend to use the type `()` here instead?
 
 error[E0277]: the trait bound `!: Default` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:35:5
+  --> $DIR/never-type-fallback-breaking.rs:37:5
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -16,13 +16,13 @@ LL |     deserialize()?;
    = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
    = help: did you intend to use the type `()` here instead?
 note: required by a bound in `deserialize`
-  --> $DIR/never-type-fallback-breaking.rs:31:23
+  --> $DIR/never-type-fallback-breaking.rs:33:23
    |
 LL |     fn deserialize<T: Default>() -> Option<T> {
    |                       ^^^^^^^ required by this bound in `deserialize`
 
 error[E0277]: the trait bound `(): From<!>` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:48:5
+  --> $DIR/never-type-fallback-breaking.rs:50:5
    |
 LL |     help(1)?;
    |     ^^^^^^^ the trait `From<!>` is not implemented for `()`
@@ -39,11 +39,36 @@ LL |     help(1)?;
            and 4 others
    = note: required for `!` to implement `Into<()>`
 note: required by a bound in `help`
-  --> $DIR/never-type-fallback-breaking.rs:42:20
+  --> $DIR/never-type-fallback-breaking.rs:44:20
    |
 LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
    |                    ^^^^^^^^ required by this bound in `help`
 
-error: aborting due to 3 previous errors
+error[E0277]: the trait bound `!: Default` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:62:19
+   |
+LL |     takes_apit(|| Default::default())?;
+   |                   ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
+   |
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
+   = help: did you intend to use the type `()` here instead?
+
+error[E0277]: the trait bound `!: Default` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:76:17
+   |
+LL |     takes_apit2(mk()?);
+   |     ----------- ^^^^^ the trait `Default` is not implemented for `!`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
+   = help: did you intend to use the type `()` here instead?
+note: required by a bound in `takes_apit2`
+  --> $DIR/never-type-fallback-breaking.rs:71:25
+   |
+LL | fn takes_apit2(_x: impl Default) {}
+   |                         ^^^^^^^ required by this bound in `takes_apit2`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs
index 24e33ff6bf6..daafc526eff 100644
--- a/tests/ui/editions/never-type-fallback-breaking.rs
+++ b/tests/ui/editions/never-type-fallback-breaking.rs
@@ -11,6 +11,8 @@ fn main() {
     m();
     q();
     let _ = meow();
+    let _ = fallback_return();
+    let _ = fully_apit();
 }
 
 fn m() {
@@ -49,3 +51,29 @@ fn meow() -> Result<(), ()> {
     //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
     Ok(())
 }
+
+pub fn takes_apit<T>(_y: impl Fn() -> T) -> Result<T, ()> {
+    Err(())
+}
+
+pub fn fallback_return() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit(|| Default::default())?;
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
+
+fn mk<T>() -> Result<T, ()> {
+    Err(())
+}
+
+fn takes_apit2(_x: impl Default) {}
+
+fn fully_apit() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
+    takes_apit2(mk()?);
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+    Ok(())
+}
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr
index 3bb93cf2ea0..0c5b8a4d3b6 100644
--- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types-pointers.stderr
@@ -7,7 +7,7 @@ LL |     fn foo(self: *const Self) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `*mut Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:12:18
@@ -18,7 +18,7 @@ LL |     fn bar(self: *mut Self) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary-self-types-pointers.rs:2:18
@@ -29,7 +29,7 @@ LL |     fn foo(self: *const Self);
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr
index 7f0e02c91f8..3ffba533d63 100644
--- a/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr
+++ b/tests/ui/feature-gates/feature-gate-arbitrary-self-types.stderr
@@ -7,7 +7,7 @@ LL |     fn foo(self: Ptr<Self>) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `Box<Ptr<Bar>>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
   --> $DIR/feature-gate-arbitrary-self-types.rs:26:18
@@ -18,7 +18,7 @@ LL |     fn bar(self: Box<Ptr<Self>>) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `Ptr<Self>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
   --> $DIR/feature-gate-arbitrary-self-types.rs:16:18
@@ -29,7 +29,7 @@ LL |     fn foo(self: Ptr<Self>);
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr b/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
index 856e0595331..3eb87adb33a 100644
--- a/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
+++ b/tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr
@@ -7,7 +7,7 @@ LL |     fn foo(self: *const Self) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18
@@ -18,7 +18,7 @@ LL |     fn bar(self: *const Self) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
   --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18
@@ -29,7 +29,7 @@ LL |     fn bar(self: *const Self);
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs
new file mode 100644
index 00000000000..d9ff45f57ec
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.rs
@@ -0,0 +1,14 @@
+//@ edition: 2021
+
+trait Foo {
+    async fn bar(&self);
+}
+
+async fn takes_dyn_trait(x: &dyn Foo) {
+    //~^ ERROR the trait `Foo` cannot be made into an object
+    x.bar().await;
+    //~^ ERROR the trait `Foo` cannot be made into an object
+    //~| ERROR the trait `Foo` cannot be made into an object
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr
new file mode 100644
index 00000000000..f78fc422410
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-async-fn-in-dyn-trait.stderr
@@ -0,0 +1,48 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:7:30
+   |
+LL | async fn takes_dyn_trait(x: &dyn Foo) {
+   |                              ^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" 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/feature-gate-async-fn-in-dyn-trait.rs:4:14
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     async fn bar(&self);
+   |              ^^^ ...because method `bar` is `async`
+   = help: consider moving `bar` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:7
+   |
+LL |     x.bar().await;
+   |       ^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" 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/feature-gate-async-fn-in-dyn-trait.rs:4:14
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     async fn bar(&self);
+   |              ^^^ ...because method `bar` is `async`
+   = help: consider moving `bar` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/feature-gate-async-fn-in-dyn-trait.rs:9:5
+   |
+LL |     x.bar().await;
+   |     ^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" 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/feature-gate-async-fn-in-dyn-trait.rs:4:14
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     async fn bar(&self);
+   |              ^^^ ...because method `bar` is `async`
+   = help: consider moving `bar` to another trait
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs
index db5d7aa06d2..210ce60ef11 100644
--- a/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs
+++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.rs
@@ -2,6 +2,5 @@
 
 fn test(_: impl async Fn()) {}
 //~^ ERROR `async` trait bounds are unstable
-//~| ERROR use of unstable library feature `async_closure`
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr
index abc7e37c45f..34727aef975 100644
--- a/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-async-trait-bounds.stderr
@@ -9,16 +9,6 @@ LL | fn test(_: impl async Fn()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: use the desugared name of the async trait, such as `AsyncFn`
 
-error[E0658]: use of unstable library feature `async_closure`
-  --> $DIR/feature-gate-async-trait-bounds.rs:3:23
-   |
-LL | fn test(_: impl async Fn()) {}
-   |                       ^^^^
-   |
-   = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
-   = help: add `#![feature(async_closure)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
index 2150effc3b7..eb9e51a04c3 100644
--- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
+++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Cell<&Self>`
 LL |     fn cell(self: Cell<&Self>);
    |                   ^^^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs b/tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs
new file mode 100644
index 00000000000..80850a2639f
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/sized-rpits-dont-need-pointer-like.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+
+// Make sure that we don't enforce that an RPIT that has `where Self: Sized` is pointer-like.
+
+trait Foo {
+    fn foo() -> impl Sized where Self: Sized {}
+}
+
+impl Foo for () {}
+
+fn main() {
+    let x: &dyn Foo = &();
+}
diff --git a/tests/ui/issues/auxiliary/issue-111011.rs b/tests/ui/issues/auxiliary/issue-111011.rs
index 7130234f41e..0c1a8ce1cf6 100644
--- a/tests/ui/issues/auxiliary/issue-111011.rs
+++ b/tests/ui/issues/auxiliary/issue-111011.rs
@@ -1,5 +1,3 @@
-#![feature(async_closure)]
-
 //@ edition:2021
 
 fn foo<X>(x: impl FnOnce() -> Box<X>) {}
diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/issues/issue-56806.stderr
index ec50d863758..4b0a59fe12d 100644
--- a/tests/ui/issues/issue-56806.stderr
+++ b/tests/ui/issues/issue-56806.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>`
 LL |     fn dyn_instead_of_self(self: Box<dyn Trait>);
    |                                  ^^^^^^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/post-mono-layout-cycle-2.rs b/tests/ui/layout/post-mono-layout-cycle-2.rs
index 2159dee7463..2daac12d7ac 100644
--- a/tests/ui/layout/post-mono-layout-cycle-2.rs
+++ b/tests/ui/layout/post-mono-layout-cycle-2.rs
@@ -1,8 +1,6 @@
 //@ build-fail
 //@ edition: 2021
 
-#![feature(async_closure)]
-
 use std::future::Future;
 use std::pin::pin;
 use std::task::*;
diff --git a/tests/ui/layout/post-mono-layout-cycle-2.stderr b/tests/ui/layout/post-mono-layout-cycle-2.stderr
index 2e8d237844e..d8c51deffe3 100644
--- a/tests/ui/layout/post-mono-layout-cycle-2.stderr
+++ b/tests/ui/layout/post-mono-layout-cycle-2.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in an async fn requires boxing
-  --> $DIR/post-mono-layout-cycle-2.rs:30:5
+  --> $DIR/post-mono-layout-cycle-2.rs:28:5
    |
 LL | /     async fn iter<T>(&mut self, iterator: T)
 LL | |
@@ -13,7 +13,7 @@ LL |           Blah::iter(self, iterator).await
    = note: a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future
 
 note: the above error was encountered while instantiating `fn Wrap::<()>::ice`
-  --> $DIR/post-mono-layout-cycle-2.rs:56:9
+  --> $DIR/post-mono-layout-cycle-2.rs:54:9
    |
 LL |         t.ice();
    |         ^^^^^^^
diff --git a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr
index 3babf63347c..46804642af8 100644
--- a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr
+++ b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr
@@ -7,7 +7,7 @@ LL |     async fn box_ref_Struct(self: Box<Self, impl FnMut(&mut Self)>) -> &u32
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.rs b/tests/ui/lint/unused/lint-unused-mut-variables.rs
index bc38af9867c..0467e87ce22 100644
--- a/tests/ui/lint/unused/lint-unused-mut-variables.rs
+++ b/tests/ui/lint/unused/lint-unused-mut-variables.rs
@@ -3,7 +3,6 @@
 // Exercise the unused_mut attribute in some positive and negative cases
 
 #![warn(unused_mut)]
-#![feature(async_closure)]
 
 async fn baz_async(
     mut a: i32,
diff --git a/tests/ui/lint/unused/lint-unused-mut-variables.stderr b/tests/ui/lint/unused/lint-unused-mut-variables.stderr
index dcda1e5306f..a16b6a378e9 100644
--- a/tests/ui/lint/unused/lint-unused-mut-variables.stderr
+++ b/tests/ui/lint/unused/lint-unused-mut-variables.stderr
@@ -1,5 +1,5 @@
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:9:5
+  --> $DIR/lint-unused-mut-variables.rs:8:5
    |
 LL |     mut a: i32,
    |     ----^
@@ -13,7 +13,7 @@ LL | #![warn(unused_mut)]
    |         ^^^^^^^^^^
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:23:9
+  --> $DIR/lint-unused-mut-variables.rs:22:9
    |
 LL |         mut a: i32,
    |         ----^
@@ -21,7 +21,7 @@ LL |         mut a: i32,
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:14:5
+  --> $DIR/lint-unused-mut-variables.rs:13:5
    |
 LL |     mut a: i32,
    |     ----^
@@ -29,7 +29,7 @@ LL |     mut a: i32,
    |     help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:29:9
+  --> $DIR/lint-unused-mut-variables.rs:28:9
    |
 LL |         mut a: i32,
    |         ----^
@@ -37,7 +37,7 @@ LL |         mut a: i32,
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:39:9
+  --> $DIR/lint-unused-mut-variables.rs:38:9
    |
 LL |         mut a: i32,
    |         ----^
@@ -45,7 +45,7 @@ LL |         mut a: i32,
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:48:9
+  --> $DIR/lint-unused-mut-variables.rs:47:9
    |
 LL |         mut a: i32,
    |         ----^
@@ -53,7 +53,7 @@ LL |         mut a: i32,
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:57:9
+  --> $DIR/lint-unused-mut-variables.rs:56:9
    |
 LL |         mut a: i32,
    |         ----^
@@ -61,7 +61,7 @@ LL |         mut a: i32,
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:62:9
+  --> $DIR/lint-unused-mut-variables.rs:61:9
    |
 LL |         mut a: i32,
    |         ----^
@@ -69,7 +69,7 @@ LL |         mut a: i32,
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:107:14
+  --> $DIR/lint-unused-mut-variables.rs:106:14
    |
 LL |     let x = |mut y: isize| 10;
    |              ----^
@@ -77,7 +77,7 @@ LL |     let x = |mut y: isize| 10;
    |              help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:69:9
+  --> $DIR/lint-unused-mut-variables.rs:68:9
    |
 LL |     let mut a = 3;
    |         ----^
@@ -85,7 +85,7 @@ LL |     let mut a = 3;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:71:9
+  --> $DIR/lint-unused-mut-variables.rs:70:9
    |
 LL |     let mut a = 2;
    |         ----^
@@ -93,7 +93,7 @@ LL |     let mut a = 2;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:73:9
+  --> $DIR/lint-unused-mut-variables.rs:72:9
    |
 LL |     let mut b = 3;
    |         ----^
@@ -101,7 +101,7 @@ LL |     let mut b = 3;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:75:9
+  --> $DIR/lint-unused-mut-variables.rs:74:9
    |
 LL |     let mut a = vec![3];
    |         ----^
@@ -109,7 +109,7 @@ LL |     let mut a = vec![3];
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:77:10
+  --> $DIR/lint-unused-mut-variables.rs:76:10
    |
 LL |     let (mut a, b) = (1, 2);
    |          ----^
@@ -117,7 +117,7 @@ LL |     let (mut a, b) = (1, 2);
    |          help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:79:9
+  --> $DIR/lint-unused-mut-variables.rs:78:9
    |
 LL |     let mut a;
    |         ----^
@@ -125,7 +125,7 @@ LL |     let mut a;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:83:9
+  --> $DIR/lint-unused-mut-variables.rs:82:9
    |
 LL |     let mut b;
    |         ----^
@@ -133,7 +133,7 @@ LL |     let mut b;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:92:9
+  --> $DIR/lint-unused-mut-variables.rs:91:9
    |
 LL |         mut x => {}
    |         ----^
@@ -141,7 +141,7 @@ LL |         mut x => {}
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:99:10
+  --> $DIR/lint-unused-mut-variables.rs:98:10
    |
 LL |         (mut x, 1) |
    |          ----^
@@ -149,7 +149,7 @@ LL |         (mut x, 1) |
    |          help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:112:9
+  --> $DIR/lint-unused-mut-variables.rs:111:9
    |
 LL |     let mut a = &mut 5;
    |         ----^
@@ -157,7 +157,7 @@ LL |     let mut a = &mut 5;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:117:9
+  --> $DIR/lint-unused-mut-variables.rs:116:9
    |
 LL |     let mut b = (&mut a,);
    |         ----^
@@ -165,7 +165,7 @@ LL |     let mut b = (&mut a,);
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:120:9
+  --> $DIR/lint-unused-mut-variables.rs:119:9
    |
 LL |     let mut x = &mut 1;
    |         ----^
@@ -173,7 +173,7 @@ LL |     let mut x = &mut 1;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:132:9
+  --> $DIR/lint-unused-mut-variables.rs:131:9
    |
 LL |     let mut v : &mut Vec<()> = &mut vec![];
    |         ----^
@@ -181,7 +181,7 @@ LL |     let mut v : &mut Vec<()> = &mut vec![];
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:187:9
+  --> $DIR/lint-unused-mut-variables.rs:186:9
    |
 LL |     let mut raw_address_of_const = 1;
    |         ----^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     let mut raw_address_of_const = 1;
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:109:13
+  --> $DIR/lint-unused-mut-variables.rs:108:13
    |
 LL |     fn what(mut foo: isize) {}
    |             ----^^^
@@ -197,7 +197,7 @@ LL |     fn what(mut foo: isize) {}
    |             help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:127:20
+  --> $DIR/lint-unused-mut-variables.rs:126:20
    |
 LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
    |                    ----^^^
@@ -205,7 +205,7 @@ LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
    |                    help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:205:9
+  --> $DIR/lint-unused-mut-variables.rs:204:9
    |
 LL |     let mut b = vec![2];
    |         ----^
@@ -213,13 +213,13 @@ LL |     let mut b = vec![2];
    |         help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/lint-unused-mut-variables.rs:201:8
+  --> $DIR/lint-unused-mut-variables.rs:200:8
    |
 LL | #[deny(unused_mut)]
    |        ^^^^^^^^^^
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:212:28
+  --> $DIR/lint-unused-mut-variables.rs:211:28
    |
 LL | fn write_through_reference(mut arg: &mut Arg) {
    |                            ----^^^
diff --git a/tests/ui/lint/unused/lint-unused-variables.rs b/tests/ui/lint/unused/lint-unused-variables.rs
index 84c26c334f0..e0035d6d725 100644
--- a/tests/ui/lint/unused/lint-unused-variables.rs
+++ b/tests/ui/lint/unused/lint-unused-variables.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: --cfg something
 //@ edition:2018
 
-#![feature(async_closure)]
 #![deny(unused_variables)]
 
 async fn foo_async(
diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr
index ef590d85aef..6106d4cd1bf 100644
--- a/tests/ui/lint/unused/lint-unused-variables.stderr
+++ b/tests/ui/lint/unused/lint-unused-variables.stderr
@@ -1,71 +1,71 @@
 error: unused variable: `a`
-  --> $DIR/lint-unused-variables.rs:8:5
+  --> $DIR/lint-unused-variables.rs:7:5
    |
 LL |     a: i32,
    |     ^ help: if this is intentional, prefix it with an underscore: `_a`
    |
 note: the lint level is defined here
-  --> $DIR/lint-unused-variables.rs:5:9
+  --> $DIR/lint-unused-variables.rs:4:9
    |
 LL | #![deny(unused_variables)]
    |         ^^^^^^^^^^^^^^^^
 
 error: unused variable: `a`
-  --> $DIR/lint-unused-variables.rs:22:9
+  --> $DIR/lint-unused-variables.rs:21:9
    |
 LL |         a: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `a`
-  --> $DIR/lint-unused-variables.rs:68:9
+  --> $DIR/lint-unused-variables.rs:67:9
    |
 LL |         a: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:14:5
+  --> $DIR/lint-unused-variables.rs:13:5
    |
 LL |     b: i32,
    |     ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:29:9
+  --> $DIR/lint-unused-variables.rs:28:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:34:9
+  --> $DIR/lint-unused-variables.rs:33:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:42:9
+  --> $DIR/lint-unused-variables.rs:41:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:47:9
+  --> $DIR/lint-unused-variables.rs:46:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:55:9
+  --> $DIR/lint-unused-variables.rs:54:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:60:9
+  --> $DIR/lint-unused-variables.rs:59:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `b`
-  --> $DIR/lint-unused-variables.rs:74:9
+  --> $DIR/lint-unused-variables.rs:73:9
    |
 LL |         b: i32,
    |         ^ help: if this is intentional, prefix it with an underscore: `_b`
diff --git a/tests/ui/lint/unused/unused-closure.rs b/tests/ui/lint/unused/unused-closure.rs
index 4633038cc9b..1f98cdfb21f 100644
--- a/tests/ui/lint/unused/unused-closure.rs
+++ b/tests/ui/lint/unused/unused-closure.rs
@@ -1,7 +1,6 @@
 // Test that closures and coroutines are "must use" types.
 //@ edition:2018
 
-#![feature(async_closure)]
 #![feature(coroutines, stmt_expr_attributes)]
 #![deny(unused_must_use)]
 
diff --git a/tests/ui/lint/unused/unused-closure.stderr b/tests/ui/lint/unused/unused-closure.stderr
index c3a82402e0a..bc0e5173c33 100644
--- a/tests/ui/lint/unused/unused-closure.stderr
+++ b/tests/ui/lint/unused/unused-closure.stderr
@@ -1,5 +1,5 @@
 error: unused closure that must be used
-  --> $DIR/unused-closure.rs:9:5
+  --> $DIR/unused-closure.rs:8:5
    |
 LL | /     || {
 LL | |         println!("Hello!");
@@ -8,13 +8,13 @@ LL | |     };
    |
    = note: closures are lazy and do nothing unless called
 note: the lint level is defined here
-  --> $DIR/unused-closure.rs:6:9
+  --> $DIR/unused-closure.rs:5:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
 
 error: unused implementer of `Future` that must be used
-  --> $DIR/unused-closure.rs:13:5
+  --> $DIR/unused-closure.rs:12:5
    |
 LL |     async {};
    |     ^^^^^^^^
@@ -22,7 +22,7 @@ LL |     async {};
    = note: futures do nothing unless you `.await` or poll them
 
 error: unused closure that must be used
-  --> $DIR/unused-closure.rs:14:5
+  --> $DIR/unused-closure.rs:13:5
    |
 LL |     || async {};
    |     ^^^^^^^^^^^
@@ -30,7 +30,7 @@ LL |     || async {};
    = note: closures are lazy and do nothing unless called
 
 error: unused closure that must be used
-  --> $DIR/unused-closure.rs:15:5
+  --> $DIR/unused-closure.rs:14:5
    |
 LL |     async || {};
    |     ^^^^^^^^^^^
@@ -38,7 +38,7 @@ LL |     async || {};
    = note: closures are lazy and do nothing unless called
 
 error: unused array of boxed arrays of closures that must be used
-  --> $DIR/unused-closure.rs:18:5
+  --> $DIR/unused-closure.rs:17:5
    |
 LL |     [Box::new([|| {}; 10]); 1];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -46,7 +46,7 @@ LL |     [Box::new([|| {}; 10]); 1];
    = note: closures are lazy and do nothing unless called
 
 error: unused closure that must be used
-  --> $DIR/unused-closure.rs:20:5
+  --> $DIR/unused-closure.rs:19:5
    |
 LL |     vec![|| "a"].pop().unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     vec![|| "a"].pop().unwrap();
    = note: closures are lazy and do nothing unless called
 
 error: unused closure that must be used
-  --> $DIR/unused-closure.rs:23:9
+  --> $DIR/unused-closure.rs:22:9
    |
 LL |         || true;
    |         ^^^^^^^
diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs
index f405cd253de..a560bf4c6ef 100644
--- a/tests/ui/macros/stringify.rs
+++ b/tests/ui/macros/stringify.rs
@@ -3,7 +3,6 @@
 //@ compile-flags: --test
 
 #![allow(incomplete_features)]
-#![feature(async_closure)]
 #![feature(auto_traits)]
 #![feature(box_patterns)]
 #![feature(const_trait_impl)]
diff --git a/tests/ui/methods/call_method_unknown_referent.rs b/tests/ui/methods/call_method_unknown_referent.rs
new file mode 100644
index 00000000000..b01e2d80f7f
--- /dev/null
+++ b/tests/ui/methods/call_method_unknown_referent.rs
@@ -0,0 +1,48 @@
+//@ edition: 2018
+
+#![feature(arbitrary_self_types)]
+
+// tests that the referent type of a reference must be known to call methods on it
+
+struct SmartPtr<T>(T);
+
+impl<T> core::ops::Receiver for SmartPtr<T> {
+    type Target = T;
+}
+
+impl<T> SmartPtr<T> {
+    fn foo(&self) {}
+}
+
+fn main() {
+    let val = 1_u32;
+    let ptr = &val;
+    let _a: i32 = (ptr as &_).read();
+    //~^ ERROR type annotations needed
+
+    // Same again, but with a smart pointer type
+    let val2 = 1_u32;
+    let rc = std::rc::Rc::new(val2);
+    let _b = (rc as std::rc::Rc<_>).read();
+    //~^ ERROR type annotations needed
+
+    // Same again, but with a smart pointer type
+    let ptr = SmartPtr(val);
+
+    // We can call unambiguous outer-type methods on this
+    (ptr as SmartPtr<_>).foo();
+    // ... but we can't follow the Receiver chain to the inner type
+    // because we end up with _.
+
+    // Because SmartPtr implements Receiver, it's arguable which of the
+    // following two diagnostics we'd want in this case:
+    // (a) "type annotations needed" (because the inner type is _)
+    // (b) "no method named `read` found for struct `SmartPtr`"
+    //     (ignoring the fact that there might have been methods on the
+    //      inner type, had it not been _)
+    // At present we produce error type (b), which is necessary because
+    // our resolution logic needs to be able to call methods such as foo()
+    // on the outer type even if the inner type is ambiguous.
+    let _c = (ptr as SmartPtr<_>).read();
+    //~^ ERROR no method named `read` found for struct `SmartPtr`
+}
diff --git a/tests/ui/methods/call_method_unknown_referent.stderr b/tests/ui/methods/call_method_unknown_referent.stderr
new file mode 100644
index 00000000000..748b02b52b5
--- /dev/null
+++ b/tests/ui/methods/call_method_unknown_referent.stderr
@@ -0,0 +1,29 @@
+error[E0282]: type annotations needed
+  --> $DIR/call_method_unknown_referent.rs:20:31
+   |
+LL |     let _a: i32 = (ptr as &_).read();
+   |                               ^^^^ cannot infer type
+
+error[E0282]: type annotations needed
+  --> $DIR/call_method_unknown_referent.rs:26:37
+   |
+LL |     let _b = (rc as std::rc::Rc<_>).read();
+   |                                     ^^^^ cannot infer type
+
+error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope
+  --> $DIR/call_method_unknown_referent.rs:46:35
+   |
+LL | struct SmartPtr<T>(T);
+   | ------------------ method `read` not found for this struct
+...
+LL |     let _c = (ptr as SmartPtr<_>).read();
+   |                                   ^^^^ method not found in `SmartPtr<_>`
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `read`, perhaps you need to implement it:
+           candidate #1: `std::io::Read`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0282, E0599.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/methods/call_method_unknown_referent2.rs b/tests/ui/methods/call_method_unknown_referent2.rs
new file mode 100644
index 00000000000..b1615bd8d44
--- /dev/null
+++ b/tests/ui/methods/call_method_unknown_referent2.rs
@@ -0,0 +1,24 @@
+//@ edition: 2018
+//@ run-pass
+
+#![feature(arbitrary_self_types)]
+
+// tests that the referent type of a reference must be known to call methods on it
+
+struct SmartPtr<T>(T);
+
+impl<T> core::ops::Receiver for SmartPtr<T> {
+    type Target = T;
+}
+
+impl<T> SmartPtr<T> {
+    fn foo(&self) -> usize { 3 }
+}
+
+fn main() {
+    let val = 1_u32;
+    let ptr = SmartPtr(val);
+    // Ensure calls to outer methods work even if inner methods can't be
+    // resolved due to the type variable
+    assert_eq!((ptr as SmartPtr<_>).foo(), 3);
+}
diff --git a/tests/ui/mir/issue-68841.rs b/tests/ui/mir/issue-68841.rs
index 5638449b684..0eed46eb6ca 100644
--- a/tests/ui/mir/issue-68841.rs
+++ b/tests/ui/mir/issue-68841.rs
@@ -2,8 +2,6 @@
 //@ edition:2018
 //@ build-pass
 
-#![feature(async_closure)]
-
 use std::future::Future;
 
 fn async_closure() -> impl Future<Output = u8> {
diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
index b5b5d87e7dd..8d08fb7f2a8 100644
--- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
+++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
@@ -15,8 +15,8 @@ LL |     foo(|| panic!());
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
 help: use `()` annotations to avoid fallback changes
    |
-LL |     foo::<(), _>(|| panic!());
-   |        +++++++++
+LL |     foo::<()>(|| panic!());
+   |        ++++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr
index a336923f4fd..112fdcad336 100644
--- a/tests/ui/parser/bad-name.stderr
+++ b/tests/ui/parser/bad-name.stderr
@@ -1,9 +1,3 @@
-error: field expressions cannot have generic arguments
-  --> $DIR/bad-name.rs:2:12
-   |
-LL |   let x.y::<isize>.z foo;
-   |            ^^^^^^^
-
 error: expected a pattern, found an expression
   --> $DIR/bad-name.rs:2:7
    |
@@ -18,5 +12,11 @@ error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator,
 LL |   let x.y::<isize>.z foo;
    |                      ^^^ expected one of 9 possible tokens
 
+error: field expressions cannot have generic arguments
+  --> $DIR/bad-name.rs:2:12
+   |
+LL |   let x.y::<isize>.z foo;
+   |            ^^^^^^^
+
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs
index e7a5d59958b..15d2a2f5ebc 100644
--- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: --cfg something --check-cfg=cfg(nothing,something)
 //@ edition:2018
 
-#![feature(async_closure)]
 #![deny(unused_variables)]
 
 extern "C" {
diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr
index 9b92166bcb7..ba92bc4a71d 100644
--- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr
+++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr
@@ -1,119 +1,119 @@
 error: unused variable: `a`
-  --> $DIR/param-attrs-cfg.rs:24:23
+  --> $DIR/param-attrs-cfg.rs:23:23
    |
 LL |     #[cfg(something)] a: i32,
    |                       ^ help: if this is intentional, prefix it with an underscore: `_a`
    |
 note: the lint level is defined here
-  --> $DIR/param-attrs-cfg.rs:5:9
+  --> $DIR/param-attrs-cfg.rs:4:9
    |
 LL | #![deny(unused_variables)]
    |         ^^^^^^^^^^^^^^^^
 
 error: unused variable: `a`
-  --> $DIR/param-attrs-cfg.rs:41:27
+  --> $DIR/param-attrs-cfg.rs:40:27
    |
 LL |         #[cfg(something)] a: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `a`
-  --> $DIR/param-attrs-cfg.rs:107:27
+  --> $DIR/param-attrs-cfg.rs:106:27
    |
 LL |         #[cfg(something)] a: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:30:23
+  --> $DIR/param-attrs-cfg.rs:29:23
    |
 LL |     #[cfg(something)] b: i32,
    |                       ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:32:40
+  --> $DIR/param-attrs-cfg.rs:31:40
    |
 LL |     #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                        ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:48:27
+  --> $DIR/param-attrs-cfg.rs:47:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:50:44
+  --> $DIR/param-attrs-cfg.rs:49:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:56:27
+  --> $DIR/param-attrs-cfg.rs:55:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:58:44
+  --> $DIR/param-attrs-cfg.rs:57:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:67:27
+  --> $DIR/param-attrs-cfg.rs:66:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:69:44
+  --> $DIR/param-attrs-cfg.rs:68:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:75:27
+  --> $DIR/param-attrs-cfg.rs:74:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:77:44
+  --> $DIR/param-attrs-cfg.rs:76:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:86:27
+  --> $DIR/param-attrs-cfg.rs:85:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:88:44
+  --> $DIR/param-attrs-cfg.rs:87:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:94:27
+  --> $DIR/param-attrs-cfg.rs:93:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:96:44
+  --> $DIR/param-attrs-cfg.rs:95:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
 
 error: unused variable: `b`
-  --> $DIR/param-attrs-cfg.rs:113:27
+  --> $DIR/param-attrs-cfg.rs:112:27
    |
 LL |         #[cfg(something)] b: i32,
    |                           ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `c`
-  --> $DIR/param-attrs-cfg.rs:115:44
+  --> $DIR/param-attrs-cfg.rs:114:44
    |
 LL |         #[cfg_attr(nothing, cfg(nothing))] c: i32,
    |                                            ^ help: if this is intentional, prefix it with an underscore: `_c`
diff --git a/tests/ui/sanitizer/cfi/async-closures.rs b/tests/ui/sanitizer/cfi/async-closures.rs
index 4eaa44cfa3f..351853ab1a7 100644
--- a/tests/ui/sanitizer/cfi/async-closures.rs
+++ b/tests/ui/sanitizer/cfi/async-closures.rs
@@ -13,7 +13,6 @@
 //@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off
 //@ run-pass
 
-#![feature(async_closure)]
 #![feature(async_fn_traits)]
 
 use std::ops::AsyncFn;
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs
new file mode 100644
index 00000000000..495d261c549
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.rs
@@ -0,0 +1,64 @@
+#![feature(arbitrary_self_types)]
+
+use std::ops::{Receiver, Deref};
+
+struct SmartPtr<'a, T: ?Sized>(&'a T);
+
+impl<'a, T: ?Sized> Deref for SmartPtr<'a, T> {
+    type Target = T;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+
+impl<'a, T: ?Sized> Clone for SmartPtr<'a, T> {
+    fn clone(&self) -> Self {
+        Self(self.0)
+    }
+}
+
+impl<'a, T: ?Sized> Copy for SmartPtr<'a, T> {
+}
+
+struct Foo(u32);
+impl Foo {
+    fn a<R: Receiver<Target=Self>>(self: R) -> u32 {
+        //~^ ERROR invalid generic `self` parameter type: `R`
+        2
+    }
+    fn b<R: Deref<Target=Self>>(self: R) -> u32 {
+        //~^ ERROR invalid generic `self` parameter type: `R`
+        self.0
+    }
+    fn c(self: impl Receiver<Target=Self>) -> u32 {
+        //~^ ERROR invalid generic `self` parameter type: `impl Receiver<Target = Self>`
+        3
+    }
+    fn d(self: impl Deref<Target=Self>) -> u32 {
+        //~^ ERROR invalid generic `self` parameter type: `impl Deref<Target = Self>`
+        self.0
+    }
+}
+
+fn main() {
+    let foo = Foo(1);
+    assert_eq!((&foo).a::<&Foo>(), 2);
+    assert_eq!((&foo).b::<&Foo>(), 1);
+    assert_eq!((&foo).a(), 2);
+    assert_eq!((&foo).b(), 1);
+    assert_eq!((&foo).c(), 3);
+    assert_eq!((&foo).d(), 1);
+    assert_eq!(foo.a::<&Foo>(), 2);
+    //~^ ERROR mismatched types
+    assert_eq!(foo.b::<&Foo>(), 1);
+    //~^ ERROR mismatched types
+    let smart_ptr = SmartPtr(&foo);
+    assert_eq!(smart_ptr.a(), 2);
+    assert_eq!(smart_ptr.b(), 1);
+    assert_eq!(smart_ptr.c(), 3);
+    assert_eq!(smart_ptr.d(), 1);
+    assert_eq!(smart_ptr.a::<&Foo>(), 2);
+    //~^ ERROR mismatched types
+    assert_eq!(smart_ptr.b::<&Foo>(), 1);
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr
new file mode 100644
index 00000000000..9af2a08f371
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-from-method-substs-with-receiver.stderr
@@ -0,0 +1,70 @@
+error[E0801]: invalid generic `self` parameter type: `R`
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:25:42
+   |
+LL |     fn a<R: Receiver<Target=Self>>(self: R) -> u32 {
+   |                                          ^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `R`
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:29:39
+   |
+LL |     fn b<R: Deref<Target=Self>>(self: R) -> u32 {
+   |                                       ^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `impl Receiver<Target = Self>`
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:33:16
+   |
+LL |     fn c(self: impl Receiver<Target=Self>) -> u32 {
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `impl Deref<Target = Self>`
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:37:16
+   |
+LL |     fn d(self: impl Deref<Target=Self>) -> u32 {
+   |                ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0308]: mismatched types
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:51:16
+   |
+LL |     assert_eq!(foo.a::<&Foo>(), 2);
+   |                ^^^ expected `&Foo`, found `Foo`
+
+error[E0308]: mismatched types
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:53:16
+   |
+LL |     assert_eq!(foo.b::<&Foo>(), 1);
+   |                ^^^ expected `&Foo`, found `Foo`
+
+error[E0308]: mismatched types
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:60:16
+   |
+LL |     assert_eq!(smart_ptr.a::<&Foo>(), 2);
+   |                ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>`
+   |
+   = note: expected reference `&Foo`
+                 found struct `SmartPtr<'_, Foo, >`
+
+error[E0308]: mismatched types
+  --> $DIR/arbitrary-self-from-method-substs-with-receiver.rs:62:16
+   |
+LL |     assert_eq!(smart_ptr.b::<&Foo>(), 1);
+   |                ^^^^^^^^^ expected `&Foo`, found `SmartPtr<'_, Foo>`
+   |
+   = note: expected reference `&Foo`
+                 found struct `SmartPtr<'_, Foo, >`
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0308, E0801.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
index 5dc3a0b0234..7cf9c9a3afd 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr
@@ -61,7 +61,7 @@ LL |     fn get6<FR: FindReceiver>(self: FR::Receiver, other: FR) -> u32 {
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature
   --> $DIR/arbitrary-self-from-method-substs.rs:61:18
@@ -72,7 +72,7 @@ LL |     fn get(self: R) {}
    = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
    = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0271]: type mismatch resolving `<Silly as FindReceiver>::Receiver == Foo`
   --> $DIR/arbitrary-self-from-method-substs.rs:92:9
diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr
index c75165d9f8e..0469aca27dc 100644
--- a/tests/ui/self/arbitrary-self-opaque.stderr
+++ b/tests/ui/self/arbitrary-self-opaque.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar`
 LL |     fn foo(self: Bar) {}
    |                  ^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
   --> $DIR/arbitrary-self-opaque.rs:7:8
diff --git a/tests/ui/self/arbitrary_self_types_by_value_reborrow.rs b/tests/ui/self/arbitrary_self_types_by_value_reborrow.rs
new file mode 100644
index 00000000000..de4db1b9afe
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_by_value_reborrow.rs
@@ -0,0 +1,69 @@
+//@ run-pass
+
+#![feature(arbitrary_self_types)]
+#![allow(dead_code)]
+
+// With arbitrary self types v2, we show an error if there are
+// multiple contenders for a method call in an inner and outer type.
+// The goal is to avoid any possibility of confusion by a new
+// 'shadowing' method calling a 'shadowed' method.
+// However, there are niche circumstances where this
+// algorithm doesn't quite work, due to reborrows to get a different
+// lifetime. The test below explicitly tests those circumstances to ensure
+// the behavior is as expected, even if it's not 100% desirable. They're
+// very niche circumstances.
+
+#[derive(Debug, PartialEq)]
+enum Callee {
+    INNER,
+    OUTER
+}
+
+struct MyNonNull<T>(T);
+
+impl<T> std::ops::Receiver for MyNonNull<T> {
+    type Target = T;
+}
+
+struct A;
+impl A {
+    fn foo(self: MyNonNull<A>) -> Callee {
+        Callee::INNER
+    }
+
+    fn bar(self: &MyNonNull<A>) -> Callee {
+        Callee::INNER
+    }
+
+    fn baz(self: &&MyNonNull<A>) -> Callee {
+        // note this is by DOUBLE reference
+        Callee::INNER
+    }
+}
+
+impl<T> MyNonNull<T> {
+    fn foo(&self) -> Callee{
+        Callee::OUTER
+    }
+
+    fn bar(&self) -> Callee{
+        Callee::OUTER
+    }
+
+    fn baz(&self) -> Callee{
+        Callee::OUTER
+    }
+}
+
+fn main() {
+    // The normal deshadowing case. Does not compile.
+    // assert_eq!(MyNonNull(A).foo(), Callee::INNER);
+
+    // Similarly, does not compile.
+    //assert_eq!(MyNonNull(A).bar(), Callee::INNER);
+
+    // The double-reference case.
+    // We call the newly-added outer type method.
+    // Not ideal but very niche so we accept it.
+    assert_eq!(MyNonNull(A).baz(), Callee::OUTER);
+}
diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.rs b/tests/ui/self/arbitrary_self_types_generic_over_receiver.rs
new file mode 100644
index 00000000000..8ccda9368ad
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.rs
@@ -0,0 +1,23 @@
+#![feature(arbitrary_self_types)]
+
+use std::ops::{Receiver, Deref};
+
+struct Foo(u32);
+impl Foo {
+    fn a(self: impl Receiver<Target=Self>) -> u32 {
+        //~^ ERROR invalid generic `self` parameter type: `impl Receiver<Target = Self>`
+        3
+    }
+    fn b(self: impl Deref<Target=Self>) -> u32 {
+        //~^ ERROR invalid generic `self` parameter type: `impl Deref<Target = Self>`
+        self.0
+    }
+}
+
+fn main() {
+    let foo = Foo(1);
+    foo.a();
+    //~^ ERROR the trait bound
+    foo.b();
+    //~^ ERROR the trait bound
+}
diff --git a/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr
new file mode 100644
index 00000000000..2da3925341e
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_generic_over_receiver.stderr
@@ -0,0 +1,59 @@
+error[E0801]: invalid generic `self` parameter type: `impl Receiver<Target = Self>`
+  --> $DIR/arbitrary_self_types_generic_over_receiver.rs:7:16
+   |
+LL |     fn a(self: impl Receiver<Target=Self>) -> u32 {
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `impl Deref<Target = Self>`
+  --> $DIR/arbitrary_self_types_generic_over_receiver.rs:11:16
+   |
+LL |     fn b(self: impl Deref<Target=Self>) -> u32 {
+   |                ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0277]: the trait bound `Foo: std::ops::Receiver` is not satisfied
+  --> $DIR/arbitrary_self_types_generic_over_receiver.rs:19:9
+   |
+LL |     foo.a();
+   |         ^ the trait `std::ops::Receiver` is not implemented for `Foo`
+   |
+   = note: required for `Foo` to implement `std::ops::Receiver`
+note: required by a bound in `Foo::a`
+  --> $DIR/arbitrary_self_types_generic_over_receiver.rs:7:21
+   |
+LL |     fn a(self: impl Receiver<Target=Self>) -> u32 {
+   |                     ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::a`
+help: consider borrowing here
+   |
+LL |     &foo.a();
+   |     +
+LL |     &mut foo.a();
+   |     ++++
+
+error[E0277]: the trait bound `Foo: Deref` is not satisfied
+  --> $DIR/arbitrary_self_types_generic_over_receiver.rs:21:9
+   |
+LL |     foo.b();
+   |         ^ the trait `Deref` is not implemented for `Foo`
+   |
+note: required by a bound in `Foo::b`
+  --> $DIR/arbitrary_self_types_generic_over_receiver.rs:11:21
+   |
+LL |     fn b(self: impl Deref<Target=Self>) -> u32 {
+   |                     ^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::b`
+help: consider borrowing here
+   |
+LL |     &foo.b();
+   |     +
+LL |     &mut foo.b();
+   |     ++++
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0801.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/self/arbitrary_self_types_generic_receiver.rs b/tests/ui/self/arbitrary_self_types_generic_receiver.rs
new file mode 100644
index 00000000000..0739fb778b6
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_generic_receiver.rs
@@ -0,0 +1,50 @@
+#![feature(arbitrary_self_types)]
+
+struct PtrA<T>(T);
+
+impl<T> core::ops::Receiver for PtrA<T> {
+    type Target = T;
+}
+
+struct PtrB<T>(T);
+
+trait SomePtr: core::ops::Receiver<Target=<Self as SomePtr>::SomeTarget> {
+    type SomeTarget;
+}
+
+impl<T> SomePtr for PtrB<T> {
+    type SomeTarget = T;
+}
+
+impl<T> core::ops::Receiver for PtrB<T> {
+    type Target = T;
+}
+
+struct Content;
+
+impl Content {
+    fn a<R: core::ops::Receiver<Target=Self>>(self: &R) {}
+    //~^ ERROR invalid generic
+    fn b<R: core::ops::Receiver<Target=Self>>(self: &mut R) {}
+    //~^ ERROR invalid generic
+    fn c<R: core::ops::Receiver<Target=Self>>(self: R) {}
+    //~^ ERROR invalid generic
+    fn d<R: SomePtr<SomeTarget=Self>>(self: R) {}
+    //~^ ERROR invalid generic
+    fn e(self: impl SomePtr<SomeTarget=Self>) {}
+    //~^ ERROR invalid generic
+}
+
+fn main() {
+    PtrA(Content).a();
+    PtrA(Content).b();
+    PtrA(Content).c();
+    std::rc::Rc::new(Content).a();
+    std::rc::Rc::new(Content).b();
+    std::rc::Rc::new(Content).c();
+    PtrB(Content).a();
+    PtrB(Content).b();
+    PtrB(Content).c();
+    PtrB(Content).d();
+    PtrB(Content).e();
+}
diff --git a/tests/ui/self/arbitrary_self_types_generic_receiver.stderr b/tests/ui/self/arbitrary_self_types_generic_receiver.stderr
new file mode 100644
index 00000000000..788c55ea2f1
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_generic_receiver.stderr
@@ -0,0 +1,48 @@
+error[E0801]: invalid generic `self` parameter type: `&R`
+  --> $DIR/arbitrary_self_types_generic_receiver.rs:26:53
+   |
+LL |     fn a<R: core::ops::Receiver<Target=Self>>(self: &R) {}
+   |                                                     ^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `&mut R`
+  --> $DIR/arbitrary_self_types_generic_receiver.rs:28:53
+   |
+LL |     fn b<R: core::ops::Receiver<Target=Self>>(self: &mut R) {}
+   |                                                     ^^^^^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `R`
+  --> $DIR/arbitrary_self_types_generic_receiver.rs:30:53
+   |
+LL |     fn c<R: core::ops::Receiver<Target=Self>>(self: R) {}
+   |                                                     ^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `R`
+  --> $DIR/arbitrary_self_types_generic_receiver.rs:32:45
+   |
+LL |     fn d<R: SomePtr<SomeTarget=Self>>(self: R) {}
+   |                                             ^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error[E0801]: invalid generic `self` parameter type: `impl SomePtr<SomeTarget = Self>`
+  --> $DIR/arbitrary_self_types_generic_receiver.rs:34:16
+   |
+LL |     fn e(self: impl SomePtr<SomeTarget=Self>) {}
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: type of `self` must not be a method generic parameter type
+   = help: use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0801`.
diff --git a/tests/ui/self/arbitrary_self_types_lifetime_elision.rs b/tests/ui/self/arbitrary_self_types_lifetime_elision.rs
new file mode 100644
index 00000000000..fd645c1013b
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_lifetime_elision.rs
@@ -0,0 +1,27 @@
+//@ run-pass
+
+#![feature(arbitrary_self_types)]
+
+#[derive(Clone)]
+struct SmartPtr<'a, T: ?Sized>(&'a T);
+
+impl<'a, T: ?Sized> std::ops::Receiver for SmartPtr<'a, T> {
+    type Target = T;
+}
+
+#[derive(Clone)]
+struct MyType;
+
+impl MyType {
+    fn m(self: SmartPtr<Self>) {}
+    fn n(self: SmartPtr<'_, Self>) {}
+    fn o<'a>(self: SmartPtr<'a, Self>) {}
+}
+
+fn main() {
+    let a = MyType;
+    let ptr = SmartPtr(&a);
+    ptr.clone().m();
+    ptr.clone().n();
+    ptr.o();
+}
diff --git a/tests/ui/self/arbitrary_self_types_no_generics.rs b/tests/ui/self/arbitrary_self_types_no_generics.rs
new file mode 100644
index 00000000000..8a6f5741882
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_no_generics.rs
@@ -0,0 +1,32 @@
+//@ run-pass
+
+#![feature(arbitrary_self_types)]
+
+pub struct A;
+
+impl A {
+    pub fn f(self: B) -> i32 { 1 }
+}
+
+pub struct B(A);
+
+impl core::ops::Receiver for B {
+    type Target = A;
+}
+
+struct C;
+
+struct D;
+
+impl C {
+    fn weird(self: D) -> i32 { 3 }
+}
+
+impl core::ops::Receiver for D {
+    type Target = C;
+}
+
+fn main() {
+    assert_eq!(B(A).f(), 1);
+    assert_eq!(D.weird(), 3);
+}
diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs
new file mode 100644
index 00000000000..26e48f69d23
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.rs
@@ -0,0 +1,38 @@
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo;
+
+struct CppRef<T>(T);
+
+impl<T> std::ops::Receiver for CppRef<T> {
+    type Target = T;
+}
+
+impl Foo{
+    fn frobnicate_self(self) {}
+    fn frobnicate_ref(&self) {}
+    fn frobnicate_cpp_ref(self: CppRef<Self>) {}
+}
+
+fn main() {
+    let foo_rc = Rc::new(Foo);
+
+    // this compiles fine, and desugars to `Foo::frobnicate_ref(&*foo_rc)`
+    foo_rc.frobnicate_ref();
+
+    let foo_cpp_ref = CppRef(Foo);
+
+    // should not compile because it would desugar to `Foo::frobnicate_ref(&*foo_cpp_ref)`
+    // and you can't deref a CppRef
+    foo_cpp_ref.frobnicate_ref();
+    //~^ ERROR no method named
+
+    foo_cpp_ref.frobnicate_self(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)`
+    //~^ ERROR no method named
+
+    // should compile, because we're not dereffing the CppRef
+    // desugars to `Foo::frobnicate_cpp_ref(foo_cpp_ref)`
+    foo_cpp_ref.frobnicate_cpp_ref();
+}
diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr
new file mode 100644
index 00000000000..4c0ab88493e
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr
@@ -0,0 +1,39 @@
+error[E0599]: no method named `frobnicate_ref` found for struct `CppRef` in the current scope
+  --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:29:17
+   |
+LL | struct CppRef<T>(T);
+   | ---------------- method `frobnicate_ref` not found for this struct
+...
+LL |     foo_cpp_ref.frobnicate_ref();
+   |                 ^^^^^^^^^^^^^^
+   |
+help: one of the expressions' fields has a method of the same name
+   |
+LL |     foo_cpp_ref.0.frobnicate_ref();
+   |                 ++
+help: there is a method `frobnicate_cpp_ref` with a similar name
+   |
+LL |     foo_cpp_ref.frobnicate_cpp_ref();
+   |                 ~~~~~~~~~~~~~~~~~~
+
+error[E0599]: no method named `frobnicate_self` found for struct `CppRef` in the current scope
+  --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:32:17
+   |
+LL | struct CppRef<T>(T);
+   | ---------------- method `frobnicate_self` not found for this struct
+...
+LL |     foo_cpp_ref.frobnicate_self(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)`
+   |                 ^^^^^^^^^^^^^^^
+   |
+help: one of the expressions' fields has a method of the same name
+   |
+LL |     foo_cpp_ref.0.frobnicate_self(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)`
+   |                 ++
+help: there is a method `frobnicate_cpp_ref` with a similar name
+   |
+LL |     foo_cpp_ref.frobnicate_cpp_ref(); // would desugar to `Foo::frobnicate_self(*foo_cpp_ref)`
+   |                 ~~~~~~~~~~~~~~~~~~
+
+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_recursive_receiver.rs b/tests/ui/self/arbitrary_self_types_recursive_receiver.rs
new file mode 100644
index 00000000000..f3e7f96d7c4
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_recursive_receiver.rs
@@ -0,0 +1,32 @@
+//@ run-pass
+#![feature(arbitrary_self_types)]
+
+struct MyNonNull<T>(*const T);
+
+impl<T> std::ops::Receiver for MyNonNull<T> {
+    type Target = T;
+}
+
+#[allow(dead_code)]
+impl<T> MyNonNull<T> {
+    fn foo<U>(&self) -> *const U {
+        self.cast::<U>().bar()
+    }
+    fn cast<U>(&self) -> MyNonNull<U> {
+        MyNonNull(self.0 as *const U)
+    }
+    fn bar(&self) -> *const T {
+        self.0
+    }
+}
+
+#[repr(transparent)]
+struct Foo(usize);
+#[repr(transparent)]
+struct Bar(usize);
+
+fn main() {
+    let a = Foo(3);
+    let ptr = MyNonNull(&a);
+    let _bar_ptr: *const Bar = ptr.foo();
+}
diff --git a/tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs b/tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs
new file mode 100644
index 00000000000..2b718cb0454
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_shadowing_val_constptr.rs
@@ -0,0 +1,33 @@
+//@ run-pass
+
+#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
+
+pub struct A;
+
+impl A {
+    pub fn f(self: *const MyNonNull<Self>) -> i32 { 1 }
+}
+
+pub struct MyNonNull<T>(T);
+
+impl<T> core::ops::Receiver for MyNonNull<T> {
+    type Target = T;
+}
+
+impl<T> MyNonNull<T> {
+    // Imagine this a NEW method in B<T> shadowing an EXISTING
+    // method in A.
+    pub fn f(self: *mut Self) -> i32 {
+        2
+    }
+}
+
+fn main() {
+    let mut b = MyNonNull(A);
+    let b = &mut b;
+    let b = b as *mut MyNonNull<A>;
+    // We actually allow the shadowing in the case of const vs mut raw
+    // pointer receivers.
+    assert_eq!(b.f(), 2);
+}
diff --git a/tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs b/tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs
new file mode 100644
index 00000000000..cebf0ea7cba
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_struct_receiver_trait.rs
@@ -0,0 +1,31 @@
+//@ run-pass
+#![feature(arbitrary_self_types)]
+
+use std::ops::Receiver;
+
+struct SmartPtr<T>(T);
+
+impl<T> Receiver for SmartPtr<T> {
+    type Target = T;
+}
+
+struct Foo {
+    x: i32,
+    y: i32,
+}
+
+impl Foo {
+    fn x(self: &SmartPtr<Self>) -> i32 {
+        self.0.x
+    }
+
+    fn y(self: SmartPtr<Self>) -> i32 {
+        self.0.y
+    }
+}
+
+fn main() {
+    let foo = SmartPtr(Foo {x: 3, y: 4});
+    assert_eq!(3, foo.x());
+    assert_eq!(4, foo.y());
+}
diff --git a/tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs b/tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs
new file mode 100644
index 00000000000..9c0402da0be
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_trait_receiver_trait.rs
@@ -0,0 +1,25 @@
+//@ run-pass
+#![feature(arbitrary_self_types)]
+#![allow(unused_allocation)]
+
+struct SmartPtr<T: ?Sized>(T);
+
+impl<T: ?Sized> std::ops::Receiver for SmartPtr<T> {
+    type Target = T;
+}
+
+trait Trait {
+    fn trait_method<'a>(self: &'a Box<SmartPtr<Self>>) -> &'a [i32];
+}
+
+impl Trait for Vec<i32> {
+    fn trait_method<'a>(self: &'a Box<SmartPtr<Self>>) -> &'a [i32] {
+        &(**self).0
+    }
+}
+
+fn main() {
+    let v = vec![1, 2, 3];
+
+    assert_eq!(&[1, 2, 3], Box::new(SmartPtr(v)).trait_method());
+}
diff --git a/tests/ui/self/arbitrary_self_types_unshadowing.rs b/tests/ui/self/arbitrary_self_types_unshadowing.rs
new file mode 100644
index 00000000000..cd195654cc1
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_unshadowing.rs
@@ -0,0 +1,55 @@
+#![feature(arbitrary_self_types)]
+
+pub struct A;
+
+// The receiver of the potentially shadowed method
+// precisely matches that of the shadower
+impl A {
+    pub fn f(self: Wrapper<Self>) -> i32 { 1 }
+    pub fn g(self: &Wrapper<Self>) -> i32 { 2 }
+    pub fn h(self: &mut Wrapper<Self>) -> i32 { 3 }
+}
+
+// The receiver of the potentially shadowed method is a reference
+pub struct B;
+
+impl B {
+    pub fn f(self: &Wrapper<Self>) -> i32 { 9 }
+}
+
+// The receiver of the potentially shadowed method is a mut reference
+
+pub struct C;
+
+impl C {
+    pub fn f(self: &mut Wrapper<Self>) -> i32 { 10 }
+    pub fn g(self: &mut Wrapper<Self>) -> i32 { 11 }
+}
+
+pub struct Wrapper<T>(T);
+
+impl<T> core::ops::Receiver for Wrapper<T> {
+    type Target = T;
+}
+
+impl<T> Wrapper<T> {
+    pub fn f(self) -> i32 { 5 }
+    pub fn g(&self) -> i32 { 6 }
+    pub fn h(&mut self) -> i32 { 7 }
+}
+
+fn main() {
+    assert_eq!(Wrapper(A).f(), 1);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(A).g(), 2);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(A).h(), 3);
+    //~^ ERROR: multiple applicable items in scope
+    let a = Wrapper(A);
+    assert_eq!(Wrapper(B).f(), 9);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(C).f(), 10);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(C).g(), 11);
+    //~^ ERROR: multiple applicable items in scope
+}
diff --git a/tests/ui/self/arbitrary_self_types_unshadowing.stderr b/tests/ui/self/arbitrary_self_types_unshadowing.stderr
new file mode 100644
index 00000000000..3a126c495c9
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_unshadowing.stderr
@@ -0,0 +1,105 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing.rs:42:27
+   |
+LL |     assert_eq!(Wrapper(A).f(), 1);
+   |                           ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:8:5
+   |
+LL |     pub fn f(self: Wrapper<Self>) -> i32 { 1 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:36:5
+   |
+LL |     pub fn f(self) -> i32 { 5 }
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing.rs:44:27
+   |
+LL |     assert_eq!(Wrapper(A).g(), 2);
+   |                           ^ multiple `g` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:9:5
+   |
+LL |     pub fn g(self: &Wrapper<Self>) -> i32 { 2 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:37:5
+   |
+LL |     pub fn g(&self) -> i32 { 6 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing.rs:46:27
+   |
+LL |     assert_eq!(Wrapper(A).h(), 3);
+   |                           ^ multiple `h` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:10:5
+   |
+LL |     pub fn h(self: &mut Wrapper<Self>) -> i32 { 3 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:38:5
+   |
+LL |     pub fn h(&mut self) -> i32 { 7 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing.rs:49:27
+   |
+LL |     assert_eq!(Wrapper(B).f(), 9);
+   |                           ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl for the type `B`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:17:5
+   |
+LL |     pub fn f(self: &Wrapper<Self>) -> i32 { 9 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:36:5
+   |
+LL |     pub fn f(self) -> i32 { 5 }
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing.rs:51:27
+   |
+LL |     assert_eq!(Wrapper(C).f(), 10);
+   |                           ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl for the type `C`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:25:5
+   |
+LL |     pub fn f(self: &mut Wrapper<Self>) -> i32 { 10 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:36:5
+   |
+LL |     pub fn f(self) -> i32 { 5 }
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing.rs:53:27
+   |
+LL |     assert_eq!(Wrapper(C).g(), 11);
+   |                           ^ multiple `g` found
+   |
+note: candidate #1 is defined in an impl for the type `C`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:26:5
+   |
+LL |     pub fn g(self: &mut Wrapper<Self>) -> i32 { 11 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing.rs:37:5
+   |
+LL |     pub fn g(&self) -> i32 { 6 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs
new file mode 100644
index 00000000000..62553c2622a
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.rs
@@ -0,0 +1,61 @@
+#![feature(arbitrary_self_types_pointers)]
+#![feature(arbitrary_self_types)]
+
+pub struct A;
+
+// The receiver of the potentially shadowed method
+// precisely matches that of the shadower
+impl A {
+    pub fn f(self: Wrapper<Self>) -> i32 { 1 }
+    pub fn g(self: &Wrapper<Self>) -> i32 { 2 }
+    pub fn h(self: &mut Wrapper<Self>) -> i32 { 3 }
+    pub fn i(self: *const Wrapper<Self>) -> i32 { 4 }
+}
+
+// The receiver of the potentially shadowed method is a reference
+pub struct B;
+
+impl B {
+    pub fn f(self: &Wrapper<Self>) -> i32 { 9 }
+}
+
+// The receiver of the potentially shadowed method is a mut reference
+
+pub struct C;
+
+impl C {
+    pub fn f(self: &mut Wrapper<Self>) -> i32 { 10 }
+    pub fn g(self: &mut Wrapper<Self>) -> i32 { 11 }
+}
+
+pub struct Wrapper<T>(T);
+
+impl<T> core::ops::Receiver for Wrapper<T> {
+    type Target = T;
+}
+
+impl<T> Wrapper<T> {
+    pub fn f(self) -> i32 { 5 }
+    pub fn g(&self) -> i32 { 6 }
+    pub fn h(&mut self) -> i32 { 7 }
+    pub fn i(self: *const Self) -> i32 { 8 }
+}
+
+fn main() {
+    assert_eq!(Wrapper(A).f(), 1);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(A).g(), 2);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(A).h(), 3);
+    //~^ ERROR: multiple applicable items in scope
+    let a = Wrapper(A);
+    let a_ptr = &a as *const Wrapper<A>;
+    assert_eq!(a_ptr.i(), 4);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(B).f(), 9);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(C).f(), 10);
+    //~^ ERROR: multiple applicable items in scope
+    assert_eq!(Wrapper(C).g(), 11);
+    //~^ ERROR: multiple applicable items in scope
+}
diff --git a/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr
new file mode 100644
index 00000000000..6d453aed0f0
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_unshadowing_ptrs.stderr
@@ -0,0 +1,122 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:45:27
+   |
+LL |     assert_eq!(Wrapper(A).f(), 1);
+   |                           ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:9:5
+   |
+LL |     pub fn f(self: Wrapper<Self>) -> i32 { 1 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:38:5
+   |
+LL |     pub fn f(self) -> i32 { 5 }
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:47:27
+   |
+LL |     assert_eq!(Wrapper(A).g(), 2);
+   |                           ^ multiple `g` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:10:5
+   |
+LL |     pub fn g(self: &Wrapper<Self>) -> i32 { 2 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:39:5
+   |
+LL |     pub fn g(&self) -> i32 { 6 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:49:27
+   |
+LL |     assert_eq!(Wrapper(A).h(), 3);
+   |                           ^ multiple `h` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:11:5
+   |
+LL |     pub fn h(self: &mut Wrapper<Self>) -> i32 { 3 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:40:5
+   |
+LL |     pub fn h(&mut self) -> i32 { 7 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:53:22
+   |
+LL |     assert_eq!(a_ptr.i(), 4);
+   |                      ^ multiple `i` found
+   |
+note: candidate #1 is defined in an impl for the type `A`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:12:5
+   |
+LL |     pub fn i(self: *const Wrapper<Self>) -> i32 { 4 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:41:5
+   |
+LL |     pub fn i(self: *const Self) -> i32 { 8 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:55:27
+   |
+LL |     assert_eq!(Wrapper(B).f(), 9);
+   |                           ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl for the type `B`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:19:5
+   |
+LL |     pub fn f(self: &Wrapper<Self>) -> i32 { 9 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:38:5
+   |
+LL |     pub fn f(self) -> i32 { 5 }
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:57:27
+   |
+LL |     assert_eq!(Wrapper(C).f(), 10);
+   |                           ^ multiple `f` found
+   |
+note: candidate #1 is defined in an impl for the type `C`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:27:5
+   |
+LL |     pub fn f(self: &mut Wrapper<Self>) -> i32 { 10 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:38:5
+   |
+LL |     pub fn f(self) -> i32 { 5 }
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:59:27
+   |
+LL |     assert_eq!(Wrapper(C).g(), 11);
+   |                           ^ multiple `g` found
+   |
+note: candidate #1 is defined in an impl for the type `C`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:28:5
+   |
+LL |     pub fn g(self: &mut Wrapper<Self>) -> i32 { 11 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<T>`
+  --> $DIR/arbitrary_self_types_unshadowing_ptrs.rs:39:5
+   |
+LL |     pub fn g(&self) -> i32 { 6 }
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/self/conflicting_inner.rs b/tests/ui/self/conflicting_inner.rs
new file mode 100644
index 00000000000..1a7037dce73
--- /dev/null
+++ b/tests/ui/self/conflicting_inner.rs
@@ -0,0 +1,38 @@
+//@ run-pass
+//@ revisions: default feature
+#![cfg_attr(feature, feature(arbitrary_self_types))]
+
+// This test aims to be like the IndexVec within rustc, and conflicts
+// over its into_iter().
+
+#[allow(dead_code)]
+trait Foo {
+    fn foo(self) -> usize;
+}
+
+struct IndexVec<T>(T);
+
+impl<T> std::ops::Deref for IndexVec<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<'a, T> Foo for &'a IndexVec<T> {
+    fn foo(self) -> usize {
+        2
+    }
+}
+
+impl<T> IndexVec<T> {
+    fn foo(self) -> usize {
+        1
+    }
+}
+
+fn main() {
+    let ivec = IndexVec(0usize);
+    assert_eq!(ivec.foo(), 1);
+}
diff --git a/tests/ui/self/conflicting_inner2.rs b/tests/ui/self/conflicting_inner2.rs
new file mode 100644
index 00000000000..e6a6b5ef793
--- /dev/null
+++ b/tests/ui/self/conflicting_inner2.rs
@@ -0,0 +1,63 @@
+//@ run-pass
+//@ revisions: default feature
+#![cfg_attr(feature, feature(arbitrary_self_types))]
+
+use std::pin::Pin;
+use std::ops::DerefMut;
+use std::marker::Unpin;
+
+struct TryChunks;
+
+impl TryChunks {
+    #[allow(dead_code)]
+    fn take(self: std::pin::Pin<&mut Self>) -> usize {
+        1
+    }
+}
+
+#[allow(dead_code)]
+trait Stream {
+    fn poll_next(self: std::pin::Pin<&mut Self>);
+}
+
+#[allow(dead_code)]
+trait StreamExt: Stream {
+    #[allow(dead_code)]
+    fn take(self) -> usize where Self: Sized
+    {
+        2
+    }
+}
+
+impl<T: ?Sized> StreamExt for T where T: Stream {}
+
+impl Stream for TryChunks {
+    fn poll_next(self: std::pin::Pin<&mut Self>) {
+        assert_eq!(self.take(), 1);
+    }
+}
+
+#[allow(dead_code)]
+impl<S: ?Sized + Stream + Unpin> Stream for &mut S {
+    #[allow(dead_code)]
+    fn poll_next(mut self: Pin<&mut Self>)  {
+        S::poll_next(Pin::new(&mut **self))
+    }
+}
+
+#[allow(dead_code)]
+impl<P> Stream for Pin<P>
+where
+    P: DerefMut + Unpin,
+    P::Target: Stream,
+{
+    #[allow(dead_code)]
+    fn poll_next(self: Pin<&mut Self>) {
+        self.get_mut().as_mut().poll_next()
+    }
+}
+
+fn main() {
+    let mut item = Box::pin(TryChunks);
+    item.as_mut().poll_next();
+}
diff --git a/tests/ui/span/issue-27522.stderr b/tests/ui/span/issue-27522.stderr
index c57a100bbe2..04904b0ddc1 100644
--- a/tests/ui/span/issue-27522.stderr
+++ b/tests/ui/span/issue-27522.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `&SomeType`
 LL |     fn handler(self: &SomeType);
    |                      ^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
index 11ed167b44a..8e67f4e7398 100644
--- a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
+++ b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
@@ -1,5 +1,4 @@
 //@ edition:2018
-#![feature(async_closure)]
 use std::future::Future;
 
 async fn foo() {}
diff --git a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index a040e71cf3b..696b156d5a5 100644
--- a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `fn() -> impl Future<Output = ()> {foo}` is not a future
-  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:9
+  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:9
    |
 LL |     bar(foo);
    |     --- ^^^ `fn() -> impl Future<Output = ()> {foo}` is not a future
@@ -8,7 +8,7 @@ LL |     bar(foo);
    |
    = help: the trait `Future` is not implemented for fn item `fn() -> impl Future<Output = ()> {foo}`
 note: required by a bound in `bar`
-  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16
+  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:6:16
    |
 LL | fn bar(f: impl Future<Output=()>) {}
    |                ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
@@ -17,17 +17,17 @@ help: use parentheses to call this function
 LL |     bar(foo());
    |            ++
 
-error[E0277]: `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}` is not a future
-  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:12:9
+error[E0277]: `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:25: 10:33}` is not a future
+  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:9
    |
 LL |     bar(async_closure);
-   |     --- ^^^^^^^^^^^^^ `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}` is not a future
+   |     --- ^^^^^^^^^^^^^ `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:25: 10:33}` is not a future
    |     |
    |     required by a bound introduced by this call
    |
-   = help: the trait `Future` is not implemented for `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}`
+   = help: the trait `Future` is not implemented for `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:10:25: 10:33}`
 note: required by a bound in `bar`
-  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16
+  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:6:16
    |
 LL | fn bar(f: impl Future<Output=()>) {}
    |                ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr
index beafd7c2ab0..eb9f9196a72 100644
--- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr
+++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr
@@ -32,8 +32,8 @@ error[E0307]: invalid `self` parameter type: `()`
 LL |     fn bar(self: ()) {}
    |                  ^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/method-missing-parentheses.rs b/tests/ui/suggestions/method-missing-parentheses.rs
index f10bfb56d2e..bc576b71f0d 100644
--- a/tests/ui/suggestions/method-missing-parentheses.rs
+++ b/tests/ui/suggestions/method-missing-parentheses.rs
@@ -1,5 +1,4 @@
 fn main() {
     let _ = vec![].into_iter().collect::<usize>;
     //~^ ERROR attempted to take value of method `collect` on type `std::vec::IntoIter<_>`
-    //~| ERROR field expressions cannot have generic arguments
 }
diff --git a/tests/ui/suggestions/method-missing-parentheses.stderr b/tests/ui/suggestions/method-missing-parentheses.stderr
index 1bfff56a6a9..f0ff1f0334a 100644
--- a/tests/ui/suggestions/method-missing-parentheses.stderr
+++ b/tests/ui/suggestions/method-missing-parentheses.stderr
@@ -1,9 +1,3 @@
-error: field expressions cannot have generic arguments
-  --> $DIR/method-missing-parentheses.rs:2:41
-   |
-LL |     let _ = vec![].into_iter().collect::<usize>;
-   |                                         ^^^^^^^
-
 error[E0615]: attempted to take value of method `collect` on type `std::vec::IntoIter<_>`
   --> $DIR/method-missing-parentheses.rs:2:32
    |
@@ -15,6 +9,6 @@ help: use parentheses to call the method
 LL |     let _ = vec![].into_iter().collect::<usize>();
    |                                                ++
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0615`.
diff --git a/tests/ui/suggestions/suggest-boxed-empty-block.fixed b/tests/ui/suggestions/suggest-boxed-empty-block.fixed
index 25cb4dc74b1..a43e4405a76 100644
--- a/tests/ui/suggestions/suggest-boxed-empty-block.fixed
+++ b/tests/ui/suggestions/suggest-boxed-empty-block.fixed
@@ -1,5 +1,3 @@
-#![feature(async_closure)]
-
 //@ edition:2021
 //@ run-rustfix
 
diff --git a/tests/ui/suggestions/suggest-boxed-empty-block.rs b/tests/ui/suggestions/suggest-boxed-empty-block.rs
index 9a8d6498fb1..47fb08e4d11 100644
--- a/tests/ui/suggestions/suggest-boxed-empty-block.rs
+++ b/tests/ui/suggestions/suggest-boxed-empty-block.rs
@@ -1,5 +1,3 @@
-#![feature(async_closure)]
-
 //@ edition:2021
 //@ run-rustfix
 
diff --git a/tests/ui/suggestions/suggest-boxed-empty-block.stderr b/tests/ui/suggestions/suggest-boxed-empty-block.stderr
index 474a37b888f..e4602341c1f 100644
--- a/tests/ui/suggestions/suggest-boxed-empty-block.stderr
+++ b/tests/ui/suggestions/suggest-boxed-empty-block.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/suggest-boxed-empty-block.rs:10:9
+  --> $DIR/suggest-boxed-empty-block.rs:8:9
    |
 LL |     foo({});
    |         ^^ expected `Box<_>`, found `()`
@@ -14,7 +14,7 @@ LL +     foo(Box::new(()));
    |
 
 error[E0308]: mismatched types
-  --> $DIR/suggest-boxed-empty-block.rs:11:12
+  --> $DIR/suggest-boxed-empty-block.rs:9:12
    |
 LL |     bar(|| {});
    |            ^^ expected `Box<_>`, found `()`
diff --git a/tests/ui/suggestions/suggest-on-bare-closure-call.rs b/tests/ui/suggestions/suggest-on-bare-closure-call.rs
index 046fe4803ec..1e6b422de5e 100644
--- a/tests/ui/suggestions/suggest-on-bare-closure-call.rs
+++ b/tests/ui/suggestions/suggest-on-bare-closure-call.rs
@@ -1,7 +1,5 @@
 //@ edition:2021
 
-#![feature(async_closure)]
-
 fn main() {
     let _ = ||{}();
     //~^ ERROR expected function, found `()`
diff --git a/tests/ui/suggestions/suggest-on-bare-closure-call.stderr b/tests/ui/suggestions/suggest-on-bare-closure-call.stderr
index e65a6eb4939..7bbb24aa622 100644
--- a/tests/ui/suggestions/suggest-on-bare-closure-call.stderr
+++ b/tests/ui/suggestions/suggest-on-bare-closure-call.stderr
@@ -1,5 +1,5 @@
 error[E0618]: expected function, found `()`
-  --> $DIR/suggest-on-bare-closure-call.rs:6:15
+  --> $DIR/suggest-on-bare-closure-call.rs:4:15
    |
 LL |     let _ = ||{}();
    |               ^^--
@@ -12,7 +12,7 @@ LL |     let _ = (||{})();
    |             +    +
 
 error[E0618]: expected function, found `()`
-  --> $DIR/suggest-on-bare-closure-call.rs:9:21
+  --> $DIR/suggest-on-bare-closure-call.rs:7:21
    |
 LL |     let _ = async ||{}();
    |                     ^^--
diff --git a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs
index aaa61e21155..e606d896e93 100644
--- a/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs
+++ b/tests/ui/traits/const-traits/effects/auxiliary/minicore.rs
@@ -110,6 +110,16 @@ impl<T: ?Sized> LegacyReceiver for &T {}
 
 impl<T: ?Sized> LegacyReceiver for &mut T {}
 
+#[lang = "receiver"]
+pub trait Receiver {
+    #[lang = "receiver_target"]
+    type Target: ?Sized;
+}
+
+impl<T: Deref + ?Sized> Receiver for T {
+    type Target = <T as Deref>::Target;
+}
+
 #[lang = "destruct"]
 #[const_trait]
 pub trait Destruct {}
diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr
index 86234d15a5d..1c58915111f 100644
--- a/tests/ui/traits/issue-78372.stderr
+++ b/tests/ui/traits/issue-78372.stderr
@@ -61,8 +61,8 @@ error[E0307]: invalid `self` parameter type: `Smaht<Self, T>`
 LL |     fn foo(self: Smaht<Self, T>);
    |                  ^^^^^^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
   --> $DIR/issue-78372.rs:3:1
diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr
index 09efd7a9e7e..c6aa0e811f3 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar<u32>`
 LL |     fn bar(self: Bar<u32>) {
    |                  ^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<u32>`
   --> $DIR/method_resolution3.rs:20:18
@@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar<u32>`
 LL |     fn baz(self: &Bar<u32>) {
    |                  ^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr
index 09efd7a9e7e..c6aa0e811f3 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar<u32>`
 LL |     fn bar(self: Bar<u32>) {
    |                  ^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<u32>`
   --> $DIR/method_resolution3.rs:20:18
@@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar<u32>`
 LL |     fn baz(self: &Bar<u32>) {
    |                  ^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
index 8ffdb21f251..e4c4d121733 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar<Foo>`
 LL |     fn foo(self: Bar<Foo>) {
    |                  ^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
   --> $DIR/method_resolution4.rs:31:20
@@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
 LL |     fn foomp(self: &Bar<Foo>) {
    |                    ^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
index 8ffdb21f251..e4c4d121733 100644
--- a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
+++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
@@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar<Foo>`
 LL |     fn foo(self: Bar<Foo>) {
    |                  ^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
   --> $DIR/method_resolution4.rs:31:20
@@ -13,8 +13,8 @@ error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
 LL |     fn foomp(self: &Bar<Foo>) {
    |                    ^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
index 2a8c4edbdb5..36bdc714e05 100644
--- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -22,8 +22,8 @@ error[E0307]: invalid `self` parameter type: `isize`
 LL |     fn foo(self: isize, x: isize) -> isize {
    |                  ^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `Bar<isize>`
   --> $DIR/ufcs-explicit-self-bad.rs:19:18
@@ -31,8 +31,8 @@ error[E0307]: invalid `self` parameter type: `Bar<isize>`
 LL |     fn foo(self: Bar<isize>, x: isize) -> isize {
    |                  ^^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0307]: invalid `self` parameter type: `&Bar<usize>`
   --> $DIR/ufcs-explicit-self-bad.rs:23:18
@@ -40,8 +40,8 @@ error[E0307]: invalid `self` parameter type: `&Bar<usize>`
 LL |     fn bar(self: &Bar<usize>, x: isize) -> isize {
    |                  ^^^^^^^^^^^
    |
-   = note: type of `self` must be `Self` or a type that dereferences to it
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+   = note: type of `self` must be `Self` or some type implementing `Receiver`
+   = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
 
 error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
diff --git a/tests/ui/unpretty/expanded-exhaustive.rs b/tests/ui/unpretty/expanded-exhaustive.rs
index 9af57fe4c3c..98fe05cf7c8 100644
--- a/tests/ui/unpretty/expanded-exhaustive.rs
+++ b/tests/ui/unpretty/expanded-exhaustive.rs
@@ -2,7 +2,6 @@
 //@ edition:2024
 //@ check-pass
 
-#![feature(async_closure)]
 #![feature(auto_traits)]
 #![feature(box_patterns)]
 #![feature(builtin_syntax)]
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index 14a274415ca..452c06dd7e4 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -3,7 +3,6 @@
 //@ edition:2024
 //@ check-pass
 
-#![feature(async_closure)]
 #![feature(auto_traits)]
 #![feature(box_patterns)]
 #![feature(builtin_syntax)]
diff --git a/triagebot.toml b/triagebot.toml
index 18bbbad234e..214fc2a21c4 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -991,13 +991,21 @@ https://github.com/rust-lang/reference/blob/HEAD/src/identifiers.md.
 cc = ["@ehuss"]
 
 [assign]
-warn_non_default_branch = true
+warn_non_default_branch.enable = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
     "jyn514",
     "celinval",
 ]
 
+[[assign.warn_non_default_branch.exceptions]]
+title = "[beta"
+branch = "beta"
+
+[[assign.warn_non_default_branch.exceptions]]
+title = "[stable"
+branch = "stable"
+
 [assign.adhoc_groups]
 compiler = [
     "@BoxyUwU",